Skip to content

Commit 5df9ce8

Browse files
author
Fabio Bernardoni
committed
merged my changes from 2019 into the new version of nipype
1 parent 8c2330d commit 5df9ce8

File tree

1 file changed

+110
-8
lines changed

1 file changed

+110
-8
lines changed

nipype/interfaces/spm/preprocess.py

Lines changed: 110 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,14 @@ class FieldMapInputSpec(SPMCommandInputSpec):
4646
desc="one of: calculatevdm, applyvdm",
4747
)
4848
phase_file = File(
49-
mandatory=True,
49+
#mandatory=True,
5050
exists=True,
5151
copyfile=False,
5252
field="subj.data.presubphasemag.phase",
5353
desc="presubstracted phase file",
5454
)
5555
magnitude_file = File(
56-
mandatory=True,
56+
#mandatory=True,
5757
exists=True,
5858
copyfile=False,
5959
field="subj.data.presubphasemag.magnitude",
@@ -62,7 +62,7 @@ class FieldMapInputSpec(SPMCommandInputSpec):
6262
echo_times = traits.Tuple(
6363
traits.Float,
6464
traits.Float,
65-
mandatory=True,
65+
#mandatory=True,
6666
field="subj.defaults.defaultsval.et",
6767
desc="short and long echo times",
6868
)
@@ -169,7 +169,7 @@ class FieldMapInputSpec(SPMCommandInputSpec):
169169
epi_file = File(
170170
copyfile=False,
171171
exists=True,
172-
mandatory=True,
172+
#mandatory=True,
173173
field="subj.session.epi",
174174
desc="EPI to unwarp",
175175
)
@@ -195,10 +195,61 @@ class FieldMapInputSpec(SPMCommandInputSpec):
195195
desc="match anatomical image to EPI",
196196
)
197197

198+
in_files = InputMultiObject(
199+
traits.Either(ImageFileSPM(exists=True),
200+
traits.List(ImageFileSPM(exists=True))),
201+
field='data.scans',mandatory=True,
202+
copyfile=True,
203+
desc='list of filenames to apply the vdm to')
204+
vdmfile = File(
205+
field='data.vdmfile',
206+
desc='Voxel displacement map to use',mandatory=True,
207+
copyfile=True)
208+
distortion_direction = traits.Int(
209+
2, field='roptions.pedir', desc='phase encode direction input data have been acquired with',
210+
usedefault=True)
211+
write_which = traits.ListInt(
212+
[2, 1],
213+
field='roptions.which',
214+
minlen=2,
215+
maxlen=2,
216+
usedefault=True,
217+
desc='determines which images to apply vdm to')
218+
interpolation = traits.Int(
219+
4, field='roptions.rinterp', desc='phase encode direction input data have been acquired with',
220+
usedefault=True)
221+
reslice_interp = traits.Range(
222+
low=0,
223+
high=7,
224+
field='roptions.rinterp',
225+
desc='degree of b-spline used for interpolation')
226+
write_wrap = traits.List(
227+
traits.Int(),
228+
minlen=3,
229+
maxlen=3,
230+
field='roptions.wrap',
231+
desc=('Check if interpolation should wrap in [x,y,z]'))
232+
write_mask = traits.Bool(
233+
field='roptions.mask', desc='True/False mask time series images')
234+
out_prefix = traits.String(
235+
'u',
236+
field='roptions.prefix',
237+
usedefault=True,
238+
desc='fieldmap corrected output prefix')
239+
198240

199241
class FieldMapOutputSpec(TraitedSpec):
200242
vdm = File(exists=True, desc="voxel difference map")
201243

244+
out_files = OutputMultiPath(
245+
traits.Either(traits.List(File(exists=True)), File(exists=True)),
246+
desc=('If jobtype is applyvdm, '
247+
'these will be the fieldmap corrected files.'
248+
' Otherwise, they will be copies '
249+
'of in_files that have had their '
250+
'headers rewritten.'))
251+
mean_image = File(exists=True, desc='Mean image')
252+
202253

