ivadomed / canproco

Code for preprocessing the CanProCo brain and spinal cord dataset
MIT License
4 stars 1 forks source link

Ground truth labeling protocol #20

Closed jcohenadad closed 1 year ago

jcohenadad commented 1 year ago

Create a script and/or SHELL syntax (inspiration from https://github.com/ivadomed/model_seg_ms_mp2rage/issues/56#issue-1501621673) that does:

valosekj commented 1 year ago

Thank you for this detailed description! This functionality could be potentially implemented into the manual_correction.py script (which already allows MS lesion segmentation/corrections for model_seg_sci project).

mchen1110 commented 1 year ago

Great suggestion @valosekj! Here is what I have so far- I based it off of the script we wrote for the mp2rage corrections along with help from @sandrinebedard and her ukbiobank script. Happy to discuss how we can integrate it into the manual_correction.py script!

#!/bin/bash
#
# Create manual MS lesion segmentation from T2w images.
#
# Usage:
#   ./ground_truth_protocol.sh <SUBJECT>
#
# Manual segmentations created by this script will be located under:
# PATH_DATA_PROCESSED/derivatives/labels/SUBJECT/anat/
#
# Authors: Sandrine Bédard, Jan Valosek, Michelle Chen, Julien Cohen-Adad
#
# How to use: sct_run_batch -jobs 1 -path-data <> -path-output <> -script ground_truth_protocol.sh

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

# Retrieve input params
SUBJECT=$1

# Save script path
PATH_SCRIPT=$PWD

# 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 list of participants in processed data folder
if [[ ! -f "participants.tsv" ]]; then
  rsync -avzh $PATH_DATA/participants.tsv .
fi
# Copy list of participants in resutls folder
if [[ ! -f $PATH_RESULTS/"participants.tsv" ]]; then
  rsync -avzh $PATH_DATA/participants.tsv $PATH_RESULTS/"participants.tsv"
fi
# Copy source images
rsync -Ravzh $PATH_DATA/./$SUBJECT .
# Copy PSIR segmentation
rsync -Ravzh $PATH_DATA/derivatives/labels/${SUBJECT}/anat/${SUBJECT//[\/]/_}_PSIR_lesion-manual.nii.gz ./$SUBJECT .
# Go to anat folder where all structural data are located
cd ${SUBJECT}/anat/

# T2w segmentation
# ------------------------------------------------------------------------------
# Define variables
# We do a substitution '/' --> '_' in case there is a subfolder 'ses-0X/'
fileT2w="${SUBJECT//[\/]/_}_T2w"
filePSIR="${SUBJECT//[\/]/_}_PSIR"
filePSIRseg="${PATH_DATA_PROCESSED}/derivatives/labels/${SUBJECT}/anat/${filePSIR}_lesion-manual"

if [[ -e ${fileT2w}.nii.gz ]]; then
    # Create a subject folder under the derivatives
    mkdir -p ${PATH_DATA_PROCESSED}/derivatives/labels/${SUBJECT}/anat/
    # denoise T2w image
    sct_maths -i ${fileT2w}.nii.gz -denoise p=1,b=2 -o ${fileT2w}_denoised-p1b2.nii.gz
    # resample existing PSIR segmentation into T2w space
    sct_resample -i ${filePSIRseg}.nii.gz -mm 0.8x0.8x0.8 -o ${filePSIRseg}_r.nii.gz    
    # create an empty mask from T2w image
    sct_create_mask -i ${fileT2w}.nii.gz -o ${PATH_DATA_PROCESSED}/derivatives/labels/${SUBJECT}/anat/${fileT2w}_lesion-manual.nii.gz -p center -size 0
    # convert mask to proper datatype
    sct_image -i ${PATH_DATA_PROCESSED}/derivatives/labels/${SUBJECT}/anat/${fileT2w}_lesion-manual.nii.gz -type uint16 -o ${PATH_DATA_PROCESSED}/derivatives/labels/${SUBJECT}/anat/${fileT2w}_lesion-manual.nii.gz
    # open fsleyes with T2w image, T2w denoised image, PSIR image, resampled PSIR segmentation, and T2w mask 
    fsleyes ${fileT2w}.nii.gz ${fileT2w}_denoised-p1b2.nii.gz ${filePSIR}.nii.gz ${filePSIRseg}_r.nii.gz ${PATH_DATA_PROCESSED}/derivatives/labels/${SUBJECT}/anat/${file}_lesion-manual.nii.gz
    # remove temporary data
    rm -f ${fileT2w}_denoised-p1b2.nii.gz ${filePSIRseg}_r.nii.gz
    # create a json sidecar
    cur_time=$(python <<< "import time;print(time.strftime('%Y-%m-%d %H:%M:%S'))")
    echo -e "{\n    \"Author\": \"Michelle Chen\",\n    \"Label\": \"lesion-manualNeuroPoly\",\n    \"Date\": \"${cur_time}\"\n}" > ${PATH_DATA_PROCESSED}/derivatives/labels/${SUBJECT}/anat/${file}_lesion-manual.json
fi

# Display useful info for the log
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 "~~~"
mchen1110 commented 1 year ago

Update- @valosekj and I had a discussion and he will help to integrate the tasks for the ground truth protocol into the manual_correction.py script later today or tomorrow.

We tested the script above on one subject and noticed that after resampling the existing PSIR segmentation into the T2w space, it was slightly shifted and some segmentations inaccurately labeled CSF. Then we opened the non-resampled PSIR segmentation and it was misaligned as well. Since existing PSIR segmentations only exist for one site and ground truth segmentations will be created on the T2w image using the PSIR segmentation as a guide, we thought it might not be necessary to include the PSIR segmentation reampling step.

valosekj commented 1 year ago

Implemented in https://github.com/spinalcordtoolbox/manual-correction/pull/8