Skip to content
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

Dog Atlas #26

Open
shinndvm opened this issue Oct 18, 2024 · 11 comments
Open

Dog Atlas #26

shinndvm opened this issue Oct 18, 2024 · 11 comments

Comments

@shinndvm
Copy link

shinndvm commented Oct 18, 2024

I am using the getting started instruction on the (https://spinalcordtoolbox.com/) main page. I get to the register multimodal and use the code as shown below but when I get to the extract method I get the following error. Any suggestions? I have tried it with the -l and without the -l for the extract metric as I thought 40 was the entire spinal cord.

sct_register_multimodal i $SCT_DIR/template-dog/templatedog_2w.nii.gz-iseg $SCT_DIR/template-dog/templatedog_cord.nii.gz -d dmri_crop_moco_dwi_mean.nii.gz -dseg.dri crop _moco dwi_mean_seg.nii.gz -param step=1,type=seg,algo=centermass:step=2,type=seg,algo=bsplinesyn,metric=MeanSquares,smooth=1,iter=3 -initwarp $SCT_DIR/HR to temp/warp_template2anat.nii.gz-initwarpinv$SCT_DIR/HB to temp/warp_anat2template.nii.gz -qc "$SCT_BP_QC_FOLDER" -owarpwarp_template2dmri.nii.gz-owarpinv warp_dmri2template.nii.gz

# Compute DTI metrics
sct_dmri_compute_dti -i dri_crop_moco.nii.gz -bval bvals.txt -bvec bvecs.txt -m dmri_crop_moco_dwi_mean_seg.nii.gz
sct_extract_metric -i dti_AD.nii.gz -l 40 -z 16 -method wa -o AD16.txt
> sct_extract_metric -i dti_AD.nii.gz -l 40 -z 16 -method wa -o AD16.txt
Spinal Cord Toolbox (git-master-4220101576d7b18a5b1af18a8b211d8a849ec2ef)
sct_extract_metric -i dti_AD.nii.gz -l 40 -z 16 -method wa -o AD16.txt
Traceback (most recent call last):
File "/Users/.../spinalcordtoolbox/spinalcordtoolbox/scripts/sct_extract_metric.py",
line 400, in ‹module>
main(sys.argv[1:])
File "/Users/.../spinalcordtoolbox/spinalcordtoolbox/scripts/sct_extract_metric.py",
line 330, in main
map_cluster=lindiv_labels_idsli_labell in map_cluster for
ValueError: True is not in list
@jcohenadad
Copy link
Member

I suspect the issue is that there is no WM atlas for this template, but @joshuacwnewton can you please double check? thank you

@joshuacwnewton
Copy link
Member

joshuacwnewton commented Oct 21, 2024

Thank you for the ping, @jcohenadad.

The lines of code that failed look like this:

    # [...]
    elif os.path.isdir(path_label):
        # Labels is an SCT atlas folder structure
        # Parse labels according to the file info_label.txt
        indiv_labels_ids, indiv_labels_names, indiv_labels_files, \
            combined_labels_ids, combined_labels_names, combined_labels_id_groups, map_clusters \
            = read_label_file(path_label, param_default.file_info_label)

        label_struc = {}
        # fill IDs for indiv labels
        for i_label in range(len(indiv_labels_ids)):
            label_struc[indiv_labels_ids[i_label]] = LabelStruc(id=indiv_labels_ids[i_label],
                                                                name=indiv_labels_names[i_label],
                                                                filename=indiv_labels_files[i_label],
                                                                map_cluster=[indiv_labels_ids[i_label] in map_cluster for
                                                                             map_cluster in map_clusters].index(True))

You can see in the code above, because of the first conditional, the code will only be run if the condition os.path.isdir(path_label) is true:

  • path_label corresponds to the CLI argument sct_extract_metric -f
  • Since the command does not specify a value for -f, the default value will be used (os.path.join("label", "atlas")).
  • Meaning, the code is trying to fetch the labels from the atlas present at ./label/atlas.

But, I am confused, because the dog template has no atlas folder at all -- it is just a template:

image

So, what I am curious about is: Why is there a non-empty atlas/ folder in your working directory? Where did it come from? The presence of this non-empty atlas/ folder is likely causing the issue.


Anyway, if you wish to extract DTI metrics from the full spinal cord mask, I would make sure the following conditions are true:

  • Remove the -l 40 from your command
  • Explicitly pass a binary mask of the spinal cord to the -f argument. (This "single label file" usage is supported by -f.)

Since you are registering to the template, I would assume that you wish to use the file templatedog_cord.nii.gz that is present in the template. I would guess that you may need to use sct_warp_template to warp the template to the subject space, then add -f ./label/template/templatedog_cord.nii.gz to your command to specify this file.

@joshuacwnewton
Copy link
Member

joshuacwnewton commented Oct 21, 2024

Some observations for SCT development:

  • The behavior of -f silently using ./label/atlas is a bit opaque. While this works fine for the PAM50 template (since the atlas is warped by default), it's less clear for non-PAM50 templates that are missing an atlas folder. I wonder if this issue was caused by sct_warp_template creating an atlas folder even when there were no atlas files? (TODO for myself: investigate sct_warp_template behavior)
  • SCT provided a very unintuitive error message. We could definitely improve the error message to make it easier to understand. (TODO for myself)

@shinndvm
Copy link
Author

Should the dog template have an atlas? I just did the following instructions:

  • install dev version of SCT (clone and then run the installer)
  • once installed, run: sct_download_data -d template-dog

@joshuacwnewton
Copy link
Member

joshuacwnewton commented Oct 29, 2024

Should the dog template have an atlas?

Not that I know of... The contents of the .zip are listed in my previous comment: #26 (comment)

((Note: The command sct_download_data -d template-dog will download the .zip listed in the most recent release (r20240709) from the template-dog repo's "Releases" page. This can be verified by navigating to the spinalcordtoolbox/download.py file and checking the URL.))

Given that there is no atlas, I am quite confused as to why the atlas-specific code is even executing. 🤔

@jcohenadad
Copy link
Member

@shinndvm Just to clarify: the dog template only consists of an averaged T2w MRI scans across 6 dogs and segmented spinal cord. There is no atlas of white matter, like there is for the PAM50 template. You could still use the template to extract metrics within the spinal cord. If you wish to create an atlas of specific tracts, this is something we could discuss.

@shinndvm
Copy link
Author

shinndvm commented Oct 29, 2024

At the moment, we’re analyzing the entire spinal cord, but targeting specific tracts would be an ideal goal down the line. Below, I’ve included the workflow steps used in the terminal. However, I’m still unable to obtain the metrics—everything runs smoothly until reaching sct_dmri_compute_dti. I’ve included the entire process here to confirm if there might be an additional step that’s needed.

Also, the dog template has been moved to the same folder, which is why there’s no path specified for it. For sct_extract_metric, I’ve tested with and without the -l option, but as the process stalls at compute_dti, I’m unsure of how much the -l option impacts the outcome at this stage.
Thank you

# sct_deepseg_sc -i T2w.nii.gz -c t2 -o T2w_label-SC_seg_initial.nii.gz 

# sct_label_utils -i T2w.nii.gz -create-viewer 1:24 -o T2w_labels-disc.nii.gz

# sct_register_to_template -i T2w.nii.gz -s T2w_label-SC_seg.nii.gz -ldisc T2w_labels-disc.nii.gz -t template-dog -c t2 -s-template-id 2 -param step=1,type=seg,algo=centermassrot:step=2,type=im,algo=syn,metric=CC,iter=3 -ofolder HB_to_temp -qc qc_HB_to_temp

# sct_dmri_transpose_bvecs -bvec bvecs.txt
# sct_dmri_separate_b0_and_dwi -i dmri.nii.gz -bvec bvecs.txt 

# sct_register_multimodal -i T2w_label-SC_seg.nii.gz -d dmri_dwi_mean.nii.gz -param step=1,type=im,algo=dl -identity 1 -x nn

# sct_create_mask -i dmri_dwi_mean.nii.gz -p centerline,T2w_label-SC_seg_reg.nii.gz -size 45mm 

# sct_crop_image -i dmri.nii.gz -m mask_dmri_dwi_mean.nii.gz -o dmri_crop.nii.gz

# sct_dmri_moco -i dmri_crop.nii.gz -bvec bvecs.txt

# sct_deepseg_sc -i dmri_crop_moco_dwi_mean.nii.gz -c dwi -qc "$SCT_BP_QC_FOLDER"

# sct_qc -i dmri_crop.nii.gz -d dmri_crop_moco.nii.gz -s dmri_crop_moco_dwi_mean_seg.nii.gz -p sct_dmri_moco -qc "$SCT_BP_QC_FOLDER"

# sct_register_multimodal -i $SCT_DIR/template-dog/templatedog_t2w.nii.gz -iseg $SCT_DIR/template-dog/templatedog_cord.nii.gz -d dmri_crop_moco_dwi_mean.nii.gz -dseg dmri_crop_moco_dwi_mean_seg.nii.gz -param step=1,type=seg,algo=centermass:step=2,type=seg,algo=bsplinesyn,metric=MeanSquares,smooth=1,iter=3 -initwarp $SCT_DIR/HB_to_temp/warp_template2anat.nii.gz -initwarpinv $SCT_DIR/HB_to_temp/warp_anat2template.nii.gz -qc "$SCT_BP_QC_FOLDER" -owarp warp_template2dmri.nii.gz -owarpinv warp_dmri2template.nii.gz

# sct_dmri_compute_dti -i dmri_crop_moco.nii.gz -bval bvals.txt -bvec bvecs.txt -m dmri_crop_moco_dwi_mean_seg.nii.gz

# sct_extract_metric -i dti_AD.nii.gz -l 40 -z 16 -method wa -o AD16.txt

@jcohenadad
Copy link
Member

Few comments here:

Using flag -l 40 only works when you use a template that has an atlas, which is not the case here. So that flag should be avoided until we develop an atlas of the dog spinal cord.

If you want to register multiple dogs to the dog template, and then extract metrics within the spinal cord, then you can use replace -l with -f, pointing to the mask you want to extract the signal from. Ex:

sct_extract_metric -i IMAGE_IN_TEMPLATE_SPACE -f $SCT_DIR/template-dog/templatedog_cord.nii.gz

If you want to extract metric in the dog-specific space (ie, not the template), then you don't need to register to a template for that. You can simply use:

sct_extract_metric -i IMAGE_IN_NATIVE_SPACE -f MASK_IN_NATIVE_SPACE

Hope that helps,
Julien

@shinndvm
Copy link
Author

Thank you. This is what I am imputing and seem to be getting values that would correlate to what they should be.

sct_extract_metric -i dti_MD.nii.gz -f dmri_crop_moco_dwi_mean_seg.nii.gz -o MD.txt

@shinndvm
Copy link
Author

shinndvm commented Oct 29, 2024

Well I thought things were running smoothly but now looking at a new patient when I run the following script:

sct_register_to_template -i T2w.nii.gz -s T2w_label-SC_seg.nii.gz -ldisc T2w_labels-disc.nii.gz -t data/template-dog -c t2 -s-template-id 2 -param step=1,type=seg,algo=centermassrot:step=2,type=im,algo=syn,metric=CC,iter=3 -ofolder HB_to_temp -qc qc_HB_to_temp

I get the following error

Image /private/var/folders/zz/m4pgv4k94xn25p3h22kdhw1m0000gp/T/sct_2024-10-29_16-56-31_register-to-template_tjarnl14/seg_bin_rpi_1mm_crop.nii.gz has different qform and sform matrices. This can produce incorrect results. Please use 'sct_image -i /private/var/folders/zz/m4pgv4k94xn25p3h22kdhw1m0000gp/T/sct_2024-10-29_16-56-31_register-to-template_tjarnl14/seg_bin_rpi_1mm_crop.nii.gz -header' to check that both affine matrices are valid. Then, consider running either 'sct_image -set-sform-to-qform' or 'sct_image -set-qform-to-sform' to fix any discrepancies you may find.
Traceback (most recent call last):
  File "/Users/richardshinn/spinalcordtoolbox/spinalcordtoolbox/scripts/sct_register_to_template.py", line 815, in <module>
    main(sys.argv[1:])
  File "/Users/richardshinn/spinalcordtoolbox/spinalcordtoolbox/scripts/sct_register_to_template.py", line 564, in main
    sc_straight.straighten()
  File "/Users/richardshinn/spinalcordtoolbox/spinalcordtoolbox/straightening.py", line 108, in straighten
    Image(fname_anat, check_sform=True).save(os.path.join(path_tmp, "data.nii"))
  File "/Users/richardshinn/spinalcordtoolbox/spinalcordtoolbox/image.py", line 343, in __init__
    raise ValueError("Image sform does not match qform")
ValueError: Image sform does not match qform

I have run

sct_image -set-sform-to-qform -i /private/var/folders/zz/m4pgv4k94xn25p3h22kdhw1m0000gp/T/sct_2024-10-29_16-45-16_register-to-template_kdzxm6zu/seg_bin_rpi_1mm_crop.nii.gz -o output_file.nii.gz

because the sform and qform do not match up (using sct_image -i output_file.nii.gz -header) but anytime I rerun the script it creates a new temp folder and then the same error pops back up.

Sorry to keep bugging you but any suggestions would be appreciated.

@joshuacwnewton
Copy link
Member

Sorry to keep bugging you but any suggestions would be appreciated.

No worries at all, we're happy to help. (For future reference, it might be easier to post on the SCT Forum, which is a more "general" place to ask for usage help with SCT, rather than the "template-dog" repo, that way others can benefit from the problem-solving.)

Anyway, you are correct, modifying the file in the temporary directory won't help because a new tmpdir will be used each time. Instead, I would recommend backing up the original image file used for -i, then changing the qform/sform on that file instead:

mv T2w.nii.gz T2w_mismatched_xforms.nii.gz
sct_image -set-sform-to-qform -i T2w_mismatched_xforms.nii.gz -o T2w.nii.gz

(Note: You may need to do this for the -s and -ldisc files as well, since they are based off of the original T2w.nii.gz file.)

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

3 participants