Summary of what happened:
I have PET-MR data (dynamic PET frames) and I am trying to compute registration from PET native space to MNI space to look at group level binding potential results. I have run fmriprep on the BOLD and anatomical data, which generated good registrations, but I am having some trouble creating a composite registration from PET native space to MNI space.
Specifics:
I used ants to create an affine registration between the PET native space (using the mean PET image as a template) and the preprocessed T1w FMRIPREP output (T1w space). This registration works really well, ie an output pet_template_space-T1w.nii.gz
is very well aligned to the preproc_T1w file. If I then apply the T1w_to_MNI .h5 transform file from FMRIPREP to this T1w space PET template, the resulting pet_template_space-MNI.nii.gz file looks well aligned to the MNI space output.
Based on this I thought I would be able to combine the affine I computed and the fmriprep composite transform into a single step to avoid resampling to T1w space in the middle, but the resulting warped pet_template is somewhat off from the MNI template. I generated the combined PET to MNI transform by calling ants.apply_transform(fixed,moving,[PET_to_T1w, T1w_to_MNI],compose=PET_to_MNI_file)
to generate an output PET_to_MNI.nii.gz
warp file and then apply this to the pet_template.nii.gz
file. I also tried just calling
ants.apply_transform(fixed,moving,[PET_to_T1w, T1w_to_MNI])
to just save the output. Both of these result in the exact same MNI space pet template image that is not properly aligned.
I tried this on multiple subjects and achieved the same result: if I actually transform the PET_template into the T1w space, and then apply the fmriprep transform, I get a good result. If I try to go directly from PET to MNI space by combining the transform I computed and the one from FMRIPREP, it doesn’t align.
Happy to hear any suggestions! I’m wondering if it has to do better performance from actually resampling to the 1mm T1w space before registering to MNI (I’m using 2mm MNI2009cAsym template). PET native space is ~ 2mm.
Below is the relevant code:
# load images for registration
template = ants.image_read(template_file)
T1w = ants.image_read(T1w_file)
# Perform affine registration between template and anatomical
registration = ants.registration(fixed=T1w, moving=template, type_of_transform='Affine',metric='MI',outprefix=REGDIR+'/')
# save T1w space PET template
template_T1w_file = template_file.split('.')[0] +'_T1w.nii.gz'
ants.image_write(registration['warpedmovout'],template_T1w_file)
# save PET to T1w registration file
PET_to_T1w_affine_file = os.path.join(REGDIR,'PET_to_T1w_Affine.mat')
shutil.move(registration['fwdtransforms'][0], PET_to_T1w_affine_file)
# load composite transforms from fmriprep
T1w_to_MNI_file=glob.glob(os.path.join(bidsdir,'derivatives','fmriprep','sub-'+subname,'anat','sub-'+subname+'*_from-T1w_to-MNI152NLin2009cAsym_mode-image_xfm.h5'))[0]
# load MNI space T1w image
T1w_MNI_file = glob.glob(os.path.join(bidsdir,'derivatives','fmriprep','sub-'+subname,'anat','sub-'+subname+'*_space-MNI152NLin2009cAsym*desc-preproc_T1w.nii.gz'))[0]
T1w_MNI = ants.image_read(T1w_MNI_file)
# combine registrations and save combined transform file
PET_to_MNI_file = os.path.join(datadir,subname,'pet','reg','PET_to_MNI_')
comptx_file = ants.apply_transforms(T1w_MNI,template,[PET_to_T1w_affine_file,T1w_to_MNI_file],compose=PET_to_MNI_file)
# apply PET to MNI transform to dynamic_template
template_MNIspace = ants.apply_transforms(T1w_MNI,template,[comptx_file])
ants.image_write(template_MNIspace,os.path.join(REGDIR,'dynamic_template_MNI.nii.gz'))
# try registering to T1w then to MNI
template_MNIspace_fromT1w = ants.apply_transforms(T1w_MNI,ants.image_read(template_T1w_file),[T1w_to_MNI_file])
ants.image_write(template_MNIspace_fromT1w,os.path.join(REGDIR,'dynamic_template_MNI_fromT1w.nii.gz'))