-
Notifications
You must be signed in to change notification settings - Fork 532
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
Conversation
nipype/algorithms/confounds.py
Outdated
@@ -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)") |
There was a problem hiding this comment.
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
?
nipype/nipype/algorithms/rapidart.py
Line 163 in 86cd8ff
parameter_source = traits.Enum("SPM", "FSL", "AFNI", "NiPy", "FSFAST", |
and parameter interpretation is done here.
nipype/nipype/algorithms/rapidart.py
Line 42 in 86cd8ff
def _get_affine_matrix(params, source): |
ps. the composite norm output of artifact detect is another way of measuring motion.
Codecov Report
@@ 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
Continue to review full report at Codecov.
|
All good after last commit @satra ? |
There was a problem hiding this 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?
nipype/algorithms/confounds.py
Outdated
@@ -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", |
There was a problem hiding this comment.
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?
nipype/algorithms/confounds.py
Outdated
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) |
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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.)
@effigies - if you hadn't seen my comments to chris earlier, here is the other place in nipype we deal with this: nipype/nipype/algorithms/rapidart.py Line 42 in 86cd8ff
|
@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. |
How does this new refactor look to you? |
Looks reasonable. |
No description provided.