Registration tips

Dear @joshuacwnewton,

Thank you for all your help.
I managed to complete the registration.
During quality checks, I noticed the following:

  • Registration is always off/less good in caudal parts of the cervical spine
    example_1

  • When I compare the images warped with the current approach (warping field from EPI - T2 concatenated with WM improved warping field from T2 to PAM50), with a simpler approach (only applying the three warping fields (EPI-T2, T2-T1, T1-PAM50), the current approach gives smaller images. It seems that the more rostral parts are partly cut off.

(red = current approach, green = simple approach)
example_2

Is there any way to solve these issues?
Best,
Evelyne

Hi @Evelyne,

I’m sorry to hear about these strange registration results!

Could you please share the full updated β€œsct_preprocess.py” script, just so we can see exactly the commands you are using for both the current approach and the simpler approaches?

Kind regards,
Joshua

Dear @joshuacwnewton ,

Hereby the script:
sct_preproces.py (42.3 KB)

The simple approach is called with final_warp_apply_old.

One note, I wanted to use the WM segmentation, but sct_maths -sub was not working for me. To get a quick workaround, I used the MATLAB image calculator for this. I will upload one of these pictures, so you can take a look. SURFdrive

Thank you in advance.
Best,
Evelyne

Dear @joshuacwnewton,

Did you have any time to look into the registration?

Best,
Evelyne

Dear @Evelyne,

My apologies for the delay in responding. I did take a look, but admittedly registration parameter adjustment is not my strongest skill (I am a software developer for SCT, rather than a researcher).

So, I have asked my colleagues for assistance on this issue, and @sandrinebedard has been taking a look. As well, @jcohenadad is now back from vacation, so he may also have some feedback.

Thank you kindly for your patience,
Joshua

Ah! It turns out that @sandrinebedard has been working on a solution, and has shared with me a summary of her conclusions, quoted below:

  • -l flag was used instead of -ldisc for registration to PAM50 template (since discs labels are used here) β†’ so T1 reg to PAM50 was poor
  • Registration T1 β†’ T2 star was poor β†’ use the segmentation and centerofmass instead
  • Registration EPI β†’ T2star was poor β†’ use the segmentation and centerofmass instead
  • I would suggest here to also test out using the T2star warping field to initialize the warping field and directly register EPI to the template
  • As a general suggestion, I would suggest to always check the intermediate steps of each registration before putting them together – using a lot of intermediate registrations can accumulate errors too.

She also shared a modified script with her changes: sct_preproces.py (45.7 KB)

The changes that were made are as follows: https://www.diffchecker.com/x9ti3koj/

Could you please test out these suggestions, then let us know how it goes? :slight_smile:

Kind regards,
Joshua

1 Like

Dear @joshuacwnewton,

Thank you for your help.

The registration is overall better, but not perfect yet.
I applied the inverse warping field to the atlases and still see a lot of mismatches at the caudal cervical parts. Also, for some parts of the spinal cord, the masks are not warped and are just blank (see missing parts in images below). I also tried to directly estimate the EPI-temp registration with initialization of the GM-informed T2s-temp warping field (as suggested in previous messages), but this did improve the registration. Overall, the individual differences are big, which leads to no results in my group-level seed-based analysis (with spinal cord horns/hemicords as seeds). Any thoughts on this?



Let me have a look at it…

Hi, few comments:

  • The T2*w scan has less coverage than the EPI scan (see below), so if you are using the former as an intermediate image to register your EPI to the template, the region not covered by the T2*w scan will result in undefined transformation, which will lead to missing part of the PAM50 objects in this region, and registration inaccuracies (such as the ones you are observing) (gray: EPI ; red: T2*w)

    image

  • I suggest working with NII.GZ instead of NII (to save space and be compatible with existing SCT batch processing scripts);

  • I suggest working with BIDS structure to facilitate reusability of existing scripts and data sharing;

  • The provided Python script is too convoluted (>1000 lines of code, no time to dig) with hard-coded paths in the middle, so I made a simple SHELL script (see below). I suggest using the combo SHELL script and sct_run_batch for multiple processing, and manual correction steps for segmentation and labeling. See notably Processing batches of subjects using pipeline scripts - Spinal Cord Toolbox documentation.

  • From the pipeline below, the automatic cord segmentation on the EPI scan requires manual correction. I did it and you will need to download that segmentation and place it in the same folder as the data, in order to properly run the pipeline: slc_f302300909_sub010-0011-00006-000011-01_moco_mean_seg-manual.nii.gz (1.2 KB)

# Create generic file names
file_t1="s302300909_sub010-0015-00001-000192-01.qform"
file_t2s="s302300909_sub010-0009-00001-000001-01.qform"
file_fmri="slc_f302300909_sub010-0011-00006-000011-01_moco_mean"

# Segment cord on T1w
sct_deepseg_sc -i ${file_t1}.nii -c t1 -qc qc
file_t1_seg=${file_t1}_seg

# Label vertebrae
sct_label_vertebrae -i ${file_t1}.nii -s ${file_t1_seg}.nii -c t1 -qc qc
file_t1_seg_labeled=${file_t1_seg}_labeled

# Create labels at in the cord at C2 and C7 mid-vertebral levels
sct_label_utils -i ${file_t1_seg_labeled}.nii -vert-body 2,7 -o labels_vert.nii.gz

# Register T1w to template
sct_register_to_template -i ${file_t1}.nii -s ${file_t1_seg}.nii -l labels_vert.nii.gz -c t1 -qc qc

# Segment cord on T2*w
sct_deepseg_sc -i ${file_t2s}.nii -c t2s -qc qc

# Segment GM on T2*w
sct_deepseg_gm -i ${file_t2s}.nii -qc qc

# Subtract GM segmentation from cord segmentation to obtain WM segmentation
sct_maths -i ${file_t2s}_seg.nii -sub ${file_t2s}_gmseg.nii -o ${file_t2s}_wmseg.nii

# Register template to T2*w (using warping field generated from template<->T1 registration)
sct_register_multimodal -i "$SCT_DIR/data/PAM50/template/PAM50_t2s.nii.gz" -iseg "$SCT_DIR/data/PAM50/template/PAM50_wm.nii.gz" -d ${file_t2s}.nii -dseg ${file_t2s}_wmseg.nii -param step=1,type=seg,algo=centermass:step=2,type=seg,algo=bsplinesyn,slicewise=1,iter=3:step=3,type=im,algo=syn,slicewise=1,iter=1,metric=CC -initwarp warp_template2anat.nii.gz -initwarpinv warp_anat2template.nii.gz -owarp warp_template2t2s.nii.gz -owarpinv warp_t2s2template.nii.gz -qc qc

# Segment cord on EPI
sct_deepseg_sc -i ${file_fmri}.nii -c t2s -qc qc
# Note: the segmentation requires manual correction with added suffix "-manual". 
file_fmri_seg=${file_fmri}_seg-manual

# Register template to EPI (using warping field generated from template<->T2*w registration)
sct_register_multimodal -i "$SCT_DIR/data/PAM50/template/PAM50_t2.nii.gz" -iseg "$SCT_DIR/data/PAM50/template/PAM50_cord.nii.gz" -d ${file_fmri}.nii -dseg ${file_fmri_seg}.nii.gz -param step=1,type=seg,algo=centermass:step=2,type=seg,algo=bsplinesyn,metric=MeanSquares,slicewise=1,iter=3:step=3,type=im,algo=syn,metric=CC,iter=3,slicewise=1 -initwarp warp_template2t2s.nii.gz -initwarpinv warp_t2s2template.nii.gz -owarp warp_template2fmri.nii.gz -owarpinv warp_fmri2template.nii.gz -qc qc

Registration results EPI overlaid on PAM50_T2w. Notice the missing slices because of the reduced coverage of the T2*w scan. If you wish to overcome that issue, you can simply ignore the T2*w scan in the registration pipeline. You won’t get the GM information for registration, but to be honest given the small inter-subject variability of GM shape and the coarse resolution of the EPI scans, I don’t think it makes a difference:

anim

And here is the full QC report: qc.zip (1.4 MB)