-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprocess_data_dcm-zurich.sh
222 lines (199 loc) · 11 KB
/
process_data_dcm-zurich.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
#!/bin/bash
#
# Process dcm-zurich dataset and run `sct_compute_compression` on T2w axial images
#
# Usage:
# sct_run_batch -c <PATH_TO_REPO>/etc/config_process_data_<DATASET>.json
#
# The following global variables are retrieved from the caller sct_run_batch
# but could be overwritten by uncommenting the lines below:
# PATH_DATA_PROCESSED="~/data_processed"
# PATH_RESULTS="~/results"
# PATH_LOG="~/log"
# PATH_QC="~/qc"
#
# Authors: Jan Valosek, Sandrine Bedard, Julien Cohen-Adad
#
# Uncomment for full verbose
set -x
# Immediately exit if error
set -e -o pipefail
# Exit if user presses CTRL+C (Linux) or CMD+C (OSX)
trap "echo Caught Keyboard Interrupt within script. Exiting now.; exit" INT
# Print retrieved variables from the sct_run_batch script to the log (to allow easier debug)
echo "Retrieved variables from from the caller sct_run_batch:"
echo "PATH_DATA: ${PATH_DATA}"
echo "PATH_DATA_PROCESSED: ${PATH_DATA_PROCESSED}"
echo "PATH_RESULTS: ${PATH_RESULTS}"
echo "PATH_LOG: ${PATH_LOG}"
echo "PATH_QC: ${PATH_QC}"
# CONVENIENCE FUNCTIONS
# ======================================================================================================================
# Check if manual spinal cord segmentation file already exists. If it does, copy it locally.
# If it doesn't, perform automatic spinal cord segmentation
segment_if_does_not_exist() {
local file="$1"
local contrast="$2"
# Update global variable with segmentation file name
FILESEG="${file}_label-SC_mask"
# TODO - change to FILESEG="${file}_label-SC_seg", once https://github.com/neuropoly/data-management/issues/225 is done
FILESEGMANUAL="${PATH_DATA}/derivatives/labels/${SUBJECT}/anat/${FILESEG}-manual.nii.gz"
echo
echo "Looking for manual segmentation: $FILESEGMANUAL"
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}
else
echo "Not found. Proceeding with automatic segmentation."
# Segment spinal cord
sct_deepseg_sc -i ${file}.nii.gz -o ${FILESEG}.nii.gz -c ${contrast} -qc ${PATH_QC} -qc-subject ${SUBJECT}
fi
}
# Check if manual label already exists. If it does, generate labeled segmentation from manual disc labels.
# If it doesn't, perform automatic spinal cord labeling
label_if_does_not_exist(){
local file="$1"
local file_seg="$2"
local contrast="$3"
# Update global variable with segmentation file name
FILELABEL="${file}_labels"
# TODO - change to FILELABEL="${file}_label-disc", once https://github.com/neuropoly/data-management/issues/225 is done
FILELABELMANUAL="${PATH_DATA}/derivatives/labels/${SUBJECT}/anat/${FILELABEL}-manual.nii.gz"
echo "Looking for manual disc labels: $FILELABELMANUAL"
if [[ -e $FILELABELMANUAL ]]; then
echo "Found! Using manual disc labels."
rsync -avzh $FILELABELMANUAL ${FILELABEL}.nii.gz
# Generate labeled segmentation from manual disc labels
sct_label_vertebrae -i ${file}.nii.gz -s ${file_seg}.nii.gz -discfile ${FILELABEL}.nii.gz -c ${contrast} -qc ${PATH_QC} -qc-subject ${SUBJECT}
else
echo "Not found. Proceeding with automatic labeling."
# Generate labeled segmentation automatically (no manual disc labels provided)
sct_label_vertebrae -i ${file}.nii.gz -s ${file_seg}.nii.gz -c ${contrast} -qc ${PATH_QC} -qc-subject ${SUBJECT}
fi
# Generate QC to access disc labels created by sct_label_vertebrae
sct_qc -i ${file}.nii.gz -s ${file_seg}_labeled_discs.nii.gz -p sct_label_utils -qc ${PATH_QC} -qc-subject ${SUBJECT}
}
# Retrieve input params and other params
SUBJECT=$1
# get starting time:
start=`date +%s`
# ------------------------------------------------------------------------------
# SCRIPT STARTS HERE
# ------------------------------------------------------------------------------
# Display useful info for the log, such as SCT version, RAM and CPU cores available
sct_check_dependencies -short
# Go to folder where data will be copied and processed
cd $PATH_DATA_PROCESSED
# Copy participants.tsv file (will be used to fetch sex) to the root folder of the dataset
PARTICIPANTS_PATH=${PATH_DATA_PROCESSED}/../participants.tsv
if [[ ! -e ../participants.tsv ]]; then
rsync -avzh ${PATH_DATA}/participants.tsv ${PARTICIPANTS_PATH}
fi
# Copy source T2w images
# Note: we use '/./' in order to include the sub-folder 'ses-0X'
rsync -Ravzh ${PATH_DATA}/./${SUBJECT}/anat/${SUBJECT}_*T2w.* .
# Go to subject folder for source images
cd ${SUBJECT}/anat
# ------------------------------------------------------------------------------
# T2w Sagittal
# ------------------------------------------------------------------------------
# Define variables
# We do a substitution '/' --> '_' in case there is a subfolder 'ses-0X/'
file_t2_sag="${SUBJECT//[\/]/_}"_acq-sagittal_T2w
# Check if file_t2_sag exists
if [[ ! -e ${file_t2_sag}.nii.gz ]]; then
echo "File ${file_t2_sag}.nii.gz does not exist" >> ${PATH_LOG}/missing_files.log
echo "ERROR: File ${file_t2_sag}.nii.gz does not exist. Exiting."
exit 1
else
# Segment SC
segment_if_does_not_exist ${file_t2_sag} 't2'
file_t2_sag_seg=$FILESEG
label_if_does_not_exist ${file_t2_sag} ${file_t2_sag_seg} 't2'
fi
# ------------------------------------------------------------------------------
# T2w Axial
# ------------------------------------------------------------------------------
# Define variables
# We do a substitution '/' --> '_' in case there is a subfolder 'ses-0X/'
file_t2_ax="${SUBJECT//[\/]/_}"_acq-axial_T2w
# Check if file_t2_ax exists.
# Note: some subjects do not have T2w axial images. In this case, analysis will be stop after processing of
# T2w sagittal image.
if [[ ! -e ${file_t2_ax}.nii.gz ]]; then
echo "File ${file_t2_ax}.nii.gz does not exist" >> ${PATH_LOG}/missing_files.log
echo "ERROR: File ${file_t2_ax}.nii.gz does not exist. Exiting."
exit 1
else
# Segment SC (if SC segmentation file already exists under derivatives folder, it will be copied)
segment_if_does_not_exist ${file_t2_ax} 't2'
file_t2_ax_seg=$FILESEG
# Label SC
# Check if manual disc labels file already exists. If so, generate labeled segmentation from manual disc labels.
echo "Looking for manual disc labels: ${PATH_DATA}/derivatives/labels/${SUBJECT}/anat/${file_t2_ax}_labels-manual.nii.gz"
if [[ -e ${PATH_DATA}/derivatives/labels/${SUBJECT}/anat/${file_t2_ax}_labels-manual.nii.gz ]]; then
echo "Found! Using manual disc labels."
rsync -avzh ${PATH_DATA}/derivatives/labels/${SUBJECT}/anat/${file_t2_ax}_labels-manual.nii.gz ${file_t2_ax}_labels.nii.gz
file_t2_ax_labels=${file_t2_ax}_labels
# If manual disc labels file does not exist, use disc labels from sagittal image
else
# Bring T2w sagittal image to T2w axial image to obtain warping field.
# This warping field will be used to bring the T2w sagittal disc labels to the T2w axial space.
# Context: https://github.com/sct-pipeline/dcm-metric-normalization/issues/9
# Note: the '-dseg' is used only for the QC report
sct_register_multimodal -i ${file_t2_sag}.nii.gz -d ${file_t2_ax}.nii.gz -identity 1 -x nn -qc ${PATH_QC} -qc-subject ${SUBJECT} -dseg ${file_t2_ax_seg}.nii.gz
# Bring T2w sagittal disc labels (located in the middle of the spinal cord) to T2w axial space
# Context: https://github.com/sct-pipeline/dcm-metric-normalization/issues/10
sct_apply_transfo -i ${file_t2_sag_seg}_labeled_discs.nii.gz -d ${file_t2_ax}.nii.gz -w warp_${file_t2_sag}2${file_t2_ax}.nii.gz -x label
# Generate QC report to assess warped disc labels
sct_qc -i ${file_t2_ax}.nii.gz -s ${file_t2_sag_seg}_labeled_discs_reg.nii.gz -p sct_label_utils -qc ${PATH_QC} -qc-subject ${SUBJECT}
file_t2_ax_labels=${file_t2_sag_seg}_labeled_discs_reg
fi
# Label T2w axial spinal cord segmentation. Either using manual disc labels or using disc labels from sagittal image.
# Note: here we use sct_label_utils instead of sct_label_vertebrae to avoid SC straightening
# Context: https://github.com/spinalcordtoolbox/spinalcordtoolbox/pull/4072
sct_label_utils -i ${file_t2_ax_seg}.nii.gz -disc ${file_t2_ax_labels}.nii.gz -o ${file_t2_ax_seg}_labeled.nii.gz
# Generate QC report to assess labeled segmentation
sct_qc -i ${file_t2_ax}.nii.gz -s ${file_t2_ax_seg}_labeled.nii.gz -p sct_label_vertebrae -qc ${PATH_QC} -qc-subject ${SUBJECT}
# Check if compression labels exists.
file_compression="${file_t2_ax}_label-compression-manual"
FILE_COMPRESSION_MANUAL="${PATH_DATA}/derivatives/labels/${SUBJECT}/anat/${file_compression}.nii.gz"
if [[ ! -e ${FILE_COMPRESSION_MANUAL} ]]; then
echo "File ${FILE_COMPRESSION_MANUAL}.nii.gz does not exist" >> ${PATH_LOG}/missing_files.log
echo "ERROR: File ${FILE_COMPRESSION_MANUAL}.nii.gz does not exist. Exiting."
exit 1
else
echo "Found! Using manual compression labels."
rsync -avzh $FILE_COMPRESSION_MANUAL ${file_compression}.nii.gz
# Fetch sex from participants.tsv file
sex=$(grep ${SUBJECT} ${PARTICIPANTS_PATH} | awk '{print $5}')
echo "${SUBJECT}: ${sex}"
# TODO: test without angle correction too
# Compute morphometric measures normalized to PAM50 template space
# Note: CSV file without normalization is also generated automatically
# Note: morphometric measures for individual subjects are appended to a single CSV file
# diameter_AP
sct_compute_compression -i ${file_t2_ax_seg}.nii.gz -vertfile ${file_t2_ax_seg}_labeled.nii.gz -l ${file_compression}.nii.gz -normalize-hc 1 -sex ${sex} -o ${PATH_RESULTS}/compression_metrics.csv
# cross-sectional area
sct_compute_compression -i ${file_t2_ax_seg}.nii.gz -vertfile ${file_t2_ax_seg}_labeled.nii.gz -l ${file_compression}.nii.gz -normalize-hc 1 -sex ${sex} -metric area -o ${PATH_RESULTS}/compression_metrics.csv
# diameter_RL
sct_compute_compression -i ${file_t2_ax_seg}.nii.gz -vertfile ${file_t2_ax_seg}_labeled.nii.gz -l ${file_compression}.nii.gz -normalize-hc 1 -sex ${sex} -metric diameter_RL -o ${PATH_RESULTS}/compression_metrics.csv
# eccentricity
sct_compute_compression -i ${file_t2_ax_seg}.nii.gz -vertfile ${file_t2_ax_seg}_labeled.nii.gz -l ${file_compression}.nii.gz -normalize-hc 1 -sex ${sex} -metric eccentricity -o ${PATH_RESULTS}/compression_metrics.csv
# solidity
sct_compute_compression -i ${file_t2_ax_seg}.nii.gz -vertfile ${file_t2_ax_seg}_labeled.nii.gz -l ${file_compression}.nii.gz -normalize-hc 1 -sex ${sex} -metric solidity -o ${PATH_RESULTS}/compression_metrics.csv
fi
fi
# ------------------------------------------------------------------------------
# End
# ------------------------------------------------------------------------------
# Display results (to easily compare integrity across SCT versions)
end=`date +%s`
runtime=$((end-start))
echo
echo "~~~"
echo "SCT version: `sct_version`"
echo "Ran on: `uname -nsr`"
echo "Duration: $(($runtime / 3600))hrs $((($runtime / 60) % 60))min $(($runtime % 60))sec"
echo "~~~"