@@ -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.
7776sct_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
117114sct_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
156152sct_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.
173165fsleyes mt1.nii.gz mt0_reg.nii.gz &
174166# Compute MTR
175167sct_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
229214cd ../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"
256227sct_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
259230sct_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
278247sct_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)
285253sct_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)
303262sct_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
328284sct_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)
351298sct_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