Problem applying h5-files from fmriprep outputs for reproduction of normalization

Dear Community,

currently I am aiming to reproduce the normalization steps in fmriprep (e.g. _desc-preproc_T1w.nii.gz → 1_space-MNI152NLin6Asym_desc-preproc_T1w.nii.gz) with nitransforms. The bigger goal is to check bit-identity between fmriprep outputs and manually produced normalization outputs allowing us to easily reproduce just the normalization with datalad (rerun) and hence throw away the normalized images alleviating our storage issues. Not being able to identify the exact code related to the normalization in the fmriprep and smriprep code base I was trying to achieve a normalization with the .h5-file produced by fmriprep (_from-T1w_to-MNI152NLin6Asym_mode-image_xfm.h5).

If I understand the documentation correctly loading the h5-file with nt.manip.load and applying / mapping it subsequently should do the job.

My code:

T1w = nib.load("sub-000480a3_ses-1_desc-preproc_T1w.nii.gz")
T1w_MNI_ref = nib.load("sub-000480a3_ses-1_space-MNI152NLin6Asym_desc-preproc_T1w.nii.gz")
xfm = nt.manip.load("sub-000480a3_ses-1_from-T1w_to-MNI152NLin6Asym_mode-image_xfm.h5", reference=T1w_MNI_ref, moving=T1w)
T1w_MNI = xfm.apply(T1w)

However, when visualising the resulting T1w_MNI with T1w_MNI.orthoview() the image is empty / black.

I was also messing around with other approaches with no avail.

Is there a suggested way to apply the transforms? I would also greatly appreciate recommendations regarding the exact reproduction of fmriprep normalizations.

nitransforms version is 21.0.0

Thanks a lot in advance.

Cheers,
Marvin

Does applying the transform with antsApplyTransforms work? If so, this sounds like a bug in nitransforms.

Hi Chris,

thanks for your immediate response.

I actually tried to replicate the normalization with antsApplyTransforms but the resulting image isn’t identical to the normalized output from fmriprep. The normalization looks satisfying but the actual intensity values in corresponding voxels differ (images below). Maybe it’s due to my approach:

I used

antsApplyTransforms -d 3 -e 3 -n Linear -i sub-000480a3_ses-1_desc-preproc_T1w.nii.gz -r sub-000480a3_ses-1_space-MNI152NLin6Asym_desc-preproc_T1w.nii.gz -o t1_in_mni.nii.gz -t sub-000480a3_ses-1_from-T1w_to-MNI152NLin6Asym_mode-image_xfm.h5

and tried the interpolation mehtods Linear, NearestNeighbor, Bspline and Gaussian.

t1_in_mni.nii.gz:

sub-000480a3_ses-1_space-MNI152NLin6Asym_desc-preproc_T1w.nii.gz

Thanks again for your help

Your result looks pretty good. The intensity difference may be due to the fact that fmriprep uses LanczosWindowedSinc interpolation that you didn’t try yet I presume?

For information, here is the (pretty long!) command I found from fmriprep working directory:

antsRegistration --collapse-output-transforms 1 --dimensionality 3 --float 1 --initial-moving-transform [ /work/temp_data_SLIP2/fmriprep_wf/single_subject_pilote2_wf/anat_preproc_wf/anat_norm_wf/_template_MNI152NLin2009cAsym/registration/transform.mat, 0 ] --initialize-transforms-per-stage 0 --interpolation LanczosWindowedSinc --output [ ants_t1_to_mni, ants_t1_to_mni_Warped.nii.gz ] --transform Rigid[ 0.05 ] --metric Mattes[ /work/temp_data_SLIP2/fmriprep_wf/single_subject_pilote2_wf/anat_preproc_wf/anat_norm_wf/_template_MNI152NLin2009cAsym/registration/fixed_masked.nii.gz, /work/temp_data_SLIP2/fmriprep_wf/single_subject_pilote2_wf/anat_preproc_wf/anat_norm_wf/_template_MNI152NLin2009cAsym/registration/moving_masked.nii.gz, 1, 56, Regular, 0.25 ] --convergence [ 100x100, 1e-06, 20 ] --smoothing-sigmas 2.0x1.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform Affine[ 0.08 ] --metric Mattes[ /work/temp_data_SLIP2/fmriprep_wf/single_subject_pilote2_wf/anat_preproc_wf/anat_norm_wf/_template_MNI152NLin2009cAsym/registration/fixed_masked.nii.gz, /work/temp_data_SLIP2/fmriprep_wf/single_subject_pilote2_wf/anat_preproc_wf/anat_norm_wf/_template_MNI152NLin2009cAsym/registration/moving_masked.nii.gz, 1, 56, Regular, 0.25 ] --convergence [ 100x100, 1e-06, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.1, 3.0, 0.0 ] --metric CC[ /work/temp_data_SLIP2/fmriprep_wf/single_subject_pilote2_wf/anat_preproc_wf/anat_norm_wf/_template_MNI152NLin2009cAsym/registration/fixed_masked.nii.gz, /work/temp_data_SLIP2/fmriprep_wf/single_subject_pilote2_wf/anat_preproc_wf/anat_norm_wf/_template_MNI152NLin2009cAsym/registration/moving_masked.nii.gz, 1, 4, None, 1 ] --convergence [ 100x70x50x20, 1e-06, 10 ] --smoothing-sigmas 3.0x2.0x1.0x0.0vox --shrink-factors 8x4x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.005, 0.995 ] --write-composite-transform 1

1 Like

Hi Julien,

thanks! Providing LanczosWindowedSinc as the interpolation to AntsApplyTransforms did the trick.

Cheers,
Marvin