Unexpected zero-valued slices when computing Jacobian determinant from SCT warp field

Hi SCT team,

I am trying to compute a Jacobian determinant image from the deformation field generated by sct_register_to_template.

My registration command was approximately:

sct_register_to_template \
  -i data.nii.gz \
  -s seg.nii.gz \
  -ldisc labels_disc.nii.gz \
  -c t1 \
  -ofolder reg

I then tried to compute the Jacobian determinant using ANTs:

CreateJacobianDeterminantImage \
  3 \
  reg/warp_anat2template.nii.gz \
  spinal_jacobian.nii.gz \
  0 \
  0

The command runs, but the resulting spinal_jacobian.nii.gz contains many zero-valued voxels, including some entire z-slices with value 0. Some of these zero-valued areas are inside the PAM50 template signal range, and the corresponding warp_anat2template.nii.gz voxel has a non-zero value.

For example, in FSLeyes I can see a voxel where:

warp_anat2template: non-zero value
spinal_jacobian: 0.0
PAM50_t1: spinal cord area with non-zero signal

So I am wondering whether I am using the wrong command or whether the SCT warp field needs to be converted before being passed to CreateJacobianDeterminantImage.

The header of the warp field is:

dim0        5
dim1        141
dim2        141
dim3        991
dim4        1
dim5        3
datatype    16
pixdim0     -1.000000
pixdim1     0.500000
pixdim2     0.500000
pixdim3     0.500000
pixdim4     0.000000
pixdim5     0.000000
intent      Vector
intent_code 1007

PrintHeader also shows:

Spacing [0.5, 0.5, 0.5]
Size : 141 141 991
Image Dimensions : [141, 141, 991]
Intensity Range  : [-100000, 3.40282e+38]
Mean Intensity   : 4.17588e+35

My questions are:

  1. Is CreateJacobianDeterminantImage the correct way to compute the Jacobian determinant from warp_anat2template.nii.gz generated by SCT?
  2. Does the SCT warp field need to be converted from the 5D vector NIfTI format before Jacobian calculation?
  3. Are the extreme values in the warp field, such as -100000 and 3.40282e+38, expected padding values? Could they explain the zero-valued Jacobian slices?
  4. Is there an SCT-recommended way to generate a Jacobian determinant image from sct_register_to_template outputs?

I have attached a minimal set of files for testing via Google Drive:
testing data

Thanks!

Xiaomin

Hi Xiaomin,

Thank you so much for your questions. I’m happy to take a look. :blush:

Initial questions

    1. Is CreateJacobianDeterminantImage the correct way to compute the Jacobian determinant from warp_anat2template.nii.gz generated by SCT?
    1. Is there an SCT-recommended way to generate a Jacobian determinant image from sct_register_to_template outputs?

I will have to check in with my colleagues, as I have not used the CreateJacobianDeterminantImage script before.

    1. Does the SCT warp field need to be converted from the 5D vector NIfTI format before Jacobian calculation?

I believe that SCT should output the warping field in the correct 5D format to begin with (see this section of our Warping fields documentation page). I think the 5D format outlined there matches the snippet of the header you shared (i.e. t=1 for dim4):

dim0        5
dim1        141
dim2        141
dim3        991
dim4        1
dim5        3
  1. Are the extreme values in the warp field, such as -100000 and 3.40282e+38, expected padding values? Could they explain the zero-valued Jacobian slices?

Yes, those are expected padding values. I am not sure if they explain the zero-valued slices, but we can put a pin in that for now and come back to it. :slight_smile:

ANTs call

Just for my own understanding and for posterity, I wanted to make sure I understand the positional arguments in the function call you shared using the ANTs documentation. The script usage seems to be:

CreateJacobianDeterminantImage imageDimension deformationField outputImage [doLogJacobian=0] [useGeometric=0] [deformationGradient=0]

And so your command is something like:

