Images with different affines after fmriprep preprocessing

Hi!

I have a dataset with 33 participants and 3 runs of the same task. I preprocessed the dataset with fmriprep and I want to analyze it with nilearn. However, while doinf the analysis I’ve discovered that masks and preprocessed bold for some images have affines different from the rest of the dataset, and because of that I can’t run GLM analysis via nilearn.
Do you know why this might be the issue and what can be done about it?

Best,
Anastasia

Hi, can you share some details about how you ran fMRIPrep and what your outputs look like (e.g., what affines are you seeing)?

To take a stab in the dark, you may have some tasks of different resolution, which will lead to differently shaped outputs. To normalize to a single resolution, you can add :res-2 to your output spaces specification. See Defining standard and nonstandard spaces where data will be resampled - Standard spaces from the fMRIPrep documentation.

I checked raw nifti, and the sizes of the images are the same, but the affines are different.
So did I understand correctly: the only solution is to rerun fmriprep with this new output space specification?

I ran fmriprep and following:
fmriprep-docker /media/alando/TOSHIBA_EXT/motor_imagery_study/data/Nifti media/alando/TOSHIBA_EXT/motor_imagery_study/data/preprocessed/derivatives --participant-label L1212052 --use-aroma --fs-license-file /home/alando/installed/license.txt --omp-nthreads 8 --nthreads 8 --low-mem

I use fmriprep outputs with the suffix _space-MNI152NLin2009cAsym_desc-preproc_bold.nii.gz for my GLM analysis, and I see 2 types of affines:
array([[ 3.43799996, 0. , 0. , -96.5 ],
[ 0. , 3.43799996, 0. , -132.5 ],
[ 0. , 0. , 4.4000001 , -78.5 ],
[ 0. , 0. , 0. , 1. ]])

array([[ 3.43700004, 0. , 0. , -96.5 ],
[ 0. , 3.43799996, 0. , -132.5 ],
[ 0. , 0. , 4.4000001 , -78.5 ],
[ 0. , 0. , 0. , 1. ]])

I’m sorry, I didn’t finish writing this last week…


If you look at the pixdim field (you can use fslhd or similar), I expect you’ll see something like the following rows (where TR is your repetition time):

4 3.43799996 3.43799996 4.4000001 TR 0 0 0
4 3.43700004 3.43799996 4.4000001 TR 0 0 0

For such a small difference (0.0001mm), you can probably just overwrite the header. An example:

import numpy as np
import nibabel as nb

good_img = nb.load(fname1)        # Use this image's affine
img_to_update = nb.load(fname2)   # Use this image's data
new_img = nb.Nifti1Image(
    np.asanyarray(img_to_update.dataobj),
    affine=good_img.affine,
    header=img_to_update.header)  # Keep everything in the header but the affine
new_img.to_filename(fname2)

Thanks a lot!

I also realized that I can simply resample images

Yes, you can do that, though I have seen some weird results when resampling images with such small differences in voxel sizes. I would make sure to have a close look at the results.

Hi there,

I’m encountering a similar issue. My functional images have voxel dimensions of 2.973 x 2.973 x 3 mm. Is it suitable to use ‘res-2’? I’m inclined to find a template with a resolution closer to the native space (e.g., 3x3x3). However, I couldn’t locate an option for the default template MNI152NLin2009cAsym with a voxel size of 3x3x3. Could you suggest which template might be appropriate? I stumbled upon ‘tpl-MNI152NLin2009cAsym_res-03_atlas-DiFuMo’ in TemplateFlow, but I’m unsure if this is the right choice and how to specify the use of this template.

Your insights would be greatly appreciated.

Thanks,
Anna