203254
class FieldMap(SPMCommand):
204255
"""Use the fieldmap toolbox from spm to calculate the voxel displacement map (VDM).
@@ -231,25 +282,76 @@ class FieldMap(SPMCommand):
231282

232283
def _format_arg(self, opt, spec, val):
233284
"""Convert input to appropriate format for spm"""
234-
if opt in ["phase_file", "magnitude_file", "anat_file", "epi_file"]:
285+
286+
if ((self.inputs.jobtype == "calculatevdm") and (opt in ['phase_file', 'magnitude_file', 'anat_file', 'epi_file'])):
235287
return scans_for_fname(ensure_list(val))
236288

289+
if ((self.inputs.jobtype == "applyvdm") and (opt =='in_files')):
290+
return scans_for_fnames(ensure_list(val))
291+
if ((self.inputs.jobtype == "applyvdm") and (opt =='vdmfile')):
292+
return scans_for_fname(ensure_list(val))
237293
return super(FieldMap, self)._format_arg(opt, spec, val)
238294

295+
239296
def _parse_inputs(self):
240297
"""validate spm fieldmap options if set to None ignore"""
241-
einputs = super(FieldMap, self)._parse_inputs()
242-
return [{self.inputs.jobtype: einputs[0]}]
298+
299+
if self.inputs.jobtype == "applyvdm":
300+
einputs = (super(FieldMap, self)
301+
._parse_inputs(skip=('jobtype','phase_file', 'magnitude_file',
302+
'echo_times', 'blip_direction',
303+
'total_readout_time','maskbrain',
304+
'epifm','jacobian_modulation',
305+
'method','unwarp_fwhm','pad','ws',
306+
'template','mask_fwhm','nerode','ndilate',
307+
'thresh','reg','epi_file','matchvdm',
308+
'sessname','writeunwarped',
309+
'anat_file','matchanat')))
310+
311+
else:
312+
einputs = (super(FieldMap, self)
313+
._parse_inputs(skip=('jobtype','in_files', 'vdmfile')))
314+
jobtype = self.inputs.jobtype
315+
316+
return [{'%s' % (jobtype): einputs[0]}]
317+
243318

244319
def _list_outputs(self):
245320
outputs = self._outputs().get()
246321
jobtype = self.inputs.jobtype
322+
resliced_all = self.inputs.write_which[0] > 0
323+
resliced_mean = self.inputs.write_which[1] > 0
247324
if jobtype == "calculatevdm":
248-
outputs["vdm"] = fname_presuffix(self.inputs.phase_file, prefix="vdm5_sc")
325+
outputs['vdm'] = fname_presuffix(self.inputs.phase_file, prefix='vdm5_sc')
326+
elif jobtype == "applyvdm":
327+
if resliced_mean:
328+
if isinstance(self.inputs.in_files[0], list):
329+
first_image = self.inputs.in_files[0][0]
330+
else:
331+
first_image = self.inputs.in_files[0]
332+
outputs['mean_image'] = fname_presuffix(
333+
first_image, prefix='meanu')
334+
335+
if resliced_all:
336+
outputs['out_files'] = []
337+
for idx, imgf in enumerate(ensure_list(self.inputs.in_files)):
338+
appliedvdm_run = []
339+
if isinstance(imgf, list):
340+
for i, inner_imgf in enumerate(ensure_list(imgf)):
341+
newfile = fname_presuffix(inner_imgf,
342+
prefix=self.inputs.out_prefix)
343+
appliedvdm_run.append(newfile)
344+
else:
345+
appliedvdm_run = fname_presuffix(imgf,
346+
prefix=self.inputs.out_prefix)
347+
outputs['out_files'].append(appliedvdm_run)
348+
return outputs
349+
249350

250351
return outputs
251352

252353

354+
253355
class SliceTimingInputSpec(SPMCommandInputSpec):
254356
in_files = InputMultiPath(
255357
traits.Either(

0 commit comments

Comments
 (0)