1111import os
1212
1313from .base import ANTSCommand , ANTSCommandInputSpec
14- from ..base import (TraitedSpec , File , traits ,
15- isdefined , InputMultiPath )
14+ from ..base import TraitedSpec , File , traits , isdefined , InputMultiPath
1615from ...utils .filemanip import split_filename
1716
1817
@@ -64,7 +63,8 @@ class WarpTimeSeriesImageMultiTransform(ANTSCommand):
6463 >>> wtsimt.inputs.reference_image = 'ants_deformed.nii.gz'
6564 >>> wtsimt.inputs.transformation_series = ['ants_Warp.nii.gz','ants_Affine.txt']
6665 >>> wtsimt.cmdline
67- 'WarpTimeSeriesImageMultiTransform 4 resting.nii resting_wtsimt.nii -R ants_deformed.nii.gz ants_Warp.nii.gz ants_Affine.txt'
66+ 'WarpTimeSeriesImageMultiTransform 4 resting.nii resting_wtsimt.nii -R ants_deformed.nii.gz ants_Warp.nii.gz \
67+ ants_Affine.txt'
6868
6969 """
7070
@@ -99,7 +99,7 @@ def _list_outputs(self):
9999 ext )))
100100 return outputs
101101
102- def _run_interface (self , runtime ):
102+ def _run_interface (self , runtime , correct_return_codes = [ 0 ] ):
103103 runtime = super (WarpTimeSeriesImageMultiTransform , self )._run_interface (runtime , correct_return_codes = [0 , 1 ])
104104 if "100 % complete" not in runtime .stdout :
105105 self .raise_exception (runtime )
@@ -113,7 +113,7 @@ class WarpImageMultiTransformInputSpec(ANTSCommandInputSpec):
113113 desc = ('image to apply transformation to (generally a '
114114 'coregistered functional)' ), position = 2 )
115115 output_image = File (genfile = True , hash_files = False , argstr = '%s' ,
116- desc = ( 'name of the output warped image' ) , position = 3 , xor = ['out_postfix' ])
116+ desc = 'name of the output warped image' , position = 3 , xor = ['out_postfix' ])
117117 out_postfix = File ("_wimt" , usedefault = True , hash_files = False ,
118118 desc = ('Postfix that is prepended to all output '
119119 'files (default = _wimt)' ), xor = ['output_image' ])
@@ -159,15 +159,18 @@ class WarpImageMultiTransform(ANTSCommand):
159159 >>> wimt.inputs.reference_image = 'ants_deformed.nii.gz'
160160 >>> wimt.inputs.transformation_series = ['ants_Warp.nii.gz','ants_Affine.txt']
161161 >>> wimt.cmdline
162- 'WarpImageMultiTransform 3 structural.nii structural_wimt.nii -R ants_deformed.nii.gz ants_Warp.nii.gz ants_Affine.txt'
162+ 'WarpImageMultiTransform 3 structural.nii structural_wimt.nii -R ants_deformed.nii.gz ants_Warp.nii.gz \
163+ ants_Affine.txt'
163164
164165 >>> wimt = WarpImageMultiTransform()
165166 >>> wimt.inputs.input_image = 'diffusion_weighted.nii'
166167 >>> wimt.inputs.reference_image = 'functional.nii'
167- >>> wimt.inputs.transformation_series = ['func2anat_coreg_Affine.txt','func2anat_InverseWarp.nii.gz','dwi2anat_Warp.nii.gz','dwi2anat_coreg_Affine.txt']
168+ >>> wimt.inputs.transformation_series = ['func2anat_coreg_Affine.txt','func2anat_InverseWarp.nii.gz', \
169+ 'dwi2anat_Warp.nii.gz','dwi2anat_coreg_Affine.txt']
168170 >>> wimt.inputs.invert_affine = [1]
169171 >>> wimt.cmdline
170- 'WarpImageMultiTransform 3 diffusion_weighted.nii diffusion_weighted_wimt.nii -R functional.nii -i func2anat_coreg_Affine.txt func2anat_InverseWarp.nii.gz dwi2anat_Warp.nii.gz dwi2anat_coreg_Affine.txt'
172+ 'WarpImageMultiTransform 3 diffusion_weighted.nii diffusion_weighted_wimt.nii -R functional.nii \
173+ -i func2anat_coreg_Affine.txt func2anat_InverseWarp.nii.gz dwi2anat_Warp.nii.gz dwi2anat_coreg_Affine.txt'
171174
172175 """
173176
@@ -221,9 +224,8 @@ class ApplyTransformsInputSpec(ANTSCommandInputSpec):
221224 desc = ('image to apply transformation to (generally a '
222225 'coregistered functional)' ),
223226 exists = True )
224- output_image = traits .Str (argstr = '--output %s' ,
225- desc = ('output file name' ), genfile = True ,
226- hash_files = False )
227+ output_image = traits .Str (argstr = '--output %s' , desc = 'output file name' ,
228+ genfile = True , hash_files = False )
227229 out_postfix = traits .Str ("_trans" , usedefault = True ,
228230 desc = ('Postfix that is appended to all output '
229231 'files (default = _trans)' ))
@@ -240,17 +242,17 @@ class ApplyTransformsInputSpec(ANTSCommandInputSpec):
240242 'Gaussian' ,
241243 'BSpline' ,
242244 argstr = '%s' , usedefault = True )
243- # TODO: Implement these options for multilabel, gaussian, and bspline
244- # interpolation_sigma = traits.Float(requires=['interpolation'] )
245- # interpolation_alpha = traits.Float(requires=['interpolation_sigma'] )
246- # bspline_order = traits.Int(3, requires=['interpolation'] )
245+ interpolation_parameters = traits . Either ( traits . Tuple ( traits . Int ()), # BSpline (order)
246+ traits .Tuple ( traits . Float (), # Gaussian/MultiLabel (sigma, alpha )
247+ traits .Float () )
248+ )
247249 transforms = InputMultiPath (
248- File (exists = True ), argstr = '%s' , mandatory = True , desc = ( '' ) )
250+ File (exists = True ), argstr = '%s' , mandatory = True , desc = 'transform files' )
249251 invert_transform_flags = InputMultiPath (traits .Bool ())
250- default_value = traits .Float (
251- 0.0 , argstr = '--default-value %g' , usedefault = True )
252- print_out_composite_warp_file = traits . Enum (
253- 0 , 1 , requires = [ "output_image" ] , desc = ( '' )) # TODO: Change to boolean
252+ default_value = traits .Float (0.0 , argstr = '--default-value %g' , usedefault = True )
253+ print_out_composite_warp_file = traits . Bool ( False , requires = [ "output_image" ],
254+ desc = 'output a composite warp file instead of a transformed image' )
255+ float = traits . Bool ( argstr = '--float %d' , default = False , desc = 'Use float instead of double for computations.' )
254256
255257
256258class ApplyTransformsOutputSpec (TraitedSpec ):
@@ -275,7 +277,24 @@ class ApplyTransforms(ANTSCommand):
275277 >>> at.inputs.transforms = ['trans.mat', 'ants_Warp.nii.gz']
276278 >>> at.inputs.invert_transform_flags = [False, False]
277279 >>> at.cmdline
278- 'antsApplyTransforms --default-value 0 --dimensionality 3 --input moving1.nii --interpolation Linear --output deformed_moving1.nii --reference-image fixed1.nii --transform [trans.mat,0] --transform [ants_Warp.nii.gz,0]'
280+ 'antsApplyTransforms --default-value 0 --dimensionality 3 --input moving1.nii --interpolation Linear \
281+ --output deformed_moving1.nii --reference-image fixed1.nii --transform [ trans.mat, 0 ] \
282+ --transform [ ants_Warp.nii.gz, 0 ]'
283+
284+ >>> at1 = ApplyTransforms()
285+ >>> at1.inputs.dimension = 3
286+ >>> at1.inputs.input_image = 'moving1.nii'
287+ >>> at1.inputs.reference_image = 'fixed1.nii'
288+ >>> at1.inputs.output_image = 'deformed_moving1.nii'
289+ >>> at1.inputs.interpolation = 'BSpline'
290+ >>> at1.inputs.interpolation_parameters = (5,)
291+ >>> at1.inputs.default_value = 0
292+ >>> at1.inputs.transforms = ['trans.mat', 'ants_Warp.nii.gz']
293+ >>> at1.inputs.invert_transform_flags = [False, False]
294+ >>> at1.cmdline
295+ 'antsApplyTransforms --default-value 0 --dimensionality 3 --input moving1.nii --interpolation BSpline[ 5 ] \
296+ --output deformed_moving1.nii --reference-image fixed1.nii --transform [ trans.mat, 0 ] \
297+ --transform [ ants_Warp.nii.gz, 0 ]'
279298
280299
281300 """
@@ -292,35 +311,42 @@ def _gen_filename(self, name):
292311 return output
293312 return None
294313
295- def _getTransformFileNames (self ):
314+ def _get_transform_filenames (self ):
296315 retval = []
297316 for ii in range (len (self .inputs .transforms )):
298317 if isdefined (self .inputs .invert_transform_flags ):
299318 if len (self .inputs .transforms ) == len (self .inputs .invert_transform_flags ):
300319 invert_code = 1 if self .inputs .invert_transform_flags [
301320 ii ] else 0
302- retval .append ("--transform [%s,%d ]" %
321+ retval .append ("--transform [ %s, %d ]" %
303322 (self .inputs .transforms [ii ], invert_code ))
304323 else :
305- raise Exception ("ERROR: The useInverse list must have the same number of entries as the transformsFileName list." )
324+ raise Exception (("ERROR: The useInverse list must have the same number "
325+ "of entries as the transformsFileName list." ))
306326 else :
307327 retval .append ("--transform %s" % self .inputs .transforms [ii ])
308328 return " " .join (retval )
309329
310- def _getOutputWarpedFileName (self ):
330+ def _get_output_warped_filename (self ):
311331 if isdefined (self .inputs .print_out_composite_warp_file ):
312- return "--output [%s,%s]" % (self ._gen_filename ("output_image" ), self .inputs .print_out_composite_warp_file )
332+ return "--output [ %s, %d ]" % (self ._gen_filename ("output_image" ),
333+ int (self .inputs .print_out_composite_warp_file ))
313334 else :
314335 return "--output %s" % (self ._gen_filename ("output_image" ))
315336
316337 def _format_arg (self , opt , spec , val ):
317338 if opt == "output_image" :
318- return self ._getOutputWarpedFileName ()
339+ return self ._get_output_warped_filename ()
319340 elif opt == "transforms" :
320- return self ._getTransformFileNames ()
341+ return self ._get_transform_filenames ()
321342 elif opt == 'interpolation' :
322- # TODO: handle multilabel, gaussian, and bspline options
323- return '--interpolation %s' % self .inputs .interpolation
343+ if self .inputs .interpolation in ['BSpline' , 'MultiLabel' , 'Gaussian' ] and \
344+ isdefined (self .inputs .interpolation_parameters ):
345+ return '--interpolation %s[ %s ]' % (self .inputs .interpolation ,
346+ ', ' .join ([str (param )
347+ for param in self .inputs .interpolation_parameters ]))
348+ else :
349+ return '--interpolation %s' % self .inputs .interpolation
324350 return super (ApplyTransforms , self )._format_arg (opt , spec , val )
325351
326352 def _list_outputs (self ):
@@ -348,12 +374,12 @@ class ApplyTransformsToPointsInputSpec(ANTSCommandInputSpec):
348374 "expecting." ),
349375 exists = True )
350376 output_file = traits .Str (argstr = '--output %s' ,
351- desc = ( 'Name of the output CSV file' ) , name_source = ['input_file' ],
377+ desc = 'Name of the output CSV file' , name_source = ['input_file' ],
352378 hash_files = False , name_template = '%s_transformed.csv' )
353379 transforms = traits .List (File (exists = True ), argstr = '%s' , mandatory = True ,
354- desc = ( 'transforms that will be applied to the points' ) )
380+ desc = 'transforms that will be applied to the points' )
355381 invert_transform_flags = traits .List (traits .Bool (),
356- desc = ( 'list indicating if a transform should be reversed' ) )
382+ desc = 'list indicating if a transform should be reversed' )
357383
358384
359385class ApplyTransformsToPointsOutputSpec (TraitedSpec ):
@@ -374,30 +400,32 @@ class ApplyTransformsToPoints(ANTSCommand):
374400 >>> at.inputs.transforms = ['trans.mat', 'ants_Warp.nii.gz']
375401 >>> at.inputs.invert_transform_flags = [False, False]
376402 >>> at.cmdline
377- 'antsApplyTransformsToPoints --dimensionality 3 --input moving.csv --output moving_transformed.csv --transform [trans.mat,0] --transform [ants_Warp.nii.gz,0]'
403+ 'antsApplyTransformsToPoints --dimensionality 3 --input moving.csv --output moving_transformed.csv \
404+ --transform [ trans.mat, 0 ] --transform [ ants_Warp.nii.gz, 0 ]'
378405
379406
380407 """
381408 _cmd = 'antsApplyTransformsToPoints'
382409 input_spec = ApplyTransformsToPointsInputSpec
383410 output_spec = ApplyTransformsToPointsOutputSpec
384411
385- def _getTransformFileNames (self ):
412+ def _get_transform_filenames (self ):
386413 retval = []
387414 for ii in range (len (self .inputs .transforms )):
388415 if isdefined (self .inputs .invert_transform_flags ):
389416 if len (self .inputs .transforms ) == len (self .inputs .invert_transform_flags ):
390417 invert_code = 1 if self .inputs .invert_transform_flags [
391418 ii ] else 0
392- retval .append ("--transform [%s,%d ]" %
419+ retval .append ("--transform [ %s, %d ]" %
393420 (self .inputs .transforms [ii ], invert_code ))
394421 else :
395- raise Exception ("ERROR: The useInverse list must have the same number of entries as the transformsFileName list." )
422+ raise Exception (("ERROR: The useInverse list must have the same number "
423+ "of entries as the transformsFileName list." ))
396424 else :
397425 retval .append ("--transform %s" % self .inputs .transforms [ii ])
398426 return " " .join (retval )
399427
400428 def _format_arg (self , opt , spec , val ):
401429 if opt == "transforms" :
402- return self ._getTransformFileNames ()
430+ return self ._get_transform_filenames ()
403431 return super (ApplyTransformsToPoints , self )._format_arg (opt , spec , val )
0 commit comments