Skip to content

Commit 1ac4025

Browse files
committed
Merge remote-tracking branch 'upstream/pr/1278' into fix/use_current_prov
* upstream/pr/1278: Removed verbose input (only available in current master of ANTs). Will wait for next release to add. Added old class names for backwards compatibility, included DeprecationWarning Standardized imports for ANTs Finished TODO items in ApplyTransforms and added option to Atropos Added interpolation_parameters, float and verbose to ApplyTransforms and added use_random_seed and verbose to Atropos Finished TODO items in resampling (ApplyTransforms) PEP8 and other style corrections. Including doctstrings using multi-line string formatting. Changed class names for antsBrainExtraction and antsCorticalThickness. Removed redundant _format_xarray from ANTSCommand and replaced other join functions with _format_xarray
2 parents 8cacff0 + 603d20c commit 1ac4025

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)