Skip to content

Commit fcafd8b

Browse files
authored
Merge pull request #4 from spinalcordtoolbox/jn/add-review-comments-from-nov-5-meeting
Modify `batch_single_subject.sh` to include feedback from Nov 4 meeting
2 parents 0b3c453 + 13f180f commit fcafd8b

1 file changed

Lines changed: 34 additions & 91 deletions

File tree

single_subject/batch_single_subject.sh

Lines changed: 34 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,18 @@ sct_label_vertebrae -i t2.nii.gz -s t2_seg.nii.gz -c t2 -qc ~/qc_singleSubj
6969
# inter-vertebral disc level. The convention is: Value 3 —> C2-C3 disc, Value 4 —> C3-C4 disc, etc.
7070

7171
# OPTIONAL: If automatic labeling did not work, you can initialize with manual identification of C2-C3 disc:
72-
#sct_label_utils -i t2.nii.gz -create-viewer 3 -o label_c2c3.nii.gz \
73-
# -msg "Click at the posterior tip of C2/C3 inter-vertebral disc"
72+
#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"
7473
#sct_label_vertebrae -i t2.nii.gz -s t2_seg.nii.gz -c t2 -initlabel label_c2c3.nii.gz -qc ~/qc_singleSubj
7574

7675
# Create labels at C3 and T2 mid-vertebral levels. These labels are needed for template registration.
7776
sct_label_utils -i t2_seg_labeled.nii.gz -vert-body 3,9 -o t2_labels_vert.nii.gz
77+
# Generate a QC report to visualize the two selected labels on the anatomical image
78+
sct_qc -i t2.nii.gz -s t2_labels_vert.nii.gz -p sct_label_utils -qc ~/qc_singleSubj
7879

7980
# OPTIONAL: You might want to completely bypass sct_label_vertebrae and do the labeling manually. In that case, we
8081
# provide a viewer to do so conveniently. In the example command below, we will create labels at the inter-vertebral
8182
# discs C2-C3 (value=3), C3-C4 (value=4) and C4-C5 (value=5).
82-
#sct_label_utils -i t2.nii.gz -create-viewer 3,4,5 -o labels_disc.nii.gz \
83-
# -msg "Place labels at the posterior tip of each inter-vertebral disc. E.g. Label 3: C2/C3, Label 4: C3/C4, etc."
83+
#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."
8484

8585

8686

@@ -98,11 +98,8 @@ sct_warp_template -d t2.nii.gz -w warp_template2anat.nii.gz -a 0 -qc ~/qc_single
9898
# Note: A folder label/template/ is created, which contains template objects in the space of the subject. The file
9999
# info_label.txt lists all template files.
100100

101-
# Check results using Fsleyes. Tips: use the right arrow key to switch overlay on/off.
102-
fsleyes t2.nii.gz -cm greyscale -a 100.0 \
103-
label/template/PAM50_t2.nii.gz -cm greyscale -dr 0 4000 -a 100.0 \
104-
label/template/PAM50_gm.nii.gz -cm red-yellow -dr 0.4 1 -a 50.0 \
105-
label/template/PAM50_wm.nii.gz -cm blue-lightblue -dr 0.4 1 -a 50.0 &
101+
# Check results using Fsleyes.
102+
fsleyes t2.nii.gz -cm greyscale -a 100.0 label/template/PAM50_t2.nii.gz -cm greyscale -dr 0 4000 -a 100.0 label/template/PAM50_gm.nii.gz -cm red-yellow -dr 0.4 1 -a 50.0 label/template/PAM50_wm.nii.gz -cm blue-lightblue -dr 0.4 1 -a 50.0 &
106103

107104

108105

@@ -116,6 +113,13 @@ sct_process_segmentation -i t2_seg.nii.gz -vert 3:4 -vertfile ./label/template/P
116113
# Aggregate CSA value per slices
117114
sct_process_segmentation -i t2_seg.nii.gz -z 30:35 -perslice 1 -o csa_perslice.csv
118115

116+
# A drawback of vertebral level-based CSA is that it doesn’t consider neck flexion and extension.
117+
# To overcome this limitation, the CSA can instead be computed using the distance to a reference point.
118+
# Here, we use the Pontomedullary Junction (PMJ), since the distance from the PMJ along the centerline
119+
# of the spinal cord will vary depending on the position of the neck.
120+
sct_detect_pmj -i t2.nii.gz -c t2 -qc ~/qc_singleSubj
121+
# Check the QC to make sure PMJ was properly detected, then compute CSA using the distance from the PMJ:
122+
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
119123

