From 8d126069962cf29e80590d9d0198d5feeba6b9f1 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Mon, 29 Feb 2016 11:21:26 -0500 Subject: [PATCH 1/4] ENH: Specify motion parameter source in modelgen --- nipype/algorithms/modelgen.py | 11 +++++++++-- nipype/algorithms/tests/test_auto_SpecifyModel.py | 1 + nipype/algorithms/tests/test_auto_SpecifySPMModel.py | 1 + .../algorithms/tests/test_auto_SpecifySparseModel.py | 1 + 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/nipype/algorithms/modelgen.py b/nipype/algorithms/modelgen.py index 98333ed1b5..be6862ea49 100644 --- a/nipype/algorithms/modelgen.py +++ b/nipype/algorithms/modelgen.py @@ -195,6 +195,8 @@ class SpecifyModelInputSpec(BaseInterfaceInputSpec): desc='Realignment parameters returned ' 'by motion correction algorithm', copyfile=False) + parameter_source = traits.Enum("SPM", "FSL", "AFNI", "NiPy", "FSFAST", + desc="Source of motion parameters") outlier_files = InputMultiPath(File(exists=True), desc='Files containing scan outlier indices ' 'that should be tossed', @@ -389,11 +391,16 @@ def _generate_standard_design(self, infolist, functional_runs=None, def _generate_design(self, infolist=None): """Generate design specification for a typical fmri paradigm """ + par_selection = slice(6) + if isdefined(self.inputs.parameter_source): + source = self.inputs.parameter_source + if source == 'FSFAST': + par_selection = slice(1, 7) realignment_parameters = [] if isdefined(self.inputs.realignment_parameters): for parfile in self.inputs.realignment_parameters: - realignment_parameters.append(np.loadtxt(parfile)) - + realignment_parameters.append( + np.loadtxt(parfile)[:, par_selection]) outliers = [] if isdefined(self.inputs.outlier_files): for filename in self.inputs.outlier_files: diff --git a/nipype/algorithms/tests/test_auto_SpecifyModel.py b/nipype/algorithms/tests/test_auto_SpecifyModel.py index 8d0095e4af..31c7ff8272 100644 --- a/nipype/algorithms/tests/test_auto_SpecifyModel.py +++ b/nipype/algorithms/tests/test_auto_SpecifyModel.py @@ -19,6 +19,7 @@ def test_SpecifyModel_inputs(): ), outlier_files=dict(copyfile=False, ), + parameter_source=dict(), realignment_parameters=dict(copyfile=False, ), subject_info=dict(mandatory=True, diff --git a/nipype/algorithms/tests/test_auto_SpecifySPMModel.py b/nipype/algorithms/tests/test_auto_SpecifySPMModel.py index 437a7c4422..74542f815d 100644 --- a/nipype/algorithms/tests/test_auto_SpecifySPMModel.py +++ b/nipype/algorithms/tests/test_auto_SpecifySPMModel.py @@ -23,6 +23,7 @@ def test_SpecifySPMModel_inputs(): ), output_units=dict(usedefault=True, ), + parameter_source=dict(), realignment_parameters=dict(copyfile=False, ), subject_info=dict(mandatory=True, diff --git a/nipype/algorithms/tests/test_auto_SpecifySparseModel.py b/nipype/algorithms/tests/test_auto_SpecifySparseModel.py index ec99d945d3..e15ce8fc97 100644 --- a/nipype/algorithms/tests/test_auto_SpecifySparseModel.py +++ b/nipype/algorithms/tests/test_auto_SpecifySparseModel.py @@ -20,6 +20,7 @@ def test_SpecifySparseModel_inputs(): model_hrf=dict(), outlier_files=dict(copyfile=False, ), + parameter_source=dict(), realignment_parameters=dict(copyfile=False, ), save_plot=dict(), From cd49748be5d7a8201496548922d85f63bb4034dc Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Mon, 27 Feb 2017 10:47:43 -0500 Subject: [PATCH 2/4] Use normalize_mc_params in SpecifyModel --- nipype/algorithms/modelgen.py | 16 ++++++++-------- .../algorithms/tests/test_auto_SpecifyModel.py | 3 ++- .../tests/test_auto_SpecifySPMModel.py | 3 ++- .../tests/test_auto_SpecifySparseModel.py | 3 ++- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/nipype/algorithms/modelgen.py b/nipype/algorithms/modelgen.py index be6862ea49..f24e5d9dbd 100644 --- a/nipype/algorithms/modelgen.py +++ b/nipype/algorithms/modelgen.py @@ -33,6 +33,7 @@ traits, File, Bunch, BaseInterfaceInputSpec, isdefined) from ..utils.filemanip import filename_to_list +from ..utils.misc import normalize_mc_params from .. import config, logging iflogger = logging.getLogger('interface') @@ -195,7 +196,7 @@ class SpecifyModelInputSpec(BaseInterfaceInputSpec): desc='Realignment parameters returned ' 'by motion correction algorithm', copyfile=False) - parameter_source = traits.Enum("SPM", "FSL", "AFNI", "NiPy", "FSFAST", + parameter_source = traits.Enum("SPM", "FSL", "AFNI", "FSFAST", usedefault=True, desc="Source of motion parameters") outlier_files = InputMultiPath(File(exists=True), desc='Files containing scan outlier indices ' @@ -391,16 +392,13 @@ def _generate_standard_design(self, infolist, functional_runs=None, def _generate_design(self, infolist=None): """Generate design specification for a typical fmri paradigm """ - par_selection = slice(6) - if isdefined(self.inputs.parameter_source): - source = self.inputs.parameter_source - if source == 'FSFAST': - par_selection = slice(1, 7) realignment_parameters = [] if isdefined(self.inputs.realignment_parameters): for parfile in self.inputs.realignment_parameters: realignment_parameters.append( - np.loadtxt(parfile)[:, par_selection]) + np.apply_along_axis(func1d=normalize_mc_params, + axis=1, arr=np.loadtxt(parfile), + source=self.inputs.parameter_source)) outliers = [] if isdefined(self.inputs.outlier_files): for filename in self.inputs.outlier_files: @@ -563,7 +561,9 @@ def _generate_design(self, infolist=None): if isdefined(self.inputs.realignment_parameters): realignment_parameters = [] for parfile in self.inputs.realignment_parameters: - mc = np.loadtxt(parfile) + mc = np.apply_along_axis(func1d=normalize_mc_params, + axis=1, arr=np.loadtxt(parfile), + source=self.inputs.parameter_source) if not realignment_parameters: realignment_parameters.insert(0, mc) else: diff --git a/nipype/algorithms/tests/test_auto_SpecifyModel.py b/nipype/algorithms/tests/test_auto_SpecifyModel.py index 31c7ff8272..33d5435b5f 100644 --- a/nipype/algorithms/tests/test_auto_SpecifyModel.py +++ b/nipype/algorithms/tests/test_auto_SpecifyModel.py @@ -19,7 +19,8 @@ def test_SpecifyModel_inputs(): ), outlier_files=dict(copyfile=False, ), - parameter_source=dict(), + parameter_source=dict(usedefault=True, + ), realignment_parameters=dict(copyfile=False, ), subject_info=dict(mandatory=True, diff --git a/nipype/algorithms/tests/test_auto_SpecifySPMModel.py b/nipype/algorithms/tests/test_auto_SpecifySPMModel.py index 74542f815d..7a33ac63c4 100644 --- a/nipype/algorithms/tests/test_auto_SpecifySPMModel.py +++ b/nipype/algorithms/tests/test_auto_SpecifySPMModel.py @@ -23,7 +23,8 @@ def test_SpecifySPMModel_inputs(): ), output_units=dict(usedefault=True, ), - parameter_source=dict(), + parameter_source=dict(usedefault=True, + ), realignment_parameters=dict(copyfile=False, ), subject_info=dict(mandatory=True, diff --git a/nipype/algorithms/tests/test_auto_SpecifySparseModel.py b/nipype/algorithms/tests/test_auto_SpecifySparseModel.py index e15ce8fc97..4caf1c1033 100644 --- a/nipype/algorithms/tests/test_auto_SpecifySparseModel.py +++ b/nipype/algorithms/tests/test_auto_SpecifySparseModel.py @@ -20,7 +20,8 @@ def test_SpecifySparseModel_inputs(): model_hrf=dict(), outlier_files=dict(copyfile=False, ), - parameter_source=dict(), + parameter_source=dict(usedefault=True, + ), realignment_parameters=dict(copyfile=False, ), save_plot=dict(), From 05a18fa0f2b1722995b11f96aea0461654ebb6af Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Wed, 8 Mar 2017 14:29:24 -0500 Subject: [PATCH 3/4] Normalize nipy parameters --- nipype/utils/misc.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/nipype/utils/misc.py b/nipype/utils/misc.py index ea99daca36..552e24c435 100644 --- a/nipype/utils/misc.py +++ b/nipype/utils/misc.py @@ -248,10 +248,25 @@ def unflatten(in_list, prev_structure): def normalize_mc_params(params, source): """ Normalize a single row of motion parameters to the SPM format. + + SPM saves motion parameters as: + x Right-Left (mm) + y Anterior-Posterior (mm) + z Superior-Inferior (mm) + rx Pitch (rad) + ry Yaw (rad) + rz Roll (rad) """ - if source == 'FSL': + if source.upper() == 'FSL': params = params[[3, 4, 5, 0, 1, 2]] - elif source in ('AFNI', 'FSFAST'): + elif source.upper() in ('AFNI', 'FSFAST'): params = params[np.asarray([4, 5, 3, 1, 2, 0]) + (len(params) > 6)] params[3:] = params[3:] * np.pi / 180. - return params \ No newline at end of file + elif source.upper() == 'NIPY': + from nipy.algorithms.registration import to_matrix44, aff2euler + matrix = to_matrix44(params) + params = np.zeros(6) + params[:3] = matrix[:3, 3] + params[-1:2:-1] = aff2euler(matrix) + + return params From 8072cafbd7553d64677a3d8725ee53bf118d16d8 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Wed, 8 Mar 2017 14:33:08 -0500 Subject: [PATCH 4/4] Add NIPY as paramater_source --- nipype/algorithms/confounds.py | 2 +- nipype/algorithms/modelgen.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/nipype/algorithms/confounds.py b/nipype/algorithms/confounds.py index 09d7493264..ecb8d4e8a8 100644 --- a/nipype/algorithms/confounds.py +++ b/nipype/algorithms/confounds.py @@ -208,7 +208,7 @@ def _list_outputs(self): class FramewiseDisplacementInputSpec(BaseInterfaceInputSpec): in_file = File(exists=True, mandatory=True, desc='motion parameters') - parameter_source = traits.Enum("FSL", "AFNI", "SPM", "FSFAST", + parameter_source = traits.Enum("FSL", "AFNI", "SPM", "FSFAST", "NIPY", desc="Source of movement parameters", mandatory=True) radius = traits.Float(50, usedefault=True, diff --git a/nipype/algorithms/modelgen.py b/nipype/algorithms/modelgen.py index f24e5d9dbd..87367f7955 100644 --- a/nipype/algorithms/modelgen.py +++ b/nipype/algorithms/modelgen.py @@ -196,7 +196,8 @@ class SpecifyModelInputSpec(BaseInterfaceInputSpec): desc='Realignment parameters returned ' 'by motion correction algorithm', copyfile=False) - parameter_source = traits.Enum("SPM", "FSL", "AFNI", "FSFAST", usedefault=True, + parameter_source = traits.Enum("SPM", "FSL", "AFNI", "FSFAST", "NIPY", + usedefault=True, desc="Source of motion parameters") outlier_files = InputMultiPath(File(exists=True), desc='Files containing scan outlier indices '