@@ -338,3 +338,160 @@ def _list_outputs(self):
338338 outputs = self .output_spec ().get ()
339339 outputs ['out_file' ] = os .path .abspath (self .inputs .out_file )
340340 return outputs
341+
342+
343+ class MRICoregInputSpec (FSTraitedSpec ):
344+ source_file = File (argstr = '--mov %s' , desc = 'source file to be registered' ,
345+ mandatory = True , copyfile = False )
346+ reference_file = File (argstr = '--ref %s' , desc = 'reference (target) file' ,
347+ mandatory = True , copyfile = False , xor = ['subject_id' ])
348+ out_lta_file = traits .Either (True , File , argstr = '--lta %s' , default = True ,
349+ usedefault = True ,
350+ desc = 'output registration file (LTA format)' )
351+ out_reg_file = traits .Either (True , File , argstr = '--regdat %s' ,
352+ desc = 'output registration file (REG format)' )
353+ out_params_file = traits .Either (True , File , argstr = '--params %s' ,
354+ desc = 'output parameters file' )
355+
356+ subjects_dir = Directory (exists = True , argstr = '--sd %s' ,
357+ desc = 'FreeSurfer SUBJECTS_DIR' )
358+ subject_id = traits .Str (
359+ argstr = '--s %s' , position = 1 , mandatory = True , xor = ['reference_file' ],
360+ requires = ['subjects_dir' ],
361+ desc = 'freesurfer subject ID (implies ``reference_mask == '
362+ 'aparc+aseg.mgz`` unless otherwise specified)' )
363+ dof = traits .Enum (6 , 9 , 12 , argstr = '--dof %d' ,
364+ desc = 'number of transform degrees of freedom' )
365+ reference_mask = traits .Either (
366+ False , traits .Str , argstr = '--ref-mask %s' , position = 2 ,
367+ desc = 'mask reference volume with given mask, or None if ``False``' )
368+ source_mask = traits .Str (argstr = '--mov-mask' ,
369+ desc = 'mask source file with given mask' )
370+ num_threads = traits .Int (argstr = '--threads %d' ,
371+ desc = 'number of OpenMP threads' )
372+ no_coord_dithering = traits .Bool (argstr = '--no-coord-dither' ,
373+ desc = 'turn off coordinate dithering' )
374+ no_intensity_dithering = traits .Bool (argstr = '--no-intensity-dither' ,
375+ desc = 'turn off intensity dithering' )
376+ sep = traits .List (argstr = '--sep %s...' , minlen = 1 , maxlen = 2 ,
377+ desc = 'set spatial scales, in voxels (default [2, 4])' )
378+ initial_translation = traits .Tuple (
379+ traits .Float , traits .Float , traits .Float , argstr = '--trans %g %g %g' ,
380+ desc = 'initial translation in mm (implies no_cras0)' )
381+ initial_rotation = traits .Tuple (
382+ traits .Float , traits .Float , traits .Float , argstr = '--rot %g %g %g' ,
383+ desc = 'initial rotation in degrees' )
384+ initial_scale = traits .Tuple (
385+ traits .Float , traits .Float , traits .Float , argstr = '--scale %g %g %g' ,
386+ desc = 'initial scale' )
387+ initial_shear = traits .Tuple (
388+ traits .Float , traits .Float , traits .Float , argstr = '--shear %g %g %g' ,
389+ desc = 'initial shear (Hxy, Hxz, Hyz)' )
390+ no_cras0 = traits .Bool (argstr = '--no-cras0' ,
391+ desc = 'do not set translation parameters to align '
392+ 'centers of source and reference files' )
393+ max_iters = traits .Range (low = 1 , argstr = '--nitersmax %d' ,
394+ desc = 'maximum iterations (default: 4)' )
395+ ftol = traits .Float (argstr = '--ftol %e' ,
396+ desc = 'floating-point tolerance (default=1e-7)' )
397+ linmintol = traits .Float (argstr = '--linmintol %e' )
398+ saturation_threshold = traits .Range (
399+ low = 0.0 , high = 100.0 , argstr = '--sat %g' ,
400+ desc = 'saturation threshold (default=9.999)' )
401+ conform_reference = traits .Bool (argstr = '--conf-ref' ,
402+ desc = 'conform reference without rescaling' )
403+ no_brute_force = traits .Bool (argstr = '--no-bf' ,
404+ desc = 'do not brute force search' )
405+ brute_force_limit = traits .Float (
406+ argstr = '--bf-lim %g' , xor = ['no_brute_force' ],
407+ desc = 'constrain brute force search to +/- lim' )
408+ brute_force_samples = traits .Int (
409+ argstr = '--bf-nsamp %d' , xor = ['no_brute_force' ],
410+ desc = 'number of samples in brute force search' )
411+ no_smooth = traits .Bool (
412+ argstr = '--no-smooth' ,
413+ desc = 'do not apply smoothing to either reference or source file' )
414+ ref_fwhm = traits .Float (argstr = '--ref-fwhm' ,
415+ desc = 'apply smoothing to reference file' )
416+ source_oob = traits .Bool (
417+ argstr = '--mov-oob' ,
418+ desc = 'count source voxels that are out-of-bounds as 0' )
419+ # Skipping mat2par
420+
421+
422+ class MRICoregOutputSpec (TraitedSpec ):
423+ out_reg_file = File (exists = True , desc = 'output registration file' )
424+ out_lta_file = File (exists = True , desc = 'output LTA-style registration file' )
425+ out_params_file = File (exists = True , desc = 'output parameters file' )
426+
427+
428+ class MRICoreg (FSCommand ):
429+ """ This program registers one volume to another
430+
431+ mri_coreg is a C reimplementation of spm_coreg in FreeSurfer
432+
433+ Examples
434+ ========
435+ >>> from nipype.interfaces.freesurfer import MRICoreg
436+ >>> coreg = MRICoreg()
437+ >>> coreg.inputs.source_file = 'moving1.nii'
438+ >>> coreg.inputs.reference_file = 'fixed1.nii'
439+ >>> coreg.inputs.subjects_dir = '.'
440+ >>> coreg.cmdline # doctest: +ALLOW_UNICODE +ELLIPSIS
441+ 'mri_coreg --lta .../registration.lta --ref fixed1.nii --mov moving1.nii --sd .'
442+
443+ If passing a subject ID, the reference mask may be disabled:
444+
445+ >>> coreg = MRICoreg()
446+ >>> coreg.inputs.source_file = 'moving1.nii'
447+ >>> coreg.inputs.subjects_dir = '.'
448+ >>> coreg.inputs.subject_id = 'fsaverage'
449+ >>> coreg.inputs.reference_mask = False
450+ >>> coreg.cmdline # doctest: +ALLOW_UNICODE +ELLIPSIS
451+ 'mri_coreg --s fsaverage --no-ref-mask --lta .../registration.lta --mov moving1.nii --sd .'
452+
453+ Spatial scales may be specified as a list of one or two separations:
454+
455+ >>> coreg.inputs.sep = [4]
456+ >>> coreg.cmdline # doctest: +ALLOW_UNICODE +ELLIPSIS
457+ 'mri_coreg --s fsaverage --no-ref-mask --lta .../registration.lta --sep 4 --mov moving1.nii --sd .'
458+
459+ >>> coreg.inputs.sep = [4, 5]
460+ >>> coreg.cmdline # doctest: +ALLOW_UNICODE +ELLIPSIS
461+ 'mri_coreg --s fsaverage --no-ref-mask --lta .../registration.lta --sep 4 --sep 5 --mov moving1.nii --sd .'
462+ """
463+
464+ _cmd = 'mri_coreg'
465+ input_spec = MRICoregInputSpec
466+ output_spec = MRICoregOutputSpec
467+
468+ def _format_arg (self , opt , spec , val ):
469+ if opt in ('out_reg_file' , 'out_lta_file' ,
470+ 'out_params_file' ) and val is True :
471+ val = self ._list_outputs ()[opt ]
472+ elif opt == 'reference_mask' and val is False :
473+ return '--no-ref-mask'
474+ return super (MRICoreg , self )._format_arg (opt , spec , val )
475+
476+ def _list_outputs (self ):
477+ outputs = self .output_spec ().get ()
478+
479+ out_lta_file = self .inputs .out_lta_file
480+ if isdefined (out_lta_file ):
481+ if out_lta_file is True :
482+ out_lta_file = 'registration.lta'
483+ outputs ['out_lta_file' ] = os .path .abspath (out_lta_file )
484+
485+ out_reg_file = self .inputs .out_reg_file
486+ if isdefined (out_reg_file ):
487+ if out_reg_file is True :
488+ out_reg_file = 'registration.dat'
489+ outputs ['out_reg_file' ] = os .path .abspath (out_reg_file )
490+
491+ out_params_file = self .inputs .out_params_file
492+ if isdefined (out_params_file ):
493+ if out_params_file is True :
494+ out_params_file = 'registration.par'
495+ outputs ['out_params_file' ] = os .path .abspath (out_params_file )
496+
497+ return outputs
0 commit comments