120124

121125
# Registering additional MT data to the PAM50 template
@@ -132,33 +136,22 @@ sct_create_mask -i mt1.nii.gz -p centerline,mt1_seg.nii.gz -size 35mm -f cylinde
132136

133137
# Register template->mt1. The flag -initwarp ../t2/warp_template2anat.nii.gz initializes the registration using the
134138
# template->t2 transformation which was previously estimated
135-
sct_register_multimodal -i $SCT_DIR/data/PAM50/template/PAM50_t2.nii.gz \
136-
-iseg $SCT_DIR/data/PAM50/template/PAM50_cord.nii.gz \
137-
-d mt1.nii.gz \
138-
-dseg mt1_seg.nii.gz \
139-
-m mask_mt1.nii.gz \
140-
-initwarp ../t2/warp_template2anat.nii.gz \
141-
-param step=1,type=seg,algo=centermass:step=2,type=seg,algo=bsplinesyn,slicewise=1,iter=3 \
142-
-owarp warp_template2mt.nii.gz \
143-
-qc ~/qc_singleSubj
139+
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 -m mask_mt1.nii.gz -initwarp ../t2/warp_template2anat.nii.gz -param step=1,type=seg,algo=centermass:step=2,type=seg,algo=bsplinesyn,slicewise=1,iter=3 -owarp warp_template2mt.nii.gz -qc ~/qc_singleSubj
144140
# Tips: Here we only use the segmentations (type=seg) to minimize the sensitivity of the registration procedure to
145141
# image artifacts.
146142
# Tips: Step 1: algo=centermass to align source and destination segmentations, then Step 2: algo=bpslinesyn to adapt the
147143
# shape of the cord to the mt modality (in case there are distortions between the t2 and the mt scan).
148144

149-
# OPTIONAL: If you don't have a corresponding anatomical image to register first (in this case, the T2 warping field we're using for `-initwarp`), you can register the template directly to a metric image, without going via an anatomical image. For that, you just need to create one or two labels in the metric space. For example, if you know that your FOV is centered at C3/C4 disc, then you can create a label automatically with:
145+
# OPTIONAL: Registration with -initwarp requires pre-registration, but in some cases you won't have an anatomical image to do a pre-registration. So, as an alternative, you can register the template directly to a metric image. For that, you just need to create one or two labels in the metric space. For example, if you know that your FOV is centered at C3/C4 disc, then you can create a label automatically with:
150146
# sct_label_utils -i mt1_seg.nii.gz -create-seg -1,4 -o label_c3c4.nii.gz
151147
# Then, you can register to the template.
152148
# Note: In case the metric image has axial resolution with thick slices, we recommend to do the registration in the subject space (instead of the template space), without cord straightening.
153149
# sct_register_to_template -i mt1.nii.gz -s mt1_seg.nii.gz -ldisc label_c3c4.nii.gz -ref subject -param step=1,type=seg,algo=centermassrot:step=2,type=seg,algo=bsplinesyn,slicewise=1
154150

155151
# Warp template
156152
sct_warp_template -d mt1.nii.gz -w warp_template2mt.nii.gz -a 1 -qc ~/qc_singleSubj
157-
# Check results using Fsleyes. Tips: use the right arrow key to switch overlay on/off.
158-
fsleyes mt1.nii.gz -cm greyscale -a 100.0 \
159-
label/template/PAM50_t2.nii.gz -cm greyscale -dr 0 4000 -a 100.0 \
160-
label/template/PAM50_gm.nii.gz -cm red-yellow -dr 0.4 1 -a 50.0 \
161-
label/template/PAM50_wm.nii.gz -cm blue-lightblue -dr 0.4 1 -a 50.0 &
153+
# Check results using Fsleyes.
154+
fsleyes mt1.nii.gz -cm greyscale -a 100.0 label/template/PAM50_t2.nii.gz -cm greyscale -dr 0 4000 -a 100.0 label/template/PAM50_gm.nii.gz -cm red-yellow -dr 0.4 1 -a 50.0 label/template/PAM50_wm.nii.gz -cm blue-lightblue -dr 0.4 1 -a 50.0 &
162155

