Skip to content

Support for motion parameters produced by AFNI (FD) #1840

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 24, 2017

Conversation

chrisgorgo
Copy link
Member

No description provided.

@@ -195,7 +195,8 @@ def _list_outputs(self):


class FramewiseDisplacementInputSpec(BaseInterfaceInputSpec):
in_plots = File(exists=True, mandatory=True, desc='motion parameters as written by FSL MCFLIRT')
in_file = File(exists=True, mandatory=True, desc='motion parameters as written by FSL MCFLIRT or AFNI 3dvolreg')
format = traits.Enum("FSL", "AFNI", desc="Format of the motion parameters file: FSL (radians), AFNI (degrees)")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not use the same set of support that's in ArtifactDetect?

parameter_source = traits.Enum("SPM", "FSL", "AFNI", "NiPy", "FSFAST",

and parameter interpretation is done here.

def _get_affine_matrix(params, source):

ps. the composite norm output of artifact detect is another way of measuring motion.

@codecov-io
Copy link

codecov-io commented Feb 24, 2017

Codecov Report

Merging #1840 into master will decrease coverage by -0.39%.
The diff coverage is 88.88%.

@@            Coverage Diff             @@
##           master    #1840      +/-   ##
==========================================
- Coverage    73.1%   72.72%   -0.39%     
==========================================
  Files        1064     1059       -5     
  Lines       53322    52559     -763     
==========================================
- Hits        38980    38221     -759     
+ Misses      14342    14338       -4
Flag Coverage Δ
#unittests 72.72% <88.88%> (-0.39%)
Impacted Files Coverage Δ
...lgorithms/tests/test_auto_FramewiseDisplacement.py 92.3% <ø> (-0.55%)
nipype/algorithms/confounds.py 80.52% <100%> (+0.28%)
nipype/algorithms/tests/test_confounds.py 93.33% <100%> (-1.41%)
nipype/algorithms/rapidart.py 37.46% <100%> (+0.14%)
nipype/utils/misc.py 88.97% <71.42%> (-1.03%)
...faces/utility/tests/test_auto_IdentityInterface.py 69.23% <ø> (-2.2%)
nipype/interfaces/tests/test_auto_S3DataGrabber.py 84.61% <ø> (-1.1%)
nipype/algorithms/tests/test_auto_MergeROIs.py 84.61% <ø> (-1.1%)
.../interfaces/mrtrix/tests/test_auto_MRTrixViewer.py 84.61% <ø> (-1.1%)
... and 700 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0ac8143...ff2160a. Read the comment docs.

@chrisgorgo
Copy link
Member Author

All good after last commit @satra ?

Copy link
Member

@effigies effigies left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that this issue occurs multiple times (see also #1379), would it be useful to have a util function that loads/normalizes motion parameter files?

@@ -195,7 +195,10 @@ def _list_outputs(self):


class FramewiseDisplacementInputSpec(BaseInterfaceInputSpec):
in_plots = File(exists=True, mandatory=True, desc='motion parameters as written by FSL MCFLIRT')
in_file = File(exists=True, mandatory=True, desc='motion parameters as written by FSL MCFLIRT or AFNI 3dvolreg')
parameter_source = traits.Enum("FSL", "AFNI",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FSFAST can be supported pretty easily, given AFNI support. See other comment. And I believe SPM and FSL parameter files are the same?

diff = mpars[:-1, :] - mpars[1:, :]
diff[:, :3] *= self.inputs.radius
if self.inputs.parameter_source == "AFNI":
diff[:, :3] *= (np.pi / 180)
fd_res = np.abs(diff).sum(axis=1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest modifying the mpars rather than the diff, just to make it a little clearer what's going on. Following also adds FSFAST support.

mpars = np.loadtxt(self.inputs.in_file)  # mpars is N_t x 6 (N_t x 7 for FSFAST)
if self.inputs.parameter_source in ('AFNI', 'FSFAST'):
    mpars = mpars[np.asarray([4, 5, 3, 1, 2, 0]) + (mpars.shape[1] > 6)]
    mpars[:, 3:] *= np.pi / 180
diff = np.diff(mpars, axis=0)
diff[:, :3] *= self.inputs.radius
fd_res = np.abs(diff).sum(axis=1)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UGH. Do not use the above, which re-sorts the parameters. This can be done more simply by taking the last 6 columns.

mpars = np.loadtxt(self.inputs.in_file)[:, -6:]  # mpars is N_t x 6
if self.inputs.parameter_source in ('AFNI', 'FSFAST'):
    mpars[:, :3] *= np.pi / 180
diff = np.diff(mpars, axis=0)
diff[:, :3] *= self.inputs.radius
fd_res = np.abs(diff).sum(axis=1)

And this doesn't handle SPM, contra my previous comment, because SPM puts its rotation parameters first. (Though my confused comments may support the idea of solving the "load normalized motion params" issue once and reusing.)

@satra
Copy link
Member

satra commented Feb 24, 2017

@effigies - if you hadn't seen my comments to chris earlier, here is the other place in nipype we deal with this:

def _get_affine_matrix(params, source):

@effigies
Copy link
Member

@satra I did, and that's what I was working off of for my first comment (and completely skipped over the FSL/SPM difference). Which makes this (if we count #1379) three places where we (at least partially) solve the same problem of normalizing for parameter source. That one only handles a single row, so it's not quite a drop-in replacement, but still.

@chrisgorgo
Copy link
Member Author

How does this new refactor look to you?

@effigies
Copy link
Member

Looks reasonable.

@chrisgorgo chrisgorgo merged commit b52524e into nipy:master Feb 24, 2017
@effigies effigies mentioned this pull request Mar 6, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants