Skip to content

Commit 81fae84

Browse files
authored
Merge pull request #2674 from mgxd/fix/cmd
MAINT: ensure interface _cmd only includes executable
2 parents 91fbcce + b1007ef commit 81fae84

File tree

4 files changed

+219
-111
lines changed

4 files changed

+219
-111
lines changed

nipype/interfaces/afni/preprocess.py

+51-101
Original file line numberDiff line numberDiff line change
@@ -2953,107 +2953,6 @@ def _list_outputs(self):
29532953
return outputs
29542954

29552955

2956-
class QwarpPlusMinusInputSpec(CommandLineInputSpec):
2957-
source_file = File(
2958-
desc=
2959-
'Source image (opposite phase encoding direction than base image).',
2960-
argstr='-source %s',
2961-
mandatory=True,
2962-
exists=True,
2963-
copyfile=False)
2964-
base_file = File(
2965-
desc=
2966-
'Base image (opposite phase encoding direction than source image).',
2967-
argstr='-base %s',
2968-
mandatory=True,
2969-
exists=True,
2970-
copyfile=False)
2971-
pblur = traits.List(
2972-
traits.Float(),
2973-
desc='The fraction of the patch size that'
2974-
'is used for the progressive blur by providing a '
2975-
'value between 0 and 0.25. If you provide TWO '
2976-
'values, the first fraction is used for '
2977-
'progressively blurring the base image and the '
2978-
'second for the source image.',
2979-
argstr='-pblur %s',
2980-
minlen=1,
2981-
maxlen=2)
2982-
blur = traits.List(
2983-
traits.Float(),
2984-
desc="Gaussian blur the input images by (FWHM) voxels "
2985-
"before doing the alignment (the output dataset "
2986-
"will not be blurred). The default is 2.345 (for "
2987-
"no good reason). Optionally, you can provide 2 "
2988-
"values, and then the first one is applied to the "
2989-
"base volume, the second to the source volume. A "
2990-
"negative blur radius means to use 3D median "
2991-
"filtering, rather than Gaussian blurring. This "
2992-
"type of filtering will better preserve edges, "
2993-
"which can be important in alignment.",
2994-
argstr='-blur %s',
2995-
minlen=1,
2996-
maxlen=2)
2997-
noweight = traits.Bool(
2998-
desc='If you want a binary weight (the old default), use this option.'
2999-
'That is, each voxel in the base volume automask will be'
3000-
'weighted the same in the computation of the cost functional.',
3001-
argstr='-noweight')
3002-
minpatch = traits.Int(
3003-
desc="Set the minimum patch size for warp searching to 'mm' voxels.",
3004-
argstr='-minpatch %d')
3005-
nopadWARP = traits.Bool(
3006-
desc='If for some reason you require the warp volume to'
3007-
'match the base volume, then use this option to have the output'
3008-
'WARP dataset(s) truncated.',
3009-
argstr='-nopadWARP')
3010-
3011-
3012-
class QwarpPlusMinusOutputSpec(TraitedSpec):
3013-
warped_source = File(desc='Undistorted source file.', exists=True)
3014-
warped_base = File(desc='Undistorted base file.', exists=True)
3015-
source_warp = File(
3016-
desc="Field suceptibility correction warp (in 'mm') for source image.",
3017-
exists=True)
3018-
base_warp = File(
3019-
desc="Field suceptibility correction warp (in 'mm') for base image.",
3020-
exists=True)
3021-
3022-
3023-
class QwarpPlusMinus(CommandLine):
3024-
"""A version of 3dQwarp for performing field susceptibility correction
3025-
using two images with opposing phase encoding directions.
3026-
3027-
For complete details, see the `3dQwarp Documentation.
3028-
<https://afni.nimh.nih.gov/pub/dist/doc/program_help/3dQwarp.html>`_
3029-
3030-
Examples
3031-
========
3032-
3033-
>>> from nipype.interfaces import afni
3034-
>>> qwarp = afni.QwarpPlusMinus()
3035-
>>> qwarp.inputs.source_file = 'sub-01_dir-LR_epi.nii.gz'
3036-
>>> qwarp.inputs.nopadWARP = True
3037-
>>> qwarp.inputs.base_file = 'sub-01_dir-RL_epi.nii.gz'
3038-
>>> qwarp.cmdline
3039-
'3dQwarp -prefix Qwarp.nii.gz -plusminus -base sub-01_dir-RL_epi.nii.gz -nopadWARP -source sub-01_dir-LR_epi.nii.gz'
3040-
>>> res = warp.run() # doctest: +SKIP
3041-
3042-
"""
3043-
_cmd = '3dQwarp -prefix Qwarp.nii.gz -plusminus'
3044-
input_spec = QwarpPlusMinusInputSpec
3045-
output_spec = QwarpPlusMinusOutputSpec
3046-
3047-
def _list_outputs(self):
3048-
outputs = self.output_spec().get()
3049-
outputs['warped_source'] = os.path.abspath("Qwarp_PLUS.nii.gz")
3050-
outputs['warped_base'] = os.path.abspath("Qwarp_MINUS.nii.gz")
3051-
outputs['source_warp'] = os.path.abspath("Qwarp_PLUS_WARP.nii.gz")
3052-
outputs['base_warp'] = os.path.abspath("Qwarp_MINUS_WARP.nii.gz")
3053-
3054-
return outputs
3055-
3056-
30572956
class QwarpInputSpec(AFNICommandInputSpec):
30582957
in_file = File(
30592958
desc=
@@ -3722,3 +3621,54 @@ def _list_outputs(self):
37223621
def _gen_filename(self, name):
37233622
if name == 'out_file':
37243623
return self._gen_fname(self.inputs.source_file, suffix='_QW')
3624+
3625+
3626+
class QwarpPlusMinusInputSpec(QwarpInputSpec):
3627+
source_file = File(
3628+
desc='Source image (opposite phase encoding direction than base image)',
3629+
argstr='-source %s',
3630+
exists=True,
3631+
deprecated='1.1.2',
3632+
new_name='in_file',
3633+
copyfile=False)
3634+
out_file = File(
3635+
argstr='-prefix %s',
3636+
value='Qwarp.nii.gz',
3637+
position=0,
3638+
usedefault=True,
3639+
desc="Output file")
3640+
plusminus = traits.Bool(
3641+
True,
3642+
usedefault=True,
3643+
position=1,
3644+
desc='Normally, the warp displacements dis(x) are defined to match'
3645+
'base(x) to source(x+dis(x)). With this option, the match'
3646+
'is between base(x-dis(x)) and source(x+dis(x)) -- the two'
3647+
'images \'meet in the middle\'. For more info, view Qwarp` interface',
3648+
argstr='-plusminus',
3649+
xor=['duplo', 'allsave', 'iwarp'])
3650+
3651+
3652+
class QwarpPlusMinus(Qwarp):
3653+
"""A version of 3dQwarp for performing field susceptibility correction
3654+
using two images with opposing phase encoding directions.
3655+
3656+
For complete details, see the `3dQwarp Documentation.
3657+
<https://afni.nimh.nih.gov/pub/dist/doc/program_help/3dQwarp.html>`_
3658+
3659+
Examples
3660+
========
3661+
3662+
>>> from nipype.interfaces import afni
3663+
>>> qwarp = afni.QwarpPlusMinus()
3664+
>>> qwarp.inputs.in_file = 'sub-01_dir-LR_epi.nii.gz'
3665+
>>> qwarp.inputs.nopadWARP = True
3666+
>>> qwarp.inputs.base_file = 'sub-01_dir-RL_epi.nii.gz'
3667+
>>> qwarp.cmdline
3668+
'3dQwarp -prefix Qwarp.nii.gz -plusminus -base sub-01_dir-RL_epi.nii.gz \
3669+
-source sub-01_dir-LR_epi.nii.gz -nopadWARP'
3670+
>>> res = warp.run() # doctest: +SKIP
3671+
3672+
"""
3673+
3674+
input_spec = QwarpPlusMinusInputSpec

nipype/interfaces/afni/tests/test_auto_QwarpPlusMinus.py

+132-2
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,154 @@
55

66
def test_QwarpPlusMinus_inputs():
77
input_map = dict(
8+
Qfinal=dict(argstr='-Qfinal', ),
9+
Qonly=dict(argstr='-Qonly', ),
10+
allineate=dict(argstr='-allineate', ),
11+
allineate_opts=dict(
12+
argstr='-allineate_opts %s',
13+
requires=['allineate'],
14+
),
15+
allsave=dict(
16+
argstr='-allsave',
17+
xor=['nopadWARP', 'duplo', 'plusminus'],
18+
),
819
args=dict(argstr='%s', ),
20+
ballopt=dict(
21+
argstr='-ballopt',
22+
xor=['workhard', 'boxopt'],
23+
),
924
base_file=dict(
1025
argstr='-base %s',
1126
copyfile=False,
1227
mandatory=True,
1328
),
29+
baxopt=dict(
30+
argstr='-boxopt',
31+
xor=['workhard', 'ballopt'],
32+
),
1433
blur=dict(argstr='-blur %s', ),
34+
duplo=dict(
35+
argstr='-duplo',
36+
xor=[
37+
'gridlist', 'maxlev', 'inilev', 'iniwarp', 'plusminus',
38+
'allsave'
39+
],
40+
),
41+
emask=dict(
42+
argstr='-emask %s',
43+
copyfile=False,
44+
),
1545
environ=dict(
1646
nohash=True,
1747
usedefault=True,
1848
),
49+
expad=dict(
50+
argstr='-expad %d',
51+
xor=['nopadWARP'],
52+
),
53+
gridlist=dict(
54+
argstr='-gridlist %s',
55+
copyfile=False,
56+
xor=['duplo', 'plusminus'],
57+
),
58+
hel=dict(
59+
argstr='-hel',
60+
xor=['nmi', 'mi', 'lpc', 'lpa', 'pear'],
61+
),
62+
in_file=dict(
63+
argstr='-source %s',
64+
copyfile=False,
65+
mandatory=True,
66+
),
67+
inilev=dict(
68+
argstr='-inilev %d',
69+
xor=['duplo'],
70+
),
71+
iniwarp=dict(
72+
argstr='-iniwarp %s',
73+
xor=['duplo'],
74+
),
75+
iwarp=dict(
76+
argstr='-iwarp',
77+
xor=['plusminus'],
78+
),
79+
lpa=dict(
80+
argstr='-lpa',
81+
xor=['nmi', 'mi', 'lpc', 'hel', 'pear'],
82+
),
83+
lpc=dict(
84+
argstr='-lpc',
85+
position=-2,
86+
xor=['nmi', 'mi', 'hel', 'lpa', 'pear'],
87+
),
88+
maxlev=dict(
89+
argstr='-maxlev %d',
90+
position=-1,
91+
xor=['duplo'],
92+
),
93+
mi=dict(
94+
argstr='-mi',
95+
xor=['mi', 'hel', 'lpc', 'lpa', 'pear'],
96+
),
1997
minpatch=dict(argstr='-minpatch %d', ),
20-
nopadWARP=dict(argstr='-nopadWARP', ),
98+
nmi=dict(
99+
argstr='-nmi',
100+
xor=['nmi', 'hel', 'lpc', 'lpa', 'pear'],
101+
),
102+
noXdis=dict(argstr='-noXdis', ),
103+
noYdis=dict(argstr='-noYdis', ),
104+
noZdis=dict(argstr='-noZdis', ),
105+
noneg=dict(argstr='-noneg', ),
106+
nopad=dict(argstr='-nopad', ),
107+
nopadWARP=dict(
108+
argstr='-nopadWARP',
109+
xor=['allsave', 'expad'],
110+
),
111+
nopenalty=dict(argstr='-nopenalty', ),
112+
nowarp=dict(argstr='-nowarp', ),
21113
noweight=dict(argstr='-noweight', ),
114+
num_threads=dict(
115+
nohash=True,
116+
usedefault=True,
117+
),
118+
out_file=dict(
119+
argstr='-prefix %s',
120+
position=0,
121+
usedefault=True,
122+
),
123+
out_weight_file=dict(argstr='-wtprefix %s', ),
124+
outputtype=dict(),
125+
overwrite=dict(argstr='-overwrite', ),
22126
pblur=dict(argstr='-pblur %s', ),
127+
pear=dict(argstr='-pear', ),
128+
penfac=dict(argstr='-penfac %f', ),
129+
plusminus=dict(
130+
argstr='-plusminus',
131+
position=1,
132+
usedefault=True,
133+
xor=['duplo', 'allsave', 'iwarp'],
134+
),
135+
quiet=dict(
136+
argstr='-quiet',
137+
xor=['verb'],
138+
),
139+
resample=dict(argstr='-resample', ),
23140
source_file=dict(
24141
argstr='-source %s',
25142
copyfile=False,
26-
mandatory=True,
143+
deprecated='1.1.2',
144+
new_name='in_file',
145+
),
146+
verb=dict(
147+
argstr='-verb',
148+
xor=['quiet'],
149+
),
150+
wball=dict(argstr='-wball %s', ),
151+
weight=dict(argstr='-weight %s', ),
152+
wmask=dict(argstr='-wpass %s %f', ),
153+
workhard=dict(
154+
argstr='-workhard',
155+
xor=['boxopt', 'ballopt'],
27156
),
28157
)
29158
inputs = QwarpPlusMinus.input_spec()
@@ -37,6 +166,7 @@ def test_QwarpPlusMinus_outputs():
37166
source_warp=dict(),
38167
warped_base=dict(),
39168
warped_source=dict(),
169+
weights=dict(),
40170
)
41171
outputs = QwarpPlusMinus.output_spec()
42172

