-
Notifications
You must be signed in to change notification settings - Fork 2
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
Derivation of motion parameters from HMC transforms #94
Comments
Okay, dug around the FSL source code and came up with the following: import numpy as np
import nibabel as nb
import nitransforms as nt
import pandas as pd
from scipy.spatial import transform as sst
from scipy import ndimage as ndi
hmc = nt.linear.load(motion_xfm)
timeseries = pd.read_csv(timeseries_tsv, delimiter='\t')[['rot_x', 'rot_y', 'rot_z', 'trans_x', 'trans_y', 'trans_z']]
boldref = nb.load(boldref_nii)
center_of_gravity = np.diag(boldref.header.get_zooms()) @ ndi.center_of_mass(boldref.dataobj)
fsl_hmc = nt.io.fsl.FSLLinearTransformArray.from_ras(hmc.matrix, reference=boldref, moving=boldref)
fsl_matrix = np.stack([xfm['parameters'] for xfm in fsl_hmc.xforms])
mats = fsl_matrix[:, :3, :3].transpose(0, 2, 1)
rot_xyz = sst.Rotation.from_matrix(mats).as_euler('XYZ')
trans_xyz = fsl_matrix[:, :3, 3] - mats @ center_of_gravity + center_of_gravity
recon = pd.DataFrame(data=np.hstack((rot_xyz, trans_xyz)), columns=timeseries.columns)
assert np.abs((recon - timeseries).values).max() < 1e-3 |
@oesteban Is converting to/from motion parameters as calculated by the different tools (mcflirt, 3dvolreg, spm_realign) in-scope for nitransforms? If not, I'll implement this in fmriprep for now. |
effigies
added a commit
to nipreps/fmriprep
that referenced
this issue
Feb 7, 2025
After an exploration in nipreps/fmripost-aroma#94, we now know how to reconstruct the original motion parameters (to at least 0.001 mm/rad precision) from the ITK transforms we generate. To ensure consistency between single-shot and fit+apply runs, I propose to use this function in place of the original outputs.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
FSL motion parameters are not straightforwardly related to the transform matrices that they generate. They are calculated relative to the center of mass of the reference image, rather than the reference frame, which is what the affines encode.
This is the straightforward way to extract extract motion parameters from the affines:
Here are the original FSL (left) and affine-derived (right) parameters (rotations * 50 for comparability):
Here is the correlation matrix with the FSL parameters:
The correlations are reasonably good (>0.8 for all but
trans_x
).Some code for generating similar plots:
Related: #12
The text was updated successfully, but these errors were encountered: