44import os
55
66from .base import ANTSCommand , ANTSCommandInputSpec
7- from ..base import TraitedSpec , File , traits , isdefined , InputMultiPath
7+ from ..base import TraitedSpec , File , traits , isdefined , InputMultiObject
88from ...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