In case this might be useful to someone who wants to conduct the similar process. After researching this issue a bit I could reproduce <...>_space-T1w_desc-aseg_dseg.nii.gz
generated by fmriprep.
First of all, this bug https://github.com/nipreps/smriprep/pull/268 is the reason why sub-<subjID>_run-<runID>_desc-aseg_dseg.nii.gz
under fmriprep/sub-<>/anat
folder looks different to aseg.mgz
under fmriprep/source/freesurfer/sub-<>/mri
folder
Then I rerun fmriprep with 21.0.0rc2 version and did the following to reproduce <...>_space-T1w_desc-aseg_dseg.nii.gz
from aseg.mgz
in freefurfer folder, after reading the source code. Tested with 3 subjects and got identical segmentations resampled in BOLD resolution
# fmriprep used two steps
# step 1, resample aseg.mgz to T1w.nii.gz and convert it to aseg.nii.gz, smriprep code below
# step 1a, use fsnative2t1w_xfm to calculate lta file () from T1.mgz to T1w.nii.gz
#fsnative2t1w_xfm = pe.Node(
# RobustRegister(auto_sens=True, est_int_scale=True), name="fsnative2t1w_xfm"
# )
# RobustRegister is from freesurfer mri_robust_register auto_sens is --satit est_int_scale is --iscale
mri_robust_register --mov $SUBJECTS_DIR/$subject_name/mri/T1.mgz \
--dst $root_DIR/$subject_name/anat/${subject_name}_run-01_T1w.nii.gz \
--lta $work_DIR/${subject_name}_run-01_fsnative2t1w_xfm.lta \
--satit \
--iscale
# step 1b, use fs.ApplyVolTransform with nearest interpolation to transfer
# aseg.mgz to T1w space and convert to aseg.nii.gz
# # Resample from T1.mgz to T1w.nii.gz, applying any offset in fsnative2t1w_xfm,
# # and convert to NIfTI while we're at it
# resample = pe.Node(
# fs.ApplyVolTransform(transformed_file="seg.nii.gz", interp="nearest"),
# name="resample",
# )
# fs.ApplyVolTransform is mri_vol2vol
mri_vol2vol --mov $SUBJECTS_DIR/$subject_name/mri/aseg.mgz \
--targ $root_DIR/$subject_name/anat/${subject_name}_run-01_T1w.nii.gz \
--lta $work_DIR/${subject_name}_run-01_fsnative2t1w_xfm.lta \
--o $work_DIR/${subject_name}_run-01_t1_aseg.nii.gz \
--nearest
# 2 use antsApplyTransforms resample aseg.nii.gz to bold ref
# # Resample aseg and aparc in T1w space (no transforms needed), fmriperp code below
# aseg_t1w_tfm = pe.Node(
# ApplyTransforms(interpolation='MultiLabel', transforms='identity'),
# name='aseg_t1w_tfm', mem_gb=0.1)
# aparc_t1w_tfm = pe.Node(
# ApplyTransforms(interpolation='MultiLabel', transforms='identity'),
# name='aparc_t1w_tfm', mem_gb=0.1)
antsApplyTransforms --dimensionality 3 --float 1 --interpolation MultiLabel \
--input $work_DIR/${subject_name}_run-01_t1_aseg.nii.gz \
--reference-image $fmriprep_DIR/$subject_name/func/${subject_name}_${task_name}_run-2_space-T1w_boldref.nii.gz \
--output $fmriprep_DIR/$subject_name/func/${subject_name}_${task_name}_run-2_space-T1w_desc-aseg-rep.nii.gz \
--transform identity
According to FsAnat-to-NativeAnat - Free Surfer Wiki freesurfer suggested using mri_label2vol
to transform segmentation back to native space, so I tried the following. It could reproduce the above process, but in one subject only very few voxels are labeled differently, not sure why.
# using freesurfer mri_label2vol https://surfer.nmr.mgh.harvard.edu/fswiki/FsAnat-to-NativeAnat
mri_label2vol --seg $SUBJECTS_DIR/$subject_name/mri/aseg.mgz \
--temp $SUBJECTS_DIR/$subject_name/mri/rawavg.mgz \
--o $work_DIR/${subject_name}_run-01_t1_aseg_rep.mgz \
--regheader $SUBJECTS_DIR/$subject_name/mri/aseg.mgz
antsApplyTransforms --dimensionality 3 --float 1 --interpolation MultiLabel \
--input $work_DIR/${subject_name}_run-01_t1_aseg_rep.mgz\
--reference-image $fmriprep_DIR/$subject_name/func/${subject_name}_${task_name}_run-2_space-T1w_boldref.nii.gz \
--output $fmriprep_DIR/$subject_name/func/${subject_name}_${task_name}_run-2_space-T1w_desc-aseg-rep.nii.gz \
--transform identity
Finally, I tried the very first logic, using _run-1_from-fsnative_to-T1w_mode-image_xfm.txt
provided by fmriprep to ignore recalculation of transformation from fs to T1w. The following code still can not reproduce <...>_space-T1w_desc-aseg_dseg.nii.gz
. According to this bug https://github.com/nipreps/smriprep/pull/268 I was expecting the _run-1_from-fsnative_to-T1w_mode-image_xfm.txt
be different from fmriprep versions, but the one I got from 20.2.4 is identical to 21.0.0rc2, this explains why the following code gave me the same result as the snapshot showed in the first post. Maybe I am wrong so _run-1_from-fsnative_to-T1w_mode-image_xfm.txt
is not the transformation from fs to T1w. Also, the above mri_robust_register
and then mri_vol2vol
process could not reproduce <...>_space-T1w_desc-aseg_dseg.nii.gz
generated by fmriprep 20.2.4
antsApplyTransforms --dimensionality 3 --float 1 --interpolation MultiLabel \
--input $SUBJECTS_DIR/$subject_name/mri/aseg.mgz\
--reference-image $fmriprep_DIR/$subject_name/func/${subject_name}_${task_name}_run-2_space-T1w_boldref.nii.gz \
--output $fmriprep_DIR/$subject_name/func/${subject_name}_${task_name}_run-2_space-T1w_desc-aseg-rep.nii.gz \
--transform $fmriprep_DIR/$subject_name/anat/${subject_name}_run-1_from-fsnative_to-T1w_mode-image_xfm.txt