@@ -338,3 +338,160 @@ def _list_outputs(self):
338
338
outputs = self .output_spec ().get ()
339
339
outputs ['out_file' ] = os .path .abspath (self .inputs .out_file )
340
340
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