Skip to content

MONet Bundle Integration into MONAI Deploy #543

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 218 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
218 commits
Select commit Hold shift + click to select a range
ed2a45c
Bump version: 0.3.0 → 0.4.0
MMelQin Jul 11, 2022
f84493f
Update release notes for v0.4.0
MMelQin Jul 11, 2022
e0f6780
Add the newly introduced example to readme.md (#313)
MMelQin Jul 13, 2022
fc81010
DOC: Use upstream/downstream instead of source/destination (#316)
Leengit Aug 1, 2022
e3418b2
Implement highdicom seg operator (#327)
CPBridge Aug 18, 2022
60de91b
Fix the setting of init state in its own PR, instead of rolled into o…
MMelQin Aug 22, 2022
5384e7d
Add highdicom license to the Third Party Notices (#334)
MMelQin Aug 24, 2022
f6b56a0
Improve STL operator so the enclosing app obj can run repetitively (#…
MMelQin Sep 14, 2022
d443c29
Added support of matching instance level tags, and update liver seg (…
MMelQin Sep 14, 2022
7053478
Nuance PIN MONAI Integration Example App (#328)
aihsani Sep 21, 2022
eb97cd4
minor adjustment for proper result alignment (#354)
aihsani Sep 21, 2022
aa4e52f
Nuance pin integration minor adjustments (#355)
aihsani Sep 21, 2022
f11a1a3
Enhance some attributes in the text SR writer (#346)
MMelQin Oct 3, 2022
ff526eb
Update executor path to new version (#135)
KavinKrishnan Oct 12, 2022
9614fe4
App SDK updated to be compatible with monai 1.0.0 and its MetaTensor …
MMelQin Oct 12, 2022
c6548f9
Minor typo in property method
diazandr3s Oct 13, 2022
cc98293
Update method name
diazandr3s Oct 13, 2022
a1f39cc
Add DICOM PDF Writer and split dicom_utils common module out of Text …
MMelQin Oct 13, 2022
b6f22be
Add the missing python package, PyPDF2 (#372)
MMelQin Oct 17, 2022
1c76efa
Enhanced multi-value DateElement parsing (#370)
MMelQin Oct 18, 2022
f76de96
Doc changes for addressing issues and for releasing App SDK v0.5 (#373)
MMelQin Oct 19, 2022
e3089ec
Add missed change (#374)
MMelQin Oct 19, 2022
1392e0a
Update notebook output after retest (#375)
MMelQin Oct 19, 2022
659b1d3
Various fixes to PIN integration example
Oct 13, 2022
c865b0a
Fix style errors
Oct 14, 2022
a13410c
Fix f-strings
Oct 14, 2022
39bfb35
Tweak to README
Oct 18, 2022
cbbb016
Release v0.5.0 (#376)
MMelQin Oct 19, 2022
d8e516f
Enhanced code to extract and parse specific config files from TorchSc…
MMelQin Oct 21, 2022
27aad68
Deprecate the MIS as it does not serve intended purpose (#379)
MMelQin Oct 22, 2022
f32441d
Fix app requirements to working version (#380)
aihsani Oct 25, 2022
2abdbb2
Merge Nuance Updates (#377)
iain-henderson Oct 25, 2022
52f695c
Add Pancreas Seg app, multi-model app, and Jupyter Notebook tutorial …
MMelQin Oct 27, 2022
401871c
Added breast density classifier app
Nov 1, 2022
17e650e
Fied formatting and readme
Nov 1, 2022
d29fca7
Fixed typo
Nov 1, 2022
86b2889
Added a Nifti data loader for issue #270
Oct 3, 2022
a4ad962
Quick fix to avoid package not found error by use optional import (#386)
MMelQin Nov 2, 2022
ca3f937
ENH: Versions as strings, not numbers, so that 3.1 != 3.10, etc. (#385)
Leengit Nov 3, 2022
26f65d9
Enhance Packager to make the MAP more secure, easier to use, and base…
MMelQin Nov 3, 2022
2ae514a
Make app.py's __main__ to init and run the app, as this is how MAP is…
MMelQin Nov 3, 2022
897e676
Update README.md
dbericat Nov 8, 2022
c25f54e
changed name from integrations to platforms (#390)
dbericat Nov 8, 2022
a599e94
Create Enhancement
MMelQin Nov 11, 2022
f27d90d
Update and rename Enhancement to enhancement_request.md
MMelQin Nov 11, 2022
24d661a
Create aide
dbericat Nov 14, 2022
fb1949f
Create mayo_cai_viewer
dbericat Nov 14, 2022
cb423fa
Rename aide to london_aicentre_aide
dbericat Nov 14, 2022
262444d
Make the output DICOM SR instance part of the original study
MMelQin Nov 12, 2022
eb8f02f
Use simple series selection rule on modality and image type
MMelQin Nov 12, 2022
8630d94
Delete london_aicentre_aide
hshuaib90 Nov 17, 2022
9513bf3
Create README.md
hshuaib90 Nov 17, 2022
8eac5b1
Add new image and update text
hshuaib90 Nov 29, 2022
7d45c67
Expose option to omit empty frames
Dec 7, 2022
1cdc076
Fix issue 410 where the latest typeguard version 3.x is incompatible …
MMelQin Mar 23, 2023
8f03e32
Update enhancement_request.md
MMelQin Mar 23, 2023
447ebc5
enable AMD GPU (#406)
vickytsang Apr 6, 2023
cfe663a
Fix broken links in Readme (#432)
MMelQin Jun 5, 2023
0b95a7c
Update importutil.py (#436)
filipmu Jul 5, 2023
83f4559
Added option for SimpleInferer (#428)
vikashg Jul 6, 2023
94c4b02
Updated the mednist notebooks adding the dependencies of pydicom and …
MMelQin Jul 7, 2023
00d8462
Update pr.yml
MMelQin Jul 11, 2023
83efc3d
Update SDK to support typeguard v3.0 and above, which has a breaking …
MMelQin Jul 12, 2023
907319f
Update Read The Docs configuration to support Python 3.8 (#439)
gigony Jul 13, 2023
34859a3
Bump version: 0.5.0 → 0.5.1
MMelQin Jul 13, 2023
b7fddfb
Create aws_healthimaging.md (#449)
flamingofugang Aug 31, 2023
03bcc40
App SDK Migration (to depend on Holoscan SDK) (#441)
MMelQin Aug 31, 2023
66e7142
Merge V0.6 release notes to main (#452)
MMelQin Sep 1, 2023
a1438f0
test build
MMelQin Nov 17, 2023
300fe19
Address a removed monai function, fix CUDA 11 runtime lib, and resurr…
MMelQin Nov 17, 2023
98dff55
Update pr.yml to pip install cuda12 runtime
MMelQin Apr 9, 2024
5978263
Update pr.yml
MMelQin Apr 9, 2024
8ff73f8
Update pr.yml
MMelQin Apr 9, 2024
edc70d1
Update pr.yml
MMelQin Apr 10, 2024
4123c92
Update pr.yml
MMelQin Apr 10, 2024
e084b4e
Update pr.yml
MMelQin Apr 10, 2024
1f54d1d
Updating the SDK to use newer and updated dependencies, namely Holosc…
MMelQin Apr 11, 2024
919912b
Releasing and tagging V1.0 (#482)
MMelQin Apr 12, 2024
8467932
test out the minimal set of reqs
MMelQin Apr 12, 2024
680f00d
Update readthedocs configuration
gigony Apr 12, 2024
e114513
removed the commented out reqs
MMelQin Apr 12, 2024
d5d5957
Fix package and LD_LIBRARY_PATH issues for readthedocs
gigony Apr 12, 2024
9c4612f
Update pr.yml to set LD_LIBRARY_PATH consistently with Holoscan SDK 2.0
MMelQin Apr 17, 2024
4e1b32b
Update to release v2.0 that is dependent on HSDK v2 (#485)
MMelQin Apr 24, 2024
65f6693
V2.0 (#487)
MMelQin Apr 25, 2024
b1a5c4a
Changes to v2 release did not get saved (#488)
MMelQin Apr 25, 2024
e8fadf2
Fix breast density example application to make it work with SDK v0.6+…
MMelQin Jun 5, 2024
08e789a
Adding missed step for setting input env var to fix the doc issue (#496)
MMelQin Jul 2, 2024
d74e0c2
Update example apps' test data path, patch hsdk in local env, and ens…
MMelQin Jan 17, 2025
5efee16
DICOM Seg Writer operater: Fix for case where input image is already …
CPBridge Jan 23, 2025
7528d9c
Update tutorials after testing with holoscan v2.9.0 (#522)
MMelQin Jan 31, 2025
5632b9c
Update README.md (#499)
vikashg Feb 4, 2025
0e386e9
DICOMSeriesSelectorOperator Enhancements (#501)
bluna301 Feb 4, 2025
f677275
Added a sample integration for LLM models in huggingface (#494)
vikashg Feb 5, 2025
e65ec33
Editorial changes to correct typos, rename parameters, and add commen…
MMelQin Feb 13, 2025
16c4b6f
slice removal fix (#527)
bluna301 Feb 25, 2025
558cfec
Add nnUNet segmentation application and dependencies
SimoneBendazzoli93 Apr 2, 2025
1887fb7
CCHMC Ped Abd CT Seg Example App (#525)
bluna301 Mar 27, 2025
c359a04
Fix meta_data handling in MonaiBundleInferenceOperator to ensure it d…
SimoneBendazzoli93 Apr 10, 2025
ee9a3e6
Update requirements and fix data shape handling in Monai nUNet Bundle…
SimoneBendazzoli93 Apr 16, 2025
e72535b
Add NiftiDataWriter operator and update NiftiDataLoader to return Sim…
SimoneBendazzoli93 Apr 16, 2025
51f5b21
Add nvflare to requirements for ai_spleen_nnunet_seg_app
SimoneBendazzoli93 Apr 22, 2025
a0835ea
duplicate ipps non-loaded (#535)
bluna301 Apr 21, 2025
fdec500
ModelInfo arg added to DICOMSegWriterOp (#533)
bluna301 Apr 21, 2025
0774906
Support remote inference on Triton Inference Server with ease of use …
MMelQin Apr 21, 2025
9d90ea1
Fix DICOMSeriesToVolumeOperator casting bug (#529)
WillButAgain Apr 22, 2025
eecb747
Formatting changes and tag value for unsigned int is 0 (#537)
MMelQin Apr 22, 2025
75c2a53
Prepared changes for releasing v3 (#538)
MMelQin Apr 23, 2025
cff8edf
Fix _version.py and various version-related issues (#539)
MMelQin Apr 23, 2025
f7ef3fd
Bump version: 2.0.0 → 3.0.0 (#540)
MMelQin Apr 23, 2025
5e7f12a
Fix NiftiDataWriter spacing handling for 1mm pixel dimensions
SimoneBendazzoli93 May 12, 2025
7dc2ed8
Refactor nnUNet bundle inference operator to MONetBundleInferenceOper…
SimoneBendazzoli93 Jun 17, 2025
4aa297d
Update documentation to reflect changes from nnUNet to MONet Bundle i…
SimoneBendazzoli93 Jun 17, 2025
65bb871
Refactor import statements in app.py and monet_bundle_inference_opera…
SimoneBendazzoli93 Jun 17, 2025
9c5aca7
Update application title and fix operator name in imports for MONet B…
SimoneBendazzoli93 Jun 17, 2025
96d30b7
Refactor NiftiDataLoader to return transposed numpy array from NIfTI …
SimoneBendazzoli93 Jun 17, 2025
e80ecde
Remove NiftiDataWriter operator and clean up imports in __init__.py
SimoneBendazzoli93 Jun 17, 2025
225f9eb
Remove SimpleITK image handling from MonaiBundleInferenceOperator
SimoneBendazzoli93 Jun 17, 2025
c512780
Fix import statement for MONetBundleInferenceOperator to use the corr…
SimoneBendazzoli93 Jun 24, 2025
e6cf4ac
Fix _version.py and various version-related issues (#539)
MMelQin Apr 23, 2025
dbe645c
Bump version: 2.0.0 → 3.0.0 (#540)
MMelQin Apr 23, 2025
6eab3d9
Fix formatting in docstring and remove unused import statements in MO…
SimoneBendazzoli93 Jun 26, 2025
99eb8c9
Enhance predict method to support multimodal data concatenation and u…
SimoneBendazzoli93 Jun 26, 2025
1447f5a
Add NiftiDataWriter operator and update NiftiDataLoader to return Sim…
SimoneBendazzoli93 Apr 16, 2025
86628e6
Fix _version.py and various version-related issues (#539)
MMelQin Apr 23, 2025
8c76e99
Bump version: 2.0.0 → 3.0.0 (#540)
MMelQin Apr 23, 2025
22085d5
Fix NiftiDataWriter spacing handling for 1mm pixel dimensions
SimoneBendazzoli93 May 12, 2025
560cd44
Update application title and fix operator name in imports for MONet B…
SimoneBendazzoli93 Jun 17, 2025
adab674
Refactor NiftiDataLoader to return transposed numpy array from NIfTI …
SimoneBendazzoli93 Jun 17, 2025
6236a19
Remove NiftiDataWriter operator and clean up imports in __init__.py
SimoneBendazzoli93 Jun 17, 2025
b0d12d7
Remove SimpleITK image handling from MonaiBundleInferenceOperator
SimoneBendazzoli93 Jun 17, 2025
4ec9dba
Fix _version.py and various version-related issues (#539)
MMelQin Apr 23, 2025
ca73591
Bump version: 2.0.0 → 3.0.0 (#540)
MMelQin Apr 23, 2025
6c0f134
test build
MMelQin Nov 17, 2023
d017501
Address a removed monai function, fix CUDA 11 runtime lib, and resurr…
MMelQin Nov 17, 2023
a917623
Update pr.yml to pip install cuda12 runtime
MMelQin Apr 9, 2024
2371476
Update pr.yml
MMelQin Apr 9, 2024
8f74f43
Update pr.yml
MMelQin Apr 9, 2024
a7bd084
Update pr.yml
MMelQin Apr 10, 2024
cb116b1
Update pr.yml
MMelQin Apr 10, 2024
ae22e88
Update pr.yml
MMelQin Apr 10, 2024
0634f2c
Updating the SDK to use newer and updated dependencies, namely Holosc…
MMelQin Apr 11, 2024
17c997c
Releasing and tagging V1.0 (#482)
MMelQin Apr 12, 2024
a3ff417
test out the minimal set of reqs
MMelQin Apr 12, 2024
1261b8a
Update readthedocs configuration
gigony Apr 12, 2024
b542174
removed the commented out reqs
MMelQin Apr 12, 2024
111569d
Fix package and LD_LIBRARY_PATH issues for readthedocs
gigony Apr 12, 2024
61f3a67
Update pr.yml to set LD_LIBRARY_PATH consistently with Holoscan SDK 2.0
MMelQin Apr 17, 2024
7bebf05
Update to release v2.0 that is dependent on HSDK v2 (#485)
MMelQin Apr 24, 2024
e9d5050
V2.0 (#487)
MMelQin Apr 25, 2024
7748e49
Changes to v2 release did not get saved (#488)
MMelQin Apr 25, 2024
55036a2
Fix breast density example application to make it work with SDK v0.6+…
MMelQin Jun 5, 2024
07ea1f7
Adding missed step for setting input env var to fix the doc issue (#496)
MMelQin Jul 2, 2024
ef25d17
Update example apps' test data path, patch hsdk in local env, and ens…
MMelQin Jan 17, 2025
10c8459
DICOM Seg Writer operater: Fix for case where input image is already …
CPBridge Jan 23, 2025
eb9eb70
Update tutorials after testing with holoscan v2.9.0 (#522)
MMelQin Jan 31, 2025
05966bb
Update README.md (#499)
vikashg Feb 4, 2025
76d8dc3
Added a sample integration for LLM models in huggingface (#494)
vikashg Feb 5, 2025
104c4e7
Editorial changes to correct typos, rename parameters, and add commen…
MMelQin Feb 13, 2025
489d105
Add nnUNet segmentation application and dependencies
SimoneBendazzoli93 Apr 2, 2025
140e652
CCHMC Ped Abd CT Seg Example App (#525)
bluna301 Mar 27, 2025
46ea98e
Update requirements and fix data shape handling in Monai nUNet Bundle…
SimoneBendazzoli93 Apr 16, 2025
9aadccf
Add NiftiDataWriter operator and update NiftiDataLoader to return Sim…
SimoneBendazzoli93 Apr 16, 2025
3fe4a3f
Add nvflare to requirements for ai_spleen_nnunet_seg_app
SimoneBendazzoli93 Apr 22, 2025
d94b4aa
duplicate ipps non-loaded (#535)
bluna301 Apr 21, 2025
c0f75e9
ModelInfo arg added to DICOMSegWriterOp (#533)
bluna301 Apr 21, 2025
da9939f
Support remote inference on Triton Inference Server with ease of use …
MMelQin Apr 21, 2025
112723d
Fix DICOMSeriesToVolumeOperator casting bug (#529)
WillButAgain Apr 22, 2025
57a9481
Formatting changes and tag value for unsigned int is 0 (#537)
MMelQin Apr 22, 2025
c89a0b9
Prepared changes for releasing v3 (#538)
MMelQin Apr 23, 2025
26114a2
Fix _version.py and various version-related issues (#539)
MMelQin Apr 23, 2025
a892131
Bump version: 2.0.0 → 3.0.0 (#540)
MMelQin Apr 23, 2025
1cefd11
Fix NiftiDataWriter spacing handling for 1mm pixel dimensions
SimoneBendazzoli93 May 12, 2025
7dd1975
Refactor nnUNet bundle inference operator to MONetBundleInferenceOper…
SimoneBendazzoli93 Jun 17, 2025
4389ef5
Update documentation to reflect changes from nnUNet to MONet Bundle i…
SimoneBendazzoli93 Jun 17, 2025
e0b99dc
Refactor import statements in app.py and monet_bundle_inference_opera…
SimoneBendazzoli93 Jun 17, 2025
14d7101
Update application title and fix operator name in imports for MONet B…
SimoneBendazzoli93 Jun 17, 2025
aa78d07
Refactor NiftiDataLoader to return transposed numpy array from NIfTI …
SimoneBendazzoli93 Jun 17, 2025
183be50
Remove NiftiDataWriter operator and clean up imports in __init__.py
SimoneBendazzoli93 Jun 17, 2025
fef8593
Remove SimpleITK image handling from MonaiBundleInferenceOperator
SimoneBendazzoli93 Jun 17, 2025
9e9fc97
Fix import statement for MONetBundleInferenceOperator to use the corr…
SimoneBendazzoli93 Jun 24, 2025
33f4a75
Fix _version.py and various version-related issues (#539)
MMelQin Apr 23, 2025
0a75061
Bump version: 2.0.0 → 3.0.0 (#540)
MMelQin Apr 23, 2025
e548447
Fix formatting in docstring and remove unused import statements in MO…
SimoneBendazzoli93 Jun 26, 2025
b2838de
Enhance predict method to support multimodal data concatenation and u…
SimoneBendazzoli93 Jun 26, 2025
e1f702e
Add nnUNet segmentation application and dependencies
SimoneBendazzoli93 Apr 2, 2025
fb74df5
CCHMC Ped Abd CT Seg Example App (#525)
bluna301 Mar 27, 2025
6bd4fcc
Update requirements and fix data shape handling in Monai nUNet Bundle…
SimoneBendazzoli93 Apr 16, 2025
b28b0ee
Add NiftiDataWriter operator and update NiftiDataLoader to return Sim…
SimoneBendazzoli93 Apr 16, 2025
9ec0ea5
Add nvflare to requirements for ai_spleen_nnunet_seg_app
SimoneBendazzoli93 Apr 22, 2025
15931b4
Support remote inference on Triton Inference Server with ease of use …
MMelQin Apr 21, 2025
6f5570e
Fix DICOMSeriesToVolumeOperator casting bug (#529)
WillButAgain Apr 22, 2025
2d48751
Formatting changes and tag value for unsigned int is 0 (#537)
MMelQin Apr 22, 2025
bf8d361
Prepared changes for releasing v3 (#538)
MMelQin Apr 23, 2025
3d9f752
Fix _version.py and various version-related issues (#539)
MMelQin Apr 23, 2025
677c8a9
Bump version: 2.0.0 → 3.0.0 (#540)
MMelQin Apr 23, 2025
9036d24
Fix NiftiDataWriter spacing handling for 1mm pixel dimensions
SimoneBendazzoli93 May 12, 2025
292c70c
Refactor nnUNet bundle inference operator to MONetBundleInferenceOper…
SimoneBendazzoli93 Jun 17, 2025
58f7a29
Update documentation to reflect changes from nnUNet to MONet Bundle i…
SimoneBendazzoli93 Jun 17, 2025
8656d2d
Refactor import statements in app.py and monet_bundle_inference_opera…
SimoneBendazzoli93 Jun 17, 2025
d08f35f
Update application title and fix operator name in imports for MONet B…
SimoneBendazzoli93 Jun 17, 2025
7941da9
Refactor NiftiDataLoader to return transposed numpy array from NIfTI …
SimoneBendazzoli93 Jun 17, 2025
f6e3e64
Remove NiftiDataWriter operator and clean up imports in __init__.py
SimoneBendazzoli93 Jun 17, 2025
3ff1250
Remove SimpleITK image handling from MonaiBundleInferenceOperator
SimoneBendazzoli93 Jun 17, 2025
8b4d4ac
Fix import statement for MONetBundleInferenceOperator to use the corr…
SimoneBendazzoli93 Jun 24, 2025
5724bbe
CCHMC Ped Abd CT Seg Example App (#525)
bluna301 Mar 27, 2025
4c5e506
Support remote inference on Triton Inference Server with ease of use …
MMelQin Apr 21, 2025
111f5c3
Prepared changes for releasing v3 (#538)
MMelQin Apr 23, 2025
d8da34f
Fix _version.py and various version-related issues (#539)
MMelQin Apr 23, 2025
6011478
Bump version: 2.0.0 → 3.0.0 (#540)
MMelQin Apr 23, 2025
56155c0
Fix formatting in docstring and remove unused import statements in MO…
SimoneBendazzoli93 Jun 26, 2025
343e5fd
Enhance predict method to support multimodal data concatenation and u…
SimoneBendazzoli93 Jun 26, 2025
75fe572
DICOMSeriesSelectorOperator Improvements (#542)
bluna301 Jun 27, 2025
3b127ed
Regression tests with HSDK 3.4 and CLI 3.4.1 (#545)
MMelQin Jul 14, 2025
dcc20c8
Merge branch 'main' into main
SimoneBendazzoli93 Jul 17, 2025
44803a2
Remove unused import
SimoneBendazzoli93 Jul 17, 2025
7804d84
Add method to set model network for nnUNet predictor and validate inp…
SimoneBendazzoli93 Jul 17, 2025
fe15cf6
Merge branch 'Project-MONAI:main' into main
SimoneBendazzoli93 Aug 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions examples/apps/ai_spleen_nnunet_seg_app/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2021-2023 MONAI Consortium
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import sys

_current_dir = os.path.abspath(os.path.dirname(__file__))
if sys.path and os.path.abspath(sys.path[0]) != _current_dir:
sys.path.insert(0, _current_dir)
del _current_dir
19 changes: 19 additions & 0 deletions examples/apps/ai_spleen_nnunet_seg_app/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copyright 2021-2023 MONAI Consortium
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import logging

from app import AISpleennnUNetSegApp

if __name__ == "__main__":
logging.info(f"Begin {__name__}")
AISpleennnUNetSegApp().run()
logging.info(f"End {__name__}")
163 changes: 163 additions & 0 deletions examples/apps/ai_spleen_nnunet_seg_app/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
# Copyright 2021-2023 MONAI Consortium
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import logging
from pathlib import Path

from pydicom.sr.codedict import codes

from monai.deploy.conditions import CountCondition
from monai.deploy.core import AppContext, Application
from monai.deploy.core.domain import Image
from monai.deploy.core.io_type import IOType
from monai.deploy.operators.dicom_data_loader_operator import DICOMDataLoaderOperator
from monai.deploy.operators.dicom_seg_writer_operator import DICOMSegmentationWriterOperator, SegmentDescription
from monai.deploy.operators.dicom_series_selector_operator import DICOMSeriesSelectorOperator
from monai.deploy.operators.dicom_series_to_volume_operator import DICOMSeriesToVolumeOperator
from monai.deploy.operators.monai_bundle_inference_operator import BundleConfigNames, IOMapping
from monai.deploy.operators.monet_bundle_inference_operator import MONetBundleInferenceOperator
from monai.deploy.operators.stl_conversion_operator import STLConversionOperator


# @resource(cpu=1, gpu=1, memory="7Gi")
# pip_packages can be a string that is a path(str) to requirements.txt file or a list of packages.
# The monai pkg is not required by this class, instead by the included operators.
class AISpleennnUNetSegApp(Application):
"""Demonstrates inference with built-in MONet Bundle inference operator with DICOM files as input/output

This application loads a set of DICOM instances, select the appropriate series, converts the series to
3D volume image, performs inference with the built-in MONet Bundle inference operator, including nnUNet resampling, pre-processing
and post-processing, save the segmentation image in a DICOM Seg OID in an instance file, and optionally the
surface mesh in STL format.

Pertinent nnUNet MONAI Bundle:
<Upload to the MONAI Model Zoo>

Execution Time Estimate:
With a Nvidia RTXA600 48GB GPU, for an input DICOM Series of size 106x415x415 and patches of size 64x192x160, the execution time is around
50 seconds with saving both DICOM Seg and surface mesh STL file.
"""

def __init__(self, *args, **kwargs):
"""Creates an application instance."""
self._logger = logging.getLogger("{}.{}".format(__name__, type(self).__name__))
super().__init__(*args, **kwargs)

def run(self, *args, **kwargs):
# This method calls the base class to run. Can be omitted if simply calling through.
self._logger.info(f"Begin {self.run.__name__}")
super().run(*args, **kwargs)
self._logger.info(f"End {self.run.__name__}")

def compose(self):
"""Creates the app specific operators and chain them up in the processing DAG."""

logging.info(f"Begin {self.compose.__name__}")

# Use Commandline options over environment variables to init context.
app_context: AppContext = Application.init_app_context(self.argv)
app_input_path = Path(app_context.input_path)
app_output_path = Path(app_context.output_path)

# Create the custom operator(s) as well as SDK built-in operator(s).
study_loader_op = DICOMDataLoaderOperator(
self, CountCondition(self, 1), input_folder=app_input_path, name="study_loader_op"
)
series_selector_op = DICOMSeriesSelectorOperator(self, rules=Sample_Rules_Text, name="series_selector_op")
series_to_vol_op = DICOMSeriesToVolumeOperator(self, name="series_to_vol_op")

# Create the inference operator that supports MONAI Bundle and automates the inference.
# The IOMapping labels match the input and prediction keys in the pre and post processing.
# The model_name is optional when the app has only one model.
# The bundle_path argument optionally can be set to an accessible bundle file path in the dev
# environment, so when the app is packaged into a MAP, the operator can complete the bundle parsing
# during init.

config_names = BundleConfigNames(config_names=["inference"]) # Same as the default

bundle_spleen_seg_op = MONetBundleInferenceOperator(
self,
input_mapping=[IOMapping("image", Image, IOType.IN_MEMORY)],
output_mapping=[IOMapping("pred", Image, IOType.IN_MEMORY)],
app_context=app_context,
bundle_config_names=config_names,
name="nnunet_bundle_spleen_seg_op",
)

# Create DICOM Seg writer providing the required segment description for each segment with
# the actual algorithm and the pertinent organ/tissue. The segment_label, algorithm_name,
# and algorithm_version are of DICOM VR LO type, limited to 64 chars.
# https://dicom.nema.org/medical/dicom/current/output/chtml/part05/sect_6.2.html
segment_descriptions = [
SegmentDescription(
segment_label="Spleen",
segmented_property_category=codes.SCT.Organ,
segmented_property_type=codes.SCT.Spleen,
algorithm_name="volumetric (3D) segmentation of the spleen from CT image",
algorithm_family=codes.DCM.ArtificialIntelligence,
algorithm_version="0.3.2",
)
]

custom_tags = {"SeriesDescription": "AI generated Seg, not for clinical use."}

dicom_seg_writer = DICOMSegmentationWriterOperator(
self,
segment_descriptions=segment_descriptions,
custom_tags=custom_tags,
output_folder=app_output_path,
name="dicom_seg_writer",
)

# Create the processing pipeline, by specifying the source and destination operators, and
# ensuring the output from the former matches the input of the latter, in both name and type.
self.add_flow(study_loader_op, series_selector_op, {("dicom_study_list", "dicom_study_list")})
self.add_flow(
series_selector_op, series_to_vol_op, {("study_selected_series_list", "study_selected_series_list")}
)
self.add_flow(series_to_vol_op, bundle_spleen_seg_op, {("image", "image")})
# Note below the dicom_seg_writer requires two inputs, each coming from a source operator.
self.add_flow(
series_selector_op, dicom_seg_writer, {("study_selected_series_list", "study_selected_series_list")}
)
self.add_flow(bundle_spleen_seg_op, dicom_seg_writer, {("pred", "seg_image")})
# Create the surface mesh STL conversion operator and add it to the app execution flow, if needed, by
# uncommenting the following couple lines.
stl_conversion_op = STLConversionOperator(
self, output_file=app_output_path.joinpath("stl/spleen.stl"), name="stl_conversion_op"
)
self.add_flow(bundle_spleen_seg_op, stl_conversion_op, {("pred", "image")})

logging.info(f"End {self.compose.__name__}")


# This is a sample series selection rule in JSON, simply selecting CT series.
# If the study has more than 1 CT series, then all of them will be selected.
# Please see more detail in DICOMSeriesSelectorOperator.
Sample_Rules_Text = """
{
"selections": [
{
"name": "CT Series",
"conditions": {
"StudyDescription": "(.*?)",
"Modality": "(?i)CT",
"SeriesDescription": "(.*?)"
}
}
]
}
"""

if __name__ == "__main__":
logging.info(f"Begin {__name__}")
AISpleennnUNetSegApp().run()
logging.info(f"End {__name__}")
27 changes: 27 additions & 0 deletions examples/apps/ai_spleen_nnunet_seg_app/app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
%YAML 1.2
# SPDX-FileCopyrightText: Copyright (c) 2022-2023 MONAI. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
application:
title: MONAI Deploy App Package - Spleen MONet Seg Inference
version: 1.0
inputFormats: ["file"]
outputFormats: ["file"]

resources:
cpu: 1
gpu: 1
memory: 1Gi
gpuMemory: 7Gi
13 changes: 13 additions & 0 deletions examples/apps/ai_spleen_nnunet_seg_app/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
scikit-image>=0.17.2
pydicom>=2.3.0
highdicom>=0.18.2
SimpleITK>=2.0.0
Pillow>=8.0.0
numpy-stl>=2.12.0
trimesh>=3.8.11
nibabel>=3.2.1
torch>=1.12.0
nvflare
git+https://github.com/SimoneBendazzoli93/dynamic-network-architectures.git
Copy link
Preview

Copilot AI Jun 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Including dependencies directly from forks may hinder reproducibility; consider pinning to a stable release or official package versions.

Copilot uses AI. Check for mistakes.

git+https://github.com/SimoneBendazzoli93/MONAI.git@dev
git+https://github.com/SimoneBendazzoli93/nnUNet.git
2 changes: 2 additions & 0 deletions monai/deploy/operators/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
IOMapping
ModelInfo
MonaiBundleInferenceOperator
MONetBundleInferenceOperator
MonaiSegInferenceOperator
PNGConverterOperator
PublisherOperator
Expand All @@ -48,6 +49,7 @@
from .inference_operator import InferenceOperator
from .monai_bundle_inference_operator import BundleConfigNames, IOMapping, MonaiBundleInferenceOperator
from .monai_seg_inference_operator import MonaiSegInferenceOperator
from .monet_bundle_inference_operator import MONetBundleInferenceOperator
from .nii_data_loader_operator import NiftiDataLoader
from .png_converter_operator import PNGConverterOperator
from .publisher_operator import PublisherOperator
Expand Down
5 changes: 3 additions & 2 deletions monai/deploy/operators/monai_bundle_inference_operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def get_bundle_config(bundle_path, config_names):
Gets the configuration parser from the specified Torchscript bundle file path.
"""

bundle_suffixes = (".json", ".yaml", "yml") # The only supported file ext(s)
bundle_suffixes = (".json", ".yaml", ".yml") # The only supported file ext(s)
config_folder = "extra"

def _read_from_archive(archive, root_name: str, config_name: str, do_search=True):
Expand Down Expand Up @@ -90,7 +90,7 @@ def _read_from_archive(archive, root_name: str, config_name: str, do_search=True
name_list = archive.namelist()
for suffix in bundle_suffixes:
for n in name_list:
if (f"{config_name}{suffix}").casefold in n.casefold():
if (f"{config_name}{suffix}").casefold() in n.casefold():
logging.debug(f"Trying to read content of config {config_name!r} from {n!r}.")
content_text = archive.read(n)
break
Expand Down Expand Up @@ -577,6 +577,7 @@ def compute(self, op_input, op_output, context):
# value: NdarrayOrTensor # MyPy complaints
value, meta_data = self._receive_input(name, op_input, context)
value = convert_to_dst_type(value, dst=value)[0]
meta_data = meta_data or {}
if not isinstance(meta_data, dict):
raise ValueError("`meta_data` must be a dict.")
value = MetaTensor.ensure_torch_and_prune_meta(value, meta_data)
Expand Down
91 changes: 91 additions & 0 deletions monai/deploy/operators/monet_bundle_inference_operator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Copyright 2002 MONAI Consortium
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import Any, Dict, Tuple, Union

from monai.deploy.core import Image
from monai.deploy.operators.monai_bundle_inference_operator import MonaiBundleInferenceOperator, get_bundle_config
from monai.deploy.utils.importutil import optional_import
from monai.transforms import ConcatItemsd, ResampleToMatch

torch, _ = optional_import("torch", "1.10.2")
MetaTensor, _ = optional_import("monai.data.meta_tensor", name="MetaTensor")
__all__ = ["MONetBundleInferenceOperator"]


class MONetBundleInferenceOperator(MonaiBundleInferenceOperator):
"""
A specialized operator for performing inference using the MONet bundle.
This operator extends the `MonaiBundleInferenceOperator` to support nnUNet-specific
configurations and prediction logic. It initializes the nnUNet predictor and provides
a method for performing inference on input data.

Attributes
----------
_nnunet_predictor : torch.nn.Module
The nnUNet predictor module used for inference.

Methods
-------
_init_config(config_names)
Initializes the configuration for the nnUNet bundle, including parsing the bundle
configuration and setting up the nnUNet predictor.
predict(data, *args, **kwargs)
Performs inference on the input data using the nnUNet predictor.
"""

def __init__(
self,
*args,
**kwargs,
):

super().__init__(*args, **kwargs)

self._nnunet_predictor: torch.nn.Module = None

def _init_config(self, config_names):

super()._init_config(config_names)
parser = get_bundle_config(str(self._bundle_path), config_names)
self._parser = parser

self._nnunet_predictor = parser.get_parsed_content("network_def")

def _set_model_network(self, model_network):
"""
Sets the model network for the nnUNet predictor.

Parameters
----------
model_network : torch.nn.Module or torch.jit.ScriptModule
The model network to be used for inference.
"""
if not isinstance(model_network, torch.nn.Module) and not torch.jit.isinstance(model_network, torch.jit.ScriptModule):
raise TypeError("model_network must be an instance of torch.nn.Module or torch.jit.ScriptModule")
self._model_network = model_network

def predict(self, data: Any, *args, **kwargs) -> Union[Image, Any, Tuple[Any, ...], Dict[Any, Any]]:
"""Predicts output using the inferer. If multimodal data is provided as keyword arguments,
it concatenates the data with the main input data."""

self._set_model_network(self._nnunet_predictor)

if len(kwargs) > 0:
multimodal_data = {"image": data}
for key in kwargs.keys():
if isinstance(kwargs[key], MetaTensor):
multimodal_data[key] = ResampleToMatch(mode="bilinear")(kwargs[key], img_dst=data
)
data = ConcatItemsd(keys=list(multimodal_data.keys()),name="image")(multimodal_data)["image"]
if len(data.shape) == 4:
data = data[None]
return self._nnunet_predictor(data)