From 2dfcd554b1219db663479f474482cb336e7e4a6d Mon Sep 17 00:00:00 2001 From: ccosmin97 Date: Mon, 4 Dec 2023 21:37:30 +0000 Subject: [PATCH 1/9] init commit for prostate158 model --- models/monai_prostate158/config/default.yml | 39 ++++++ .../monai_prostate158/dockerfiles/dockerfile | 28 ++++ models/monai_prostate158/meta.json | 125 ++++++++++++++++++ .../utils/Prostate158Runner.py | 1 + 4 files changed, 193 insertions(+) create mode 100644 models/monai_prostate158/config/default.yml create mode 100644 models/monai_prostate158/dockerfiles/dockerfile create mode 100644 models/monai_prostate158/meta.json create mode 100644 models/monai_prostate158/utils/Prostate158Runner.py diff --git a/models/monai_prostate158/config/default.yml b/models/monai_prostate158/config/default.yml new file mode 100644 index 00000000..20ca9eb1 --- /dev/null +++ b/models/monai_prostate158/config/default.yml @@ -0,0 +1,39 @@ +general: + data_base_dir: /app/data + version: 1.0 + description: default configuration for MONAI Prostate158 MR Prostate zonal regions segmentation (dicom to dicom) + +execute: +- DicomImporter +- NiftiConverter +- NNUnetRunner +- DsegConverter +- DataOrganizer + +modules: + DicomImporter: + source_dir: input_data + import_dir: sorted_data + sort_data: true + meta: + mod: 'mr' + + NiftiConverter: + in_datas: dicom:mod=mr + engine: dcm2niix + + Prostate158Runner: + in_data: nifti:mod=mr + nnunet_task: prostate_mri_anatomy + # nnunet_model: 3d_fullres + roi: PROSTATE + + DsegConverter: + source_segs: nifti:mod=seg + target_dicom: dicom:mod=mr + model_name: 'Prostate158' + skip_empty_slices: True + + DataOrganizer: + targets: + - dicomseg-->[i:sid]/nnunet_mr_prostate.seg.dcm \ No newline at end of file diff --git a/models/monai_prostate158/dockerfiles/dockerfile b/models/monai_prostate158/dockerfiles/dockerfile new file mode 100644 index 00000000..c5debeee --- /dev/null +++ b/models/monai_prostate158/dockerfiles/dockerfile @@ -0,0 +1,28 @@ +FROM mhubai/base:latest + +# FIXME: set this environment variable as a shortcut to avoid nnunet crashing the build +# by pulling sklearn instead of scikit-learn +# N.B. this is a known issue: +# https://github.com/MIC-DKFZ/nnUNet/issues/1281 +# https://github.com/MIC-DKFZ/nnUNet/pull/1209 +ENV SKLEARN_ALLOW_DEPRECATED_SKLEARN_PACKAGE_INSTALL=True + +# Install nnunet and platipy +RUN pip3 install --no-cache-dir \ + "monai[fire]" + +# Clone the main branch of MHubAI/models +ARG MHUB_MODELS_REPO +RUN buildutils/import_mhub_model.sh monai_prostate158 ${MHUB_MODELS_REPO} + +# Pull weights into the container +ENV WEIGHTS_DIR=/root/.monai/bundles/ +RUN mkdir -p $WEIGHTS_DIR +RUN python -m monai.bundle download "prostate_mri_anatomy" --bundle_dir ${WEIGHTS_DIR} + +# specify nnunet specific environment variables +# ENV WEIGHTS_FOLDER=$WEIGHTS_DIR + +# Default run script +ENTRYPOINT ["mhub.run"] +CMD ["--config", "/app/models/monai_prostate158/config/default.yml"] \ No newline at end of file diff --git a/models/monai_prostate158/meta.json b/models/monai_prostate158/meta.json new file mode 100644 index 00000000..50c4e568 --- /dev/null +++ b/models/monai_prostate158/meta.json @@ -0,0 +1,125 @@ +{ + "id": "...", + "name": "nnunet_prostate_task24_promise", + "title": "nnU-Net (Whole prostate segmentation)", + "summary": { + "description": "nnU-Net's whole prostate segmentation model is a single-modality (i.e. T2) input AI-based pipeline for the automated segmentation of the whole prostate on MRI scans.", + "inputs": [ + { + "label": "T2 input image", + "description": "The T2 axial-acquired sequence being the input image", + "format": "DICOM", + "modality": "MR", + "bodypartexamined": "Prostate", + "slicethickness": "3.6 mm", + "non-contrast": true, + "contrast": false + } + ], + "outputs": [ + { + "type": "Segmentation", + "classes": [ + "PROSTATE" + ] + } + ], + "model": { + "architecture": "U-net", + "training": "supervised", + "cmpapproach": "3D" + }, + "data": { + "training": { + "vol_samples": 50 + }, + "evaluation": { + "vol_samples": 30 + }, + "public": true, + "external": false + } + }, + "details": { + "name": "nnU-Net whole prostate segmentation model", + "version": "1.0.0", + "devteam": "MIC-DKFZ (Helmholtz Imaging Applied Computer Vision Lab)", + "type": "nnU-Net (U-Net structure, optimized by data-driven heuristics)", + "date": { + "weights": "2020", + "code": "2020", + "pub": "2020" + }, + "cite": "Isensee, F., Jaeger, P. F., Kohl, S. A., Petersen, J., & Maier-Hein, K. H. (2020). nnU-Net: a self-configuring method for deep learning-based biomedical image segmentation. Nature Methods, 1-9.", + "license": { + "code": "Apache 2.0", + "weights": "CC BY-NC 4.0" + }, + "publications": [ + { + "title": "nnU-Net: a self-configuring method for deep learning-based biomedical image segmentation", + "uri": "https://www.nature.com/articles/s41592-020-01008-z" + } + ], + "github": "https://github.com/MIC-DKFZ/nnUNet/tree/nnunetv1", + "zenodo": "https://zenodo.org/record/4485926" + }, + "info": { + "use": { + "title": "Intended Use", + "text": "This model is intended to perform prostate anatomy segmentation in MR T2 scans. The slice thickness of the training data is 2.2~4mm. Endorectal coil was present during training." + }, + "analyses": { + "title": "Quantitative Analyses", + "text": "The model's performance was assessed using the Dice Coefficient, in the context of the Promise12 challenge. The complete breakdown of the metrics can be consulted on GrandChallenge [1] and is reported in the supplementary material to the publication [2].", + "references": [ + { + "label": "Evaluation of prostate segmentation algorithms for MRI: The PROMISE12 challenge", + "uri": "https://doi.org/10.1016/j.media.2013.12.002" + }, + { + "label": "nnU-Net: a self-configuring method for deep learning-based biomedical image segmentation", + "uri": "https://www.nature.com/articles/s41592-020-01008-z" + } + ] + }, + "evaluation": { + "title": "Evaluation Data", + "text": "The evaluation dataset consists of 30 test samples coming from the Promise12 challenge.", + "tables": [], + "references": [ + { + "label": "Evaluation of prostate segmentation algorithms for MRI: The PROMISE12 challenge", + "uri": "https://doi.org/10.1016/j.media.2013.12.002" + }, + { + "label": "PROMISE12 dataset (direct download)", + "uri": "https://zenodo.org/records/8026660" + } + ] + }, + "training": { + "title": "Training Data", + "text": "The training dataset consists of 50 MRI cases containing the prostate, from the Promise12 challenge. The authors report the following characteristics for the training dataset:", + "tables": [ + { + "label": "Medical Image Decathlon dataset (training)", + "entries": { + "Slice Thickness": "2.2~4 mm", + "In-Plane Resolution": "0.27 mm" + } + } + ], + "references": [ + { + "label": "Evaluation of prostate segmentation algorithms for MRI: The PROMISE12 challenge", + "uri": "https://doi.org/10.1016/j.media.2013.12.002" + }, + { + "label": "PROMISE12 dataset (direct download)", + "uri": "https://zenodo.org/records/8026660" + } + ] + } + } +} \ No newline at end of file diff --git a/models/monai_prostate158/utils/Prostate158Runner.py b/models/monai_prostate158/utils/Prostate158Runner.py new file mode 100644 index 00000000..dbd265c6 --- /dev/null +++ b/models/monai_prostate158/utils/Prostate158Runner.py @@ -0,0 +1 @@ +#.... \ No newline at end of file From c7fb52b18a3dc4edf38b3c60d0d437f1496e3ad3 Mon Sep 17 00:00:00 2001 From: ccosmin97 Date: Fri, 15 Dec 2023 22:30:07 +0000 Subject: [PATCH 2/9] added meta.json, config and dockerfiles, tried testing with and without center cropping --- models/monai_prostate158/config/default.yml | 12 ++- .../monai_prostate158/dockerfiles/dockerfile | 13 ++- models/monai_prostate158/meta.json | 82 ++++++++---------- .../utils/Prostate158Runner.py | 86 ++++++++++++++++++- models/monai_prostate158/utils/__init__.py | 1 + 5 files changed, 135 insertions(+), 59 deletions(-) create mode 100644 models/monai_prostate158/utils/__init__.py diff --git a/models/monai_prostate158/config/default.yml b/models/monai_prostate158/config/default.yml index 20ca9eb1..d56939bc 100644 --- a/models/monai_prostate158/config/default.yml +++ b/models/monai_prostate158/config/default.yml @@ -6,7 +6,7 @@ general: execute: - DicomImporter - NiftiConverter -- NNUnetRunner +- Prostate158Runner - DsegConverter - DataOrganizer @@ -24,16 +24,14 @@ modules: Prostate158Runner: in_data: nifti:mod=mr - nnunet_task: prostate_mri_anatomy - # nnunet_model: 3d_fullres - roi: PROSTATE + apply_center_crop: False DsegConverter: - source_segs: nifti:mod=seg + source_segs: nifti:mod=seg:roi=PROSTATE_TRANSITION_ZONE,PROSTATE_PERIPHERAL_ZONE target_dicom: dicom:mod=mr - model_name: 'Prostate158' + model_name: 'Segmentation of prostate regions, Prostate158' skip_empty_slices: True DataOrganizer: targets: - - dicomseg-->[i:sid]/nnunet_mr_prostate.seg.dcm \ No newline at end of file + - dicomseg-->[i:sid]/prostate158.seg.dcm \ No newline at end of file diff --git a/models/monai_prostate158/dockerfiles/dockerfile b/models/monai_prostate158/dockerfiles/dockerfile index c5debeee..9e741b49 100644 --- a/models/monai_prostate158/dockerfiles/dockerfile +++ b/models/monai_prostate158/dockerfiles/dockerfile @@ -7,18 +7,23 @@ FROM mhubai/base:latest # https://github.com/MIC-DKFZ/nnUNet/pull/1209 ENV SKLEARN_ALLOW_DEPRECATED_SKLEARN_PACKAGE_INSTALL=True +ARG MONAI_BUNDLE_DIR='https://github.com/Project-MONAI/model-zoo/releases/download/hosting_storage_v1/prostate_mri_anatomy_v0.1.0.zip' +ARG MONAI_MODEL_NAME='prostate_mri_anatomy' + # Install nnunet and platipy -RUN pip3 install --no-cache-dir \ - "monai[fire]" +RUN python3 -m pip install --upgrade pip && pip3 install --no-cache-dir "monai[ignite]" fire nibabel simpleITK # Clone the main branch of MHubAI/models ARG MHUB_MODELS_REPO RUN buildutils/import_mhub_model.sh monai_prostate158 ${MHUB_MODELS_REPO} # Pull weights into the container -ENV WEIGHTS_DIR=/root/.monai/bundles/ +ENV WEIGHTS_DIR=/app/models/monai_prostate158/bundle RUN mkdir -p $WEIGHTS_DIR -RUN python -m monai.bundle download "prostate_mri_anatomy" --bundle_dir ${WEIGHTS_DIR} +RUN python3 -m monai.bundle download "prostate_mri_anatomy" --bundle_dir ${WEIGHTS_DIR} + +#define path to bundle root +ENV BUNDLE_ROOT=/app/models/monai_prostate158/bundle/prostate_mri_anatomy # specify nnunet specific environment variables # ENV WEIGHTS_FOLDER=$WEIGHTS_DIR diff --git a/models/monai_prostate158/meta.json b/models/monai_prostate158/meta.json index 50c4e568..01f9514a 100644 --- a/models/monai_prostate158/meta.json +++ b/models/monai_prostate158/meta.json @@ -1,17 +1,17 @@ { "id": "...", - "name": "nnunet_prostate_task24_promise", - "title": "nnU-Net (Whole prostate segmentation)", + "name": "monai_prostate158", + "title": "Prostate158 (Prostate transitional zone and peripheral zone segmentation)", "summary": { - "description": "nnU-Net's whole prostate segmentation model is a single-modality (i.e. T2) input AI-based pipeline for the automated segmentation of the whole prostate on MRI scans.", + "description": "Prostate158 is a zonal prostate segmentation model, a multi-modality input AI-based pipeline for the automated segmentation of the peripheral and central gland of the prostate on MRI T2 axial scans.", "inputs": [ { "label": "T2 input image", - "description": "The T2 axial-acquired sequence being the input image", + "description": "The T2 axial sequence being one of the two input image", "format": "DICOM", "modality": "MR", "bodypartexamined": "Prostate", - "slicethickness": "3.6 mm", + "slicethickness": "3 mm", "non-contrast": true, "contrast": false } @@ -20,7 +20,8 @@ { "type": "Segmentation", "classes": [ - "PROSTATE" + "PROSTATE_TRANSITION_ZONE", + "PROSTATE_PERIPHERAL_ZONE" ] } ], @@ -31,93 +32,80 @@ }, "data": { "training": { - "vol_samples": 50 + "vol_samples": 139 }, "evaluation": { - "vol_samples": 30 + "vol_samples": 20 }, "public": true, "external": false } }, "details": { - "name": "nnU-Net whole prostate segmentation model", + "name": "Prostate158 - An expert-annotated 3T MRI dataset and algorithm for prostate cancer detection", "version": "1.0.0", - "devteam": "MIC-DKFZ (Helmholtz Imaging Applied Computer Vision Lab)", - "type": "nnU-Net (U-Net structure, optimized by data-driven heuristics)", + "devteam": "Lisa C. Adams, Keno K. Bressem", + "type": "Prostate158 (U-Net structure for prostate segmentation)", "date": { - "weights": "2020", - "code": "2020", - "pub": "2020" + "weights": "2022", + "code": "2022", + "pub": "2022" }, - "cite": "Isensee, F., Jaeger, P. F., Kohl, S. A., Petersen, J., & Maier-Hein, K. H. (2020). nnU-Net: a self-configuring method for deep learning-based biomedical image segmentation. Nature Methods, 1-9.", + "cite": "Lisa C. Adams and Marcus R. Makowski and Günther Engel and Maximilian Rattunde and Felix Busch and Patrick Asbach and Stefan M. Niehues and Shankeeth Vinayahalingam and Bram {van Ginneken} and Geert Litjens and Keno K. Bressem, Prostate158 - An expert-annotated 3T MRI dataset and algorithm for prostate cancer detection", "license": { "code": "Apache 2.0", - "weights": "CC BY-NC 4.0" + "weights": "" }, "publications": [ { - "title": "nnU-Net: a self-configuring method for deep learning-based biomedical image segmentation", - "uri": "https://www.nature.com/articles/s41592-020-01008-z" + "title": "Prostate158 - An expert-annotated 3T MRI dataset and algorithm for prostate cancer detection", + "uri": "https://doi.org/10.1016/j.compbiomed.2022.105817" } ], - "github": "https://github.com/MIC-DKFZ/nnUNet/tree/nnunetv1", - "zenodo": "https://zenodo.org/record/4485926" + "github": "https://github.com/Project-MONAI/model-zoo/tree/dev/models/prostate_mri_anatomy", + "zenodo": "https://zenodo.org/records/6481141" }, "info": { "use": { "title": "Intended Use", - "text": "This model is intended to perform prostate anatomy segmentation in MR T2 scans. The slice thickness of the training data is 2.2~4mm. Endorectal coil was present during training." + "text": "This model is intended to perform prostate regions anatomy segmentation in MR ADC and T2 scans. The slice thickness of the training data is 3mm. T2 input modality is used during training. To align with the model training pre-processing scheme, center-cropping of the input T2 image is recommended. No endorectal coil was present during training." }, "analyses": { "title": "Quantitative Analyses", - "text": "The model's performance was assessed using the Dice Coefficient, in the context of the Promise12 challenge. The complete breakdown of the metrics can be consulted on GrandChallenge [1] and is reported in the supplementary material to the publication [2].", + "text": "The model's performance was assessed using the Dice Coefficient, on an internal test set and ProstateX collection. The complete breakdown of the metrics can be consulted in the publication.", "references": [ { - "label": "Evaluation of prostate segmentation algorithms for MRI: The PROMISE12 challenge", - "uri": "https://doi.org/10.1016/j.media.2013.12.002" - }, - { - "label": "nnU-Net: a self-configuring method for deep learning-based biomedical image segmentation", - "uri": "https://www.nature.com/articles/s41592-020-01008-z" + "label": "Prostate158 - An expert-annotated 3T MRI dataset and algorithm for prostate cancer detection", + "uri": "https://doi.org/10.1016/j.compbiomed.2022.105817" } ] }, "evaluation": { "title": "Evaluation Data", - "text": "The evaluation dataset consists of 30 test samples coming from the Promise12 challenge.", + "text": "The evaluation dataset consists of 20 internal validation samples.", "tables": [], - "references": [ - { - "label": "Evaluation of prostate segmentation algorithms for MRI: The PROMISE12 challenge", - "uri": "https://doi.org/10.1016/j.media.2013.12.002" - }, - { - "label": "PROMISE12 dataset (direct download)", - "uri": "https://zenodo.org/records/8026660" - } - ] + "references": [] }, "training": { "title": "Training Data", - "text": "The training dataset consists of 50 MRI cases containing the prostate, from the Promise12 challenge. The authors report the following characteristics for the training dataset:", + "text": "The training dataset consists of 139 MRI cases containing the prostate, from the Prostate158 collection. The authors report the following characteristics for the T2 imaging sequeneces:", "tables": [ { - "label": "Medical Image Decathlon dataset (training)", + "label": "Prostate158 dataset (training)", "entries": { - "Slice Thickness": "2.2~4 mm", - "In-Plane Resolution": "0.27 mm" + "Slice Thickness": "3 mm", + "In-Plane Resolution": "0.47 mm" } } ], "references": [ { - "label": "Evaluation of prostate segmentation algorithms for MRI: The PROMISE12 challenge", - "uri": "https://doi.org/10.1016/j.media.2013.12.002" + "label": "Medical Segmentation Decathlon", + "uri": "https://www.nature.com/articles/s41467-022-30695-9" }, { - "label": "PROMISE12 dataset (direct download)", - "uri": "https://zenodo.org/records/8026660" + "label": "Prostate158 dataset (Zenodo access)", + "uri": "https://zenodo.org/records/6481141" } ] } diff --git a/models/monai_prostate158/utils/Prostate158Runner.py b/models/monai_prostate158/utils/Prostate158Runner.py index dbd265c6..24a631ca 100644 --- a/models/monai_prostate158/utils/Prostate158Runner.py +++ b/models/monai_prostate158/utils/Prostate158Runner.py @@ -1 +1,85 @@ -#.... \ No newline at end of file +""" +------------------------------------------------- +MHub - MONAI Prostate158 Runner +------------------------------------------------- + +------------------------------------------------- +Author: Cosmin Ciausu +Email: cciausu97@gmail.com +------------------------------------------------- +""" +# TODO: support multi-i/o and batch processing on multiple instances + +from typing import List, Optional +import os, subprocess, shutil, glob, sys +import SimpleITK as sitk, numpy as np +from mhubio.core import Module, Instance, InstanceData, DataType, FileType, IO +from mhubio.modules.runner.ModelRunner import ModelRunner +import json + +@IO.Config('apply_center_crop', bool, False, the='flag to apply center cropping to input_image') + +class Prostate158Runner(ModelRunner): + + apply_center_crop : bool + + @IO.Instance() + @IO.Input("in_data", 'nifti:mod=mr', the="input T2 sequence data to run prostate158 on") + @IO.Output('out_data', 'monai_prostate158.nii.gz', + 'nifti:mod=seg:model=Prostate158:roi=PROSTATE_TRANSITION_ZONE,PROSTATE_PERIPHERAL_ZONE', + data='in_data', bundle='model', the="predicted segmentation model") + + def task(self, instance: Instance, in_data: InstanceData, out_data: InstanceData) -> None: + + # bring input data in nnunet specific format + # NOTE: only for nifti data as we hardcode the nnunet-formatted-filename (and extension) for now. + assert in_data.type.ftype == FileType.NIFTI + assert in_data.abspath.endswith('.nii.gz') + datalist = [in_data.abspath] + + if self.apply_center_crop: + in_dir_cropped = self.config.data.requestTempDir(label="monai-crop-in") + in_data_processed = os.path.join(in_dir_cropped, "image_cropped.nii.gz") + self.subprocess([sys.executable, f"{os.path.join(os.environ['BUNDLE_ROOT'], 'scripts', 'center_crop.py')}", + "--file_name", in_data.abspath, "--out_name",in_data_processed], text=True) + datalist = [in_data_processed] + + # define output folder (temp dir) and also override environment variable for nnunet + out_dir = self.config.data.requestTempDir(label="monai-model-out") + + bash_command = [sys.executable, + "-m", "monai.bundle", "run", "evaluating"] + bash_command += ["--meta_file", os.path.join(os.environ['BUNDLE_ROOT'], "configs", "metadata.json")] + bash_command += ["--config_file", os.path.join(os.environ['BUNDLE_ROOT'], "configs", "inference.json")] + bash_command += ["--datalist", str(datalist)] + bash_command += ["--output_dir", out_dir] + bash_command += ["--bundle_root", os.environ['BUNDLE_ROOT']] + bash_command += ["--dataloader#num_workers", "0"] + print(bash_command) + self.subprocess(bash_command, text=True) + + # get output data + out_path = glob.glob(os.path.join(out_dir, "**", + "*.nii.gz"), recursive=True)[0] + + if self.apply_center_crop: + out_dir_padded = self.config.data.requestTempDir(label="monai-padded-out") + out_data_padded = os.path.join(out_dir_padded, "seg_padded.nii.gz") + paddedFilter = sitk.ConstantPadImageFilter() + seg_image = sitk.ReadImage(out_path) + t2_image = sitk.ReadImage(in_data.abspath) + out_seg_shape = sitk.GetArrayFromImage(seg_image).shape + t2_image_shape = sitk.GetArrayFromImage(t2_image).shape + x_bound_lower = int((t2_image_shape[2] - out_seg_shape[2])/2) + x_bound_upper = int(int(t2_image_shape[2] - out_seg_shape[2])/2 + ((t2_image_shape[2] - out_seg_shape[2]) % 2)) + y_bound_lower = int((t2_image_shape[1] - out_seg_shape[1])/2) + y_bound_upper = int(int(t2_image_shape[1] - out_seg_shape[1])/2 + ((t2_image_shape[1] - out_seg_shape[1]) % 2)) + paddedFilter.SetConstant(0) + paddedFilter.SetPadLowerBound([x_bound_lower, y_bound_lower, 0]) + paddedFilter.SetPadUpperBound([x_bound_upper, y_bound_upper, 0]) + padded_img = paddedFilter.Execute(seg_image) + sitk.WriteImage(padded_img, out_data_padded) + out_path = out_data_padded + + # copy output data to instance + shutil.copyfile(out_path, out_data.abspath) diff --git a/models/monai_prostate158/utils/__init__.py b/models/monai_prostate158/utils/__init__.py new file mode 100644 index 00000000..d03d6b1f --- /dev/null +++ b/models/monai_prostate158/utils/__init__.py @@ -0,0 +1 @@ +from .Prostate158Runner import * \ No newline at end of file From f3be4986dadc50087f617f3f979520ae4437ef42 Mon Sep 17 00:00:00 2001 From: ccosmin97 Date: Fri, 15 Dec 2023 22:42:24 +0000 Subject: [PATCH 3/9] fixed dockerfile --- models/monai_prostate158/config/default.yml | 2 +- models/monai_prostate158/dockerfiles/{dockerfile => Dockerfile} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename models/monai_prostate158/dockerfiles/{dockerfile => Dockerfile} (100%) diff --git a/models/monai_prostate158/config/default.yml b/models/monai_prostate158/config/default.yml index d56939bc..e62ac281 100644 --- a/models/monai_prostate158/config/default.yml +++ b/models/monai_prostate158/config/default.yml @@ -24,7 +24,7 @@ modules: Prostate158Runner: in_data: nifti:mod=mr - apply_center_crop: False + apply_center_crop: True DsegConverter: source_segs: nifti:mod=seg:roi=PROSTATE_TRANSITION_ZONE,PROSTATE_PERIPHERAL_ZONE diff --git a/models/monai_prostate158/dockerfiles/dockerfile b/models/monai_prostate158/dockerfiles/Dockerfile similarity index 100% rename from models/monai_prostate158/dockerfiles/dockerfile rename to models/monai_prostate158/dockerfiles/Dockerfile From d36dc19ea0cd2211e62a0db7ff30faddf99373f9 Mon Sep 17 00:00:00 2001 From: Cosmin Ciausu Date: Mon, 22 Jan 2024 12:35:06 -0500 Subject: [PATCH 4/9] Update Dockerfile removed commented code --- models/monai_prostate158/dockerfiles/Dockerfile | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/models/monai_prostate158/dockerfiles/Dockerfile b/models/monai_prostate158/dockerfiles/Dockerfile index 9e741b49..22cab1b7 100644 --- a/models/monai_prostate158/dockerfiles/Dockerfile +++ b/models/monai_prostate158/dockerfiles/Dockerfile @@ -25,9 +25,6 @@ RUN python3 -m monai.bundle download "prostate_mri_anatomy" --bundle_dir ${WEIGH #define path to bundle root ENV BUNDLE_ROOT=/app/models/monai_prostate158/bundle/prostate_mri_anatomy -# specify nnunet specific environment variables -# ENV WEIGHTS_FOLDER=$WEIGHTS_DIR - # Default run script ENTRYPOINT ["mhub.run"] -CMD ["--config", "/app/models/monai_prostate158/config/default.yml"] \ No newline at end of file +CMD ["--config", "/app/models/monai_prostate158/config/default.yml"] From 459790bba1209f55d6e4ac8db9e28fe46bbf02b4 Mon Sep 17 00:00:00 2001 From: Cosmin Ciausu Date: Mon, 22 Jan 2024 14:29:11 -0500 Subject: [PATCH 5/9] Update default.yml delete center_crop = True argument, since its enabled by default renamed model_name in DsegConverter --- models/monai_prostate158/config/default.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/models/monai_prostate158/config/default.yml b/models/monai_prostate158/config/default.yml index e62ac281..b4284bbb 100644 --- a/models/monai_prostate158/config/default.yml +++ b/models/monai_prostate158/config/default.yml @@ -24,14 +24,13 @@ modules: Prostate158Runner: in_data: nifti:mod=mr - apply_center_crop: True - + DsegConverter: source_segs: nifti:mod=seg:roi=PROSTATE_TRANSITION_ZONE,PROSTATE_PERIPHERAL_ZONE target_dicom: dicom:mod=mr - model_name: 'Segmentation of prostate regions, Prostate158' + model_name: 'MONAI Prostate158' skip_empty_slices: True DataOrganizer: targets: - - dicomseg-->[i:sid]/prostate158.seg.dcm \ No newline at end of file + - dicomseg-->[i:sid]/prostate158.seg.dcm From e003d046d80f7e15d6db58b08d2ff655029de13f Mon Sep 17 00:00:00 2001 From: Cosmin Ciausu Date: Mon, 22 Jan 2024 14:36:48 -0500 Subject: [PATCH 6/9] Update Prostate158Runner.py --- models/monai_prostate158/utils/Prostate158Runner.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/models/monai_prostate158/utils/Prostate158Runner.py b/models/monai_prostate158/utils/Prostate158Runner.py index 24a631ca..c0b42a5e 100644 --- a/models/monai_prostate158/utils/Prostate158Runner.py +++ b/models/monai_prostate158/utils/Prostate158Runner.py @@ -17,18 +17,16 @@ from mhubio.modules.runner.ModelRunner import ModelRunner import json -@IO.Config('apply_center_crop', bool, False, the='flag to apply center cropping to input_image') - -class Prostate158Runner(ModelRunner): +@IO.Config('apply_center_crop', bool, True, the='flag to apply center cropping to input_image') +class Prostate158Runner(Module): apply_center_crop : bool @IO.Instance() @IO.Input("in_data", 'nifti:mod=mr', the="input T2 sequence data to run prostate158 on") @IO.Output('out_data', 'monai_prostate158.nii.gz', - 'nifti:mod=seg:model=Prostate158:roi=PROSTATE_TRANSITION_ZONE,PROSTATE_PERIPHERAL_ZONE', + 'nifti:mod=seg:model=MonaiProstate158:roi=PROSTATE_TRANSITION_ZONE,PROSTATE_PERIPHERAL_ZONE', data='in_data', bundle='model', the="predicted segmentation model") - def task(self, instance: Instance, in_data: InstanceData, out_data: InstanceData) -> None: # bring input data in nnunet specific format From fca4f16b30bd99474ebdccf12744d0ad8b956dd4 Mon Sep 17 00:00:00 2001 From: Cosmin Ciausu Date: Mon, 22 Jan 2024 14:53:04 -0500 Subject: [PATCH 7/9] Update meta.json added external evaluation tables and references --- models/monai_prostate158/meta.json | 36 ++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/models/monai_prostate158/meta.json b/models/monai_prostate158/meta.json index 01f9514a..95092f2a 100644 --- a/models/monai_prostate158/meta.json +++ b/models/monai_prostate158/meta.json @@ -81,10 +81,32 @@ ] }, "evaluation": { - "title": "Evaluation Data", - "text": "The evaluation dataset consists of 20 internal validation samples.", - "tables": [], - "references": [] + "title": "External Evaluation Data", + "text": "The evaluation datasets consist of 186 ProstateX samples and 32 prostate MRI Medical Decathlon dataset samples.", + "tables": [ + { + "label": "Medical Decathlon mean DSC for the segmentation of the central gland and peripheral zone", + "entries": { + "Central gland": "0.82", + "Peripheral zone": "0.64" + } + }, + { + "label": "ProstateX mean DSC for the segmentation of the central gland and peripheral zone", + "entries": { + "Central gland": "0.86", + "Peripheral zone": "0.71" + } + } + ], + "references": [{ + "label": "Medical Segmentation Decathlon", + "uri": "https://www.nature.com/articles/s41467-022-30695-9" + }, + { + "label": "Quality control and whole-gland, zonal and lesion annotations for the PROSTATEx challenge public dataset", + "uri": "https://www.sciencedirect.com/science/article/abs/pii/S0720048X21001273" + }] }, "training": { "title": "Training Data", @@ -99,10 +121,6 @@ } ], "references": [ - { - "label": "Medical Segmentation Decathlon", - "uri": "https://www.nature.com/articles/s41467-022-30695-9" - }, { "label": "Prostate158 dataset (Zenodo access)", "uri": "https://zenodo.org/records/6481141" @@ -110,4 +128,4 @@ ] } } -} \ No newline at end of file +} From b4c696bb934cc24b2fdb9b5ab00e25a32510c1a7 Mon Sep 17 00:00:00 2001 From: Cosmin Ciausu Date: Fri, 1 Mar 2024 17:57:42 -0500 Subject: [PATCH 8/9] Update default.yml changed seg output name and added '%Modality' filter --- models/monai_prostate158/config/default.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/models/monai_prostate158/config/default.yml b/models/monai_prostate158/config/default.yml index b4284bbb..4f8c1a57 100644 --- a/models/monai_prostate158/config/default.yml +++ b/models/monai_prostate158/config/default.yml @@ -16,7 +16,7 @@ modules: import_dir: sorted_data sort_data: true meta: - mod: 'mr' + mod: '%Modality' NiftiConverter: in_datas: dicom:mod=mr @@ -33,4 +33,4 @@ modules: DataOrganizer: targets: - - dicomseg-->[i:sid]/prostate158.seg.dcm + - dicomseg-->[i:sid]/monai_prostate158.seg.dcm From ca2805b1dc87fee7f9db25bcfad88b2a05a28bcc Mon Sep 17 00:00:00 2001 From: Cosmin Ciausu Date: Fri, 1 Mar 2024 18:20:38 -0500 Subject: [PATCH 9/9] Update meta.json added license information --- models/monai_prostate158/meta.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/models/monai_prostate158/meta.json b/models/monai_prostate158/meta.json index 95092f2a..ad964732 100644 --- a/models/monai_prostate158/meta.json +++ b/models/monai_prostate158/meta.json @@ -47,14 +47,14 @@ "devteam": "Lisa C. Adams, Keno K. Bressem", "type": "Prostate158 (U-Net structure for prostate segmentation)", "date": { - "weights": "2022", - "code": "2022", - "pub": "2022" + "weights": "March 2022", + "code": "April 2022", + "pub": "September 2022" }, "cite": "Lisa C. Adams and Marcus R. Makowski and Günther Engel and Maximilian Rattunde and Felix Busch and Patrick Asbach and Stefan M. Niehues and Shankeeth Vinayahalingam and Bram {van Ginneken} and Geert Litjens and Keno K. Bressem, Prostate158 - An expert-annotated 3T MRI dataset and algorithm for prostate cancer detection", "license": { - "code": "Apache 2.0", - "weights": "" + "code": "MIT", + "weights": "CC BY-NC 4.0" }, "publications": [ {