Skip to content

Commit ffae5be

Browse files
committed
Add interpolation_parameters input, cleaned docs
Added interpolation_parameters input to allow for BSpline, Gaussian and MultiLabel interpolation. Also cleaned up some doc typos. Fixed winsorize format_arg to reset to false after second winsorize (docs perform correctly).
1 parent 1a6a3e1 commit ffae5be

File tree

2 files changed

+40
-14
lines changed

2 files changed

+40
-14
lines changed

nipype/interfaces/ants/registration.py

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -285,11 +285,12 @@ class RegistrationInputSpec(ANTSCommandInputSpec):
285285
default=True, usedefault=True)
286286
interpolation = traits.Enum(
287287
'Linear', 'NearestNeighbor', 'CosineWindowedSinc', 'WelchWindowedSinc',
288-
'HammingWindowedSinc', 'LanczosWindowedSinc', 'BSpline',
289-
# MultiLabel[<sigma=imageSpacing>,<alpha=4.0>]
290-
# Gaussian[<sigma=imageSpacing>,<alpha=1.0>]
291-
# BSpline[<order=3>]
288+
'HammingWindowedSinc', 'LanczosWindowedSinc', 'BSpline', 'MultiLabel', 'Gaussian',
292289
argstr='%s', usedefault=True)
290+
interpolation_parameters = traits.Either(traits.Tuple(traits.Int()), # BSpline (order)
291+
traits.Tuple(traits.Float(), # Gaussian/MultiLabel (sigma, alpha)
292+
traits.Float)
293+
)
293294