163156

164157

@@ -167,9 +160,8 @@ fsleyes mt1.nii.gz -cm greyscale -a 100.0 \
167160

168161
# Register mt0->mt1 using z-regularized slicewise translations (algo=slicereg)
169162
# Note: Segmentation and mask can be re-used from "MT registration" section
170-
sct_register_multimodal -i mt0.nii.gz -d mt1.nii.gz -dseg mt1_seg.nii.gz -m mask_mt1.nii.gz \
171-
-param step=1,type=im,algo=slicereg,metric=CC -x spline -qc ~/qc_singleSubj
172-
# Check results using Fsleyes. Tips: use the right arrow key to switch overlay on/off.
163+
sct_register_multimodal -i mt0.nii.gz -d mt1.nii.gz -dseg mt1_seg.nii.gz -m mask_mt1.nii.gz -param step=1,type=im,algo=slicereg,metric=CC -x spline -qc ~/qc_singleSubj
164+
# Check results using Fsleyes.
173165
fsleyes mt1.nii.gz mt0_reg.nii.gz &
174166
# Compute MTR
175167
sct_compute_mtr -mt0 mt0_reg.nii.gz -mt1 mt1.nii.gz
@@ -215,42 +207,21 @@ sct_extract_metric -i t2s.nii.gz -f t2s_gmseg.nii.gz -method bin -z 2:12 -o t2s_
215207

216208
# Register template->t2s (using warping field generated from template<->t2 registration)
217209
# Tips: Here we use the WM seg for the iseg/dseg fields in order to account for both the cord and the GM shape.
218-
sct_register_multimodal -i "${SCT_DIR}/data/PAM50/template/PAM50_t2s.nii.gz" \
219-
-iseg "${SCT_DIR}/data/PAM50/template/PAM50_wm.nii.gz" \
220-
-d t2s.nii.gz \
221-
-dseg t2s_wmseg.nii.gz \
222-
-initwarp ../t2/warp_template2anat.nii.gz \
223-
-initwarpinv ../t2/warp_anat2template.nii.gz \
224-
-owarp warp_template2t2s.nii.gz \
225-
-owarpinv warp_t2s2template.nii.gz \
226-
-param step=1,type=seg,algo=rigid:step=2,type=seg,algo=bsplinesyn,slicewise=1,iter=3 \
227-
-qc ~/qc_singleSubj
210+
sct_register_multimodal -i "${SCT_DIR}/data/PAM50/template/PAM50_t2s.nii.gz" -iseg "${SCT_DIR}/data/PAM50/template/PAM50_wm.nii.gz" -d t2s.nii.gz -dseg t2s_wmseg.nii.gz -initwarp ../t2/warp_template2anat.nii.gz -initwarpinv ../t2/warp_anat2template.nii.gz -owarp warp_template2t2s.nii.gz -owarpinv warp_t2s2template.nii.gz -param step=1,type=seg,algo=rigid:step=2,type=seg,algo=bsplinesyn,slicewise=1,iter=3 -qc ~/qc_singleSubj
211+
# Warp template
212+
sct_warp_template -d t2s.nii.gz -w warp_template2t2s.nii.gz -qc ~/qc_singleSubj
228213

229214
cd ../mt
230215
# Register template->mt via t2s to account for GM segmentation
231-
sct_register_multimodal -i "${SCT_DIR}/data/PAM50/template/PAM50_t2.nii.gz" \
232-
-iseg "${SCT_DIR}/data/PAM50/template/PAM50_cord.nii.gz" \
233-
-d mt1.nii.gz \
234-
-dseg mt1_seg.nii.gz \
235-
-param step=1,type=seg,algo=centermass:step=2,type=seg,algo=bsplinesyn,slicewise=1,iter=3 \
236-
-m mask_mt1.nii.gz \
237-
-initwarp ../t2s/warp_template2t2s.nii.gz \
238-
-owarp warp_template2mt.nii.gz \
239-
-qc ~/qc_singleSubj
240-
241-
216+
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
217+
# Warp template
218+
sct_warp_template -d mt1.nii.gz -w warp_template2mt.nii.gz -qc ~/qc_singleSubj
219+
# Check results
220+
fsleyes mt1.nii.gz -cm greyscale -a 100.0 label/template/PAM50_t2.nii.gz -cm greyscale -dr 0 4000 -a 100.0 label/template/PAM50_gm.nii.gz -cm red-yellow -dr 0.4 1 -a 100.0 label/template/PAM50_wm.nii.gz -cm blue-lightblue -dr 0.4 1 -a 100.0 &
242221

