@@ -393,7 +393,7 @@ class NormalizeInputSpec(SPMCommandInputSpec):
393393 desc = 'source smoothing (opt)' )
394394 template_image_smoothing = traits .Float (field = 'eoptions.smoref' ,
395395 desc = 'template smoothing (opt)' )
396- affine_regularization_type = traits .Enum ('mni' , 'size' , 'none' , field = 'eoptions.regype ' ,
396+ affine_regularization_type = traits .Enum ('mni' , 'size' , 'none' , field = 'eoptions.regtype ' ,
397397 desc = 'mni, size, none (opt)' )
398398 DCT_period_cutoff = traits .Float (field = 'eoptions.cutoff' ,
399399 desc = 'Cutoff of for DCT bases (opt)' )
@@ -461,7 +461,7 @@ def _format_arg(self, opt, spec, val):
461461 return super (Normalize , self )._format_arg (opt , spec , val )
462462
463463 def _parse_inputs (self ):
464- """validate spm realign options if set to None ignore
464+ """validate spm normalize options if set to None ignore
465465 """
466466 einputs = super (Normalize , self )._parse_inputs (skip = ('jobtype' ,
467467 'apply_to_files' ))
@@ -509,6 +509,149 @@ def _list_outputs(self):
509509 return outputs
510510
511511
512+ class Normalize12InputSpec (SPMCommandInputSpec ):
513+ image_to_align = File (exists = True , field = 'subj.vol' ,
514+ desc = 'file to estimate the normalization parameters with' ,
515+ xor = ['deformation_file' ],
516+ mandatory = True , copyfile = True )
517+ apply_to_files = InputMultiPath (traits .Either (File (exists = True ),
518+ traits .List (File (exists = True ))),
519+ field = 'subj.resample' ,
520+ desc = 'files to apply transformation to' ,
521+ copyfile = True )
522+ deformation_file = File (field = 'subj.def' , mandatory = True ,
523+ xor = ['image_to_align' , 'tpm' ],
524+ desc = 'file y_*.nii containing 3 deformation fields for the deformation in x, y and z dimension' ,
525+ copyfile = False )
526+ jobtype = traits .Enum ('estwrite' , 'est' , 'write' ,
527+ desc = 'one of: est, write, estwrite (opt, estwrite)' ,
528+ usedefault = True )
529+ bias_regularization = traits .Enum (0 , 0.00001 , 0.0001 , 0.001 , 0.01 , 0.1 , 1 , 10 ,
530+ field = 'eoptions.biasreg' ,
531+ desc = 'no(0) - extremely heavy (10) (opt)' )
532+ bias_fwhm = traits .Enum (30 , 40 , 50 , 60 , 70 , 80 , 90 , 100 , 110 , 120 , 130 , 140 , 150 ,
533+ 'Inf' , field = 'eoptions.biasfwhm' ,
534+ desc = 'FWHM of Gaussian smoothness of bias (opt)' )
535+ tpm = File (exists = True , field = 'eoptions.tpm' ,
536+ desc = 'template in form of a tissue probablitiy map to normalize to (opt)' ,
537+ mandatory = False , xor = ['deformation_file' ],
538+ copyfile = False )
539+ affine_regularization_type = traits .Enum ('mni' , 'size' , 'none' , field = 'eoptions.affreg' ,
540+ desc = 'mni, size, none (opt)' )
541+ warping_regularization = traits .List (traits .Float (), field = 'eoptions.reg' ,
542+ minlen = 5 , maxlen = 5 ,
543+ desc = 'Controls balance between parameters and data (opt)' )
544+ smoothness = traits .Float (field = 'eoptions.fwhm' ,
545+ desc = 'value (in mm) to smooth the data before normalization (opt)' )
546+ sampling_distance = traits .Float (field = 'eoptions.samp' ,
547+ desc = 'Sampling distance on data for parameter estimation (opt)' )
548+ write_bounding_box = traits .List (traits .List (traits .Float (),
549+ minlen = 3 , maxlen = 3 ),
550+ field = 'woptions.bb' , minlen = 2 , maxlen = 2 ,
551+ desc = '3x2-element list of lists representing the bounding box (in mm) to be written (opt)' )
552+ write_voxel_sizes = traits .List (traits .Float (), field = 'woptions.vox' ,
553+ minlen = 3 , maxlen = 3 ,
554+ desc = '3-element list representing the voxel sizes (in mm) of the written normalised images (opt)' )
555+ write_interp = traits .Range (low = 0 , high = 7 , field = 'woptions.interp' ,
556+ desc = 'degree of b-spline used for interpolation (opt)' )
557+
558+
559+ class Normalize12OutputSpec (TraitedSpec ):
560+ deformation_field = OutputMultiPath (File (exists = True ), desc = 'NIfTI file containing 3 deformation fields for the deformation in x, y and z dimension' )
561+ normalized_image = OutputMultiPath (File (exists = True ), desc = 'Normalized file that needed to be aligned' )
562+ normalized_files = OutputMultiPath (File (exists = True ), desc = 'Normalized other files' )
563+
564+
565+ class Normalize12 (SPMCommand ):
566+ """uses SPM12's new Normalise routine for warping an image to a template.
567+ Spatial normalisation is now done via the segmentation routine (which was
568+ known as ``New Segment`` in SPM8). Note that the normalisation in SPM12
569+ is done towards a file containing multiple tissue probability maps, which
570+ was not the cass in SPM8.
571+
572+ http://www.fil.ion.ucl.ac.uk/spm/doc/manual.pdf#page=49
573+
574+ Examples
575+ --------
576+ >>> import nipype.interfaces.spm as spm
577+ >>> norm12 = spm.Normalize12()
578+ >>> norm12.inputs.image_to_align = 'structural.nii'
579+ >>> norm12.inputs.apply_to_files = 'functional.nii'
580+ >>> norm12.run() # doctest: +SKIP
581+
582+ """
583+
584+ input_spec = Normalize12InputSpec
585+ output_spec = Normalize12OutputSpec
586+ _jobtype = 'spatial'
587+ _jobname = 'normalise'
588+
589+ def _format_arg (self , opt , spec , val ):
590+ """Convert input to appropriate format for spm
591+ """
592+ if opt == 'tpm' :
593+ return scans_for_fname (filename_to_list (val ))
594+ if opt == 'image_to_align' :
595+ return scans_for_fname (filename_to_list (val ))
596+ if opt == 'apply_to_files' :
597+ return scans_for_fnames (filename_to_list (val ))
598+ if opt == 'deformation_file' :
599+ return np .array ([list_to_filename (val )], dtype = object )
600+ if opt in ['nonlinear_regularization' ]:
601+ if len (val ) != 5 :
602+ raise ValueError ('%s must have 5 elements' % opt )
603+ return super (Normalize12 , self )._format_arg (opt , spec , val )
604+
605+ def _parse_inputs (self ):
606+ """validate spm normalize options if set to None ignore
607+ """
608+ einputs = super (Normalize12 , self )._parse_inputs (skip = ('jobtype' ,
609+ 'apply_to_files' ))
610+ if isdefined (self .inputs .apply_to_files ):
611+ inputfiles = deepcopy (self .inputs .apply_to_files )
612+ if isdefined (self .inputs .image_to_align ):
613+ inputfiles .extend ([self .inputs .image_to_align ])
614+ einputs [0 ]['subj' ]['resample' ] = scans_for_fnames (inputfiles )
615+ jobtype = self .inputs .jobtype
616+ if jobtype in ['estwrite' , 'write' ]:
617+ if not isdefined (self .inputs .apply_to_files ):
618+ if isdefined (self .inputs .image_to_align ):
619+ einputs [0 ]['subj' ]['resample' ] = scans_for_fname (self .inputs .image_to_align )
620+ return [{'%s' % (jobtype ): einputs [0 ]}]
621+
622+ def _list_outputs (self ):
623+ outputs = self ._outputs ().get ()
624+
625+ jobtype = self .inputs .jobtype
626+ if jobtype .startswith ('est' ):
627+ outputs ['deformation_field' ] = []
628+ for imgf in filename_to_list (self .inputs .image_to_align ):
629+ outputs ['deformation_field' ].append (fname_presuffix (imgf ,prefix = 'y_' ))
630+ outputs ['deformation_field' ] = list_to_filename (outputs ['deformation_field' ])
631+
632+ if self .inputs .jobtype == "estimate" :
633+ if isdefined (self .inputs .apply_to_files ):
634+ outputs ['normalized_files' ] = self .inputs .apply_to_files
635+ outputs ['normalized_image' ] = fname_presuffix (self .inputs .image_to_align ,
636+ prefix = 'w' )
637+ elif 'write' in self .inputs .jobtype :
638+ outputs ['normalized_files' ] = []
639+ if isdefined (self .inputs .apply_to_files ):
640+ filelist = filename_to_list (self .inputs .apply_to_files )
641+ for f in filelist :
642+ if isinstance (f , list ):
643+ run = [fname_presuffix (in_f ,prefix = 'w' ) for in_f in f ]
644+ else :
645+ run = [fname_presuffix (f ,prefix = 'w' )]
646+ outputs ['normalized_files' ].extend (run )
647+ if isdefined (self .inputs .image_to_align ):
648+ outputs ['normalized_image' ] = fname_presuffix (self .inputs .image_to_align ,
649+ prefix = 'w' )
650+
651+ return outputs
652+
653+
654+
512655class SegmentInputSpec (SPMCommandInputSpec ):
513656 data = InputMultiPath (File (exists = True ), field = 'data' , desc = 'one scan per subject' ,
514657 copyfile = False , mandatory = True )
0 commit comments