Skip to content

Commit 87f90dd

Browse files
authored
Merge pull request #3237 from effigies/fix/applytransforms_identity
FIX: Permit identity transforms in list of transforms given to ants.ApplyTransforms
2 parents 02d1500 + c729c1c commit 87f90dd

File tree

1 file changed

+39
-31
lines changed

1 file changed

+39
-31
lines changed

nipype/interfaces/ants/resampling.py

Lines changed: 39 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import os
55

66
from .base import ANTSCommand, ANTSCommandInputSpec
7-
from ..base import TraitedSpec, File, traits, isdefined, InputMultiPath
7+
from ..base import TraitedSpec, File, traits, isdefined, InputMultiObject
88
from ...utils.filemanip import split_filename
99

1010

@@ -52,7 +52,7 @@ class WarpTimeSeriesImageMultiTransformInputSpec(ANTSCommandInputSpec):
5252
use_bspline = traits.Bool(
5353
argstr="--use-Bspline", desc="Use 3rd order B-Spline interpolation"
5454
)
55-
transformation_series = InputMultiPath(
55+
transformation_series = InputMultiObject(
5656
File(exists=True),
5757
argstr="%s",
5858
desc="transformation file(s) to be applied",
@@ -204,7 +204,7 @@ class WarpImageMultiTransformInputSpec(ANTSCommandInputSpec):
204204
use_bspline = traits.Bool(
205205
argstr="--use-BSpline", desc="Use 3rd order B-Spline interpolation"
206206
)
207-
transformation_series = InputMultiPath(
207+
transformation_series = InputMultiObject(
208208
File(exists=True),
209209
argstr="%s",
210210
desc="transformation file(s) to be applied",
@@ -369,15 +369,14 @@ class ApplyTransformsInputSpec(ANTSCommandInputSpec):
369369
traits.Float(), traits.Float() # Gaussian/MultiLabel (sigma, alpha)
370370
),
371371
)
372-
transforms = traits.Either(
373-
InputMultiPath(File(exists=True)),
374-
"identity",
372+
transforms = InputMultiObject(
373+
traits.Either(File(exists=True), "identity"),
375374
argstr="%s",
376375
mandatory=True,
377376
desc="transform files: will be applied in reverse order. For "
378377
"example, the last specified transform will be applied first.",
379378
)
380-
invert_transform_flags = InputMultiPath(traits.Bool())
379+
invert_transform_flags = InputMultiObject(traits.Bool())
381380
default_value = traits.Float(0.0, argstr="--default-value %g", usedefault=True)
382381
print_out_composite_warp_file = traits.Bool(
383382
False,
@@ -411,7 +410,7 @@ class ApplyTransforms(ANTSCommand):
411410
>>> at.cmdline
412411
'antsApplyTransforms --default-value 0 --float 0 --input moving1.nii \
413412
--interpolation Linear --output moving1_trans.nii \
414-
--reference-image fixed1.nii -t identity'
413+
--reference-image fixed1.nii --transform identity'
415414
416415
>>> at = ApplyTransforms()
417416
>>> at.inputs.dimension = 3
@@ -421,11 +420,11 @@ class ApplyTransforms(ANTSCommand):
421420
>>> at.inputs.interpolation = 'Linear'
422421
>>> at.inputs.default_value = 0
423422
>>> at.inputs.transforms = ['ants_Warp.nii.gz', 'trans.mat']
424-
>>> at.inputs.invert_transform_flags = [False, False]
423+
>>> at.inputs.invert_transform_flags = [False, True]
425424
>>> at.cmdline
426425
'antsApplyTransforms --default-value 0 --dimensionality 3 --float 0 --input moving1.nii \
427426
--interpolation Linear --output deformed_moving1.nii --reference-image fixed1.nii \
428-
--transform [ ants_Warp.nii.gz, 0 ] --transform [ trans.mat, 0 ]'
427+
--transform ants_Warp.nii.gz --transform [ trans.mat, 1 ]'
429428
430429
>>> at1 = ApplyTransforms()
431430
>>> at1.inputs.dimension = 3
@@ -440,7 +439,23 @@ class ApplyTransforms(ANTSCommand):
440439
>>> at1.cmdline
441440
'antsApplyTransforms --default-value 0 --dimensionality 3 --float 0 --input moving1.nii \
442441
--interpolation BSpline[ 5 ] --output deformed_moving1.nii --reference-image fixed1.nii \
443-
--transform [ ants_Warp.nii.gz, 0 ] --transform [ trans.mat, 0 ]'
442+
--transform ants_Warp.nii.gz --transform trans.mat'
443+
444+
Identity transforms may be used as part of a chain:
445+
446+
>>> at2 = ApplyTransforms()
447+
>>> at2.inputs.dimension = 3
448+
>>> at2.inputs.input_image = 'moving1.nii'
449+
>>> at2.inputs.reference_image = 'fixed1.nii'
450+
>>> at2.inputs.output_image = 'deformed_moving1.nii'
451+
>>> at2.inputs.interpolation = 'BSpline'
452+
>>> at2.inputs.interpolation_parameters = (5,)
453+
>>> at2.inputs.default_value = 0
454+
>>> at2.inputs.transforms = ['identity', 'ants_Warp.nii.gz', 'trans.mat']
455+
>>> at2.cmdline
456+
'antsApplyTransforms --default-value 0 --dimensionality 3 --float 0 --input moving1.nii \
457+
--interpolation BSpline[ 5 ] --output deformed_moving1.nii --reference-image fixed1.nii \
458+
--transform identity --transform ants_Warp.nii.gz --transform trans.mat'
444459
"""
445460

446461
_cmd = "antsApplyTransforms"
@@ -458,25 +473,20 @@ def _gen_filename(self, name):
458473

459474
def _get_transform_filenames(self):
460475
retval = []
461-
for ii in range(len(self.inputs.transforms)):
462-
if isdefined(self.inputs.invert_transform_flags):
463-
if len(self.inputs.transforms) == len(
464-
self.inputs.invert_transform_flags
465-
):
466-
invert_code = 1 if self.inputs.invert_transform_flags[ii] else 0
467-
retval.append(
468-
"--transform [ %s, %d ]"
469-
% (self.inputs.transforms[ii], invert_code)
470-
)
471-
else:
472-
raise Exception(
473-
(
474-
"ERROR: The useInverse list must have the same number "
475-
"of entries as the transformsFileName list."
476-
)
477-
)
476+
invert_flags = self.inputs.invert_transform_flags
477+
if not isdefined(invert_flags):
478+
invert_flags = [False] * len(self.inputs.transforms)
479+
elif len(self.inputs.transforms) != len(invert_flags):
480+
raise ValueError(
481+
"ERROR: The invert_transform_flags list must have the same number "
482+
"of entries as the transforms list."
483+
)
484+
485+
for transform, invert in zip(self.inputs.transforms, invert_flags):
486+
if invert:
487+
retval.append(f"--transform [ {transform}, 1 ]")
478488
else:
479-
retval.append("--transform %s" % self.inputs.transforms[ii])
489+
retval.append(f"--transform {transform}")
480490
return " ".join(retval)
481491

482492
def _get_output_warped_filename(self):
@@ -492,8 +502,6 @@ def _format_arg(self, opt, spec, val):
492502
if opt == "output_image":
493503
return self._get_output_warped_filename()
494504
elif opt == "transforms":
495-
if val == "identity":
496-
return "-t identity"
497505
return self._get_transform_filenames()
498506
elif opt == "interpolation":
499507
if self.inputs.interpolation in [

0 commit comments

Comments
 (0)