Warping tck files using FLIRT (fsl)

Hi Mrtrix community,

We have tried to realign the tck file into structural image with the same way we did before the upgrade. However, the image resulting of the new version of program is not satisfactory. We have used the following pipeline:

1. Create the identity images:
warpinit T1_image flirt-[].nii
2. Convert a transformation matrix produced by FSL’s flirt command into a format usable by MRtrix:
transformconvert inv_epi2struct.mat* T1_image DWI image flirt_import inv_epi2struct.mrtrix
3. Apply spatial transformations to an image:
for i in 0 1 2;do
fslchfiletype NIFTI_GZ flirt-${i}
mrtransform flirt-${i}.nii.gz -linear inv_epi2struct.mrtrix flirt2tck-${i}.nii.gz -template T1_image -inverse -half -grad encoding.b
done
4. warpcorrect flirt2tck-[].nii.gz flirt2tck.mif
5. Apply a normalisation map to a tracks file:
tcknormalise brain_track.tck flirt2tck.mif ${Folder T1_image}/brain_track.tck -quiet -force

*Matrix coregister T1 to DWI

We attached the tck file in DWI and the tck file in T1_image (after applying the transformation).

Thanks in advance,

Eloy


1 Like

Not sure I understand what the problem is but I am wondering why you chose to transform flirt-${i}.nii.gz to the half space:

Hi @maxpietch,

We performed the command line without -half, but unfortunately we obtained the same results.

Moreover, we have also used the ants to ensure the correct registration and also we obtained the same results. We introduced the following command lines:

1. ANTS coregister:
ANTS 3 -m PR[DWI,T1_image,1,2] -i 50x20x10 -o T1_to_diffusion_synants.nii.gz -t SyN[0.3] -r Gauss[3,0]
2. Create the identity images:
warpinit DWI.nii.gz flirt-.nii
3. Apply spatial transformations to an image:
for i in 0 1 2;do
fsl-fslchfiletype NIFTI flirt-{i}
WarpImageMultiTransform 3 flirt-{i}.nii mrtrix_warp{i}.nii -R T1_image -i T1_to_diffusion_synantsAffine.txt T1_to_diffusion_synantsInverseWarp.nii
done
4. warpcorrect mrtrix_warp.nii mrtrix_warp_corrected.mif
5. Apply a normalisation map to a tracks file:
tcknormalise brain_track.tck flirt2tck.mif ${Folder T1_image}/brain_track.tck -quiet -force

We do not understand why the coregister with tck file is suboptimal. We follow the same procedure with the previous version with optimal results.

I would greatly appreciate any help,

Eloy

What previous version do you refer to?

Just to check, could you execute this to make sure you are not using the beta version of Eigen?

We have used the library: 3.2.0

Hi @maxpietsch

We converted the tck file into track-weighted image. We realized that the alignment of the images are the same. Only differ in the datatype. However, the visualization are not corrected.

Thanks in advance,

Eloy

Hi Eloy,

A lot of things going here, I’ll try to respond to a few issues as I come across them - not all of them have anything to do with the problem at hand:

Probably none of my business, but can I just check why you need to do this? You could simply coregister the T1 to the diffusion data, at which point the tracks should overlay with the T1 just as well? Maybe you have a particular application that requires the T1 be in a particular space? But if all you’re after is the ability to overlay the tracks on the T1, then aligning the T1 to the diffusion is the simplest way to achieve this.

  • You shouldn’t need to change the fslchfiletype command here, MRtrix3 will accept *.nii files as-is anyway.

  • mrtransform can take the 3 warp images in one go using the square bracket syntax, which means it treats the 3 images as a single 4D image. You’d then only need one call to mrtransform rather than 3.

  • I agree with @maxpietsch that you shouldn’t need the -half option here - that will definitely give you the wrong transformation.

  • You also don’t need the -grad encoding.b option, that will insert the DW scheme into the header for the transform images - which makes little sense. Regardless, the output is produced in NIfTI format, which can’t actually store that information anyway…

  • so this should mean you can write the above for loop as a single command:

      mrtransform flirt-[].nii -linear inv_epi2struct.mrtrix flirt2tck.mif -template T1_image -inverse
    

The only purpose of warpcorrect is to remove unwanted zeros that other registration packages might write in places where the target voxel has no correspondence in the original image (i.e. it maps to a point outside the FoV). The relevant MRtrix3 commands should write a NaN to indicate this, so shouldn’t need special handling - let us know if that’s not the case.

Finally, by using the -template option to mrconvert, the images will be regridded, which might be unnecessary, assuming this is a rigid-body linear transform: in this case only the transform matrix in the header needs to be modified. You’d be better off removing the -template T1_image option here.

That might be a problem - I’m not sure. I seem to recall that MRtrix3 wouldn’t even compile with anything older the Eigen 3.2.4 or so, so I’m surprised to hear that you’d even be able to use an older version…? In any case, I’d recommend updating to the current stable 3.2.9 version if you can - although I doubt this will sort out this issue: if there was a problem, I’d expect it wouldn’t even compile, crash at runtime, or produce outright garbage…

