Skip to content

Commit fc2c5b4

Browse files
authored
Merge pull request #2229 from djarecka/warp_image_arg
changing _format_arg in WarpImageMultiTransform, should fix #2192
2 parents 450c7d2 + a8f32b6 commit fc2c5b4

File tree

2 files changed

+118
-5
lines changed

2 files changed

+118
-5
lines changed

nipype/interfaces/ants/resampling.py

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,12 @@ class WarpTimeSeriesImageMultiTransformInputSpec(ANTSCommandInputSpec):
4343
desc='transformation file(s) to be applied',
4444
mandatory=True, copyfile=False)
4545
invert_affine = traits.List(traits.Int,
46-
desc=('List of Affine transformations to invert. '
46+
desc=('List of Affine transformations to invert.'
4747
'E.g.: [1,4,5] inverts the 1st, 4th, and 5th Affines '
48-
'found in transformation_series'))
48+
'found in transformation_series. Note that indexing '
49+
'starts with 1 and does not include warp fields. Affine '
50+
'transformations are distinguished '
51+
'from warp fields by the word "affine" included in their filenames.'))
4952

5053

5154
class WarpTimeSeriesImageMultiTransformOutputSpec(TraitedSpec):
@@ -67,6 +70,14 @@ class WarpTimeSeriesImageMultiTransform(ANTSCommand):
6770
'WarpTimeSeriesImageMultiTransform 4 resting.nii resting_wtsimt.nii -R ants_deformed.nii.gz ants_Warp.nii.gz \
6871
ants_Affine.txt'
6972
73+
>>> wtsimt = WarpTimeSeriesImageMultiTransform()
74+
>>> wtsimt.inputs.input_image = 'resting.nii'
75+
>>> wtsimt.inputs.reference_image = 'ants_deformed.nii.gz'
76+
>>> wtsimt.inputs.transformation_series = ['ants_Warp.nii.gz','ants_Affine.txt']
77+
>>> wtsimt.inputs.invert_affine = [1] # # this will invert the 1st Affine file: ants_Affine.txt
78+
>>> wtsimt.cmdline # doctest: +ALLOW_UNICODE
79+
'WarpTimeSeriesImageMultiTransform 4 resting.nii resting_wtsimt.nii -R ants_deformed.nii.gz ants_Warp.nii.gz \
80+
-i ants_Affine.txt'
7081
"""
7182

7283
_cmd = 'WarpTimeSeriesImageMultiTransform'
@@ -81,13 +92,22 @@ def _format_arg(self, opt, spec, val):
8192
if opt == 'transformation_series':
8293
series = []
8394
affine_counter = 0
95+
affine_invert = []
8496
for transformation in val:
8597
if 'Affine' in transformation and \
8698
isdefined(self.inputs.invert_affine):
8799
affine_counter += 1
88100
if affine_counter in self.inputs.invert_affine:
89-
series += ['-i'],
101+
series += ['-i']
102+
affine_invert.append(affine_counter)
90103
series += [transformation]
104+
105+
if isdefined(self.inputs.invert_affine):
106+
diff_inv = set(self.inputs.invert_affine) - set(affine_invert)
107+
if diff_inv:
108+
raise Exceptions("Review invert_affine, not all indexes from invert_affine were used, "
109+
"check the description for the full definition")
110+
91111
return ' '.join(series)
92112
return super(WarpTimeSeriesImageMultiTransform, self)._format_arg(opt, spec, val)
93113

@@ -168,7 +188,7 @@ class WarpImageMultiTransform(ANTSCommand):
168188
>>> wimt.inputs.reference_image = 'functional.nii'
169189
>>> wimt.inputs.transformation_series = ['func2anat_coreg_Affine.txt','func2anat_InverseWarp.nii.gz', \
170190
'dwi2anat_Warp.nii.gz','dwi2anat_coreg_Affine.txt']
171-
>>> wimt.inputs.invert_affine = [1]
191+
>>> wimt.inputs.invert_affine = [1] # this will invert the 1st Affine file: 'func2anat_coreg_Affine.txt'
172192
>>> wimt.cmdline # doctest: +ALLOW_UNICODE
173193
'WarpImageMultiTransform 3 diffusion_weighted.nii diffusion_weighted_wimt.nii -R functional.nii \
174194
-i func2anat_coreg_Affine.txt func2anat_InverseWarp.nii.gz dwi2anat_Warp.nii.gz dwi2anat_coreg_Affine.txt'
@@ -190,14 +210,24 @@ def _format_arg(self, opt, spec, val):
190210
if opt == 'transformation_series':
191211
series = []
192212
affine_counter = 0
213+
affine_invert = []
193214
for transformation in val:
194215
if "affine" in transformation.lower() and \
195216
isdefined(self.inputs.invert_affine):
196217
affine_counter += 1
197218
if affine_counter in self.inputs.invert_affine:
198-
series += '-i',
219+
series += ['-i']
220+
affine_invert.append(affine_counter)
199221
series += [transformation]
222+
223+
if isdefined(self.inputs.invert_affine):
224+
diff_inv = set(self.inputs.invert_affine) - set(affine_invert)
225+
if diff_inv:
226+
raise Exceptions("Review invert_affine, not all indexes from invert_affine were used, "
227+
"check the description for the full definition")
228+
200229
return ' '.join(series)
230+
201231
return super(WarpImageMultiTransform, self)._format_arg(opt, spec, val)
202232

203233
def _list_outputs(self):
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
2+
# vi: set ft=python sts=4 ts=4 sw=4 et:
3+
4+
from nipype.interfaces.ants import WarpImageMultiTransform, WarpTimeSeriesImageMultiTransform
5+
import os
6+
import pytest
7+
8+
9+
@pytest.fixture()
10+
def change_dir(request):
11+
orig_dir = os.getcwd()
12+
filepath = os.path.dirname( os.path.realpath( __file__ ) )
13+
datadir = os.path.realpath(os.path.join(filepath, '../../../testing/data'))
14+
os.chdir(datadir)
15+
16+
def move2orig():
17+
os.chdir(orig_dir)
18+
19+
request.addfinalizer(move2orig)
20+
21+
22+
@pytest.fixture()
23+
def create_wimt():
24+
wimt = WarpImageMultiTransform()
25+
wimt.inputs.input_image = 'diffusion_weighted.nii'
26+
wimt.inputs.reference_image = 'functional.nii'
27+
wimt.inputs.transformation_series = ['func2anat_coreg_Affine.txt','func2anat_InverseWarp.nii.gz', \
28+
'dwi2anat_Warp.nii.gz','dwi2anat_coreg_Affine.txt']
29+
return wimt
30+
31+
def test_WarpImageMultiTransform(change_dir, create_wimt):
32+
wimt = create_wimt
33+
assert wimt.cmdline == 'WarpImageMultiTransform 3 diffusion_weighted.nii diffusion_weighted_wimt.nii -R functional.nii \
34+
func2anat_coreg_Affine.txt func2anat_InverseWarp.nii.gz dwi2anat_Warp.nii.gz dwi2anat_coreg_Affine.txt'
35+
36+
37+
def test_WarpImageMultiTransform_invaffine_1(change_dir, create_wimt):
38+
wimt = create_wimt
39+
wimt.inputs.invert_affine = [1]
40+
assert wimt.cmdline == 'WarpImageMultiTransform 3 diffusion_weighted.nii diffusion_weighted_wimt.nii -R functional.nii \
41+
-i func2anat_coreg_Affine.txt func2anat_InverseWarp.nii.gz dwi2anat_Warp.nii.gz dwi2anat_coreg_Affine.txt'
42+
43+
44+
def test_WarpImageMultiTransform_invaffine_2(change_dir, create_wimt):
45+
wimt = create_wimt
46+
wimt.inputs.invert_affine = [2]
47+
assert wimt.cmdline == 'WarpImageMultiTransform 3 diffusion_weighted.nii diffusion_weighted_wimt.nii -R functional.nii func2anat_coreg_Affine.txt func2anat_InverseWarp.nii.gz dwi2anat_Warp.nii.gz -i dwi2anat_coreg_Affine.txt'
48+
49+
50+
def test_WarpImageMultiTransform_invaffine_wrong(change_dir, create_wimt):
51+
wimt = create_wimt
52+
wimt.inputs.invert_affine = [3]
53+
with pytest.raises(Exception):
54+
assert wimt.cmdline
55+
56+
57+
@pytest.fixture()
58+
def create_wtsimt():
59+
wtsimt = WarpTimeSeriesImageMultiTransform()
60+
wtsimt.inputs.input_image = 'resting.nii'
61+
wtsimt.inputs.reference_image = 'ants_deformed.nii.gz'
62+
wtsimt.inputs.transformation_series = ['ants_Warp.nii.gz','ants_Affine.txt']
63+
return wtsimt
64+
65+
66+
def test_WarpTimeSeriesImageMultiTransform(change_dir, create_wtsimt):
67+
wtsimt = create_wtsimt
68+
assert wtsimt.cmdline == 'WarpTimeSeriesImageMultiTransform 4 resting.nii resting_wtsimt.nii \
69+
-R ants_deformed.nii.gz ants_Warp.nii.gz ants_Affine.txt'
70+
71+
72+
def test_WarpTimeSeriesImageMultiTransform_invaffine(change_dir, create_wtsimt):
73+
wtsimt = create_wtsimt
74+
wtsimt.inputs.invert_affine = [1]
75+
assert wtsimt.cmdline == 'WarpTimeSeriesImageMultiTransform 4 resting.nii resting_wtsimt.nii \
76+
-R ants_deformed.nii.gz ants_Warp.nii.gz -i ants_Affine.txt'
77+
78+
79+
def test_WarpTimeSeriesImageMultiTransform_invaffine_wrong(change_dir, create_wtsimt):
80+
wtsimt = create_wtsimt
81+
wtsimt.inputs.invert_affine = [0]
82+
with pytest.raises(Exception):
83+
wtsimt.cmdline

0 commit comments

Comments
 (0)