Skip to content

Commit cbdc3dd

Browse files
committed
Merge pull request #1278 from nipy/fix/ants_cleanup
Fix: ANTs cleanup
2 parents 52d64c3 + 603d20c commit cbdc3dd

13 files changed

+367
-250
lines changed

nipype/interfaces/ants/__init__.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@
77
from .registration import ANTS, Registration
88

99
# Resampling Programs
10-
from .resampling import ApplyTransforms, ApplyTransformsToPoints, WarpImageMultiTransform, WarpTimeSeriesImageMultiTransform
11-
10+
from .resampling import (ApplyTransforms, ApplyTransformsToPoints, WarpImageMultiTransform,
11+
WarpTimeSeriesImageMultiTransform)
1212

1313
# Segmentation Programs
14-
from .segmentation import Atropos, LaplacianThickness, N4BiasFieldCorrection, JointFusion, antsCorticalThickness, antsBrainExtraction
14+
from .segmentation import (Atropos, LaplacianThickness, N4BiasFieldCorrection, JointFusion, CorticalThickness,
15+
BrainExtraction)
1516

1617
# Visualization Programs
1718
from .visualization import ConvertScalarImageToRGB, CreateTiledMosaic

nipype/interfaces/ants/base.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,3 @@ def set_default_num_threads(cls, num_threads):
8484
<instance>.inputs.num_threads
8585
"""
8686
cls._num_threads = num_threads
87-
88-
def _format_xarray(self, val):
89-
""" Convienence method for converting [1,2,3] -> 1x2x3 """
90-
val = 'x'.join([str(x) for x in val])
91-
return val

nipype/interfaces/ants/legacy.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@
1818

1919

2020
from .base import ANTSCommand, ANTSCommandInputSpec
21-
from ..base import (TraitedSpec, File, traits, InputMultiPath,
22-
isdefined, OutputMultiPath)
21+
from ..base import TraitedSpec, File, traits, isdefined, OutputMultiPath
2322
from ...utils.filemanip import split_filename
2423

2524

nipype/interfaces/ants/registration.py

Lines changed: 209 additions & 136 deletions
Large diffs are not rendered by default.

nipype/interfaces/ants/resampling.py

Lines changed: 66 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@
1111
import os
1212

1313
from .base import ANTSCommand, ANTSCommandInputSpec
14-
from ..base import (TraitedSpec, File, traits,
15-
isdefined, InputMultiPath)
14+
from ..base import TraitedSpec, File, traits, isdefined, InputMultiPath
1615
from ...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

256258
class 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

359385
class 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

Comments
 (0)