294295
write_composite_transform = traits.Bool(
295296
argstr='--write-composite-transform %d',
@@ -439,8 +440,8 @@ class Registration(ANTSCommand):
439440
440441
>>> # Test collapse transforms flag
441442
>>> reg4 = copy.deepcopy(reg)
442-
>>> reg.inputs.save_state = 'trans.mat'
443-
>>> reg.inputs.restore_state = 'trans.mat'
443+
>>> reg4.inputs.save_state = 'trans.mat'
444+
>>> reg4.inputs.restore_state = 'trans.mat'
444445
>>> reg4.inputs.initialize_transforms_per_stage = True
445446
>>> reg4.inputs.collapse_output_transforms = True
446447
>>> outputs = reg4._list_outputs()
@@ -452,8 +453,10 @@ class Registration(ANTSCommand):
452453
'inverse_warped_image': <undefined>,
453454
'reverse_invert_flags': [],
454455
'reverse_transforms': [],
455-
'save_state': <undefined>,
456+
'save_state': '.../nipype/testing/data/trans.mat',
456457
'warped_image': '.../nipype/testing/data/output_warped_image.nii.gz'}
458+
>>> reg4.cmdline
459+
'antsRegistration --collapse-output-transforms 1 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 1 --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --restore-state trans.mat --save-state trans.mat --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, 1.0 ] --write-composite-transform 1'
457460
458461
>>> # Test collapse transforms flag
459462
>>> reg4b = copy.deepcopy(reg4)
@@ -468,9 +471,11 @@ class Registration(ANTSCommand):
468471
'inverse_warped_image': <undefined>,
469472
'reverse_invert_flags': [True, False],
470473
'reverse_transforms': ['.../nipype/testing/data/output_0GenericAffine.mat', '.../nipype/testing/data/output_1InverseWarp.nii.gz'],
471-
'save_state': <undefined>,
474+
'save_state': '.../nipype/testing/data/trans.mat',
472475
'warped_image': '.../nipype/testing/data/output_warped_image.nii.gz'}
473476
>>> reg4b.aggregate_outputs() # doctest: +SKIP
477+
>>> reg4b.cmdline
478+
'antsRegistration --collapse-output-transforms 1 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 1 --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --restore-state trans.mat --save-state trans.mat --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, 1.0 ] --write-composite-transform 0'
474479
475480
>>> # Test multiple metrics per stage
476481
>>> reg5 = copy.deepcopy(reg)
@@ -482,14 +487,28 @@ class Registration(ANTSCommand):
482487
>>> reg5.inputs.sampling_strategy = ['Random', None] # use default strategy in second stage
483488
>>> reg5.inputs.sampling_percentage = [0.05, [0.05, 0.10]]
484489
>>> reg5.cmdline
485-
'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 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, 0.5, 32, None, 0.05 ] --metric CC[ fixed1.nii, moving1.nii, 0.5, 4, 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'
490+
'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, 0.5, 32, None, 0.05 ] --metric CC[ fixed1.nii, moving1.nii, 0.5, 4, 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'
486491
487492
>>> # Test multiple inputs
488493
>>> reg6 = copy.deepcopy(reg5)
489494
>>> reg6.inputs.fixed_image = ['fixed1.nii', 'fixed2.nii']
490495
>>> reg6.inputs.moving_image = ['moving1.nii', 'moving2.nii']
491496
>>> reg6.cmdline
492-
'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 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, 0.5, 32, None, 0.05 ] --metric CC[ fixed2.nii, moving2.nii, 0.5, 4, 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 --write-composite-transform 1'
497+
'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, 0.5, 32, None, 0.05 ] --metric CC[ fixed2.nii, moving2.nii, 0.5, 4, 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'
498+
499+
>>> # Test Interpolation Parameters (BSpline)
500+
>>> reg7a = copy.deepcopy(reg)
501+
>>> reg7a.inputs.interpolation = 'BSpline'
502+
>>> reg7a.inputs.interpolation_parameters = (3,)
503+
>>> reg7a.cmdline
504+
'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 0 --interpolation BSpline[ 3 ] --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, 1.0 ] --write-composite-transform 1'
505+
506+
>>> # Test Interpolation Parameters (MultiLabel/Gaussian)
507+
>>> reg7b = copy.deepcopy(reg)
508+
>>> reg7b.inputs.interpolation = 'Gaussian'
509+
>>> reg7b.inputs.interpolation_parameters = (1.0, 1.0)
510+
>>> reg7b.cmdline
511+
'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 0 --interpolation Gaussian[ 1.0, 1.0 ] --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, 1.0 ] --write-composite-transform 1'
493512
"""
494513
DEF_SAMPLING_STRATEGY = 'None'
495514
"""The default sampling strategy argument."""
@@ -669,7 +688,6 @@ def _formatWinsorizeImageIntensities(self):
669688
self._quantilesDone = True
670689
return '--winsorize-image-intensities [ %s, %s ]' % (self.inputs.winsorize_lower_quantile, self.inputs.winsorize_upper_quantile)
671690

672-
673691
def _format_arg(self, opt, spec, val):
674692
if opt == 'fixed_image_mask':
675693
if isdefined(self.inputs.moving_image_mask):
@@ -698,8 +716,13 @@ def _format_arg(self, opt, spec, val):
698716
0],
699717
doCenterOfMassInit)
700718
elif opt == 'interpolation':
701-
# TODO: handle multilabel, gaussian, and bspline options
702-
return '--interpolation %s' % self.inputs.interpolation
719+
if self.inputs.interpolation in ['BSpline', 'MultiLabel', 'Gaussian'] and \
720+
isdefined(self.inputs.interpolation_parameters):
721+
return '--interpolation %s[ %s ]' % (self.inputs.interpolation,
722+
', '.join([str(param)
723+
for param in self.inputs.interpolation_parameters]))
724+
else:
725+
return '--interpolation %s' % self.inputs.interpolation
703726
elif opt == 'output_transform_prefix':
704727
out_filename = self._get_outputfilenames(inverse=False)
705728
inv_out_filename = self._get_outputfilenames(inverse=True)
@@ -715,7 +738,9 @@ def _format_arg(self, opt, spec, val):
715738
elif opt == 'winsorize_upper_quantile' or opt == 'winsorize_lower_quantile':
716739
if not self._quantilesDone:
717740
return self._formatWinsorizeImageIntensities()
718-
return '' # Must return something for argstr!
741+
else:
742+
self._quantilesDone = False
743+
return '' # Must return something for argstr!
719744
# This feature was removed from recent versions of antsRegistration due to corrupt outputs.
720745
# elif opt == 'collapse_linear_transforms_to_fixed_image_header':
721746
# return self._formatCollapseLinearTransformsToFixedImageHeader()

nipype/interfaces/ants/tests/test_auto_Registration.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ def test_Registration_inputs():
4141
interpolation=dict(argstr='%s',
4242
usedefault=True,
4343
),
44+
interpolation_parameters=dict(),
4445
invert_initial_moving_transform=dict(requires=['initial_moving_transform'],
4546
xor=['initial_moving_transform_com'],
4647
),

0 commit comments

Comments
 (0)