From 614f2a82e54b4ba2b6549f37b4cbb089b21d38bb Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Tue, 26 Nov 2024 12:14:05 -0500 Subject: [PATCH 01/41] `batch_single_subject.sh`: `sct_deepseg_sc` -> `sct_deepseg` --- single_subject/batch_single_subject.sh | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index d2f2f5d..99ca181 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -38,11 +38,18 @@ fi # Go to T2 contrast cd data/t2 -# Spinal cord segmentation ( -sct_deepseg_sc -i t2.nii.gz -c t2 -qc ~/qc_singleSubj +# Spinal cord segmentation (using new 2024 method) +sct_deepseg -task seg_sc_contrast_agnostic -i t2.nii.gz -qc ~/qc_singleSubj +# You can also choose your own output filename using the “-o” argument +# sct_deepseg -task seg_sc_contrast_agnostic -i t2.nii.gz -o t2_seg_test.nii.gz + # To check the QC report, use your web browser to open the file qc_singleSubj/qc/index.html, which has been created in # your home directory +# View the rest of the `sct_deepseg` tasks +sct_deepseg -h +# See also: https://spinalcordtoolbox.com/stable/user_section/command-line/sct_deepseg.html + # Vertebral labeling From 3d9815190c91a11b031f0eeaacfe30225b42935c Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Tue, 26 Nov 2024 12:15:52 -0500 Subject: [PATCH 02/41] `batch_single_subject.sh`: Move `sct_label_utils` to registration section --- single_subject/batch_single_subject.sh | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index 99ca181..89ceb3f 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -66,17 +66,6 @@ sct_label_vertebrae -i t2.nii.gz -s t2_seg.nii.gz -c t2 -qc ~/qc_singleSubj #sct_label_utils -i t2.nii.gz -create-viewer 3 -o label_c2c3.nii.gz -msg "Click at the posterior tip of C2/C3 inter-vertebral disc" #sct_label_vertebrae -i t2.nii.gz -s t2_seg.nii.gz -c t2 -initlabel label_c2c3.nii.gz -qc ~/qc_singleSubj -# Create labels at C3 and T2 mid-vertebral levels. These labels are needed for template registration. -sct_label_utils -i t2_seg_labeled.nii.gz -vert-body 3,9 -o t2_labels_vert.nii.gz -# Generate a QC report to visualize the two selected labels on the anatomical image -sct_qc -i t2.nii.gz -s t2_labels_vert.nii.gz -p sct_label_utils -qc ~/qc_singleSubj - -# OPTIONAL: You might want to completely bypass sct_label_vertebrae and do the labeling manually. In that case, we -# provide a viewer to do so conveniently. In the example command below, we will create labels at the inter-vertebral -# discs C2-C3 (value=3), C3-C4 (value=4) and C4-C5 (value=5). -#sct_label_utils -i t2.nii.gz -create-viewer 3,4,5 -o labels_disc.nii.gz -msg "Place labels at the posterior tip of each inter-vertebral disc. E.g. Label 3: C2/C3, Label 4: C3/C4, etc." - - # Computing shape metrics @@ -153,6 +142,17 @@ fsleyes t2.nii.gz -cm greyscale t2_seg.nii.gz -cm subcortical -a 70.0 & # Registering T2 data to the PAM50 template # ====================================================================================================================== cd ../t2 + +# Create labels at C3 and T2 mid-vertebral levels. These labels are needed for template registration. +sct_label_utils -i t2_seg_labeled.nii.gz -vert-body 3,9 -o t2_labels_vert.nii.gz +# Generate a QC report to visualize the two selected labels on the anatomical image +sct_qc -i t2.nii.gz -s t2_labels_vert.nii.gz -p sct_label_utils -qc ~/qc_singleSubj + +# OPTIONAL: You might want to completely bypass sct_label_vertebrae and do the labeling manually. In that case, we +# provide a viewer to do so conveniently. In the example command below, we will create labels at the inter-vertebral +# discs C2-C3 (value=3), C3-C4 (value=4) and C4-C5 (value=5). +#sct_label_utils -i t2.nii.gz -create-viewer 3,4,5 -o labels_disc.nii.gz -msg "Place labels at the posterior tip of each inter-vertebral disc. E.g. Label 3: C2/C3, Label 4: C3/C4, etc." + # Register t2->template. sct_register_to_template -i t2.nii.gz -s t2_seg.nii.gz -l t2_labels_vert.nii.gz -c t2 -qc ~/qc_singleSubj # Note: By default the PAM50 template is selected. You can also select your own template using flag -t. From fdaf9762c0061a1e7e4e457a18059220c2d06318 Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Tue, 26 Nov 2024 12:20:03 -0500 Subject: [PATCH 03/41] `batch_single_subject.sh`: Move new features to end of script Rootlets and lesion analysis should be incorporated more deeply into the tutorials, but for this year's SCT Course, they are in the "New Features" section, so we should put them at the end as to not disrupt the flow of the script. --- single_subject/batch_single_subject.sh | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index 89ceb3f..9b8bbb3 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -409,5 +409,30 @@ sct_smooth_spinalcord -i t1.nii.gz -s t1_seg.nii.gz sct_flatten_sagittal -i t1.nii.gz -s t1_seg.nii.gz # Note: Use for visualization purposes only + + +# New features (SCT v6.5, December 2024) +# ====================================================================================================================== + +# Lesion analysis +cd ../t2_lesion +# Segment the spinal cord and intramedullary lesion using the SCIsegV2 model +# Note: t2.nii.gz contains a fake lesion for the purpose of this tutorial +sct_deepseg -i t2.nii.gz -task seg_sc_lesion_t2w_sci -qc ~/qc_singleSubj +# Note: Two files are output: +# - t2_sc_seg.nii.gz: the spinal cord segmentation +# - t2_lesion_seg.nii.gz: the lesion segmentation +# Check results using FSLeyes +fsleyes t2.nii.gz -cm greyscale t2_sc_seg.nii.gz -cm red -a 70.0 t2_lesion_seg.nii.gz -cm blue-lightblue -a 70.0 & +# Compute various morphometric measures, such as number of lesions, lesion length, lesion volume, etc. +sct_analyze_lesion -m t2_lesion_seg.nii.gz -s t2_sc_seg.nii.gz -qc ~/qc_singleSubj + +# Rootlets segmentation +cd ../t2 +# Segment the spinal nerve rootlets +sct_deepseg -i t2.nii.gz -task seg_spinal_rootlets_t2w -qc ~/qc_singleSubj +# Check results using FSLeyes +fsleyes t2.nii.gz -cm greyscale t2_seg.nii.gz -cm subcortical -a 70.0 & + # Return to parent directory cd .. From ad7880cbf58208f1bcf590039d63b25b0e23a80f Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Tue, 26 Nov 2024 12:23:32 -0500 Subject: [PATCH 04/41] `batch_single_subject.sh`: Add missing `-normalize-PAM50` command --- single_subject/batch_single_subject.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index 9b8bbb3..d1dcc3b 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -86,6 +86,10 @@ sct_detect_pmj -i t2.nii.gz -c t2 -qc ~/qc_singleSubj # Check the QC to make sure PMJ was properly detected, then compute CSA using the distance from the PMJ: sct_process_segmentation -i t2_seg.nii.gz -pmj t2_pmj.nii.gz -pmj-distance 64 -pmj-extent 30 -o csa_pmj.csv -qc ~/qc_singleSubj -qc-image t2.nii.gz +# The above commands will output the metrics in the subject space (with the original image's slice numbers) +# However, you can get the corresponding slice number in the PAM50 space by using the flag `-normalize-PAM50 1` +sct_process_segmentation -i t2_seg.nii.gz -vertfile t2_seg_labeled.nii.gz -perslice 1 -normalize-PAM50 1 -o csa_PAM50.csv + # Computing normalized shape metrics for compressed data From 398968330b31f72947cc297213e56d0a6c9b568c Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Tue, 26 Nov 2024 12:25:53 -0500 Subject: [PATCH 05/41] `batch_single_subject.sh`: Update Compression title --- single_subject/batch_single_subject.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index d1dcc3b..2a4752f 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -92,7 +92,7 @@ sct_process_segmentation -i t2_seg.nii.gz -vertfile t2_seg_labeled.nii.gz -persl -# Computing normalized shape metrics for compressed data +# Quantifying spinal cord compression (MSCC) and normalize against database of healthy controls # ====================================================================================================================== cd ../t2_compression # Segment the spinal cord of the compressed spine From 51ab7acae342c880a0d5bb8fc7f303bbc846f04d Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Tue, 26 Nov 2024 12:30:23 -0500 Subject: [PATCH 06/41] `batch_single_subject.sh`: Add missing registration commands --- single_subject/batch_single_subject.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index 2a4752f..9461d14 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -161,6 +161,18 @@ sct_qc -i t2.nii.gz -s t2_labels_vert.nii.gz -p sct_label_utils -qc ~/qc_singleS sct_register_to_template -i t2.nii.gz -s t2_seg.nii.gz -l t2_labels_vert.nii.gz -c t2 -qc ~/qc_singleSubj # Note: By default the PAM50 template is selected. You can also select your own template using flag -t. +# Register t2->template with modified parameters (advanced usage of `-param`) +sct_register_to_template -i t2.nii.gz -s t2_seg.nii.gz -l t2_labels_vert.nii.gz -qc ~/qc_singleSubj -ofolder advanced_param -c t2 -param step=1,type=seg,algo=rigid:step=2,type=seg,metric=CC,algo=bsplinesyn,slicewise=1,iter=3:step=3,type=im,metric=CC,algo=syn,slicewise=1,iter=2 + +# Register t2->template with large FOV (e.g. C2-L1) using `-ldisc` option +# sct_register_to_template -i t2.nii.gz -s t2_seg.nii.gz -ldisc t2_seg_labeled_discs.nii.gz -c t2 + +# Register t2->template in compressed cord (example command) +# In case of highly compressed cord, the algo columnwise can be used, which allows for more deformation than bsplinesyn. +# NB: In the example below, the registration is done in the subject space (no straightening) using a single label point at disc C3-C4 (). +# sct_register_to_template -i -s -ldisc -ref subject -param step=1,type=seg, +# algo=centermassrot:step=2,type=seg,algo=columnwise + # Warp template objects (T2, cord segmentation, vertebral levels, etc.). Here we use -a 0 because we don’t need the # white matter atlas at this point. sct_warp_template -d t2.nii.gz -w warp_template2anat.nii.gz -a 0 -qc ~/qc_singleSubj From 78e10b18d11103bd961d5ec55213a709f1336c16 Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Tue, 26 Nov 2024 12:34:44 -0500 Subject: [PATCH 07/41] `batch_single_subject.sh`: Replace `sct_deepseg_sc` with contrast agnostic --- single_subject/batch_single_subject.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index 9461d14..48dc6af 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -96,7 +96,7 @@ sct_process_segmentation -i t2_seg.nii.gz -vertfile t2_seg_labeled.nii.gz -persl # ====================================================================================================================== cd ../t2_compression # Segment the spinal cord of the compressed spine -sct_deepseg_sc -i t2_compressed.nii.gz -c t2 -qc ~/qc_singleSubj +sct_deepseg -task seg_sc_contrast_agnostic -i t2_compressed.nii.gz -qc ~/qc_singleSubj # Label the vertebrae using the compressed spinal cord segmentation sct_label_vertebrae -i t2_compressed.nii.gz -s t2_compressed_seg.nii.gz -c t2 -qc ~/qc_singleSubj # Generate labels for each spinal cord compression site. @@ -190,7 +190,7 @@ fsleyes t2.nii.gz -cm greyscale -a 100.0 label/template/PAM50_t2.nii.gz -cm grey # Go to mt folder cd ../mt # Segment cord -sct_deepseg_sc -i mt1.nii.gz -c t2 -qc ~/qc_singleSubj +sct_deepseg -task seg_sc_contrast_agnostic -i mt1.nii.gz -qc ~/qc_singleSubj # Create a close mask around the spinal cord for more accurate registration (i.e. does not account for surrounding # tissue which could move independently from the cord) @@ -236,13 +236,13 @@ sct_compute_mtr -mt0 mt0_reg.nii.gz -mt1 mt1.nii.gz # 1. T2w preprocessing (cropping around spinal cord) cd ../t2 -sct_deepseg_sc -i t2.nii.gz -c t2 -qc ~/qc_singleSubj +sct_deepseg -task seg_sc_contrast_agnostic -i t2.nii.gz -qc ~/qc_singleSubj sct_create_mask -i t2.nii.gz -p centerline,t2_seg.nii.gz -size 35mm -f cylinder -o mask_t2.nii.gz sct_crop_image -i t2.nii.gz -m mask_t2.nii.gz # 2. T1w preprocessing (cropping around spinal cord) cd ../t1 -sct_deepseg_sc -i t1.nii.gz -c t1 -qc ~/qc_singleSubj +sct_deepseg -task seg_sc_contrast_agnostic -i t1.nii.gz -qc ~/qc_singleSubj sct_create_mask -i t1.nii.gz -p centerline,t1_seg.nii.gz -size 35mm -f cylinder -o mask_t1.nii.gz sct_crop_image -i t1.nii.gz -m mask_t1.nii.gz @@ -285,7 +285,7 @@ cd ../t2s # Segment gray matter (check QC report afterwards) sct_deepseg_gm -i t2s.nii.gz -qc ~/qc_singleSubj # Spinal cord segmentation -sct_deepseg_sc -i t2s.nii.gz -c t2s -qc ~/qc_singleSubj +sct_deepseg -task seg_sc_contrast_agnostic -i t2s.nii.gz -qc ~/qc_singleSubj # Subtract GM segmentation from cord segmentation to obtain WM segmentation sct_maths -i t2s_seg.nii.gz -sub t2s_gmseg.nii.gz -o t2s_wmseg.nii.gz @@ -353,7 +353,7 @@ cd ../dmri sct_dmri_separate_b0_and_dwi -i dmri.nii.gz -bvec bvecs.txt # Segment SC on mean dMRI data # Note: This segmentation does not need to be accurate-- it is only used to create a mask around the cord -sct_deepseg_sc -i dmri_dwi_mean.nii.gz -c dwi -qc ~/qc_singleSubj +sct_deepseg -task seg_sc_contrast_agnostic -i dmri_dwi_mean.nii.gz -qc ~/qc_singleSubj # Create mask (for subsequent cropping) sct_create_mask -i dmri_dwi_mean.nii.gz -p centerline,dmri_dwi_mean_seg.nii.gz -f cylinder -size 35mm @@ -362,7 +362,7 @@ sct_dmri_moco -i dmri.nii.gz -m mask_dmri_dwi_mean.nii.gz -bvec bvecs.txt -qc ~/ # Check results in the QC report # Segment SC on motion-corrected mean dwi data (check results in the QC report) -sct_deepseg_sc -i dmri_moco_dwi_mean.nii.gz -c dwi -qc ~/qc_singleSubj +sct_deepseg -task seg_sc_contrast_agnostic -i dmri_moco_dwi_mean.nii.gz -qc ~/qc_singleSubj # Register template->dwi via t2s to account for GM segmentation # Tips: Here we use the PAM50 contrast t1, which is closer to the dwi contrast (although we are not using type=im in @@ -415,7 +415,7 @@ sct_warp_template -d fmri_moco_mean.nii.gz -w warp_template2fmri.nii.gz -a 0 -qc cd ../t1 # Segment T1-weighted image (to be used in later steps) -sct_deepseg_sc -i t1.nii.gz -c t1 +sct_deepseg -task seg_sc_contrast_agnostic -i t1.nii.gz # Smooth spinal cord along centerline (extracted from the segmentation) sct_smooth_spinalcord -i t1.nii.gz -s t1_seg.nii.gz From d9bab73c5f78b8028a55c521f36ed389462c437e Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Tue, 26 Nov 2024 12:47:29 -0500 Subject: [PATCH 08/41] `batch_single_subject.sh`: Remove algo=dl section (no longer in course) --- single_subject/batch_single_subject.sh | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index 48dc6af..13566ec 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -231,27 +231,6 @@ sct_compute_mtr -mt0 mt0_reg.nii.gz -mt1 mt1.nii.gz -# Contrast-agnostic registration -# ====================================================================================================================== - -# 1. T2w preprocessing (cropping around spinal cord) -cd ../t2 -sct_deepseg -task seg_sc_contrast_agnostic -i t2.nii.gz -qc ~/qc_singleSubj -sct_create_mask -i t2.nii.gz -p centerline,t2_seg.nii.gz -size 35mm -f cylinder -o mask_t2.nii.gz -sct_crop_image -i t2.nii.gz -m mask_t2.nii.gz - -# 2. T1w preprocessing (cropping around spinal cord) -cd ../t1 -sct_deepseg -task seg_sc_contrast_agnostic -i t1.nii.gz -qc ~/qc_singleSubj -sct_create_mask -i t1.nii.gz -p centerline,t1_seg.nii.gz -size 35mm -f cylinder -o mask_t1.nii.gz -sct_crop_image -i t1.nii.gz -m mask_t1.nii.gz - -# 3. Perform registration -# NB: `-dseg` is not necessary for registration, but is provided for the `-qc` reporting to help with spinal cord visualization -sct_register_multimodal -i t1_crop.nii.gz -d ../t2/t2_crop.nii.gz -param step=1,type=im,algo=dl -qc ~/qc_singleSubj -dseg ../t2/t2_seg.nii.gz - - - # Registering lumbar data to the PAM50 template # ====================================================================================================================== cd ../t2_lumbar From 70e1482782aa706364af3ca1c00f0e8a517af33f Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Tue, 26 Nov 2024 12:55:33 -0500 Subject: [PATCH 09/41] `batch_single_subject.sh`: Fix GM-informed MT1 reg comments --- single_subject/batch_single_subject.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index 13566ec..900497f 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -298,8 +298,9 @@ sct_register_multimodal -i "${SCT_DIR}"/data/PAM50/template/PAM50_t2s.nii.gz -is # Warp template sct_warp_template -d t2s.nii.gz -w warp_template2t2s.nii.gz -qc ~/qc_singleSubj +# Register another metric while reusing newly-created GM-informed warping fields cd ../mt -# Register template->mt via t2s to account for GM segmentation +# Register template->mt using `-initwarp` with t2s to account for GM segmentation sct_register_multimodal -i "${SCT_DIR}"/data/PAM50/template/PAM50_t2.nii.gz -iseg "${SCT_DIR}"/data/PAM50/template/PAM50_cord.nii.gz -d mt1.nii.gz -dseg mt1_seg.nii.gz -param step=1,type=seg,algo=centermass:step=2,type=seg,algo=bsplinesyn,slicewise=1,iter=3 -m mask_mt1.nii.gz -initwarp ../t2s/warp_template2t2s.nii.gz -owarp warp_template2mt.nii.gz -qc ~/qc_singleSubj # Warp template sct_warp_template -d mt1.nii.gz -w warp_template2mt.nii.gz -qc ~/qc_singleSubj From 3c7323d777a98a2ac40714ae2c9b81cd0e2a66c3 Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Tue, 26 Nov 2024 12:59:39 -0500 Subject: [PATCH 10/41] `batch_single_subject.sh`: Add missing `sct_analyze_lesion -f` command --- single_subject/batch_single_subject.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index 900497f..a31f0ca 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -422,6 +422,8 @@ sct_deepseg -i t2.nii.gz -task seg_sc_lesion_t2w_sci -qc ~/qc_singleSubj fsleyes t2.nii.gz -cm greyscale t2_sc_seg.nii.gz -cm red -a 70.0 t2_lesion_seg.nii.gz -cm blue-lightblue -a 70.0 & # Compute various morphometric measures, such as number of lesions, lesion length, lesion volume, etc. sct_analyze_lesion -m t2_lesion_seg.nii.gz -s t2_sc_seg.nii.gz -qc ~/qc_singleSubj +# Lesion analysis using PAM50 (the -f flag is used to specify the folder containing the atlas/template) +sct_analyze_lesion -m t2_lesion_seg.nii.gz -s t2_sc_seg.nii.gz -f label_T2w -qc ~/qc_singleSubj # Rootlets segmentation cd ../t2 From 04234a86e6dc7e12dc1dad82a0cdbfa2050ecf19 Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Tue, 26 Nov 2024 13:17:08 -0500 Subject: [PATCH 11/41] `batch_single_subject.sh`: Add missing totalspineseg command --- single_subject/batch_single_subject.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index a31f0ca..30e4785 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -432,5 +432,10 @@ sct_deepseg -i t2.nii.gz -task seg_spinal_rootlets_t2w -qc ~/qc_singleSubj # Check results using FSLeyes fsleyes t2.nii.gz -cm greyscale t2_seg.nii.gz -cm subcortical -a 70.0 & +# Full spinal segmentation (Vertebrae, Intervertebral discs, Spinal cord and Spinal canal) +# Segment using totalspineseg +sct_deepseg -i t2.nii.gz -task totalspineseg -qc ~/qc_singleSubj +# Check results using FSLeyes +fsleyes t2.nii.gz -cm greyscale t2_step1_canal.nii.gz -cm YlOrRd -a 70.0 t2_step1_cord.nii.gz -cm YlOrRd -a 70.0 t2_step1_levels.nii.gz -cm subcortical -a 70.0 t2_step1_output.nii.gz -cm subcortical -a 70.0 t2_step2_output.nii.gz -cm subcortical -a 70.0 & # Return to parent directory cd .. From 4e9553ad429785b46520672b649543e39738248c Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Tue, 26 Nov 2024 13:19:53 -0500 Subject: [PATCH 12/41] `batch_single_subject.sh`: Add missing MS lesion commands --- single_subject/batch_single_subject.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index 30e4785..5d9182b 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -410,7 +410,7 @@ sct_flatten_sagittal -i t1.nii.gz -s t1_seg.nii.gz # New features (SCT v6.5, December 2024) # ====================================================================================================================== -# Lesion analysis +# Lesion analysis for SCI and MS lesions cd ../t2_lesion # Segment the spinal cord and intramedullary lesion using the SCIsegV2 model # Note: t2.nii.gz contains a fake lesion for the purpose of this tutorial @@ -425,6 +425,11 @@ sct_analyze_lesion -m t2_lesion_seg.nii.gz -s t2_sc_seg.nii.gz -qc ~/qc_singleSu # Lesion analysis using PAM50 (the -f flag is used to specify the folder containing the atlas/template) sct_analyze_lesion -m t2_lesion_seg.nii.gz -s t2_sc_seg.nii.gz -f label_T2w -qc ~/qc_singleSubj +# Note: We also have a contrast-agnostic segmentation command for MS lesions, too: +sct_deepseg -i t2.nii.gz -task seg_ms_lesion -qc ~/qc_singleSubj +# As well as a segmentation command tailored to MP2RAGE MS lesions +sct_deepseg -i t2.nii.gz -task seg_ms_lesion_mp2rage -qc ~/qc_singleSubj + # Rootlets segmentation cd ../t2 # Segment the spinal nerve rootlets From 576828a751ab3e14af1ee66e3069044e6a0584af Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Tue, 26 Nov 2024 13:28:43 -0500 Subject: [PATCH 13/41] `batch_single_subject.sh`: Add missing canal seg command --- single_subject/batch_single_subject.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index 5d9182b..7311b2c 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -437,6 +437,11 @@ sct_deepseg -i t2.nii.gz -task seg_spinal_rootlets_t2w -qc ~/qc_singleSubj # Check results using FSLeyes fsleyes t2.nii.gz -cm greyscale t2_seg.nii.gz -cm subcortical -a 70.0 & +# Canal segmentation +sct_deepseg -i t2.nii.gz -task canal_t2w -qc ~/qc_singleSubj +# Check results using FSLeyes +fsleyes t2.nii.gz -cm greyscale t2_canal_seg_seg.nii.gz -cm red -a 70.0 & + # Full spinal segmentation (Vertebrae, Intervertebral discs, Spinal cord and Spinal canal) # Segment using totalspineseg sct_deepseg -i t2.nii.gz -task totalspineseg -qc ~/qc_singleSubj From dea569bd4680cca66cf0e91fa5083c11ef39c52a Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Tue, 26 Nov 2024 14:46:05 -0500 Subject: [PATCH 14/41] `batch_single_subject.sh`: Comment out -f command (needs reg) --- single_subject/batch_single_subject.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index 7311b2c..e93f55f 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -422,8 +422,10 @@ sct_deepseg -i t2.nii.gz -task seg_sc_lesion_t2w_sci -qc ~/qc_singleSubj fsleyes t2.nii.gz -cm greyscale t2_sc_seg.nii.gz -cm red -a 70.0 t2_lesion_seg.nii.gz -cm blue-lightblue -a 70.0 & # Compute various morphometric measures, such as number of lesions, lesion length, lesion volume, etc. sct_analyze_lesion -m t2_lesion_seg.nii.gz -s t2_sc_seg.nii.gz -qc ~/qc_singleSubj + # Lesion analysis using PAM50 (the -f flag is used to specify the folder containing the atlas/template) -sct_analyze_lesion -m t2_lesion_seg.nii.gz -s t2_sc_seg.nii.gz -f label_T2w -qc ~/qc_singleSubj +# Note: You must go through the "Register to Template" steps (labeling, registration) first +# sct_analyze_lesion -m t2_lesion_seg.nii.gz -s t2_sc_seg.nii.gz -f label -qc ~/qc_singleSubj # Note: We also have a contrast-agnostic segmentation command for MS lesions, too: sct_deepseg -i t2.nii.gz -task seg_ms_lesion -qc ~/qc_singleSubj From bb812ed1c5c3f095a70dd8b8427bf9ea09ae5b3e Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Wed, 27 Nov 2024 13:50:53 -0500 Subject: [PATCH 15/41] `process_data.sh`: Replace `sct_deepseg_sc` with `sct_deepseg` --- multi_subject/process_data.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/multi_subject/process_data.sh b/multi_subject/process_data.sh index d10fcb4..457e6bf 100755 --- a/multi_subject/process_data.sh +++ b/multi_subject/process_data.sh @@ -80,11 +80,11 @@ segment_if_does_not_exist() { if [[ -e "${FILESEGMANUAL}" ]]; then echo "Found! Using manual segmentation." rsync -avzh "${FILESEGMANUAL}" "${FILESEG}".nii.gz - sct_qc -i "${file}".nii.gz -s "${FILESEG}".nii.gz -p sct_deepseg_sc -qc "${PATH_QC}" -qc-subject "${SUBJECT}" + sct_qc -i "${file}".nii.gz -s "${FILESEG}".nii.gz -p sct_deepseg -qc "${PATH_QC}" -qc-subject "${SUBJECT}" else echo "Not found. Proceeding with automatic segmentation." # Segment spinal cord - sct_deepseg_sc -i "${file}".nii.gz -c "${contrast}" -qc "${PATH_QC}" -qc-subject "${SUBJECT}" + sct_deepseg -task seg_sc_contrast_agnostic -i "${file}".nii.gz -qc "${PATH_QC}" -qc-subject "${SUBJECT}" fi } From abbc08dbeb5257a9c77593079cbfa5aaf5f670cd Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Thu, 28 Nov 2024 13:08:32 -0500 Subject: [PATCH 16/41] `batch_single_subject.sh`: Apply rewording suggestions for comments Co-authored-by: Jan Valosek <39456460+valosekj@users.noreply.github.com> --- single_subject/batch_single_subject.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index e93f55f..ff5314a 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -36,10 +36,11 @@ fi # Spinal cord segmentation # ====================================================================================================================== -# Go to T2 contrast +# Go to T2 folder cd data/t2 -# Spinal cord segmentation (using new 2024 method) +# Spinal cord segmentation (using the new 2024 contrast-agnostic method) sct_deepseg -task seg_sc_contrast_agnostic -i t2.nii.gz -qc ~/qc_singleSubj +# The default output is t2_seg.nii.gz # You can also choose your own output filename using the “-o” argument # sct_deepseg -task seg_sc_contrast_agnostic -i t2.nii.gz -o t2_seg_test.nii.gz @@ -92,7 +93,7 @@ sct_process_segmentation -i t2_seg.nii.gz -vertfile t2_seg_labeled.nii.gz -persl -# Quantifying spinal cord compression (MSCC) and normalize against database of healthy controls +# Quantifying spinal cord compression using maximum spinal cord compression (MSCC) and normalizing with database of healthy controls # ====================================================================================================================== cd ../t2_compression # Segment the spinal cord of the compressed spine From 9ade09ff2e690646a01ab29d2a28007b4ef44bf5 Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Thu, 28 Nov 2024 13:09:05 -0500 Subject: [PATCH 17/41] `batch_single_subject.sh`: `t2_seg.nii.gz` -> `t2_rootlets.nii.gz` Co-authored-by: Jan Valosek <39456460+valosekj@users.noreply.github.com> --- single_subject/batch_single_subject.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index ff5314a..370caad 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -438,7 +438,7 @@ cd ../t2 # Segment the spinal nerve rootlets sct_deepseg -i t2.nii.gz -task seg_spinal_rootlets_t2w -qc ~/qc_singleSubj # Check results using FSLeyes -fsleyes t2.nii.gz -cm greyscale t2_seg.nii.gz -cm subcortical -a 70.0 & +fsleyes t2.nii.gz -cm greyscale t2_rootlets.nii.gz -cm subcortical -a 70.0 & # Canal segmentation sct_deepseg -i t2.nii.gz -task canal_t2w -qc ~/qc_singleSubj From 7708ee252ec2c491f23fe01fda126152bf8087e6 Mon Sep 17 00:00:00 2001 From: Kalum Ost <43527660+SomeoneInParticular@users.noreply.github.com> Date: Thu, 28 Nov 2024 17:07:17 -0500 Subject: [PATCH 18/41] Added missing `-vertfile` flag --- single_subject/batch_single_subject.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index 370caad..b7c7bee 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -77,7 +77,7 @@ sct_process_segmentation -i t2_seg.nii.gz -vert 3:4 -vertfile t2_seg_labeled.nii # Aggregate CSA value per level sct_process_segmentation -i t2_seg.nii.gz -vert 3:4 -vertfile t2_seg_labeled.nii.gz -perlevel 1 -o csa_perlevel.csv # Aggregate CSA value per slices -sct_process_segmentation -i t2_seg.nii.gz -z 30:35 -perslice 1 -o csa_perslice.csv +sct_process_segmentation -i t2_seg.nii.gz -z 30:35 -vertfile t2_seg_labeled.nii.gz -perslice 1 -o csa_perslice.csv # A drawback of vertebral level-based CSA is that it doesn’t consider neck flexion and extension. # To overcome this limitation, the CSA can instead be computed using the distance to a reference point. From 3ecf3147cc7521389cb9b536ac79899470811c73 Mon Sep 17 00:00:00 2001 From: Kalum Ost <43527660+SomeoneInParticular@users.noreply.github.com> Date: Thu, 28 Nov 2024 17:55:51 -0500 Subject: [PATCH 19/41] batch_single_subject.sh; updated lumbar-specific label_utils target points No clue why they were changed, but better to match them than have a hair--pulling bug later --- single_subject/batch_single_subject.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index b7c7bee..10bdf34 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -246,7 +246,7 @@ sct_deepseg -i t2_lumbar.nii.gz -task seg_lumbar_sc_t2w # # However, since this is an automated script with example data, we will place the labels at known locations for the # sake of reproducing the results in the tutorial. -sct_label_utils -i t2_lumbar.nii.gz -create 22,77,187,17:27,79,80,60 -o t2_lumbar_labels.nii.gz +sct_label_utils -i t2_lumbar.nii.gz -create 27,76,187,17:27,79,80,60 -o t2_lumbar_labels.nii.gz # Register the image to the template using segmentation and labels sct_register_to_template -i t2_lumbar.nii.gz \ From 73e874cd9d3319f63e26bea8c902e82ae89e7899 Mon Sep 17 00:00:00 2001 From: Kalum Ost <43527660+SomeoneInParticular@users.noreply.github.com> Date: Thu, 28 Nov 2024 18:34:01 -0500 Subject: [PATCH 20/41] batch_single_subject.sh: Removed '-f cylinder' which is no longer used in the slides --- single_subject/batch_single_subject.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index 10bdf34..525af85 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -336,7 +336,7 @@ sct_dmri_separate_b0_and_dwi -i dmri.nii.gz -bvec bvecs.txt # Note: This segmentation does not need to be accurate-- it is only used to create a mask around the cord sct_deepseg -task seg_sc_contrast_agnostic -i dmri_dwi_mean.nii.gz -qc ~/qc_singleSubj # Create mask (for subsequent cropping) -sct_create_mask -i dmri_dwi_mean.nii.gz -p centerline,dmri_dwi_mean_seg.nii.gz -f cylinder -size 35mm +sct_create_mask -i dmri_dwi_mean.nii.gz -p centerline,dmri_dwi_mean_seg.nii.gz -size 35mm # Motion correction (moco) sct_dmri_moco -i dmri.nii.gz -m mask_dmri_dwi_mean.nii.gz -bvec bvecs.txt -qc ~/qc_singleSubj -qc-seg dmri_dwi_mean_seg.nii.gz From a6d684c8365ebf79908d37586ca45c20c60f89f2 Mon Sep 17 00:00:00 2001 From: Kalum Ost <43527660+SomeoneInParticular@users.noreply.github.com> Date: Thu, 28 Nov 2024 18:48:01 -0500 Subject: [PATCH 21/41] batch_single_subject.sh: Added missing second-pass segmentation using smoothed SC --- single_subject/batch_single_subject.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index 525af85..40e2890 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -402,6 +402,9 @@ sct_deepseg -task seg_sc_contrast_agnostic -i t1.nii.gz sct_smooth_spinalcord -i t1.nii.gz -s t1_seg.nii.gz # Tips: use flag "-sigma" to specify smoothing kernel size (in mm) +# Second-pass segmentation using the smoothed anatomical image +sct_deepseg_sc -i t1_smooth.nii.gz -c t1 -qc ~/qc_singleSubj + # Align the spinal cord in the right-left direction using slice-wise translations. sct_flatten_sagittal -i t1.nii.gz -s t1_seg.nii.gz # Note: Use for visualization purposes only From ce7466d035e9773ce02f3348114bca6ec5d518f1 Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Fri, 29 Nov 2024 13:47:44 -0500 Subject: [PATCH 22/41] `process_data.sh`: Preserve `-p sct_deepseg_sc` `sct_deepseg` QC is not yet available in `sct_qc` script --- multi_subject/process_data.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/multi_subject/process_data.sh b/multi_subject/process_data.sh index 457e6bf..0d5b645 100755 --- a/multi_subject/process_data.sh +++ b/multi_subject/process_data.sh @@ -80,7 +80,7 @@ segment_if_does_not_exist() { if [[ -e "${FILESEGMANUAL}" ]]; then echo "Found! Using manual segmentation." rsync -avzh "${FILESEGMANUAL}" "${FILESEG}".nii.gz - sct_qc -i "${file}".nii.gz -s "${FILESEG}".nii.gz -p sct_deepseg -qc "${PATH_QC}" -qc-subject "${SUBJECT}" + sct_qc -i "${file}".nii.gz -s "${FILESEG}".nii.gz -p sct_deepseg_sc -qc "${PATH_QC}" -qc-subject "${SUBJECT}" else echo "Not found. Proceeding with automatic segmentation." # Segment spinal cord From 1a104c43ce86297d1e1c519fb3cda1fefb03b737 Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Fri, 29 Nov 2024 13:48:53 -0500 Subject: [PATCH 23/41] `process_data.sh`: Remove now-unneeded `contrast` argument --- multi_subject/process_data.sh | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/multi_subject/process_data.sh b/multi_subject/process_data.sh index 0d5b645..9fd2155 100755 --- a/multi_subject/process_data.sh +++ b/multi_subject/process_data.sh @@ -71,7 +71,6 @@ segment_if_does_not_exist() { # This allows you to add manual segmentations on a subject-by-subject basis without disrupting the pipeline. ### local file="${1}" - local contrast="${2}" # Update global variable with segmentation file name FILESEG="${file}"_seg FILESEGMANUAL="${PATH_DATA}"/derivatives/labels/"${SUBJECT}"/anat/"${FILESEG}".nii.gz @@ -111,8 +110,8 @@ rsync -avzh "${PATH_DATA}"/"${SUBJECT}" . # ====================================================================================================================== cd "${SUBJECT}"/anat/ file_t2="${SUBJECT}"_T2w -# Segment spinal cord (only if it does not exist) -segment_if_does_not_exist "${file_t2}" "t2" +# Segment spinal cord (only if it does not exist) using contrast-agnostic model +segment_if_does_not_exist "${file_t2}" file_t2_seg="${FILESEG}" # Create labels in the cord at C2 and C5 mid-vertebral levels (only if it does not exist) label_if_does_not_exist "${file_t2}" "${file_t2_seg}" @@ -132,8 +131,8 @@ sct_process_segmentation -i "${file_t2_seg}".nii.gz -vert 2:3 -vertfile label_T2 # ====================================================================================================================== file_mt1="${SUBJECT}"_acq-MTon_MTS file_mt0="${SUBJECT}"_acq-MToff_MTS -# Segment spinal cord -segment_if_does_not_exist "${file_mt1}" "t2s" +# Segment spinal cord using contrast-agnostic model +segment_if_does_not_exist "${file_mt1}" file_mt1_seg="${FILESEG}" # Create mask sct_create_mask -i "${file_mt1}".nii.gz -p centerline,"${file_mt1_seg}".nii.gz -size 45mm From d54a612d5b0627a4d2a807e9d974b9a1fb108cf7 Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Fri, 29 Nov 2024 13:50:22 -0500 Subject: [PATCH 24/41] `batch_single_subject.sh`: Remove rootlets/lesion sections Since the sections are moved to the end of the course, these are now redundant. --- single_subject/batch_single_subject.sh | 29 -------------------------- 1 file changed, 29 deletions(-) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index 40e2890..336a6d3 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -115,35 +115,6 @@ sct_compute_compression -i t2_compressed_seg.nii.gz -vertfile t2_compressed_seg_ -# Lesion analysis -# ====================================================================================================================== -cd ../t2_lesion -# Segment the spinal cord and intramedullary lesion using the SCIsegV2 model -# Note: t2.nii.gz contains a fake lesion for the purpose of this tutorial -sct_deepseg -i t2.nii.gz -task seg_sc_lesion_t2w_sci -qc ~/qc_singleSubj -# Note: Two files are output: -# - t2_sc_seg.nii.gz: the spinal cord segmentation -# - t2_lesion_seg.nii.gz: the lesion segmentation - -# Check results using FSLeyes -fsleyes t2.nii.gz -cm greyscale t2_sc_seg.nii.gz -cm red -a 70.0 t2_lesion_seg.nii.gz -cm blue-lightblue -a 70.0 & - -# Compute various morphometric measures, such as number of lesions, lesion length, lesion volume, etc. -sct_analyze_lesion -m t2_lesion_seg.nii.gz -s t2_sc_seg.nii.gz -qc ~/qc_singleSubj - - - -# Rootlets segmentation -# ====================================================================================================================== -cd ../t2 -# Segment the spinal nerve rootlets -sct_deepseg -i t2.nii.gz -task seg_spinal_rootlets_t2w -qc ~/qc_singleSubj - -# Check results using FSLeyes -fsleyes t2.nii.gz -cm greyscale t2_seg.nii.gz -cm subcortical -a 70.0 & - - - # Registering T2 data to the PAM50 template # ====================================================================================================================== cd ../t2 From ee5d8ddc4ce572e20d523c5c303efe0f02c6f9c9 Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Fri, 29 Nov 2024 13:51:27 -0500 Subject: [PATCH 25/41] `batch_single_subject.sh`: Fix `-qc qc` -> `-qc ~/qc_singleSubj` --- single_subject/batch_single_subject.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index 336a6d3..7b167b2 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -223,7 +223,7 @@ sct_label_utils -i t2_lumbar.nii.gz -create 27,76,187,17:27,79,80,60 -o t2_lumba sct_register_to_template -i t2_lumbar.nii.gz \ -s t2_lumbar_seg.nii.gz \ -ldisc t2_lumbar_labels.nii.gz \ - -c t2 -qc qc \ + -c t2 -qc ~/qc_singleSubj/ \ -param step=1,type=seg,algo=centermassrot:step=2,type=seg,algo=bsplinesyn,metric=MeanSquares,iter=3,slicewise=0:step=3,type=im,algo=syn,metric=CC,iter=3,slicewise=0 From 4034ad14637290c915497d8f4ff3bf96a15841a6 Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Fri, 29 Nov 2024 14:26:01 -0500 Subject: [PATCH 26/41] `batch_single_subject.sh`: Add missing `-qc ~/qc_singleSubj` --- single_subject/batch_single_subject.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index 7b167b2..e933d9a 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -367,7 +367,7 @@ sct_warp_template -d fmri_moco_mean.nii.gz -w warp_template2fmri.nii.gz -a 0 -qc cd ../t1 # Segment T1-weighted image (to be used in later steps) -sct_deepseg -task seg_sc_contrast_agnostic -i t1.nii.gz +sct_deepseg -task seg_sc_contrast_agnostic -i t1.nii.gz -qc ~/qc_singleSubj/ # Smooth spinal cord along centerline (extracted from the segmentation) sct_smooth_spinalcord -i t1.nii.gz -s t1_seg.nii.gz From 255ecf49eb9db14093421a827fd54496c0e3221e Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Fri, 6 Dec 2024 14:06:15 -0500 Subject: [PATCH 27/41] `batch_single_subject.sh`: Update "test" command to match slides Showing users that they can specify an output folder is important! --- single_subject/batch_single_subject.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index e933d9a..a6c480b 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -42,7 +42,7 @@ cd data/t2 sct_deepseg -task seg_sc_contrast_agnostic -i t2.nii.gz -qc ~/qc_singleSubj # The default output is t2_seg.nii.gz # You can also choose your own output filename using the “-o” argument -# sct_deepseg -task seg_sc_contrast_agnostic -i t2.nii.gz -o t2_seg_test.nii.gz +sct_deepseg -task seg_sc_contrast_agnostic -i t2.nii.gz -o test/t2_seg_2.nii.gz # To check the QC report, use your web browser to open the file qc_singleSubj/qc/index.html, which has been created in # your home directory From 35acbd637419c3f848eed9d3abd191555959c7ab Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Fri, 6 Dec 2024 14:07:56 -0500 Subject: [PATCH 28/41] `batch_single_subject.sh`: Update section titles Now they are more in line with the sections in the slides --- single_subject/batch_single_subject.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index a6c480b..14f3660 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -69,7 +69,7 @@ sct_label_vertebrae -i t2.nii.gz -s t2_seg.nii.gz -c t2 -qc ~/qc_singleSubj -# Computing shape metrics +# Shape-based analysis # ====================================================================================================================== # Compute cross-sectional area (CSA) of spinal cord and average it across levels C3 and C4 @@ -115,7 +115,7 @@ sct_compute_compression -i t2_compressed_seg.nii.gz -vertfile t2_compressed_seg_ -# Registering T2 data to the PAM50 template +# Registration to template # ====================================================================================================================== cd ../t2 @@ -156,7 +156,7 @@ fsleyes t2.nii.gz -cm greyscale -a 100.0 label/template/PAM50_t2.nii.gz -cm grey -# Registering additional MT data to the PAM50 template +# Registering additional contrasts (MT registration to T2 template) # ====================================================================================================================== # Go to mt folder @@ -189,7 +189,7 @@ fsleyes mt1.nii.gz -cm greyscale -a 100.0 label/template/PAM50_t2.nii.gz -cm gre -# Computing MTR using MT0/MT1 coregistration +# Registering additional contrasts (MT0/MT1 coregistration to compute MTR) # ====================================================================================================================== # Register mt0->mt1 using z-regularized slicewise translations (algo=slicereg) @@ -203,7 +203,7 @@ sct_compute_mtr -mt0 mt0_reg.nii.gz -mt1 mt1.nii.gz -# Registering lumbar data to the PAM50 template +# Registering additional contrasts (T2 lumbar data) # ====================================================================================================================== cd ../t2_lumbar @@ -228,7 +228,7 @@ sct_register_to_template -i t2_lumbar.nii.gz \ -# Gray/white matter: Segmentation +# Gray matter segmentation (GM/WM seg) # ====================================================================================================================== # Go to T2*-weighted data, which has good GM/WM contrast and high in-plane resolution @@ -242,7 +242,7 @@ sct_maths -i t2s_seg.nii.gz -sub t2s_gmseg.nii.gz -o t2s_wmseg.nii.gz -# Gray/white matter: Computing metrics using binary segmentation masks +# Gray matter segmentation (Shape-based analysis and metric extraction) # ====================================================================================================================== # Compute cross-sectional area (CSA) of the gray and white matter for all slices in the volume. @@ -261,7 +261,7 @@ sct_extract_metric -i t2s.nii.gz -f t2s_gmseg.nii.gz -method bin -z 2:12 -o t2s_ -# Gray/white matter: Improving registration results using binary segmentation masks +# Gray matter segmentation (Improving registration results using binary segmentation masks) # ====================================================================================================================== # Register template->t2s (using warping field generated from template<->t2 registration) From 0ade35a67bc26a403fd32bb8bcb4538137b86586 Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Fri, 6 Dec 2024 14:29:40 -0500 Subject: [PATCH 29/41] `batch_single_subject.sh`: Compress lumbar reg command to 1 line This is the preferred syntax for the script, rather than using `\` to split the command over multiple lines. --- single_subject/batch_single_subject.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index 14f3660..9efb4b0 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -220,11 +220,7 @@ sct_deepseg -i t2_lumbar.nii.gz -task seg_lumbar_sc_t2w sct_label_utils -i t2_lumbar.nii.gz -create 27,76,187,17:27,79,80,60 -o t2_lumbar_labels.nii.gz # Register the image to the template using segmentation and labels -sct_register_to_template -i t2_lumbar.nii.gz \ - -s t2_lumbar_seg.nii.gz \ - -ldisc t2_lumbar_labels.nii.gz \ - -c t2 -qc ~/qc_singleSubj/ \ - -param step=1,type=seg,algo=centermassrot:step=2,type=seg,algo=bsplinesyn,metric=MeanSquares,iter=3,slicewise=0:step=3,type=im,algo=syn,metric=CC,iter=3,slicewise=0 +sct_register_to_template -i t2_lumbar.nii.gz -s t2_lumbar_seg.nii.gz -ldisc t2_lumbar_labels.nii.gz -c t2 -qc ~/qc_singleSubj -param step=1,type=seg,algo=centermassrot:step=2,type=seg,algo=bsplinesyn,metric=MeanSquares,iter=3,slicewise=0:step=3,type=im,algo=syn,metric=CC,iter=3,slicewise=0 From fba69f57b74e6972186a708b379f65a7eb030a18 Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Fri, 6 Dec 2024 14:32:32 -0500 Subject: [PATCH 30/41] `batch_single_subject.sh`: Update `-sub` command to use `-thr 0` --- single_subject/batch_single_subject.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index 9efb4b0..ced7b6e 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -234,7 +234,10 @@ sct_deepseg_gm -i t2s.nii.gz -qc ~/qc_singleSubj # Spinal cord segmentation sct_deepseg -task seg_sc_contrast_agnostic -i t2s.nii.gz -qc ~/qc_singleSubj # Subtract GM segmentation from cord segmentation to obtain WM segmentation -sct_maths -i t2s_seg.nii.gz -sub t2s_gmseg.nii.gz -o t2s_wmseg.nii.gz +# Note that we use the flag -thr 0 in case some voxels in the GM segmentation are *not* included in the cord +# segmentation. That would results in voxels in the WM segmentation having the value “-1”, which would cause issues +# with the registration. +sct_maths -i t2s_seg.nii.gz -sub t2s_gmseg.nii.gz -thr 0 -o t2s_wmseg.nii.gz From 4893e6f3f1fcd7b3c7bca36168c5110467d84584 Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Fri, 6 Dec 2024 14:43:28 -0500 Subject: [PATCH 31/41] `batch_single_subject.sh`: Update dmri/fmri reg to use T2 warps See: https://docs.google.com/presentation/d/1uUOpgshwnyC2p8r2GalXlUczQLpX6PfJbtzNELxbqdI/edit?disco=AAABZfV8T8A --- single_subject/batch_single_subject.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index ced7b6e..a7c15c8 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -315,12 +315,12 @@ sct_dmri_moco -i dmri.nii.gz -m mask_dmri_dwi_mean.nii.gz -bvec bvecs.txt -qc ~/ # Segment SC on motion-corrected mean dwi data (check results in the QC report) sct_deepseg -task seg_sc_contrast_agnostic -i dmri_moco_dwi_mean.nii.gz -qc ~/qc_singleSubj -# Register template->dwi via t2s to account for GM segmentation +# Register template->dwi via t2 to account for cord shape (which is better defined in T2 contrast) # Tips: Here we use the PAM50 contrast t1, which is closer to the dwi contrast (although we are not using type=im in # -param, so it will not make a difference here) # Note: the flag “-initwarpinv" provides a transformation dmri->template, in case you would like to bring all your DTI # metrics in the PAM50 space (e.g. group averaging of FA maps) -sct_register_multimodal -i "${SCT_DIR}"/data/PAM50/template/PAM50_t1.nii.gz -iseg "${SCT_DIR}"/data/PAM50/template/PAM50_cord.nii.gz -d dmri_moco_dwi_mean.nii.gz -dseg dmri_moco_dwi_mean_seg.nii.gz -initwarp ../t2s/warp_template2t2s.nii.gz -initwarpinv ../t2s/warp_t2s2template.nii.gz -owarp warp_template2dmri.nii.gz -owarpinv warp_dmri2template.nii.gz -param step=1,type=seg,algo=centermass:step=2,type=seg,algo=bsplinesyn,slicewise=1,iter=3 -qc ~/qc_singleSubj +sct_register_multimodal -i "${SCT_DIR}"/data/PAM50/template/PAM50_t1.nii.gz -iseg "${SCT_DIR}"/data/PAM50/template/PAM50_cord.nii.gz -d dmri_moco_dwi_mean.nii.gz -dseg dmri_moco_dwi_mean_seg.nii.gz -initwarp ../t2/warp_template2anat.nii.gz -initwarpinv ../t2/warp_anat2template.nii.gz -owarp warp_template2dmri.nii.gz -owarpinv warp_dmri2template.nii.gz -param step=1,type=seg,algo=centermass:step=2,type=seg,algo=bsplinesyn,slicewise=1,iter=3 -qc ~/qc_singleSubj # Warp template (so 'label/atlas' can be used to extract metrics) sct_warp_template -d dmri_moco_dwi_mean.nii.gz -w warp_template2dmri.nii.gz -qc ~/qc_singleSubj # Check results in the QC report @@ -351,10 +351,10 @@ sct_fmri_moco -i fmri.nii.gz -m mask_fmri.nii.gz -qc ~/qc_singleSubj -qc-seg t2_ # Register the template to the fMRI scan. # Note: here we don't rely on the segmentation because it is difficult to obtain one automatically. Instead, we rely on -# ANTs_SyN superpower to find a suitable transformation between the PAM50_t2s and the fMRI scan. We don't want to +# ANTs_SyN superpower to find a suitable transformation between the PAM50_t2 and the fMRI scan. We don't want to # put too many iterations because this registration is very sensitive to the artifacts (drop out) in the image. # Also, we want a 3D transformation (not 2D) because we need the through-z regularization. -sct_register_multimodal -i "${SCT_DIR}/data/PAM50/template/PAM50_t2s.nii.gz" -d fmri_moco_mean.nii.gz -dseg t2_seg_reg.nii.gz -param step=1,type=im,algo=syn,metric=CC,iter=5,slicewise=0 -initwarp ../t2s/warp_template2t2s.nii.gz -initwarpinv ../t2s/warp_t2s2template.nii.gz -owarp warp_template2fmri.nii.gz -owarpinv warp_fmri2template.nii.gz -qc ~/qc_singleSubj +sct_register_multimodal -i "${SCT_DIR}"/data/PAM50/template/PAM50_t2.nii.gz -iseg "${SCT_DIR}"/data/PAM50/template/PAM50_cord.nii.gz -d fmri_moco_mean.nii.gz -dseg fmri_moco_mean_seg.nii.gz -param step=1,type=seg,algo=centermass:step=2,type=seg,algo=bsplinesyn,slicewise=1,iter=3:step=3,type=im,algo=syn,metric=CC,iter=3,slicewise=1 -initwarp ../t2/warp_template2anat.nii.gz -initwarpinv ../t2/warp_anat2template.nii.gz -owarp warp_template2fmri.nii.gz -owarpinv warp_fmri2template.nii.gz -qc ~/qc_singleSubj # Check results in the QC report # Warp template with the spinal levels (can be found at $SCT_DIR/data/PAM50/template/) From 07bd03d9234ba406f31666ba7817456728d12127 Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Fri, 6 Dec 2024 14:44:11 -0500 Subject: [PATCH 32/41] `batch_single_subject.sh`: Add TSNR QC commands --- single_subject/batch_single_subject.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index a7c15c8..e678866 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -349,6 +349,13 @@ sct_create_mask -i fmri.nii.gz -p centerline,t2_seg_reg.nii.gz -size 35mm -f cyl # Motion correction (using mask) sct_fmri_moco -i fmri.nii.gz -m mask_fmri.nii.gz -qc ~/qc_singleSubj -qc-seg t2_seg_reg.nii.gz +# Cord segmentation on motion-corrected averaged time series +sct_deepseg -i fmri_moco_mean.nii.gz -task seg_sc_contrast_agnostic -qc ~/qc_singleSubj/ +# TSNR before/after motion correction with QC report +sct_fmri_compute_tsnr -i fmri.nii.gz +sct_fmri_compute_tsnr -i fmri_moco.nii.gz +sct_qc -i fmri_tsnr.nii.gz -d fmri_moco_tsnr.nii.gz -s fmri_moco_mean_seg.nii.gz -p sct_fmri_compute_tsnr -qc ~/qc_singleSubj/ + # Register the template to the fMRI scan. # Note: here we don't rely on the segmentation because it is difficult to obtain one automatically. Instead, we rely on # ANTs_SyN superpower to find a suitable transformation between the PAM50_t2 and the fMRI scan. We don't want to From 953db59d4068b38123910029e95020cc84e282aa Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Fri, 6 Dec 2024 14:48:16 -0500 Subject: [PATCH 33/41] `batch_single_subject.sh`: Move lesion analysis after MS seg To match the slides. --- single_subject/batch_single_subject.sh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index e678866..209c0a8 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -401,18 +401,19 @@ sct_deepseg -i t2.nii.gz -task seg_sc_lesion_t2w_sci -qc ~/qc_singleSubj # - t2_lesion_seg.nii.gz: the lesion segmentation # Check results using FSLeyes fsleyes t2.nii.gz -cm greyscale t2_sc_seg.nii.gz -cm red -a 70.0 t2_lesion_seg.nii.gz -cm blue-lightblue -a 70.0 & + +# Note: We also have a contrast-agnostic segmentation command for MS lesions, too: +sct_deepseg -i t2.nii.gz -task seg_ms_lesion -qc ~/qc_singleSubj +# As well as a segmentation command tailored to MP2RAGE MS lesions +# sct_deepseg -i t2.nii.gz -task seg_ms_lesion_mp2rage -qc ~/qc_singleSubj + # Compute various morphometric measures, such as number of lesions, lesion length, lesion volume, etc. sct_analyze_lesion -m t2_lesion_seg.nii.gz -s t2_sc_seg.nii.gz -qc ~/qc_singleSubj - # Lesion analysis using PAM50 (the -f flag is used to specify the folder containing the atlas/template) # Note: You must go through the "Register to Template" steps (labeling, registration) first +# This is because `sct_warp_template` is required to generate the `label` folder used for `-f` # sct_analyze_lesion -m t2_lesion_seg.nii.gz -s t2_sc_seg.nii.gz -f label -qc ~/qc_singleSubj -# Note: We also have a contrast-agnostic segmentation command for MS lesions, too: -sct_deepseg -i t2.nii.gz -task seg_ms_lesion -qc ~/qc_singleSubj -# As well as a segmentation command tailored to MP2RAGE MS lesions -sct_deepseg -i t2.nii.gz -task seg_ms_lesion_mp2rage -qc ~/qc_singleSubj - # Rootlets segmentation cd ../t2 # Segment the spinal nerve rootlets From c286c24aa99710956a714661405d927507e333c9 Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Fri, 6 Dec 2024 14:49:55 -0500 Subject: [PATCH 34/41] `batch_single_subject.sh`: Reorder the "new features" section Now matches the slides --- single_subject/batch_single_subject.sh | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index 209c0a8..53958cc 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -414,14 +414,12 @@ sct_analyze_lesion -m t2_lesion_seg.nii.gz -s t2_sc_seg.nii.gz -qc ~/qc_singleSu # This is because `sct_warp_template` is required to generate the `label` folder used for `-f` # sct_analyze_lesion -m t2_lesion_seg.nii.gz -s t2_sc_seg.nii.gz -f label -qc ~/qc_singleSubj -# Rootlets segmentation -cd ../t2 -# Segment the spinal nerve rootlets -sct_deepseg -i t2.nii.gz -task seg_spinal_rootlets_t2w -qc ~/qc_singleSubj -# Check results using FSLeyes -fsleyes t2.nii.gz -cm greyscale t2_rootlets.nii.gz -cm subcortical -a 70.0 & +# Segment the spinal cord on gradient echo EPI data +cd ../fmri/ +sct_deepseg -i fmri_moco_mean.nii.gz -task seg_sc_epi -qc ~/qc_singleSubj # Canal segmentation +cd ../t2 sct_deepseg -i t2.nii.gz -task canal_t2w -qc ~/qc_singleSubj # Check results using FSLeyes fsleyes t2.nii.gz -cm greyscale t2_canal_seg_seg.nii.gz -cm red -a 70.0 & @@ -431,5 +429,11 @@ fsleyes t2.nii.gz -cm greyscale t2_canal_seg_seg.nii.gz -cm red -a 70.0 & sct_deepseg -i t2.nii.gz -task totalspineseg -qc ~/qc_singleSubj # Check results using FSLeyes fsleyes t2.nii.gz -cm greyscale t2_step1_canal.nii.gz -cm YlOrRd -a 70.0 t2_step1_cord.nii.gz -cm YlOrRd -a 70.0 t2_step1_levels.nii.gz -cm subcortical -a 70.0 t2_step1_output.nii.gz -cm subcortical -a 70.0 t2_step2_output.nii.gz -cm subcortical -a 70.0 & + +# Segment the spinal nerve rootlets +sct_deepseg -i t2.nii.gz -task seg_spinal_rootlets_t2w -qc ~/qc_singleSubj +# Check results using FSLeyes +fsleyes t2.nii.gz -cm greyscale t2_rootlets.nii.gz -cm subcortical -a 70.0 & + # Return to parent directory cd .. From 23da235e1f78eb4924ff02a071822eaa63fc5f91 Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Fri, 6 Dec 2024 14:51:30 -0500 Subject: [PATCH 35/41] `run_batch_script.yml`: Temporarily allow warnings We don't have time to debug "RuntimeWarning: invalid value encountered in scalar divide" before SCT course. --- .github/workflows/run_batch_script.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run_batch_script.yml b/.github/workflows/run_batch_script.yml index 2794316..b7e8e3b 100644 --- a/.github/workflows/run_batch_script.yml +++ b/.github/workflows/run_batch_script.yml @@ -67,5 +67,5 @@ jobs: cd "${{ github.event.repository.name }}/multi_subject/output/log" [ "$(compgen -G "process_data_sub-0*.log")" ] # Log files should exist [ ! "$(compgen -G "err.process_data_sub-0*.log")" ] # Error files should NOT exist - grep -iF "warning" process_data_sub-01.log + # grep -iF "warning" process_data_sub-01.log grep -iF "error" process_data_sub-01.log From f0370b91a57190c94bb8a7039e76306cd20a8de8 Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Fri, 6 Dec 2024 19:45:21 -0500 Subject: [PATCH 36/41] `batch_single_subject.sh`: Revert fMRI back to PAM50_t2.nii.gz Feedback from @jcohenadad, see: https://docs.google.com/presentation/d/1uUOpgshwnyC2p8r2GalXlUczQLpX6PfJbtzNELxbqdI/edit?disco=AAABZfV8T8A --- single_subject/batch_single_subject.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index 53958cc..0919cd7 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -358,10 +358,10 @@ sct_qc -i fmri_tsnr.nii.gz -d fmri_moco_tsnr.nii.gz -s fmri_moco_mean_seg.nii.gz # Register the template to the fMRI scan. # Note: here we don't rely on the segmentation because it is difficult to obtain one automatically. Instead, we rely on -# ANTs_SyN superpower to find a suitable transformation between the PAM50_t2 and the fMRI scan. We don't want to +# ANTs_SyN superpower to find a suitable transformation between the PAM50_t2s and the fMRI scan. We don't want to # put too many iterations because this registration is very sensitive to the artifacts (drop out) in the image. # Also, we want a 3D transformation (not 2D) because we need the through-z regularization. -sct_register_multimodal -i "${SCT_DIR}"/data/PAM50/template/PAM50_t2.nii.gz -iseg "${SCT_DIR}"/data/PAM50/template/PAM50_cord.nii.gz -d fmri_moco_mean.nii.gz -dseg fmri_moco_mean_seg.nii.gz -param step=1,type=seg,algo=centermass:step=2,type=seg,algo=bsplinesyn,slicewise=1,iter=3:step=3,type=im,algo=syn,metric=CC,iter=3,slicewise=1 -initwarp ../t2/warp_template2anat.nii.gz -initwarpinv ../t2/warp_anat2template.nii.gz -owarp warp_template2fmri.nii.gz -owarpinv warp_fmri2template.nii.gz -qc ~/qc_singleSubj +sct_register_multimodal -i "${SCT_DIR}"/data/PAM50/template/PAM50_t2s.nii.gz -iseg "${SCT_DIR}"/data/PAM50/template/PAM50_cord.nii.gz -d fmri_moco_mean.nii.gz -dseg fmri_moco_mean_seg.nii.gz -param step=1,type=seg,algo=centermass:step=2,type=seg,algo=bsplinesyn,slicewise=1,iter=3:step=3,type=im,algo=syn,metric=CC,iter=3,slicewise=1 -initwarp ../t2/warp_template2anat.nii.gz -initwarpinv ../t2/warp_anat2template.nii.gz -owarp warp_template2fmri.nii.gz -owarpinv warp_fmri2template.nii.gz -qc ~/qc_singleSubj # Check results in the QC report # Warp template with the spinal levels (can be found at $SCT_DIR/data/PAM50/template/) From 0897e684300db5bf96b4e8c02a6a48bd40871caf Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Fri, 6 Dec 2024 19:45:43 -0500 Subject: [PATCH 37/41] `batch_single_subject.sh`: Change script version to v6.5 --- single_subject/batch_single_subject.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index 0919cd7..1c34053 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -5,7 +5,7 @@ # N.B. The parameters were chosen to suit SCT's sample tutorial data. With your data, # it is worthwhile to explore the various parameters and tweak them to your situation. # -# tested with Spinal Cord Toolbox (v6.1.0) +# tested with Spinal Cord Toolbox (v6.5) # Script utilities # ====================================================================================================================== From feff83336ad3b97da7405735e2dfcffac24d1412 Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Fri, 6 Dec 2024 19:51:13 -0500 Subject: [PATCH 38/41] `data_multi_subject.sh`: Add note about commented-out commands --- single_subject/batch_single_subject.sh | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index 1c34053..8f22942 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -2,8 +2,15 @@ # # Example of commands to process multi-parametric data of the spinal cord # For information about acquisition parameters, see: www.spinalcordmri.org/protocols -# N.B. The parameters were chosen to suit SCT's sample tutorial data. With your data, -# it is worthwhile to explore the various parameters and tweak them to your situation. +# +# Notes: +# - Many of the commands in this script are commented out (start with "# "). These commands won't be run by default, +# as many of them involve manual steps (e.g. via an interactive pop-up interface), or may involve data-specific +# configuration. Often these commands correspond to the "try at home" slides in the SCT Course slide deck, +# (denoted by a "red circle" in the top-right corner of the corresponding slide). Feel free to "uncomment" the +# commands by removing the "# " symbol at the start of the line, and experiment with them on your own data. +# - The parameters were chosen to suit SCT's sample tutorial data. With your data, +# it is worthwhile to explore the various parameters and tweak them to your situation. # # tested with Spinal Cord Toolbox (v6.5) From 263189bab4f9b2b047b5c7c496ba7674f55d5870 Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Fri, 6 Dec 2024 20:04:15 -0500 Subject: [PATCH 39/41] `run_batch_script.yml`: Split error checking into multiple steps This will improve debugging, so that we can see what step actually fails. Also, by splitting up the steps, we can continue to the next step on failure of an earlier step thanks to "if: always()". --- .github/workflows/run_batch_script.yml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/run_batch_script.yml b/.github/workflows/run_batch_script.yml index b7e8e3b..a53c613 100644 --- a/.github/workflows/run_batch_script.yml +++ b/.github/workflows/run_batch_script.yml @@ -62,10 +62,26 @@ jobs: fi done - - name: Check that script executed without error + - name: Check results (no error logs) + if: always() run: | cd "${{ github.event.repository.name }}/multi_subject/output/log" [ "$(compgen -G "process_data_sub-0*.log")" ] # Log files should exist + + - name: Check results (no error logs) + if: always() + run: | + cd "${{ github.event.repository.name }}/multi_subject/output/log" [ ! "$(compgen -G "err.process_data_sub-0*.log")" ] # Error files should NOT exist + + - name: Check results (warnings in log) + if: always() + run: | + cd "${{ github.event.repository.name }}/multi_subject/output/log" # grep -iF "warning" process_data_sub-01.log + + - name: Check results (errors in log) + if: always() + run: | + cd "${{ github.event.repository.name }}/multi_subject/output/log" grep -iF "error" process_data_sub-01.log From 81d0f6adf538c55a07e6879cbf5794323ce3595f Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Fri, 6 Dec 2024 20:09:40 -0500 Subject: [PATCH 40/41] `run_batch_script.yml`: Fix `grep` checks by adding `!` `grep` returns 0 if found, and 1 if not found. But we want the opposite: 1 if warning/error is present, and 0 if there are no warnings/errors. So, we need to invert the output code. I have no idea why these checks lasted as long as they did without this `!` inversion. The `grep` commands only used options `-iF`, meaning (case-insensitive) and (non-regex strings), so the options don't have anything to do with it. Hopefully this will fix the erroneous failures? --- .github/workflows/run_batch_script.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run_batch_script.yml b/.github/workflows/run_batch_script.yml index a53c613..4553393 100644 --- a/.github/workflows/run_batch_script.yml +++ b/.github/workflows/run_batch_script.yml @@ -78,10 +78,10 @@ jobs: if: always() run: | cd "${{ github.event.repository.name }}/multi_subject/output/log" - # grep -iF "warning" process_data_sub-01.log + # ! grep -iF "warning" process_data_sub-01.log - name: Check results (errors in log) if: always() run: | cd "${{ github.event.repository.name }}/multi_subject/output/log" - grep -iF "error" process_data_sub-01.log + ! grep -iF "error" process_data_sub-01.log From 0338ba697a3f790dd97ea97072335e13775a75dc Mon Sep 17 00:00:00 2001 From: Joshua Newton Date: Sun, 8 Dec 2024 19:36:28 -0500 Subject: [PATCH 41/41] `batch_single_subject.sh`: Add missing qc commands to lumbar sec. --- single_subject/batch_single_subject.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/single_subject/batch_single_subject.sh b/single_subject/batch_single_subject.sh index 8f22942..6f0a268 100755 --- a/single_subject/batch_single_subject.sh +++ b/single_subject/batch_single_subject.sh @@ -215,7 +215,7 @@ sct_compute_mtr -mt0 mt0_reg.nii.gz -mt1 mt1.nii.gz cd ../t2_lumbar # Use lumbar-specific `sct_deepseg` model to segment the spinal cord -sct_deepseg -i t2_lumbar.nii.gz -task seg_lumbar_sc_t2w +sct_deepseg -i t2_lumbar.nii.gz -task seg_lumbar_sc_t2w -qc ~/qc_singleSubj # Generate labels for the 2 spinal cord landmarks: cauda equinea ('99') and T9-T10 disc ('17') # Note: Normally this would be done manually using fsleyes' "Edit mode -> Create mask" functionality. (Uncomment below) @@ -224,7 +224,7 @@ sct_deepseg -i t2_lumbar.nii.gz -task seg_lumbar_sc_t2w # # However, since this is an automated script with example data, we will place the labels at known locations for the # sake of reproducing the results in the tutorial. -sct_label_utils -i t2_lumbar.nii.gz -create 27,76,187,17:27,79,80,60 -o t2_lumbar_labels.nii.gz +sct_label_utils -i t2_lumbar.nii.gz -create 27,76,187,17:27,79,80,60 -o t2_lumbar_labels.nii.gz -qc ~/qc_singleSubj # Register the image to the template using segmentation and labels sct_register_to_template -i t2_lumbar.nii.gz -s t2_lumbar_seg.nii.gz -ldisc t2_lumbar_labels.nii.gz -c t2 -qc ~/qc_singleSubj -param step=1,type=seg,algo=centermassrot:step=2,type=seg,algo=bsplinesyn,metric=MeanSquares,iter=3,slicewise=0:step=3,type=im,algo=syn,metric=CC,iter=3,slicewise=0