nipype/interfaces/elastix/registration.py

+22-8
Original file line numberDiff line numberDiff line change
@@ -178,21 +178,36 @@ def _list_outputs(self):
178178
return outputs
179179

180180

181-
class AnalyzeWarpInputSpec(ElastixBaseInputSpec):
182-
transform_file = File(
181+
class AnalyzeWarpInputSpec(ApplyWarpInputSpec):
182+
points = traits.Enum(
183+
'all',
184+
usedefault=True,
185+
position=0,
186+
argstr='-def %s',
187+
desc='transform all points from the input-image, which effectively'
188+
' generates a deformation field.')
189+
jac = traits.Enum(
190+
'all',
191+
usedefault=True,
192+
argstr='-jac %s',
193+
desc='generate an image with the determinant of the spatial Jacobian')
194+
jacmat = traits.Enum(
195+
'all',
196+
usedefault=True,
197+
argstr='-jacmat %s',
198+
desc='generate an image with the spatial Jacobian matrix at each voxel')
199+
moving_image = File(
183200
exists=True,
184-
mandatory=True,
185-
argstr='-tp %s',
186-
desc='transform-parameter file, only 1')
187-
201+
argstr='-in %s',
202+
desc='input image to deform (not used)')
188203

189204
class AnalyzeWarpOutputSpec(TraitedSpec):
190205
disp_field = File(desc='displacements field')
191206
jacdet_map = File(desc='det(Jacobian) map')
192207
jacmat_map = File(desc='Jacobian matrix map')
193208

194209

195-
class AnalyzeWarp(CommandLine):
210+
class AnalyzeWarp(ApplyWarp):
196211
"""
197212
Use transformix to get details from the input transform (generate
198213
the corresponding deformation field, generate the determinant of the
@@ -210,7 +225,6 @@ class AnalyzeWarp(CommandLine):
210225
211226
"""
212227

213-
_cmd = 'transformix -def all -jac all -jacmat all'
214228
input_spec = AnalyzeWarpInputSpec
215229
output_spec = AnalyzeWarpOutputSpec
216230

0 commit comments

Comments
 (0)