243222
# Atlas-based analysis (Extracting metrics (MTR) in gray/white matter tracts)
244223
# ======================================================================================================================
245224

246-
# In order to use the PAM50 atlas to extract/aggregate image data, the atlas must first be transformed to the MT space
247-
sct_warp_template -d mt1.nii.gz -w warp_template2mt.nii.gz -a 1 -qc ~/qc_singleSubj
248-
# Check results
249-
fsleyes mt1.nii.gz -cm greyscale -a 100.0 \
250-
label/template/PAM50_t2.nii.gz -cm greyscale -dr 0 4000 -a 100.0 \
251-
label/template/PAM50_gm.nii.gz -cm red-yellow -dr 0.4 1 -a 100.0 \
252-
label/template/PAM50_wm.nii.gz -cm blue-lightblue -dr 0.4 1 -a 100.0 &
253-
254225
# Extract MTR for each slice within the white matter (combined label: #51)
255226
# Tips: To list all available labels, type: "sct_extract_metric"
256227
sct_extract_metric -i mtr.nii.gz -f label/atlas -method map -l 51 -o mtr_in_wm.csv
@@ -259,9 +230,7 @@ sct_extract_metric -i mtr.nii.gz -f label/atlas -method map -l 51 -o mtr_in_wm.c
259230
sct_extract_metric -i mtr.nii.gz -f label/atlas -method map -l 4,5 -z 5:15 -o mtr_in_cst.csv
260231
# You can specify the vertebral levels to extract MTR from. For example, to quantify MTR between C2 and C4 levels in the
261232
# dorsal column (combined label: #53) using weighted average:
262-
sct_extract_metric -i mtr.nii.gz -f label/atlas -method map -l 53 \
263-
-vert 2:4 -vertfile label/template/PAM50_levels.nii.gz \
264-
-o mtr_in_dc.csv
233+
sct_extract_metric -i mtr.nii.gz -f label/atlas -method map -l 53 -vert 2:4 -vertfile label/template/PAM50_levels.nii.gz -o mtr_in_dc.csv
265234

266235

267236
# Diffusion-weighted MRI
@@ -278,8 +247,7 @@ sct_deepseg_sc -i dmri_mean.nii.gz -c dwi -qc ~/qc_singleSubj
278247
sct_create_mask -i dmri_mean.nii.gz -p centerline,dmri_mean_seg.nii.gz -f cylinder -size 35mm
279248

280249
# Motion correction (moco)
281-
sct_dmri_moco -i dmri.nii.gz -m mask_dmri_mean.nii.gz -bvec bvecs.txt \
282-
-qc ~/qc_singleSubj -qc-seg dmri_mean_seg.nii.gz
250+
sct_dmri_moco -i dmri.nii.gz -m mask_dmri_mean.nii.gz -bvec bvecs.txt -qc ~/qc_singleSubj -qc-seg dmri_mean_seg.nii.gz
283251

284252
# Segment SC on motion-corrected mean dwi data (check results in the QC report)
285253
sct_deepseg_sc -i dmri_moco_dwi_mean.nii.gz -c dwi -qc ~/qc_singleSubj
@@ -289,16 +257,7 @@ sct_deepseg_sc -i dmri_moco_dwi_mean.nii.gz -c dwi -qc ~/qc_singleSubj
289257
# -param, so it will not make a difference here)
290258
# Note: the flag “-initwarpinv" provides a transformation dmri->template, in case you would like to bring all your DTI
291259
# metrics in the PAM50 space (e.g. group averaging of FA maps)
292-
sct_register_multimodal -i "${SCT_DIR}/data/PAM50/template/PAM50_t1.nii.gz" \
293-
-iseg "${SCT_DIR}/data/PAM50/template/PAM50_cord.nii.gz" \
294-
-d dmri_moco_dwi_mean.nii.gz \
295-
-dseg dmri_moco_dwi_mean_seg.nii.gz \
296-
-initwarp ../t2s/warp_template2t2s.nii.gz \
297-
-initwarpinv ../t2s/warp_t2s2template.nii.gz \
298-
-owarp warp_template2dmri.nii.gz \
299-
-owarpinv warp_dmri2template.nii.gz \
300-
-param step=1,type=seg,algo=centermass:step=2,type=seg,algo=bsplinesyn,slicewise=1,iter=3 \
301-
-qc ~/qc_singleSubj
260+
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
302261
# Warp template (so 'label/atlas' can be used to extract metrics)
303262
sct_warp_template -d dmri_moco_dwi_mean.nii.gz -w warp_template2dmri.nii.gz -qc ~/qc_singleSubj
304263
# Check results in the QC report
@@ -308,10 +267,7 @@ sct_dmri_compute_dti -i dmri_moco.nii.gz -bval bvals.txt -bvec bvecs.txt
308267
# Tips: the flag "-method restore" estimates the tensor with robust fit (RESTORE method [2])
309268