CreateJacobianDeterminantImage \
  3 \                              # 1. imageDimension: 3D processing
  reg/warp_anat2template.nii.gz \  # 2. deformationField
  spinal_jacobian.nii.gz \         # 3. outputImage
  0 \                              # 4. doLogJacobian=0
  0 \                              # 5. useGeometric=0 -> standard Jacobian calc, not the geometric method
  0                                # 6. deformationGradient=0 -> implied default value

Aside: I notice that the documentation for ANTs contains the following notice:

Update 2025-05-29 A bug affecting Jacobian determinants in some data is fixed in #1887. The “geometric” Jacobian calculation is not affected. […] If you ran without the geometric option […] your data might be affected. Details in #1884.

Can you double-check whether your version of the function is subject to this bug? Specifically:

A quick way to check without recompiling or upgrading is to re-run CreateJacobianDeterminantImage with the geometric option on. The methods are not equivalent so the results will not be identical, but they should be similar - within the brain, they are mostly within 1% of each other in my tests.

Notes

Assuming that the bug is not the issue, then my first instinct (you have already done this) would be to overlay both the warping field and the output Jacobian image to see if the gaps are also present in the warping field itself (e.g. an issue with the registration process) or if the warping field looks okay but the gaps are introduced by the ANTs script.

My second thought (purely instinctual without a deep understanding of the ANTs script) is that perhaps because the input data is being warped from its native space to a larger space (PAM50), the non-zero slices at specific points correspond to the slices present in the input (with the zero slices corresponding to slices that would otherwise be interpolated as part of the application of the warping field). I don’t know how likely this is given that you describe the warping field as having non-zero values at those slices.

I will try to look more into this when I find a moment. I just wanted to provide an off-the-cuff reply now to let you know I’m looking at this and will follow-up. :slight_smile:

Kind regards,
Joshua

Hi Joshua,

Thank you very much for your detailed reply and suggestions.

I checked my ANTs version, and it appears to be the latest version, so I suspect the issue is probably not related to the older ANTs Jacobian determinant bug you mentioned.

I also tried changing the useGeometric option from 0 to 1. However, the result still shows alternating zero-valued slices along the z direction.

To be clear, I am not certain that CreateJacobianDeterminantImage is the correct way to compute the Jacobian determinant from an SCT-generated warp field. My understanding is still limited :baby:, but since SCT registration to the template appears to use ANTs-compatible transformations, and the nonlinear registration step seems to involve BSplineSyN, I thought this ANTs command might be a reasonable thing to try.

For brain MRI data, I have previously used ants.registration.create_jacobian_determinant_image, and the results seemed to work as expected. However, for the spinal cord case, I could not find an official SCT command or documented SCT workflow for extracting the Jacobian determinant from warp_anat2template.nii.gz, so I was experimenting with this approach.

Do you know whether SCT has an official or recommended method for computing the Jacobian determinant from the template-registration warp field? Or is there a preferred way to handle the SCT warp field before computing the Jacobian?

Thanks again for all your help — I really appreciate you taking the time to look into this. :blush:

Best,
Xiaomin

Hi @Xiaomin_Lin
This doesn’t answer your question, sorry, (I’m looking into) :upside_down_face:,
but another easy/didactic way to view the warps files (not Jacobians) is through ITKsnap: Multi-component Display/grid

Best,

Nilser

Hi @joshuacwnewton
From the multimodal-registration project, I found this script to calculate jacobians,
I tried to apply it in the @Xiaomin_Lin warps, but I think it only works in multimodal registrations :face_with_diagonal_mouth:, and not to-template registrations.

I’ll keep looking into.

Best,

Nilser

Hi @nlaines,

Thank you very much for looking into this and for the helpful suggestion.

I will try visualizing the warp field in ITK-SNAP using the Multi-component Display / grid option to better understand whether the deformation field itself looks reasonable. That sounds like a useful debugging step before focusing on the Jacobian output.

Thank you also for checking the Jacobian script from the multimodal-registration project. I see what you mean that it may be specific to multimodal registrations and may not directly apply to the to-template registration case. If you happen to find a workflow or script that is appropriate for sct_register_to_template outputs, especially warp_anat2template.nii.gz, I would be very grateful.

Thanks again for your help!

Best,
Xiaomin