Extracting individual transforms from composite .h5 files (fmriprep)

fmriprep
ants

#1

Hi there,

I’m new to using .h5 files, which fmriprep uses to store (composite) transforms. I have been able to successfully propagate labels from an individual to the template space:

antsApplyTransforms -d 3 --float 1 --verbose 1 -i sub-0086_T1w_label-aseg_roi.nii.gz -o output/sub-0086_T1w_space-MNI152NLin2009cAsym_label-aseg_roi.nii.gz -r MNI2009c_T1w.nii.gz -t sub-0086_T1w_target-MNI152NLin2009cAsym_warp.h5 -n NearestNeighbor

(Hypothetically) if I had the individual transform files (sub-0086_T1w_target-MNI152NLin2009cAsym_warp.nii.gz and sub-0086_T1w_target-MNI152NLin2009cAsym_affine.mat), I could have gotten the same result with the following call:

antsApplyTransforms -d 3 --float 1 --verbose 1 -i sub-0086_T1w_label-aseg_roi.nii.gz -o output/sub-0086_T1w_space-MNI152NLin2009cAsym_label-aseg_roi.nii.gz -r MNI2009c_T1w.nii.gz -t sub-0086_T1w_target-MNI152NLin2009cAsym_warp.nii.gz -t sub-0086_T1w_target-MNI152NLin2009cAsym_affine.mat -n NearestNeighbor

I have a particular use case where having these transformations separated would be beneficial; specifically, because I want to propagate some 3D points (e.g. anterior and posterior commissure) using antsApplyTransformsToPoints:

antsApplyTransformsToPoints -d 3 -i sub-0086_T1w_label-ACPC_points.csv -o output/sub-0086_T1w_space-MNI152NLin2009cAsym_label-ACPC_points.csv -t [sub-0086_T1w_target-MNI152NLin2009cAsym_affine.mat,1] -t sub-0086_T1w_target-MNI152NLin2009cAsym_inversewarp.nii.gz

Note that the ordering of linear and nonlinear transformations is reversed for point transformation, and also requires the inverse deformation field as input. For what it’s worth I tried inputting both forward and backward composite transforms derived from fmriprep and the coordinates were nowhere close to the true location (MNI2009c_T1w_label-ACPC_points.csv)

This is somewhat related to a few previous posts here and on the ants forum:

  1. FMRIPREP ANTS .h5 composite transform file decomposition? How exactly the .h5 decomposition was performed is not described and the focus of discussion was more on capturing the rigid component from the linear transformation matrix. @ChenChiaLan
  2. FMRIPREP: inverse t1_to_mni warp describing modifications to include both forward and inverse .h5 files.
  3. https://sourceforge.net/p/advants/discussion/840260/thread/ff4587ef/?limit=25#c007 This covers the usage of antsApplyTransformsToPoints

Any thoughts on how to resolve this? I’ve provided all the files as a .tar.gz link for anyone able to take a closer look.

-jon


Also, hope to see some of you at the INCF Montreal meeting next week!


#2

Tried digging a little deeper into this and found a thread on the ANTs forum using the python package called h5py to extract the affine transformation.

Alternatively is there an option in fmriprep that could allow storing the individual transforms rather than the composite h5?

Appreciate any thoughts on how to deal with this.


#3

Do I understand correctly that antsApplyTransformsToPoints does not work correctly with an composite transform (h5) even though antsApplyTransforms works with the same transform? If so do the ANTs developers know about it?


#4

Thanks for taking the time to respond! I think there may be two ways of considering the problem:

  1. antsApplyTransformsToPoints is not behaving as expected with the composite (h5) files; however, there is a solution that works if the linear and nonlinear warps are provided as separate files.
  2. fMRIPrep outputs two composite .h5 transforms (one forward and one backward). Was there a reason to adopt this format rather than store the output in each direction as a linear text file and nonlinear warp field? The latter seems more flexible to me for permitting different transform-based manipulations.

