diff --git a/models/bpreg/config/default.yml b/models/bpreg/config/default.yml new file mode 100644 index 00000000..2ea0fb29 --- /dev/null +++ b/models/bpreg/config/default.yml @@ -0,0 +1,14 @@ +general: + data_base_dir: /app/data + version: 1.0 + description: Body part regression pipeline from DKFZ, processing DICOM files to predict anatomical regions and anomalies +execute: +- DicomImporter +- NiftiConverter +- BPRRunner +- DataOrganizer + +modules: + DataOrganizer: + targets: + - json:type=bpreg-->[i:sid]/bpreg.json \ No newline at end of file diff --git a/models/bpreg/dockerfiles/Dockerfile b/models/bpreg/dockerfiles/Dockerfile new file mode 100644 index 00000000..92c3ba2b --- /dev/null +++ b/models/bpreg/dockerfiles/Dockerfile @@ -0,0 +1,19 @@ +FROM mhubai/base:v1 + +LABEL authors="bspai@bwh.harvard.edu,lnuernberg@bwh.harvard.edu" + +ARG MHUB_MODELS_REPO +RUN buildutils/import_mhub_model.sh bpreg ${MHUB_MODELS_REPO} + +# Install additional pip packages +RUN pip3 install --upgrade pip && \ + pip3 install bpreg && \ + pip3 install numpy -U + +# download model weights +RUN wget "https://zenodo.org/record/5113483/files/public_bpr_model.zip?download=1" -O "/app/public_inference_model.zip" && \ + unzip "/app/public_inference_model.zip" -d "/app/public_inference_model" && \ + rm "/app/public_inference_model.zip" + +ENTRYPOINT ["mhub.run"] +CMD ["--workflow", "default"] diff --git a/models/bpreg/meta.json b/models/bpreg/meta.json new file mode 100644 index 00000000..4a9fbc6d --- /dev/null +++ b/models/bpreg/meta.json @@ -0,0 +1,110 @@ +{ + "id": "", + "name": "bpreg", + "title": "Body Part Regression [CT Utility Models]", + "summary": { + "description": "The Body Part Regression (BPR) model translates the anatomy in a radiologic volume into a machine-interpretable form. Each axial slice maps to a slice score. The slice scores monotonously increase with patient height. The BPR model can be used for sorting and labeling radiologic images by body parts. Moreover, it is useful for cropping specific body parts as a pre-processing or post-processing step of medical algorithms.", + "inputs": [ + { + "label": "Input CT Image", + "description": "Input CT", + "format": "DICOM", + "modality": "CT", + "slicethickness": "5mm", + "bodypartexamined": "WHOLEBODY", + "non-contrast": true, + "contrast": true + } + ], + "outputs": [ + { + "type": "Prediction", + "valueType": "Data structure", + "description": "A set of values extracted from the input CT image for utility purposes", + "label": "bpreg" + } + ], + "model": { + "architecture": "VGG-16", + "training": "unsupervised", + "cmpapproach": "2D" + }, + "data": { + "training": { + "vol_samples": 800, + "subjects": 420 + }, + "evaluation": { + "vol_samples": 260, + "subjects": 140 + }, + "public": false, + "external": true + } + }, + "details": { + "name": "Body Part Regression", + "version": "0.0.1", + "type": "Prediction of anatomical region", + "devteam": "Researchers from the Imaging Biomarkers and Computer-Aided Diagnosis Lab, Clinical Image Processing Service, Radiology and Imaging Sciences, National Institutes of Health Clinical Center", + "date": { + "pub": "07.03.2018", + "code": "13.08.2021", + "weights": "19.07.2021" + }, + "cite": "Yan, K., Lu, L., Summers, R.M. Unsupervised Body Part Regression via Spatially Self-Ordering Convolutional Neural Networks. arXiv:1707.03891v2", + "license": { + "code": "Apache 2.0", + "weights": "CC BY-SA 4.0" + }, + "publications": [ + { + "title": "Unsupervised Body Part Regression via Spatially Self-Ordering Convolutional Neural Networks", + "uri": "https://arxiv.org/abs/1707.03891" + } + ], + "github": "https://github.com/MIC-DKFZ/BodyPartRegression", + "zenodo": "https://zenodo.org/records/5113483#.YPaBkNaxWEA", + "slicer": false + }, + "info": { + "use": { + "title": "Intended Use", + "text": "The BPR model can be used for sorting and labeling radiologic images by body parts. Moreover, it is useful for cropping specific body parts as a pre-processing or post-processing step of medical algorithms." + }, + "analyses": { + "title": "Quantitative Analyses", + "text": "The model's performance was assessed using three different downstream tasks, including network initialization and anomaly detection. Refer to the publication for more details [1].", + "references": [ + { + "label": "Unsupervised Body Part Regression via Spatially Self-Ordering Convolutional Neural Networks", + "uri": "https://arxiv.org/abs/1707.03891" + } + ] + }, + "evaluation": { + "title": "Evaluation Data", + "text": "The evaluation dataset consists of 18,195 CT slices randomly sampled from 260 CT volumes of 140 subjects, manually labeled as one of the 3 common classes: chest, abdomen, or pelvis.", + "tables": [ + { + "label": "Evaluation Tasks & Datasets", + "entries": { + "Chest": "5903 slices", + "Abdomen": "6744 slices", + "Pelvis": "5548 slices" + } + } + ], + "references": [ + + ] + }, + "training": { + "title": "Training Data", + "text": "The training dataset consists of 800 random unlabeled CT volumes of 420 subjects from NIH CC hospital PACS. Volumes are in the range of 30-700 slices each, mostly chest-abdomen-pelvis scans. The data have various pixel spacings (0.6–1.0 mm), reconstruction kernels, and pathological conditions.", + "references": [ + + ] + } + } +} \ No newline at end of file diff --git a/models/bpreg/utils/BPRRunner.py b/models/bpreg/utils/BPRRunner.py new file mode 100644 index 00000000..302b3927 --- /dev/null +++ b/models/bpreg/utils/BPRRunner.py @@ -0,0 +1,25 @@ +""" +--------------------------------------------------------- +Author: Suraj Pai, Leonard Nürnberg +Email: bspai@bwh.harvard.edu, lnuernberg@bwh.harvard.edu +Date: 15.07.2024 +--------------------------------------------------------- +""" +import os +from pathlib import Path +from mhubio.core import Instance, InstanceData, IO, Module +from bpreg.inference.inference_model import InferenceModel +import torch + + +class BPRRunner(Module): + + @IO.Instance() + @IO.Input('in_data', 'nifti:mod=ct', the='The input NIfTI CT image file.') + @IO.Output('bpreg_json', 'bpreg.json', "json:type=bpreg", bundle='model', the=' The output JSON file to save the extracted features.') + def task(self, instance: Instance, in_data: InstanceData, bpreg_json: InstanceData) -> None: + gpu_available = torch.cuda.is_available() + model = InferenceModel("/app/public_inference_model/public_bpr_model/", gpu=gpu_available) + input_path = in_data.abspath + output_path = bpreg_json.abspath + model.nifti2json(input_path, output_path, stringify_json=False) \ No newline at end of file diff --git a/models/bpreg/utils/__init__.py b/models/bpreg/utils/__init__.py new file mode 100644 index 00000000..d7b41bf0 --- /dev/null +++ b/models/bpreg/utils/__init__.py @@ -0,0 +1 @@ +from .BPRRunner import BPRRunner \ No newline at end of file