Skip to content

Commit df52dc8

Browse files
adamnaraieffigies
authored andcommitted
Adding mat 7.3 support for SPM.mat files in the spm interface
1 parent e03ab6f commit df52dc8

File tree

2 files changed

+56
-7
lines changed

2 files changed

+56
-7
lines changed

nipype/interfaces/spm/model.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
# Local imports
1414
from ... import logging
15-
from ...utils.filemanip import ensure_list, simplify_list, split_filename
15+
from ...utils.filemanip import ensure_list, simplify_list, split_filename, load_spm_mat
1616
from ..base import (
1717
Bunch,
1818
traits,
@@ -313,12 +313,10 @@ def _parse_inputs(self):
313313
return einputs
314314

315315
def _list_outputs(self):
316-
import scipy.io as sio
317-
318316
outputs = self._outputs().get()
319317
pth = os.path.dirname(self.inputs.spm_mat_file)
320318
outtype = "nii" if "12" in self.version.split(".")[0] else "img"
321-
spm = sio.loadmat(self.inputs.spm_mat_file, struct_as_record=False)
319+
spm = load_spm_mat(self.inputs.spm_mat_file, struct_as_record=False)
322320

323321
betas = [vbeta.fname[0] for vbeta in spm["SPM"][0, 0].Vbeta[0]]
324322
if (
@@ -503,6 +501,10 @@ def _make_matlab_command(self, _):
503501
load(jobs{1}.stats{1}.con.spmmat{:});
504502
SPM.swd = '%s';
505503
save(jobs{1}.stats{1}.con.spmmat{:},'SPM');
504+
[msg,id] = lastwarn('');
505+
if strcmp(id,'MATLAB:save:sizeTooBigForMATFile')
506+
save(jobs{1}.stats{1}.con.spmmat{:},'SPM','-v7.3');
507+
end
506508
names = SPM.xX.name;"""
507509
% (self.inputs.spm_mat_file, os.getcwd())
508510
]
@@ -581,11 +583,9 @@ def _make_matlab_command(self, _):
581583
return "\n".join(script)
582584

583585
def _list_outputs(self):
584-
import scipy.io as sio
585-
586586
outputs = self._outputs().get()
587587
pth, _ = os.path.split(self.inputs.spm_mat_file)
588-
spm = sio.loadmat(self.inputs.spm_mat_file, struct_as_record=False)
588+
spm = load_spm_mat(self.inputs.spm_mat_file, struct_as_record=False)
589589
con_images = []
590590
spmT_images = []
591591
for con in spm["SPM"][0, 0].xCon[0]:

nipype/utils/filemanip.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from pathlib import Path
2020
import simplejson as json
2121
from time import sleep, time
22+
import scipy.io as sio
2223

2324
from .. import logging, config, __version__ as version
2425
from .misc import is_container
@@ -932,3 +933,51 @@ def indirectory(path):
932933
yield
933934
finally:
934935
os.chdir(cwd)
936+
937+
def load_spm_mat(spm_mat_file, **kwargs):
938+
try:
939+
mat = sio.loadmat(spm_mat_file, **kwargs)
940+
except NotImplementedError:
941+
import h5py
942+
import numpy as np
943+
mat = dict(SPM=np.array([[sio.matlab.mat_struct()]]))
944+
945+
# Get Vbeta, Vcon, and Vspm file names
946+
with h5py.File(spm_mat_file, "r") as h5file:
947+
fnames = dict()
948+
try:
949+
fnames["Vbeta"] = [u"".join(chr(c[0]) for c in h5file[obj_ref[0]]) for obj_ref in h5file["SPM"]["Vbeta"]["fname"]]
950+
except Exception:
951+
fnames["Vbeta"] = []
952+
for contr_type in ["Vcon", "Vspm"]:
953+
try:
954+
fnames[contr_type] = [u"".join(chr(c[0]) for c in h5file[obj_ref[0]]["fname"]) for obj_ref in h5file["SPM"]["xCon"][contr_type]]
955+
except Exception:
956+
fnames[contr_type] = []
957+
958+
# Structure Vbeta as returned by scipy.io.loadmat
959+
obj_list = []
960+
for i in range(len(fnames["Vbeta"])):
961+
obj = sio.matlab.mat_struct()
962+
setattr(obj, "fname", np.array([fnames["Vbeta"][i]]))
963+
obj_list.append(obj)
964+
if len(obj_list) > 0:
965+
setattr(mat["SPM"][0, 0], "Vbeta", np.array([obj_list]))
966+
else:
967+
setattr(mat["SPM"][0, 0], "Vbeta", np.empty((0, 0), dtype=object))
968+
969+
# Structure Vcon and Vspm as returned by scipy.io.loadmat
970+
obj_list = []
971+
for i in range(len(fnames["Vcon"])):
972+
obj = sio.matlab.mat_struct()
973+
for contr_type in ["Vcon", "Vspm"]:
974+
temp = sio.matlab.mat_struct()
975+
setattr(temp, "fname", np.array([fnames[contr_type][i]]))
976+
setattr(obj, contr_type, np.array([[temp]]))
977+
obj_list.append(obj)
978+
if len(obj_list) > 0:
979+
setattr(mat["SPM"][0, 0], "xCon", np.array([obj_list]))
980+
else:
981+
setattr(mat["SPM"][0, 0], "xCon", np.empty((0, 0), dtype=object))
982+
983+
return mat

0 commit comments

Comments
 (0)