I decided to ask on neurostars first because some old threads on the ANTs forum suggested h5 was not being actively supported by the developers. However, I was fortunate to run into Nick Tustison this past week at the Neuroinformatics meeting. He was very receptive to finding a solution; some possibilities discussed include: (1) implementing a converter for decomposing the h5 files into component parts; (2) modifying antsApplyTransformsToPoints to handle .h5 files appropriately. Nick suggested I start a thread on the ANTs forum too, which I’ve just done: https://sourceforge.net/p/advants/discussion/840261/thread/ba6a10b0/


#5

A single file is more compact and less error prone than two files (especially considering order of applying transforms. Most users, just want to apply transforms rather than modify them.

I like option (2). Glad you are working with Nick to figure this out!


#6

I’m exploring option 2 in https://github.com/nipy/nibabel/pull/656


#7

Thanks for looking into this, @oesteban!

When you have a chance, can you expand on how the PR in nibabel would be considered a solution to option 2? I want to make sure I’m able to recap on the different possible options (once a solution is found).

Update from the parallel thread on the ants forum: I’m testing out the use of the CompositeTransformUtil --disassemble tool (recommended by Nick). Will report back once I’ve sorted out whether this works.


#8

I realize that some of the functionality I’m interested in is beyond the scope of the typical user, but what about the possibility of having those intermediate files stored in a working/scratch directory? Also one of the reasons I ask is that I don’t see any mention of the .h5 format in BEP14: the BIDS derivative document on transformations. The transform derivatives are described as separate linear _affine.txt and _warp.nii.gz files.


#9

At this point, that pull request has no functionality for that. But it is the idea to implement it some time soon.


#10

Okay specifically by option 2, you mean modifying antsApplyTransformsToPoints to handle .h5 files? Using nibabel seems like it would be a different solution.

(The numbering of options was a bit ambiguous initially – which is why I plan to recap at some point.)


#11

The implementation of a module that reads and writes transforms from whatever neuroimaging software would cover h5 files when it comes to transforms from ANTs.

I could give a command line interface for resamplings and transform conversions. In that case, then the conversions command would have a decompose option or similar.


#12

Okay turns out antsApplyTransformsToPoints works just fine with the .h5 composite transforms provided as output by fMRIPrep. One of my problems stemmed from the points being in RAS anatomical coordinate space (they were placed using 3D Slicer) rather than LPS space. Anyone interested in this issue can look at the link here.

If your goal like mine is to transform a set of points from native space to those output by fMRIPrep the following solutions work:

(1) using the .h5 inverse composite transform:

antsApplyTransformsToPoints -d 3 -i sub-0086_T1w_label-ACPC_points_LPS.csv -o subject_to_template_composite.csv -t sub-0086_T1w_space-MNI152NLin2009cAsym_target-T1w_warp.h5

(2) disassembling the .h5 transforms first using the ANTs CompositeTransformUtil --disassemble then running antsApplyTransformsToPoints:

CompositeTransformUtil --disassemble sub-0086_T1w_space-MNI152NLin2009cAsym_target-T1w_warp.h5 sub-0086_T1w_space-MNI152NLin2009cAsym_target-T1w_warp
CompositeTransformUtil --disassemble sub-0086_T1w_target-MNI152NLin2009cAsym_warp.h5 sub-0086_T1w_target-MNI152NLin2009cAsym_warp
antsApplyTransformsToPoints -d 3 -i sub-0086_T1w_label-ACPC_points.csv -o subject_to_template_disassembled.csv -t [00_sub-0086_T1w_target-MNI152NLin2009cAsym_warp_AffineTransform.mat,1] -t 00_sub-0086_T1w_space-MNI152NLin2009cAsym_target-T1w_warp_DisplacementFieldTransform.nii.gz

@oesteban is working on a module for reading and writing transforms between neuroimaging software in nibabel. Could this perhaps take advantage of the CompositeTransformUtil --disassemble function?