310269
# Compute FA within the white matter from individual level 2 to 5
311-
sct_extract_metric -i dti_FA.nii.gz -f label/atlas \
312-
-l 51 -method map \
313-
-vert 2:5 -vertfile label/template/PAM50_levels.nii.gz -perlevel 1 \
314-
-o fa_in_wm.csv
270+
sct_extract_metric -i dti_FA.nii.gz -f label/atlas -l 51 -method map -vert 2:5 -vertfile label/template/PAM50_levels.nii.gz -perlevel 1 -o fa_in_wm.csv
315271

316272

317273

@@ -328,33 +284,20 @@ sct_register_multimodal -i ../t2/t2_seg.nii.gz -d fmri_mean.nii.gz -identity 1
328284
sct_create_mask -i fmri.nii.gz -p centerline,t2_seg_reg.nii.gz -size 35mm -f cylinder
329285

330286
# Motion correction (using mask)
331-
sct_fmri_moco -i fmri.nii.gz -m mask_fmri.nii.gz \
332-
-qc ~/qc_singleSubj -qc-seg t2_seg_reg.nii.gz
287+
sct_fmri_moco -i fmri.nii.gz -m mask_fmri.nii.gz -qc ~/qc_singleSubj -qc-seg t2_seg_reg.nii.gz
333288

334289
# Register the template to the fMRI scan.
335290
# Note: here we don't rely on the segmentation because it is difficult to obtain one automatically. Instead, we rely on
336291
# ANTs_SyN superpower to find a suitable transformation between the PAM50_t2s and the fMRI scan. We don't want to
337292
# put too many iterations because this registration is very sensitive to the artifacts (drop out) in the image.
338293
# Also, we want a 3D transformation (not 2D) because we need the through-z regularization.
339-
sct_register_multimodal -i "${SCT_DIR}/data/PAM50/template/PAM50_t2s.nii.gz" \
340-
-d fmri_moco_mean.nii.gz \
341-
-dseg t2_seg_reg.nii.gz \
342-
-param step=1,type=im,algo=syn,metric=CC,iter=5,slicewise=0 \
343-
-initwarp ../t2s/warp_template2t2s.nii.gz \
344-
-initwarpinv ../t2s/warp_t2s2template.nii.gz \
345-
-owarp warp_template2fmri.nii.gz \
346-
-owarpinv warp_fmri2template.nii.gz \
347-
-qc ~/qc_singleSubj
294+
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
348295
# Check results in the QC report
349296

350297
# Warp template with the spinal levels (-s 1)
351298
sct_warp_template -d fmri_moco_mean.nii.gz -w warp_template2fmri.nii.gz -s 1 -a 0 -qc ~/qc_singleSubj
352299
# Check results
353-
fsleyes --scene lightbox --hideCursor fmri_moco_mean.nii.gz -cm greyscale -dr 0 1000 \
354-
label/spinal_levels/spinal_level_03 -cm red \
355-
label/spinal_levels/spinal_level_04 -cm blue \
356-
label/spinal_levels/spinal_level_05 -cm green \
357-
label/spinal_levels/spinal_level_06 -cm yellow
300+
fsleyes --scene lightbox --hideCursor fmri_moco_mean.nii.gz -cm greyscale -dr 0 1000 label/spinal_levels/spinal_level_03 -cm red label/spinal_levels/spinal_level_04 -cm blue label/spinal_levels/spinal_level_05 -cm green label/spinal_levels/spinal_level_06 -cm yellow &
358301

359302

360303

0 commit comments

Comments
 (0)