Skip to content
143 changes: 143 additions & 0 deletions nipype/interfaces/spm/preprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,149 @@ def _list_outputs(self):
return outputs


class Normalize12InputSpec(SPMCommandInputSpec):
image_to_align = File(exists=True, field='subj.vol',
desc='file to estimate the normalization parameters with',
xor=['deformation_file'],
mandatory=True, copyfile=True)
apply_to_files = InputMultiPath(traits.Either(File(exists=True),
traits.List(File(exists=True))),
field='subj.resample',
desc='files to apply transformation to',
copyfile=True)
deformation_file = File(field='subj.def', mandatory=True,
xor=['image_to_align', 'tpm'],
desc='file y_*.nii containing 3 deformation fields for the deformation in x, y and z dimension',
copyfile=False)
jobtype = traits.Enum('estwrite', 'est', 'write',
desc='one of: est, write, estwrite (opt, estwrite)',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need to put opt or defaults anymore in description, the help generator automatically does this.

usedefault=True)
bias_regularization = traits.Enum(0, 0.00001, 0.0001, 0.001, 0.01, 0.1, 1, 10,
field='eoptions.biasreg',
desc='no(0) - extremely heavy (10) (opt)')
bias_fwhm = traits.Enum(30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150,
'Inf', field='eoptions.biasfwhm',
desc='FWHM of Gaussian smoothness of bias (opt)')
tpm = File(exists=True, field='eoptions.tpm',
desc='template in form of a tissue probablitiy map to normalize to (opt)',
mandatory=False, xor=['deformation_file'],
copyfile=False)
affine_regularization_type = traits.Enum('mni', 'size', 'none', field='eoptions.affreg',
desc='mni, size, none (opt)')
warping_regularization = traits.List(traits.Float(), field='eoptions.reg',
minlen=5, maxlen=5,
desc='Controls balance between parameters and data (opt)')
smoothness = traits.Float(field='eoptions.fwhm',
desc='value (in mm) to smooth the data before normalization (opt)')
sampling_distance = traits.Float(field='eoptions.samp',
desc='Sampling distance on data for parameter estimation (opt)')
write_bounding_box = traits.List(traits.List(traits.Float(),
minlen=3, maxlen=3),
field='woptions.bb', minlen=2, maxlen=2,
desc='3x2-element list of lists representing the bounding box (in mm) to be written (opt)')
write_voxel_sizes = traits.List(traits.Float(), field='woptions.vox',
minlen=3, maxlen=3,
desc='3-element list representing the voxel sizes (in mm) of the written normalised images (opt)')
write_interp = traits.Range(low=0, high=7, field='woptions.interp',
desc='degree of b-spline used for interpolation (opt)')


class Normalize12OutputSpec(TraitedSpec):
deformation_field = OutputMultiPath(File(exists=True), desc='NIfTI file containing 3 deformation fields for the deformation in x, y and z dimension')
normalized_image = OutputMultiPath(File(exists=True), desc='Normalized file that needed to be aligned')
normalized_files = OutputMultiPath(File(exists=True), desc='Normalized other files')


class Normalize12(SPMCommand):
"""uses SPM12's new Normalise routine for warping an image to a template.
Spatial normalisation is now done via the segmentation routine (which was
known as ``New Segment`` in SPM8). Note that the normalisation in SPM12
is done towards a file containing multiple tissue probability maps, which
was not the cass in SPM8.

http://www.fil.ion.ucl.ac.uk/spm/doc/manual.pdf#page=49

Examples
--------
>>> import nipype.interfaces.spm as spm
>>> norm12 = spm.Normalize12()
>>> norm12.inputs.image_to_align = 'structural.nii'
>>> norm12.inputs.apply_to_files = 'functional.nii'
>>> norm12.run() # doctest: +SKIP

"""

input_spec = Normalize12InputSpec
output_spec = Normalize12OutputSpec
_jobtype = 'spatial'
_jobname = 'normalise'

def _format_arg(self, opt, spec, val):
"""Convert input to appropriate format for spm
"""
if opt == 'tpm':
return scans_for_fname(filename_to_list(val))
if opt == 'image_to_align':
return scans_for_fname(filename_to_list(val))
if opt == 'apply_to_files':
return scans_for_fnames(filename_to_list(val))
if opt == 'deformation_file':
return np.array([list_to_filename(val)], dtype=object)
if opt in ['nonlinear_regularization']:
if len(val) != 5:
raise ValueError('%s must have 5 elements' % opt)
return super(Normalize12, self)._format_arg(opt, spec, val)

def _parse_inputs(self):
"""validate spm normalize options if set to None ignore
"""
einputs = super(Normalize12, self)._parse_inputs(skip=('jobtype',
'apply_to_files'))
if isdefined(self.inputs.apply_to_files):
inputfiles = deepcopy(self.inputs.apply_to_files)
if isdefined(self.inputs.image_to_align):
inputfiles.extend([self.inputs.image_to_align])
einputs[0]['subj']['resample'] = scans_for_fnames(inputfiles)
jobtype = self.inputs.jobtype
if jobtype in ['estwrite', 'write']:
if not isdefined(self.inputs.apply_to_files):
if isdefined(self.inputs.image_to_align):
einputs[0]['subj']['resample'] = scans_for_fname(self.inputs.image_to_align)
return [{'%s' % (jobtype): einputs[0]}]

def _list_outputs(self):
outputs = self._outputs().get()

jobtype = self.inputs.jobtype
if jobtype.startswith('est'):
outputs['deformation_field'] = []
for imgf in filename_to_list(self.inputs.image_to_align):
outputs['deformation_field'].append(fname_presuffix(imgf,prefix='y_'))
outputs['deformation_field'] = list_to_filename(outputs['deformation_field'])

if self.inputs.jobtype == "estimate":
if isdefined(self.inputs.apply_to_files):
outputs['normalized_files'] = self.inputs.apply_to_files
outputs['normalized_image'] = fname_presuffix(self.inputs.image_to_align,
prefix='w')
elif 'write' in self.inputs.jobtype:
outputs['normalized_files'] = []
if isdefined(self.inputs.apply_to_files):
filelist = filename_to_list(self.inputs.apply_to_files)
for f in filelist:
if isinstance(f, list):
run = [fname_presuffix(in_f,prefix='w') for in_f in f]
else:
run = [fname_presuffix(f,prefix='w')]
outputs['normalized_files'].extend(run)
if isdefined(self.inputs.image_to_align):
outputs['normalized_image'] = fname_presuffix(self.inputs.image_to_align,
prefix='w')

return outputs



class SegmentInputSpec(SPMCommandInputSpec):
data = InputMultiPath(File(exists=True), field='data', desc='one scan per subject',
copyfile=False, mandatory=True)
Expand Down