Skip to content

Regarding the Issue of Jacobian and CorticalThickness Generation #1883

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
JinDJsuper opened this issue May 14, 2025 · 13 comments
Open

Regarding the Issue of Jacobian and CorticalThickness Generation #1883

JinDJsuper opened this issue May 14, 2025 · 13 comments

Comments

@JinDJsuper
Copy link

Operating system and version

ubuntu20

CPU architecture

x86_64 (PC, Intel Mac, other Intel/AMD)

ANTs code version

ANTs-2.4.4

ANTs installation type

Compiled from source

Summary of the problem

I need to generate a modulated tissue segmentation map using a method that involves transforming a standard space tissue segmentation map and multiplying it by a Jacobian image, which is generated through warp transformation. In theory, the total voxel count (i.e., volume) of the modulated image after extraction should match the total voxel count in the individual space. However, I observed discrepancies in the statistical results.

I noticed that in antsApplyTransforms -d 3 -o [${result_dir}/sub2sst_composite.nii.gz,1],
this option suggests that not only should the warp file be applied, but the linear displacement (i.e., _0GenericAffine.mat) should also be included. Following this approach, I combined the transformations into a single file, recalculated the Jacobian, and found that the voxel counts of the modulated standard space image and the individual space image were nearly identical, with minimal differences.

Question1: Is this method correct?

Question2: about CorticalThickness .

During the analysis of cortical thickness maps, certain gyral regions appear artificially merged due to algorithmic miscalculations, resulting in localized thickness overestimations. Could you recommend potential solutions for this topological inaccuracy in sulcal-gyral differentiation?

best wishes

For instance, the region indicated in this figure exhibits...
Image

Commands to reproduce the problem.

antsApplyTransforms-d 3 -o [${result_dir}/sub2sst_composite.nii.gz,1] -r ${sst_template} -t ${sub2sst_warp} -t ${sub2sst_affine}

CreateJacobianDeterminantImage 3 ${result_dir}/sub2sst_composite.nii.gz ${result_dir}/${output_name}_sub2sst_jacobian.nii.gz 0 0

interpolation=Linear
antsApplyTransforms-d 3 -i ${sub_gm} -o ${result_dir}/${output_name}_gm2sst.nii.gz -r ${sst_template} -n $interpolation -t ${sub2sst_warp} -t ${sub2sst_affine}

fslmaths ${result_dir}/${output_name}_gm2sst.nii.gz -mul ${result_dir}/${output_name}_sub2sst_jacobian.nii.gz ${result_dir}/m${output_name}_gm2sst.nii.gz

antsAtroposN4.sh -d 3 -a ${brain} -x ${brain_mask} -p ${result_dir}/${output_name}_tpm_%d.nii.gz -c 3 -y 2 -y 3 -w 0.25 -o ${result_dir}/${output_name}_

I will proceed with subcortical tissue removal
KellyKapowski -d 3 \ -s [ ${result_dir}/${output_name}_Segmentation_nosub.nii.gz,2,3 ] \ --verbose 1 \ -g ${result_dir}/${output_name}_SegmentationPosteriors2_nosub.nii.gz \ -w ${case_wm} \ -o ${result_dir}/${output_name}_ct.nii.gz \ -c [ 45,0.0,10 ] \ -r 0.025 \ -m 1.5 \ -n 10 \ -b 0

Output of the command with verbose output.

msub1_gm2sst.nii.gz
sub1_ct.nii.gz
sub1_SegmentationPosteriors2.nii.gz

Data to reproduce the problem

.

@cookpa
Copy link
Member

cookpa commented May 14, 2025

I'm working on Jacobians right now. There may be bugs. I would recommend following antsCorticalThickness and using the "geometric" option

@JinDJsuper
Copy link
Author

I'm working on Jacobians right now. There may be bugs. I would recommend following antsCorticalThickness and using the "geometric" option

For the antsCorticalThickness.sh script, which option should I select? I might have missed the geometric option you mentioned.

@cookpa
Copy link
Member

cookpa commented May 14, 2025

The last flag

CreateJacobianDeterminantImage 3 ${result_dir}/sub2sst_composite.nii.gz \
${result_dir}/${output_name}_sub2sst_jacobian.nii.gz 0 1

@JinDJsuper
Copy link
Author

The last flag

CreateJacobianDeterminantImage 3 ${result_dir}/sub2sst_composite.nii.gz \
${result_dir}/${output_name}_sub2sst_jacobian.nii.gz 0 1

ok, i have received .
Regarding the Jacobian-related bug, could it significantly impact the calculation of gray matter volume (GMV)?

@ntustison
Copy link
Member

Is it confirmed that a bug actually exists?

@cookpa
Copy link
Member

cookpa commented May 14, 2025

I'm trying to confirm, can discuss more in #1884

@JinDJsuper
Copy link
Author

CreateJacobianDeterminantImage 3 ${result_dir}/sub2sst_composite.nii.gz \ ${result_dir}/${output_name}_sub2sst_jacobian.nii.gz 0 1
fslmaths${result_dir}/${output_name}_gm2sst.nii.gz -mul ${result_dir}/${output_name}_sub2sst_jacobian.nii.gz ${result_dir}/m${output_name}_gm2sst.nii.gz