Can I check exactly what you mean by ‘the previous version’ here? Was this working with MRtrix3 before? Is there any way you can pinpoint the version that worked before? For example by running mrinfo on a *.mif image produced by the version of the software that worked before (the version of MRtrix3 used to generate the image is written in the header nowadays).

Not sure I do either… But assuming everything in MRtrix3 is actually working properly (not a given if you say these exact commands used to work fine…), then it’s worth emphasising how easy it is to get confused as to whether you need the transform or its inverse - see this post for details. What you need is the forward transform from DWI to T1, which is typically the inverse of the transform you’d use to warp the DWI to T1 space. One way to check that you’re using the right transform is to apply the same transformation to the T1 as you did to the initial warps you generated from it:

mrtransform T1_image -linear inv_epi2struct.mrtrix T1_image_coreg.mif -inverse

If the resulting T1_image_coreg.mif is aligned with the DWI and the tracks overlay onto it properly, then all should be fine - you should be able to run the tcknormalise command with your flirt2tck.mif. If that’s not the case, then try removing the -inverse option, or using the inverse matrix in the first place.

If that doesn’t fix it, then I’m not sure. I haven’t looked at your ANTS scripts too closely, so I’m not sure what the issue might be in this case, but there’s very little that I can think of that would explain what you’re showing other than simply having used the inverse transformation instead of the forward one…

Besides what @jdtournier said, here is a working example on how to register two 3D images (anatomical and b0) and applying the warp to the DWI data using mrtransform.

antsRegistration --verbose 1 --dimensionality 3 --float 0 --output [out,outWarped.nii.gz,outInverseWarped.nii.gz] --interpolation Linear --use-histogram-matching 0 --winsorize-image-intensities [0.005,0.995] --initial-moving-transform [anat.nii,b0.nii,1] --transform Rigid[0.1] --metric MI[anat.nii,b0.nii,1,32,Regular,0.25] --convergence [1000x500x250x100,1e-6,10] --shrink-factors 8x4x2x1 --smoothing-sigmas 3x2x1x0vox --transform Affine[0.1] --metric MI[anat.nii,b0.nii,1,32,Regular,0.25] --convergence [1000x500x250x100,1e-6,10] --shrink-factors 8x4x2x1 --smoothing-sigmas 3x2x1x0vox --transform SyN[0.1,3,0] --metric CC[anat.nii,b0.nii,1,4] --convergence [100x70x50x20,1e-6,10] --shrink-factors 8x4x2x1 --smoothing-sigmas 3x2x1x0vox

antsApplyTransforms -d 3 -e scalar -i b0.nii -r anat.nii -o b0_ants_out.nii.gz --interpolation Linear --transform out1Warp.nii.gz --transform out0GenericAffine.mat

warpinit dwi.nii identity_warp[].nii -force
for i in {0..2}; do
  WarpImageMultiTransform 3 identity_warp${i}.nii mrtrix_warp${i}.nii -R anat.nii out1Warp.nii.gz out0GenericAffine.mat;
done;

warpcorrect mrtrix_warp[].nii mrtrix_warp_corrected.mif -force 

mrtransform dwi.mif -warp mrtrix_warp_corrected.mif warped_fod_image.mif -force 

mrview warped_fod_image.mif -overlay.load anat.nii -overlay.load b0_ants_out.nii.gz
2 Likes

Hi @jdtournier and @maxpietsch

Thanks for your quick response,

I followed step by step all the tools that you suggested. However, we found some inexplicable results.

We checked the coregistration from DWI to T1 using the 4x4 ascii file derived from epi_reg (fsl). I attached the transform file.

0.9999801977 -0.004231592747 0.004662490944 -30.08091181
0.004015216118 0.9989572574 0.04547867121 -14.03378718
-0.004850076446 -0.04545904905 0.9989544713 48.5794535
0 0 0 1

When we used fsl to register DWI to T1, we obtained a satisfactory results. But, when we applied the same transformation with mrtrix tools, it did not align properly.

We have hypothesized that the problem could be when mrtrix reads the matrix.

Cheers,

Eloy

OK, so as I suggested before (and as explained in this post), tcknormalise needs the inverse transform from what you’d normally apply to transform the image. What you need is the transform you would use to map the T1 image to DWI space. Try using that transform - or just the inverse of the one you’re currently using (i.e. skip the -inverse option to the mrtransform call), see if that fixes it.

Hi @jdtournier and @maxpietsch

Thanks for your help. It was very useful.

