Conveniently, fMRIPrep produces both a from-T1w_to-${template} and from-${template}_to-T1wcomposite transform. I need to convert these into a format for use by FSL. I’m decomposing these with ANTsand then converting them with wb_command. This works great in one direction, but not the other, and I’m not sure why. It seems like there’s a missing affine, but I don’t see where.
#!/bin/bash
sub=002
standard="MNI152_T1_1mm_brain_mask.nii.gz"
highres="sub-${sub}/anat/sub-${sub}_desc-preproc_t1w.nii.gz"
# this works
standard2highres_h5="sub-${sub}/anat/sub-${sub}_from-MNI152NLin6Asym_to-T1w_mode-image_xfm.h5"
standard2highres_prefix=from-MNI152NLin6Asym_to-T1w
CompositeTransformUtil \
--disassemble $standard2highres_h5 \
${standard2highres_prefix}
standard2highres_mat=standard2highres.mat
pixi run python write_affine.py $standard2highres_h5 $highres $standard $standard2highres_mat 1
standard2highres_warp=standard2highres_warp.nii.gz
wb_command \
-convert-warpfield \
-from-itk ${standard2highres_prefix}_00_DisplacementFieldTransform.nii.gz \
-to-fnirt ${standard2highres_warp} ${standard}
applywarp \
-i MNI152_T1_1mm.nii.gz \
-o mni_highres.nii.gz \
-r ${highres} \
-w ${standard2highres_warp} \
--postmat=${standard2highres_mat}
# check
# fsleyes mni_highres.nii.gz sub-${sub}/anat/sub-${sub}_desc-brain_mask.nii.gz
highres2standard_h5="sub-${sub}/anat/sub-${sub}_from-T1w_to-MNI152NLin6Asym_mode-image_xfm.h5"
highres2standard_mat=highres2standard.mat
highres2standard_prefix=from-T1w_to-MNI152NLin6Asym
# but this fails?
CompositeTransformUtil \
--disassemble $highres2standard_h5 \
${highres2standard_prefix}
pixi run python write_affine.py $highres2standard_h5 $standard $highres $highres2standard_mat 0
highres2standard_warp=highres2standard_warp.nii.gz
wb_command \
-convert-warpfield \
-from-itk ${highres2standard_prefix}_01_DisplacementFieldTransform.nii.gz \
-to-fnirt ${highres2standard_warp} ${highres}
applywarp \
-i ${highres} \
-o mni.nii.gz \
-r ${standard} \
-w ${highres2standard_warp} \
--premat=${highres2standard_mat}
# check
# fsleyes mni.nii.gz $standard
# also, this is fine?
antsApplyTransforms -t $highres2standard_h5 -r $standard -i $highres -o mni_ants.nii.gz
# check
# fsleyes mni_ants.nii.gz $standard
with the python file
import sys
from nitransforms import io
h5 = sys.argv[1]
reference = sys.argv[2]
moving = sys.argv[3]
mat = sys.argv[4]
transform = int(sys.argv[5])
xfm = io.itk.ITKCompositeH5.from_filename(h5)
io.fsl.FSLLinearTransform.from_ras(
xfm[transform].to_ras(reference=reference, moving=moving),
moving=moving,
reference=reference,
).to_filename(mat)
and pixi environment
[workspace]
authors = ["Patrick Sadil <psadil@gmail.com>"]
channels = ["conda-forge"]
name = "tmp"
platforms = ["osx-arm64"]
version = "0.1.0"
[tasks]
[dependencies]
nitransforms = ">=24.1.4,<25"
First check (looking good)
second check (looking bad
)
third check (this looks fine, so it’s not the h5…)
I’m stuck trying to figure out what’s going wrong here and out of ideas – any help would be appreciated!
The one possibly weird thing that I’m noticing is that the wb_command has significantly expanded the range of voxel intensities for the failing warp, but I’m not sure what to make of that.
# okay
❯ fslstats from-MNI152NLin6Asym_to-T1w_00_DisplacementFieldTransform.nii.gz -R
-9.244793 6.800364
# okay
❯ fslstats $standard2highres_warp -R
-9.244797 7.281265
# okay
❯ fslstats from-T1w_to-MNI152NLin6Asym_01_DisplacementFieldTransform.nii.gz -R
-6.807850 9.237727
# different?
❯ fslstats $highres2standard_warp -R
-25.169922 84.543442
❯ wb_command -version
Connectome Workbench
Type: Command Line Application
Version: 2.1.0
Qt Compiled Version: 6.8.0
Qt Runtime Version: 6.8.0
Commit: 99bf66b28572005f6419330d3f58b6262637412d
Commit Date: 2025-05-29 13:57:32 -0500
Compiler: c++ (/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin)
Compiler Version: 15.0.0.15000309
Compiled Debug: NO
Operating System: Apple OSX
Compiled with OpenMP: YES
❯ cd $ants_repo && git rev-parse HEAD
aaa34d6a53e6c3c415b51d376333cdf44ae315f5