reateJacobianDeterminantImage 3 ${sub2sst_warp} \ ${result_dir}/${output_name}_sub2sst_jacobian.nii.gz 0 1
fslmaths${result_dir}/${output_name}_gm2sst.nii.gz -mul ${result_dir}/${output_name}_sub2sst_jacobian.nii.gz ${result_dir}/m${output_name}_gm2sst.nii.gz

I recalculated the total voxels of m${output_name}_gm2sst.nii.gz using two different Jacobian files, and observed significant discrepancies. The Jacobian generated from ${result_dir}/sub2sst_composite.nii.gz yielded voxel counts closest to those in native individual space. Does this suggest that incorporating results from linear transformations is essential?

@cookpa
Copy link
Member

cookpa commented May 14, 2025

If you want to know the total volume change (linear + nonlinear), then yes you need both transforms.

It may be more accurate to record the linear volume change separately, and multiply it by the volume change from the deformation field.

antsTransformInfo will now output the determinant of an affine transform. It's just printed to the screen, not the most helpful but good for proof of concept

@JinDJsuper
Copy link
Author

If you want to know the total volume change (linear + nonlinear), then yes you need both transforms.

It may be more accurate to record the linear volume change separately, and multiply it by the volume change from the deformation field.

antsTransformInfo will now output the determinant of an affine transform. It's just printed to the screen, not the most helpful but good for proof of concept

I may have partially understood your point – it seems parameters related to linear positional transformations are indeed required. I also attempted to inspect the matrix of 0GenericAffine.mat using antsTransformInfo, but my limited background knowledge hindered further progress. Could you provide a concrete executable command for this scenario?
for example :
antsApplyTransforms-d 3 -o [${result_dir}/sub2sst_composite.nii.gz,1] -r ${sst_template} -t ${sub2sst_warp} -t ${sub2sst_affine}
CreateJacobianDeterminantImage 3 ${result_dir}/sub2sst_composite.nii.gz ${result_dir}/${output_name}_sub2sst_jacobian.nii.gz 0 1

@cookpa
Copy link
Member

cookpa commented May 15, 2025

Your code looks good. The caveat is that you are collapsing both the affine and the warp field into a single field, so it may be less precise.

The affine transform is global and continuous, while the warp fields are discretely sampled fairly coarsely (ie, at the resolution of your data). So the Jacobian calculation, based on derivatives around these discrete sample points, may be less precise.

I haven't quantified this, so maybe it's a negligible difference, particularly if your scaling is small. For longitudinal studies, it's probably small.

In the other approach, you would do

antsTransformInfo ${sub2sst_affine}

This would give you a determinant d_aff

CreateJacobianDeterminantImage 3 ${sub2sst_warp} ${result_dir}/${output_name}_sub2sst_jacobian.nii.gz 0 1

This would give you d_def, and you would multiply this by d_aff.

If ${sub2sst_affine} is purely rigid, then its determinant should be 1, and the composite should be very similar to ${sub2sst_warp} alone.

@cookpa
Copy link
Member

cookpa commented May 15, 2025

I tried this out on a T1w brain registered to MNI space, and there is very little difference - the determinant from the composed warp is almost identical to that from the affine + warp considered separately.

Always good to verify independently in your own data, but I'm optimistic that you will be fine to use the composed warp.

@JinDJsuper
Copy link
Author

I tried this out on a T1w brain registered to MNI space, and there is very little difference - the determinant from the composed warp is almost identical to that from the affine + warp considered separately.

Always good to verify independently in your own data, but I'm optimistic that you will be fine to use the composed warp.

Thank you very much for your response, I am verifying it using my own understanding

#the affine + warp considered separately
antsTransformInfo ${sub2sst_affine}
Matrix:
0.962028 0.00228846 0.00227062
0.00502709 0.954073 0.02029
0.0106763 -0.00493578 0.957008 > matrix.txt
python -c "import numpy as np; print(np.linalg.det(np.loadtxt('matrix.txt')))" > d_aff.txt
d_aff.txt > 0.8784475957999295

CreateJacobianDeterminantImage 3 ${sub2sst_warp} ${result_dir}/${output_name}_sub2sst_jacobian.nii.gz 0 1
fslmaths ${result_dir}/${output_name}_sub2sst_jacobian.nii.gz -mul $(cat d_aff.txt) jacobian_total.nii.gz
fslmaths ${template_gm} -mul jacobian_total.nii.gz m${template_gm}
fslmaths ${template_gm} -mul jacobian_composed.nii.gz m${template_gm}1

m${template_gm} vol > total: 329080 total-volume: 41135 (the affine + warp considered separately)
m${template_gm}1 vol > total: 329080 total-volume: 41135 (composed warp)
${native_gm} vol > total: 329532 total-volume: 41191.4 (native)

I believe that (the affine + warp considered separately) and (composed warp) might yield identical results.

@gdevenyi
Copy link
Contributor

python -c "import numpy as np; print(np.linalg.det(np.loadtxt('matrix.txt')))" > d_aff.txt

antsTransformInfo has the determinant in its output.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants