Skip to content

Commit b52524e

Browse files
authored
Merge pull request #1840 from chrisfilo/enh/fd_afni
Support for motion parameters produced by AFNI (FD)
2 parents 34656ff + ff2160a commit b52524e

File tree

5 files changed

+31
-14
lines changed

5 files changed

+31
-14
lines changed

nipype/algorithms/confounds.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
from ..interfaces.base import (traits, TraitedSpec, BaseInterface,
2828
BaseInterfaceInputSpec, File, isdefined,
2929
InputMultiPath)
30-
from nipype.utils import NUMPY_MMAP
30+
from ..utils import NUMPY_MMAP
31+
from ..utils.misc import normalize_mc_params
3132

3233
IFLOG = logging.getLogger('interface')
3334

@@ -206,7 +207,10 @@ def _list_outputs(self):
206207

207208

208209
class FramewiseDisplacementInputSpec(BaseInterfaceInputSpec):
209-
in_plots = File(exists=True, mandatory=True, desc='motion parameters as written by FSL MCFLIRT')
210+
in_file = File(exists=True, mandatory=True, desc='motion parameters')
211+
parameter_source = traits.Enum("FSL", "AFNI", "SPM", "FSFAST",
212+
desc="Source of movement parameters",
213+
mandatory=True)
210214
radius = traits.Float(50, usedefault=True,
211215
desc='radius in mm to calculate angular FDs, 50mm is the '
212216
'default since it is used in Power et al. 2012')
@@ -260,9 +264,12 @@ class FramewiseDisplacement(BaseInterface):
260264
}]
261265

262266
def _run_interface(self, runtime):
263-
mpars = np.loadtxt(self.inputs.in_plots) # mpars is N_t x 6
264-
diff = mpars[:-1, :] - mpars[1:, :]
265-
diff[:, :3] *= self.inputs.radius
267+
mpars = np.loadtxt(self.inputs.in_file) # mpars is N_t x 6
268+
mpars = np.apply_along_axis(func1d=normalize_mc_params,
269+
axis=1, arr=mpars,
270+
source=self.inputs.parameter_source)
271+
diff = mpars[:-1, :6] - mpars[1:, :6]
272+
diff[:, 3:6] *= self.inputs.radius
266273
fd_res = np.abs(diff).sum(axis=1)
267274

268275
self._results = {

nipype/algorithms/rapidart.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
OutputMultiPath, TraitedSpec, File,
3535
BaseInterfaceInputSpec, isdefined)
3636
from ..utils.filemanip import filename_to_list, save_json, split_filename
37-
from ..utils.misc import find_indices
37+
from ..utils.misc import find_indices, normalize_mc_params
3838
from .. import logging, config
3939
iflogger = logging.getLogger('interface')
4040

@@ -46,15 +46,12 @@ def _get_affine_matrix(params, source):
4646
source : the package that generated the parameters
4747
supports SPM, AFNI, FSFAST, FSL, NIPY
4848
"""
49-
if source == 'FSL':
50-
params = params[[3, 4, 5, 0, 1, 2]]
51-
elif source in ('AFNI', 'FSFAST'):
52-
params = params[np.asarray([4, 5, 3, 1, 2, 0]) + (len(params) > 6)]
53-
params[3:] = params[3:] * np.pi / 180.
5449
if source == 'NIPY':
5550
# nipy does not store typical euler angles, use nipy to convert
5651
from nipy.algorithms.registration import to_matrix44
5752
return to_matrix44(params)
53+
54+
params = normalize_mc_params(params, source)
5855
# process for FSL, SPM, AFNI and FSFAST
5956
rotfunc = lambda x: np.array([[np.cos(x), np.sin(x)],
6057
[-np.sin(x), np.cos(x)]])

nipype/algorithms/tests/test_auto_FramewiseDisplacement.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def test_FramewiseDisplacement_inputs():
1111
ignore_exception=dict(nohash=True,
1212
usedefault=True,
1313
),
14-
in_plots=dict(mandatory=True,
14+
in_file=dict(mandatory=True,
1515
),
1616
normalize=dict(usedefault=True,
1717
),

nipype/algorithms/tests/test_confounds.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@
2121
def test_fd(tmpdir):
2222
tempdir = str(tmpdir)
2323
ground_truth = np.loadtxt(example_data('fsl_motion_outliers_fd.txt'))
24-
fdisplacement = FramewiseDisplacement(in_plots=example_data('fsl_mcflirt_movpar.txt'),
25-
out_file=tempdir + '/fd.txt')
24+
fdisplacement = FramewiseDisplacement(in_file=example_data('fsl_mcflirt_movpar.txt'),
25+
out_file=tempdir + '/fd.txt',
26+
parameter_source="FSL")
2627
res = fdisplacement.run()
2728

2829
with open(res.outputs.out_file) as all_lines:

nipype/utils/misc.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,3 +243,15 @@ def unflatten(in_list, prev_structure):
243243
for item in prev_structure:
244244
out.append(unflatten(in_list, item))
245245
return out
246+
247+
248+
def normalize_mc_params(params, source):
249+
"""
250+
Normalize a single row of motion parameters to the SPM format.
251+
"""
252+
if source == 'FSL':
253+
params = params[[3, 4, 5, 0, 1, 2]]
254+
elif source in ('AFNI', 'FSFAST'):
255+
params = params[np.asarray([4, 5, 3, 1, 2, 0]) + (len(params) > 6)]
256+
params[3:] = params[3:] * np.pi / 180.
257+
return params

0 commit comments

Comments
 (0)