Skip to content

Commit

Permalink
Merge pull request #2 from spinalcordtoolbox/jv/generalize_manual_cor…
Browse files Browse the repository at this point in the history
…rection_scripts

Generalize manual correction scripts
  • Loading branch information
valosekj authored Feb 1, 2023
2 parents c2b17f5 + f469355 commit e8ecccf
Show file tree
Hide file tree
Showing 7 changed files with 557 additions and 182 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.DS_Store
.idea
*/__pycache__/
venv/
45 changes: 44 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,44 @@
# manual-correction
# Manual correction

This repository contains scripts for the manual correction of spinal cord labels. Currently supported labels are:
- spinal cord segmentation
- gray matter segmentation
- disc labels
- ponto-medullary junction (PMJ) label

## Installation

```console
git clone https://github.com/spinalcordtoolbox/manual-correction.git
cd manual-correction
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
```

## Usage

> **Note** All scripts currently assume BIDS-compliant data. For more information about the BIDS standard, please visit http://bids.neuroimaging.io.
### `package_for_correction.py`

The `package_for_correction.py` script is used to create a zip file containing the processed images and labels
(segmentations, disc labels, etc.). The zip file is then sent to the user for manual correction.

This is useful when you need to correct the labels of a large dataset processed on a remote server. In this case, you do
not need to copy the whole dataset. Instead, only the images and labels that need to be corrected are zipped. The yaml
list of images to correct can be obtained from the [SCT QC html report](https://spinalcordtoolbox.com/overview/concepts/inspecting-results-qc-fsleyes.html#how-do-i-use-the-qc-report).

### `manual_correction.py`

The `manual_correction.py` script is used to correct the labels (segmentations, disc labels, etc.) of a dataset.
The script takes as input a processed dataset and outputs the corrected labels to `derivatives/labels` folder.

For the correction of spinal cord and gray matter segmentation, you can choose a viewer ([FSLeyes](https://open.win.ox.ac.uk/pages/fsl/fsleyes/fsleyes/userdoc/#), [ITK-SNAP](http://www.itksnap.org/pmwiki/pmwiki.php), [3D Slicer](https://www.slicer.org)).

For the correction of vertebral labeling and ponto-medullary junction (PMJ), [sct_label_utils](https://github.com/spinalcordtoolbox/spinalcordtoolbox/blob/master/spinalcordtoolbox/scripts/sct_label_utils.py) is used.

### `copy_files_to_derivatives.py`

The `copy_files_to_derivatives.py` script is used to copy manually corrected labels (segmentations, disc labels, etc.)
from your local `derivatives/labels` folder to the already existing git-annex BIDS dataset's `derivatives/labels` folder.
86 changes: 86 additions & 0 deletions copy_files_to_derivatives.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#!/usr/bin/env python
#
# Copy manually corrected labels (segmentations, vertebral labeling, etc.) from the preprocessed dataset to the
# git-annex BIDS dataset's derivatives folder
#
# Authors: Jan Valosek
#

import argparse
import glob
import os
import shutil
import utils


def get_parser():
"""
parser function
"""

parser = argparse.ArgumentParser(
description='Copy manually corrected files (segmentations, vertebral labeling, etc.) from the source '
'preprocessed dataset to the git-annex BIDS derivatives folder',
formatter_class=utils.SmartFormatter,
prog=os.path.basename(__file__).strip('.py')
)
parser.add_argument(
'-path-in',
metavar="<folder>",
required=True,
type=str,
help='Path to the folder with manually corrected files (usually derivatives). The script assumes that labels '
'folder is located in the provided folder.'
)
parser.add_argument(
'-path-out',
metavar="<folder>",
required=True,
type=str,
help='Path to the BIDS dataset where manually corrected files will be copied. Include also derivatives folder '
'in the path. Files will be copied to the derivatives/label folder.'
)

return parser


def main():

# Parse the command line arguments
parser = get_parser()
args = parser.parse_args()

# Check if path_in exists
if os.path.isdir(args.path_in):
path_in = os.path.join(os.path.abspath(args.path_in), 'labels')
else:
raise NotADirectoryError(f'{args.path_in} does not exist.')

# Check if path_out exists
if os.path.isdir(args.path_out):
path_out = os.path.join(os.path.abspath(args.path_out), 'labels')
else:
raise NotADirectoryError(f'{args.path_out} does not exist.')

# Loop across files in input dataset
for path_file_in in sorted(glob.glob(path_in + '/**/*.nii.gz', recursive=True)):
sub, ses, filename, contrast = utils.fetch_subject_and_session(path_file_in)
# Construct path for the output file
path_file_out = os.path.join(path_out, sub, ses, contrast, filename)
# Check if subject's folder exists in the output dataset, if not, create it
path_subject_folder_out = os.path.join(path_out, sub, ses, contrast)
if not os.path.isdir(path_subject_folder_out):
os.makedirs(path_subject_folder_out)
print(f'Creating directory: {path_subject_folder_out}')
# Copy nii and json files to the output dataset
# TODO - consider rsync instead of shutil.copy
shutil.copy(path_file_in, path_file_out)
print(f'Copying: {path_file_in} to {path_file_out}')
path_file_json_in = path_file_in.replace('nii.gz', 'json')
path_file_json_out = path_file_out.replace('nii.gz', 'json')
shutil.copy(path_file_json_in, path_file_json_out)
print(f'Copying: {path_file_json_in} to {path_file_json_out}')


if __name__ == '__main__':
main()
Loading

0 comments on commit e8ecccf

Please sign in to comment.