At last, we obtained a good realignment from tck file to T1 image. I attached the following steps:

  1. mrconvert T1_image.nii T1_image.mif -force
  2. warpinit T1_image.mif flirt-.nii
  3. transformconvert inv_epi2struct.mat T1_image.mif dwi.mif flirt_import inv_epi2struct.mrtrix
  4. transformconvert epi2struct.mat dwi.mif T1_image.mif flirt_import epi2struct.mrtrix
  5. mrtransform dti_FA.nii.gz -linear inv_epi2struct.mrtrix FA_image_coreg.mif -inverse -force # aligned with the DWI
  6. mrtransform flirt-.nii -linear epi2struct.mrtrix flirt2tck.mif -inverse
  7. tcknormalise brain_track.tck flirt2tck.mif track2T1.tck -quiet -force

Eloy

Good to hear! Just a few comments though in case it helps anyone:

  • the first mrconvert call is redundant, since all MRtrix3 command accepts NIfTI images natively - no need to convert to *.mif format (although it is a vastly superior format IMHO :wink:).

  • the second transformconvert call is probably also unnecessary, since inv_epi2struct.mrtrix is presumably just the inverse of flirt_import epi2struct.mrtrix, and mrtransform will happily invert the transform for you directly.

  • you should be able to use the original inv_epi2struct.mrtrix with mrtransform without the -inverse option, instead of computing the flirt_import epi2struct.mrtrix inverse explicitly.

So with all this, I think these commands should be sufficient:

warpinit T1_image.nii flirt-[].nii
transformconvert inv_epi2struct.mat T1_image.mif dwi.mif flirt_import inv_epi2struct.mrtrix
mrtransform flirt-[].nii -linear inv_epi2struct.mrtrix flirt2tck.mif
tcknormalise brain_track.tck flirt2tck.mif track2T1.tck

Happy to be corrected if that’s not the case though.

And given this thread, I think it’s about time I did something about documenting this

1 Like

Thanks @jtournier,

I have the last question, I promise :slight_smile:

I am wondering how to apply the warping file derived to FNIRT (in mm units). I tried to perform with the WarpImageMultiTransform tool, but it doesn’t admit the warping file.

In the oldest MRtrix version, I used the following instructions:

warpinit /usr/share/fsl/5.0/data/standard/MNI152_T1_1mm.nii.gz flirtMNI-.nii

convert_xfm -omat {STRUCTURAL}/inv_001_my_affine_transf.mat -inverse {STRUCTURAL}/001_my_affine_transf.mat

transformcalc -flirt_import /usr/share/fsl/5.0/data/standard/MNI152_T1_1mm.nii.gz {STRUCTURAL}/r001_T1.nii.gz {STRUCTURAL}/inv_001_my_affine_transf.mat ${STRUCTURAL}/inv_001_my_affine_transf.mrtrix

for i in 0 1 2;do
mrtransform flirtMNI-{i}.nii -linear {STRUCTURAL}/inv_001_my_affine_transf.mrtrix -warp_df {STRUCTURAL}/001_warps_into_T1.nii.gz {STRUCTURAL}/flirtMNI2tck-${i}.nii.gz -inverse
done

tcknormalise {STRUCTURAL}/brain_track.tck {STRUCTURAL}/flirtMNI2tck-.nii.gz ${OUT}/001_brain_track.tck -quiet

However, in the newest version the inverse transformation applying the warping file is not allowed. Could you help me?

Thanks again

Eloy

Hi @jtournier,

Finally, we performed ants in order to warp the tck file into MNI space. We obtained an optimal results.

We used the following steps:

fslchfiletype NIFTI MNI152_T1_1mm.nii.gz
ANTS 3 -m CC[MNI152_T1_1mm.nii,T1_image.nii,1,5] -t SyN[0.5] -r Gauss[2,0] -o T1_to_MNI_synants.nii -i 30x90x20 --use-Histogram-Matching
warpinit MNI152_T1_1mm.nii flirtMNI-.nii -force
for i in 0 1 2;do
WarpImageMultiTransform 3 flirtMNI-{i}.nii flirtMNI2tck-{i}.nii -R MNI152_T1_1mm.nii -i T1_to_MNI_synantsAffine.txt T1_to_MNI_synantsInverseWarp.nii
done
warpcorrect flirtMNI2tck-.nii flirtMNI2tck_corr.mif -force
tcknormalise {STRUCTURAL}/brain_track.tck flirtMNI2tck_corr.mif {OUT}/brain_track.tck -quiet -force

I really appreciate your support,

Cheers

Eloy

4 Likes

Hi @eloydelas,

Just to say: thanks for nicely reporting on the exact steps you performed in these scenarios. I reckon having some of those experiences and exact steps/commands documented here may end up potentially being very useful to a lot of other users as well; as these are not uncommon scenarios that people may want to perform!

Thanks again,
Thijs

1 Like

I concur @ThijsDhollander, these steps were rather excellent for myself trying to get seed-based tracks from Diff -> T1 -> 2009c NLIN space.

Although to note tcknormalise is now superseded by tcktransform.

Would be great if these steps could be added to the docs page or something similar.

Thanks @jdtournier & @eloydelas!

1 Like

Thank’s a lot for summing this up, worked perfect for me :slightly_smiling_face: