Skip to content

Commit ff3fedd

Browse files
committed
Merge branch 'master' into fix/reporting
* master: fix: updated doctest, pep8 and unit test doc: updated doctest to use literal string fix: display cmdline string explicitly tst: added test_fslmerge with check for tr updates rf: modify fsl.Merge api to abstract setting TR when merging along time dimension fix: indentation error fix: include name_source and name_template for mergefile in fsl.Merge input_spec add: _format_arg override to support tr rm: _list_outputs and _gen_filename from fsl.Merge doc: updated to use funcfile and test cmdline output fix: set tr position to -1 add: option 'a' for autochoose tst: included tr in test dict for fsl.Merge doc: improved for fsl.Merge and included example usage add: support for setting TR in fsl.Merge Add FSFAST option to RapidArt
2 parents 2d72200 + f9f3ffd commit ff3fedd

File tree

3 files changed

+83
-22
lines changed

3 files changed

+83
-22
lines changed

nipype/algorithms/rapidart.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,21 @@ def _get_affine_matrix(params, source):
4242
4343
params : np.array (upto 12 long) in native package format
4444
source : the package that generated the parameters
45-
supports SPM, AFNI, FSL, NIPY
45+
supports SPM, AFNI, FSFAST, FSL, NIPY
4646
"""
4747
if source == 'FSL':
4848
params = params[[3, 4, 5, 0, 1, 2]]
4949
elif source == 'AFNI':
5050
params = params[[4, 5, 3, 1, 2, 0]]
5151
params[3:] = params[3:] * np.pi / 180.
52+
elif source == 'FSFAST':
53+
params = params[[5, 6, 4, 2, 3, 1]]
54+
params[3:] = params[3:] * np.pi / 180.
5255
if source == 'NIPY':
5356
# nipy does not store typical euler angles, use nipy to convert
5457
from nipy.algorithms.registration import to_matrix44
5558
return to_matrix44(params)
56-
#process for FSL, SPM and AFNI
59+
#process for FSL, SPM, AFNI and FSFAST
5760
rotfunc = lambda x: np.array([[np.cos(x), np.sin(x)],
5861
[-np.sin(x), np.cos(x)]])
5962
q = np.array([0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0])
@@ -76,7 +79,7 @@ def _get_affine_matrix(params, source):
7679
# Shear
7780
Sh = np.eye(4)
7881
Sh[(0, 0, 1), (1, 2, 2)] = params[9:12]
79-
if source == 'AFNI':
82+
if source in ('AFNI', 'FSFAST'):
8083
return np.dot(T, np.dot(Ry, np.dot(Rx, np.dot(Rz, np.dot(S, Sh)))))
8184
return np.dot(T, np.dot(Rx, np.dot(Ry, np.dot(Rz, np.dot(S, Sh)))))
8285

@@ -158,7 +161,7 @@ class ArtifactDetectInputSpec(BaseInterfaceInputSpec):
158161
realignment_parameters = InputMultiPath(File(exists=True), mandatory=True,
159162
desc=("Names of realignment parameters"
160163
"corresponding to the functional data files"))
161-
parameter_source = traits.Enum("SPM", "FSL", "AFNI", "NiPy",
164+
parameter_source = traits.Enum("SPM", "FSL", "AFNI", "NiPy", "FSFAST",
162165
desc="Source of movement parameters",
163166
mandatory=True)
164167
use_differences = traits.ListBool([True, False], minlen=2, maxlen=2,

nipype/interfaces/fsl/tests/test_utils.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ def test_merge():
8181
dimension=dict(argstr='-%s', mandatory=True,),
8282
environ=dict(),
8383
in_files=dict(mandatory=True, argstr='%s',),
84+
tr=dict(argstr='%.2f'),
8485
merged_file=dict(argstr='%s',),
8586
output_type=dict(),
8687
)
@@ -186,6 +187,43 @@ def test_fslroi():
186187
# Fslroi class doesn't have a filled opt_map{}
187188

188189

190+
@skipif(no_fsl)
191+
def test_fslmerge():
192+
filelist, outdir, cwd = create_files_in_directory()
193+
194+
merger = fsl.Merge()
195+
196+
# make sure command gets called
197+
yield assert_equal, merger.cmd, 'fslmerge'
198+
199+
# test raising error with mandatory args absent
200+
yield assert_raises, ValueError, merger.run
201+
202+
# .inputs based parameters setting
203+
merger.inputs.in_files = filelist
204+
merger.inputs.merged_file = 'foo_merged.nii'
205+
merger.inputs.dimension = 't'
206+
merger.inputs.output_type = 'NIFTI'
207+
yield assert_equal, merger.cmdline, 'fslmerge -t foo_merged.nii %s' % ' '.join(filelist)
208+
209+
# verify that providing a tr value updates the dimension to tr
210+
merger.inputs.tr = 2.25
211+
yield assert_equal, merger.cmdline, 'fslmerge -tr foo_merged.nii %s %.2f' % (' '.join(filelist), 2.25)
212+
213+
# .run based parameter setting
214+
merger2 = fsl.Merge(in_files=filelist,
215+
merged_file='foo_merged.nii',
216+
dimension='t',
217+
output_type='NIFTI',
218+
tr=2.25)
219+
220+
yield assert_equal, merger2.cmdline, \
221+
'fslmerge -tr foo_merged.nii %s %.2f' % (' '.join(filelist), 2.25)
222+
223+
clean_directory(outdir, cwd)
224+
# test arguments for opt_map
225+
# Fslmerge class doesn't have a filled opt_map{}
226+
189227
# test fslmath
190228
@skipif(no_fsl)
191229
def test_fslmaths():

nipype/interfaces/fsl/utils.py

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,15 @@ def _format_arg(self, name, trait_spec, value):
131131
class MergeInputSpec(FSLCommandInputSpec):
132132
in_files = traits.List(File(exists=True), argstr="%s", position=2,
133133
mandatory=True)
134-
dimension = traits.Enum('t', 'x', 'y', 'z', argstr="-%s", position=0,
135-
desc="dimension along which to merge",
134+
dimension = traits.Enum('t', 'x', 'y', 'z', 'a', argstr="-%s", position=0,
135+
desc=("dimension along which to merge, optionally "
136+
"set tr input when dimension is t"),
136137
mandatory=True)
137-
merged_file = File(argstr="%s", position=1, genfile=True, hash_files=False)
138+
tr = traits.Float(position=-1, argstr='%.2f',
139+
desc=('use to specify TR in seconds (default is 1.00 '
140+
'sec), overrides dimension and sets it to tr'))
141+
merged_file = File(argstr="%s", position=1, name_source='in_files',
142+
name_template='%s_merged', hash_files=False)
138143

139144

140145
class MergeOutputSpec(TraitedSpec):
@@ -143,27 +148,42 @@ class MergeOutputSpec(TraitedSpec):
143148

144149
class Merge(FSLCommand):
145150
"""Use fslmerge to concatenate images
151+
152+
Images can be concatenated across time, x, y, or z dimensions. Across the
153+
time (t) dimension the TR is set by default to 1 sec.
154+
155+
Note: to set the TR to a different value, specify 't' for dimension and
156+
specify the TR value in seconds for the tr input. The dimension will be
157+
automatically updated to 'tr'.
158+
159+
Examples
160+
--------
161+
>>> from nipype.interfaces.fsl import Merge
162+
>>> merger = Merge()
163+
>>> merger.inputs.in_files = ['functional2.nii', 'functional3.nii']
164+
>>> merger.inputs.dimension = 't'
165+
>>> merger.inputs.output_type = 'NIFTI_GZ'
166+
>>> merger.cmdline
167+
'fslmerge -t functional2_merged.nii.gz functional2.nii functional3.nii'
168+
>>> merger.inputs.tr = 2.25
169+
>>> merger.cmdline
170+
'fslmerge -tr functional2_merged.nii.gz functional2.nii functional3.nii 2.25'
146171
"""
147172

148173
_cmd = 'fslmerge'
149174
input_spec = MergeInputSpec
150175
output_spec = MergeOutputSpec
151176

152-
def _list_outputs(self):
153-
outputs = self._outputs().get()
154-
outputs['merged_file'] = self.inputs.merged_file
155-
if not isdefined(outputs['merged_file']):
156-
outputs['merged_file'] = self._gen_fname(self.inputs.in_files[0],
157-
suffix='_merged')
158-
else:
159-
outputs['merged_file'] = os.path.realpath(self.inputs.merged_file)
160-
161-
return outputs
162-
163-
def _gen_filename(self, name):
164-
if name == 'merged_file':
165-
return self._list_outputs()[name]
166-
return None
177+
def _format_arg(self, name, spec, value):
178+
if name == 'tr':
179+
if self.inputs.dimension != 't':
180+
raise ValueError('When TR is specified, dimension must be t')
181+
return spec.argstr % value
182+
if name == 'dimension':
183+
if isdefined(self.inputs.tr):
184+
return '-tr'
185+
return spec.argstr % value
186+
return super(Merge, self)._format_arg(name, spec, value)
167187

168188

169189
class ExtractROIInputSpec(FSLCommandInputSpec):

0 commit comments

Comments
 (0)