@@ -200,11 +200,17 @@ class RegistrationInputSpec(ANTSCommandInputSpec):
200
200
fixed_image = InputMultiPath (File (exists = True ), mandatory = True ,
201
201
desc = 'image to apply transformation to (generally a coregistered functional)' )
202
202
fixed_image_mask = File (argstr = '%s' , exists = True ,
203
- desc = 'mask used to limit registration region' )
203
+ desc = 'mask used to limit metric sampling region of the fixed image ' )
204
204
moving_image = InputMultiPath (File (exists = True ), mandatory = True ,
205
205
desc = 'image to apply transformation to (generally a coregistered functional)' )
206
206
moving_image_mask = File (requires = ['fixed_image_mask' ],
207
- exists = True , desc = '' )
207
+ exists = True , desc = 'mask used to limit metric sampling region of the moving image' )
208
+
209
+ save_state = File (argstr = '--save-state %s' , exists = False ,
210
+ desc = 'Filename for saving the internal restorable state of the registration' )
211
+ restore_state = File (argstr = '--restore-state %s' , exists = True ,
212
+ desc = 'Filename for restoring the internal restorable state of the registration' )
213
+
208
214
initial_moving_transform = File (argstr = '%s' , exists = True , desc = '' ,
209
215
xor = ['initial_moving_transform_com' ])
210
216
invert_initial_moving_transform = traits .Bool (
@@ -276,6 +282,15 @@ class RegistrationInputSpec(ANTSCommandInputSpec):
276
282
'combines all adjacent linear transforms and composes all '
277
283
'adjacent displacement field transforms before writing the '
278
284
'results to disk.' ))
285
+ initialize_transforms_per_stage = traits .Bool (
286
+ argstr = '--initialize-transforms-per-stage %d' , default = False ,
287
+ usedefault = True , # This should be true for explicit completeness
288
+ desc = ('Initialize linear transforms from the previous stage. By enabling this option, '
289
+ 'the current linear stage transform is directly intialized from the previous '
290
+ 'stages linear transform; this allows multiple linear stages to be run where '
291
+ 'each stage directly updates the estimated linear transform from the previous '
292
+ 'stage. (e.g. Translation -> Rigid -> Affine). '
293
+ ))
279
294
280
295
transforms = traits .List (traits .Enum ('Rigid' , 'Affine' , 'CompositeAffine' ,
281
296
'Similarity' , 'Translation' , 'BSpline' ,
@@ -337,7 +352,7 @@ class RegistrationOutputSpec(TraitedSpec):
337
352
File (exists = True ), desc = 'Inverse composite transform file' )
338
353
warped_image = File (desc = "Outputs warped image" )
339
354
inverse_warped_image = File (desc = "Outputs the inverse of the warped image" )
340
-
355
+ save_state = File ( desc = "The saved registration state to be restored" )
341
356
342
357
class Registration (ANTSCommand ):
343
358
@@ -358,6 +373,7 @@ class Registration(ANTSCommand):
358
373
>>> reg.inputs.dimension = 3
359
374
>>> reg.inputs.write_composite_transform = True
360
375
>>> reg.inputs.collapse_output_transforms = False
376
+ >>> reg.inputs.initialize_transforms_per_stage = False
361
377
>>> reg.inputs.metric = ['Mattes']*2
362
378
>>> reg.inputs.metric_weight = [1]*2 # Default (value ignored currently by ANTs)
363
379
>>> reg.inputs.radius_or_number_of_bins = [32]*2
@@ -375,33 +391,36 @@ class Registration(ANTSCommand):
375
391
>>> reg1 = copy.deepcopy(reg)
376
392
>>> reg1.inputs.winsorize_lower_quantile = 0.025
377
393
>>> reg1.cmdline
378
- 'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.025, 1.0 ] --write-composite-transform 1'
394
+ 'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 0 -- interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.025, 1.0 ] --write-composite-transform 1'
379
395
>>> reg1.run() #doctest: +SKIP
380
396
381
397
>>> reg2 = copy.deepcopy(reg)
382
398
>>> reg2.inputs.winsorize_upper_quantile = 0.975
383
399
>>> reg2.cmdline
384
- 'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 0.975 ] --write-composite-transform 1'
400
+ 'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 0 -- interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 0.975 ] --write-composite-transform 1'
385
401
386
402
>>> reg3 = copy.deepcopy(reg)
387
403
>>> reg3.inputs.winsorize_lower_quantile = 0.025
388
404
>>> reg3.inputs.winsorize_upper_quantile = 0.975
389
405
>>> reg3.cmdline
390
- 'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.025, 0.975 ] --write-composite-transform 1'
406
+ 'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 0 -- interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.025, 0.975 ] --write-composite-transform 1'
391
407
392
408
>>> # Test collapse transforms flag
393
409
>>> reg4 = copy.deepcopy(reg)
410
+ >>> reg.inputs.save_state = 'trans.mat'
411
+ >>> reg.inputs.restore_state = 'trans.mat'
412
+ >>> reg4.inputs.initialize_transforms_per_stage = True
394
413
>>> reg4.inputs.collapse_output_transforms = True
395
414
>>> outputs = reg4._list_outputs()
396
415
>>> print outputs #doctest: +ELLIPSIS
397
- {'reverse_invert_flags': [], 'inverse_composite_transform': ['.../nipype/testing/data/output_InverseComposite.h5'], 'warped_image': '.../nipype/testing/data/output_warped_image.nii.gz', 'inverse_warped_image': <undefined>, 'forward_invert_flags': [], 'reverse_transforms': [], 'composite_transform': ['.../nipype/testing/data/output_Composite.h5'], 'forward_transforms': []}
416
+ {'reverse_invert_flags': [], 'inverse_composite_transform': ['.../nipype/testing/data/output_InverseComposite.h5'], 'warped_image': '.../nipype/testing/data/output_warped_image.nii.gz', 'inverse_warped_image': <undefined>, 'forward_invert_flags': [], 'reverse_transforms': [], 'save_state': <undefined>, ' composite_transform': ['.../nipype/testing/data/output_Composite.h5'], 'forward_transforms': []}
398
417
399
418
>>> # Test collapse transforms flag
400
419
>>> reg4b = copy.deepcopy(reg4)
401
420
>>> reg4b.inputs.write_composite_transform = False
402
421
>>> outputs = reg4b._list_outputs()
403
422
>>> print outputs #doctest: +ELLIPSIS
404
- {'reverse_invert_flags': [True, False], 'inverse_composite_transform': <undefined>, 'warped_image': '.../nipype/testing/data/output_warped_image.nii.gz', 'inverse_warped_image': <undefined>, 'forward_invert_flags': [False, False], 'reverse_transforms': ['.../nipype/testing/data/output_0GenericAffine.mat', '.../nipype/testing/data/output_1InverseWarp.nii.gz'], 'composite_transform': <undefined>, 'forward_transforms': ['.../nipype/testing/data/output_0GenericAffine.mat', '.../nipype/testing/data/output_1Warp.nii.gz']}
423
+ {'reverse_invert_flags': [True, False], 'inverse_composite_transform': <undefined>, 'warped_image': '.../nipype/testing/data/output_warped_image.nii.gz', 'inverse_warped_image': <undefined>, 'forward_invert_flags': [False, False], 'reverse_transforms': ['.../nipype/testing/data/output_0GenericAffine.mat', '.../nipype/testing/data/output_1InverseWarp.nii.gz'], 'save_state': <undefined>, ' composite_transform': <undefined>, 'forward_transforms': ['.../nipype/testing/data/output_0GenericAffine.mat', '.../nipype/testing/data/output_1Warp.nii.gz']}
405
424
>>> reg4b.aggregate_outputs() #doctest: +SKIP
406
425
407
426
>>> # Test multiple metrics per stage
@@ -412,7 +431,7 @@ class Registration(ANTSCommand):
412
431
>>> reg5.inputs.sampling_strategy = ['Random', None] # use default strategy in second stage
413
432
>>> reg5.inputs.sampling_percentage = [0.05, [0.05, 0.10]]
414
433
>>> reg5.cmdline
415
- 'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric CC[ fixed1.nii, moving1.nii, 1, 4, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric CC[ fixed1.nii, moving1.nii, 0.5, 32, None, 0.05 ] --metric Mattes[ fixed1.nii, moving1.nii, 0.5, 32, None, 0.1 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ] --write-composite-transform 1'
434
+ 'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 0 -- interpolation Linear --output [ output_, output_warped_image.nii.gz ] --restore-state trans.mat --save-state trans.mat --transform Affine[ 2.0 ] --metric CC[ fixed1.nii, moving1.nii, 1, 4, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric CC[ fixed1.nii, moving1.nii, 0.5, 32, None, 0.05 ] --metric Mattes[ fixed1.nii, moving1.nii, 0.5, 32, None, 0.1 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ] --write-composite-transform 1'
416
435
"""
417
436
DEF_SAMPLING_STRATEGY = 'None'
418
437
"""The default sampling strategy argument."""
@@ -581,13 +600,6 @@ def _formatWinsorizeImageIntensities(self):
581
600
self ._quantilesDone = True
582
601
return '--winsorize-image-intensities [ %s, %s ]' % (self .inputs .winsorize_lower_quantile , self .inputs .winsorize_upper_quantile )
583
602
584
- def _formatCollapseLinearTransformsToFixedImageHeader (self ):
585
- if self .inputs .collapse_linear_transforms_to_fixed_image_header :
586
- # return '--collapse-linear-transforms-to-fixed-image-header 1'
587
- return ''
588
- else :
589
- # return '--collapse-linear-transforms-to-fixed-image-header 0'
590
- return ''
591
603
592
604
def _format_arg (self , opt , spec , val ):
593
605
if opt == 'fixed_image_mask' :
@@ -636,7 +648,7 @@ def _format_arg(self, opt, spec, val):
636
648
return self ._formatWinsorizeImageIntensities ()
637
649
return '' # Must return something for argstr!
638
650
elif opt == 'collapse_linear_transforms_to_fixed_image_header' :
639
- return self . _formatCollapseLinearTransformsToFixedImageHeader ()
651
+ return '' # Command no longer exist, so return empty string for backwards compatibility
640
652
return super (Registration , self )._format_arg (opt , spec , val )
641
653
642
654
def _outputFileNames (self , prefix , count , transform , inverse = False ):
@@ -763,4 +775,6 @@ def _list_outputs(self):
763
775
outputs ['warped_image' ] = os .path .abspath (out_filename )
764
776
if inv_out_filename :
765
777
outputs ['inverse_warped_image' ] = os .path .abspath (inv_out_filename )
778
+ if len (self .inputs .save_state ):
779
+ outputs ['save_state' ] = os .path .abspath (self .inputs .save_state )
766
780
return outputs
0 commit comments