Skip to content

Commit 3173303

Browse files
committed
Editorial changes to correct typos, rename parameters, adding comments. Retested examples.
Signed-off-by: M Q <mingmelvinq@nvidia.com>
1 parent caf9790 commit 3173303

18 files changed

+74
-65
lines changed

examples/apps/ai_unetr_seg_app/app.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def compose(self):
8080
_algorithm_family = codes.DCM.ArtificialIntelligence
8181
_algorithm_version = "0.1.0"
8282

83-
# List of (Segment name, [Code menaing str]), not including background which is value of 0.
83+
# List of (Segment name, [Code meaning str]), not including background which is value of 0.
8484
# User must provide correct codes, which can be looked at, e.g.
8585
# https://bioportal.bioontology.org/ontologies/SNOMEDCT
8686
# Alternatively, consult the concept and code dictionaries in PyDicom

examples/apps/ai_unetr_seg_app/unetr_seg_operator.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class UnetrSegOperator(Operator):
5656

5757
def __init__(
5858
self,
59-
frament: Fragment,
59+
fragment: Fragment,
6060
*args,
6161
app_context: AppContext,
6262
model_path: Path,
@@ -71,13 +71,13 @@ def __init__(
7171
self.model_path = model_path
7272
self.output_folder = output_folder
7373
self.output_folder.mkdir(parents=True, exist_ok=True)
74-
self.fragement = frament # Cache and later pass the Fragment/Application to contained operator(s)
74+
self.app_fragment = fragment # Cache and later pass the Fragment/Application to contained operator(s)
7575
self.app_context = app_context
7676
self.input_name_image = "image"
7777
self.output_name_seg = "seg_image"
7878
self.output_name_saved_images_folder = "saved_images_folder"
7979

80-
super().__init__(frament, *args, **kwargs)
80+
super().__init__(fragment, *args, **kwargs)
8181

8282
def setup(self, spec: OperatorSpec):
8383
spec.input(self.input_name_image)
@@ -102,7 +102,7 @@ def compute(self, op_input, op_output, context):
102102

103103
# Delegates inference and saving output to the built-in operator.
104104
infer_operator = MonaiSegInferenceOperator(
105-
self.fragement,
105+
self.app_fragment,
106106
roi_size=(
107107
96,
108108
96,

examples/apps/breast_density_classifier_app/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Sample data and a torchscript model can be downloaded from https://drive.google.
99
python app.py -i <input_dir> -o <out_dir> -m <breast_density_model>
1010
```
1111

12-
## Package the application as a MONAI Application Package (contianer image)
12+
## Package the application as a MONAI Application Package (container image)
1313
In order to build the MONAI App Package, go a level up and execute the following command.
1414
```
1515
monai-deploy package breast_density_classification_app -m <breast_density_model> -c breast_density_classifer_app/app.yaml --tag breast_density:0.1.0 --platform x64-workstation -l DEBUG
@@ -20,4 +20,4 @@ monai-deploy package breast_density_classification_app -m <breast_density_model>
2020
monai-deploy run breast_density-x64-workstation-dgpu-linux-amd64:0.1.0 -i <input_dir> -o <output_dir>
2121
```
2222

23-
Once the container exits successfully, check the results in the output directory. There should be a newly creeated DICOM instance file and a `output.json` file containing the classification results.
23+
Once the container exits successfully, check the results in the output directory. There should be a newly created DICOM instance file and a `output.json` file containing the classification results.

examples/apps/breast_density_classifier_app/breast_density_classifier_operator.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class ClassifierOperator(Operator):
4040

4141
def __init__(
4242
self,
43-
frament: Fragment,
43+
fragment: Fragment,
4444
*args,
4545
model_name: Optional[str] = "",
4646
app_context: AppContext,
@@ -67,7 +67,7 @@ def __init__(
6767
# The name of the optional input port for passing data to override the output folder path.
6868
self.input_name_output_folder = "output_folder"
6969

70-
# The output folder set on the object can be overriden at each compute by data in the optional named input
70+
# The output folder set on the object can be overridden at each compute by data in the optional named input
7171
self.output_folder = output_folder
7272

7373
# Need the name when there are multiple models loaded
@@ -80,7 +80,7 @@ def __init__(
8080

8181
self.model = self._get_model(self.app_context, self.model_path, self._model_name)
8282

83-
super().__init__(frament, *args, **kwargs)
83+
super().__init__(fragment, *args, **kwargs)
8484

8585
def _get_model(self, app_context: AppContext, model_path: Path, model_name: str):
8686
"""Load the model with the given name from context or model path
@@ -116,7 +116,7 @@ def _convert_dicom_metadata_datatype(self, metadata: Dict):
116116
if not metadata:
117117
return metadata
118118

119-
# Try to convert data type for the well knowned attributes. Add more as needed.
119+
# Try to convert data type for the well known attributes. Add more as needed.
120120
if metadata.get("SeriesInstanceUID", None):
121121
try:
122122
metadata["SeriesInstanceUID"] = str(metadata["SeriesInstanceUID"])
Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,38 @@
1-
import logging
1+
import argparse
2+
import logging
23
from pathlib import Path
3-
import torch
4+
5+
import numpy as np
6+
import torch
47
from diffusers import StableDiffusionPipeline
5-
from monai.deploy.core import AppContext, Application
68
from PIL import Image
7-
import numpy as np
8-
import argparse
99

10+
from monai.deploy.core import AppContext, Application
1011

1112

1213
class App(Application):
13-
name = "Diffusion Image App"
14-
description = "Simple application showing diffusion to generate Images"
15-
def compose(self):
16-
model_id = "Nihirc/Prompt2MedImage"
17-
device = "cuda"
18-
parser = argparse.ArgumentParser()
19-
parser.add_argument("--input_prompt", type=str, default="Generate a X-ray")
20-
parser.add_argument("--output", type=str, default="./out.jpg")
21-
args = parser.parse_args()
22-
23-
input_prompt = args.input_prompt
24-
output_path = args.output
25-
print("Input Prompt: ", input_prompt)
26-
pipe = StableDiffusionPipeline.from_pretrained(model_id, torch_dtype=torch.float16)
27-
pipe = pipe.to(device)
28-
prompt = "Show me an X ray pevic fracture"
29-
image = pipe(prompt).images[0]
30-
image.save(output_path)
14+
name = "Diffusion Image App"
15+
description = "Simple application showing diffusion to generate Images"
16+
17+
def compose(self):
18+
model_id = "Nihirc/Prompt2MedImage"
19+
device = "cuda"
20+
parser = argparse.ArgumentParser()
21+
parser.add_argument("--input_prompt", type=str, default="Generate a X-ray")
22+
parser.add_argument("--output", type=str, default="./out.jpg")
23+
args = parser.parse_args()
24+
25+
input_prompt = args.input_prompt
26+
output_path = args.output
27+
print("Input Prompt: ", input_prompt)
28+
pipe = StableDiffusionPipeline.from_pretrained(model_id, torch_dtype=torch.float16)
29+
pipe = pipe.to(device)
30+
prompt = "Show me an X ray pevic fracture"
31+
image = pipe(prompt).images[0]
32+
image.save(output_path)
3133

3234

3335
if __name__ == "__main__":
34-
logging.info(f"Begin {__name__}")
35-
App().run()
36-
logging.info(f"End {__name__}")
37-
38-
39-
36+
logging.info(f"Begin {__name__}")
37+
App().run()
38+
logging.info(f"End {__name__}")

examples/apps/mednist_classifier_monaideploy/mednist_classifier_monaideploy.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ class MedNISTClassifierOperator(Operator):
100100

101101
def __init__(
102102
self,
103-
frament: Fragment,
103+
fragment: Fragment,
104104
*args,
105105
app_context: AppContext,
106106
model_name: Optional[str] = "",
@@ -127,7 +127,7 @@ def __init__(
127127
# The name of the optional input port for passing data to override the output folder path.
128128
self.input_name_output_folder = "output_folder"
129129

130-
# The output folder set on the object can be overriden at each compute by data in the optional named input
130+
# The output folder set on the object can be overridden at each compute by data in the optional named input
131131
self.output_folder = output_folder
132132

133133
# Need the name when there are multiple models loaded
@@ -138,7 +138,7 @@ def __init__(
138138
self.model = self._get_model(self.app_context, self.model_path, self._model_name)
139139

140140
# This needs to be at the end of the constructor.
141-
super().__init__(frament, *args, **kwargs)
141+
super().__init__(fragment, *args, **kwargs)
142142

143143
def _get_model(self, app_context: AppContext, model_path: Path, model_name: str):
144144
"""Load the model with the given name from context or model path

examples/apps/simple_imaging_app/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command):
307307
# TAG-NUM-gHEX
308308
mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe)
309309
if not mo:
310-
# unparseable. Maybe git-describe is misbehaving?
310+
# unparsable. Maybe git-describe is misbehaving?
311311
pieces["error"] = ("unable to parse git-describe output: '%s'"
312312
% describe_out)
313313
return pieces

examples/apps/simple_imaging_app/app.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ def compose(self):
4949
output_data_path = Path(app_context.output_path)
5050
logging.info(f"sample_data_path: {sample_data_path}")
5151

52-
# Please note that the Application object, self, is passed as the first positonal argument
52+
# Please note that the Application object, self, is passed as the first positional argument
5353
# and the others as kwargs.
5454
# Also note the CountCondition of 1 on the first operator, indicating to the application executor
55-
# to invoke this operator, hence the pipleline, only once.
55+
# to invoke this operator, hence the pipeline, only once.
5656
sobel_op = SobelOperator(self, CountCondition(self, 1), input_path=sample_data_path, name="sobel_op")
5757
median_op = MedianOperator(self, name="median_op")
5858
gaussian_op = GaussianOperator(self, output_folder=output_data_path, name="gaussian_op")

examples/apps/simple_imaging_app/gaussian_operator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class GaussianOperator(Operator):
2424
single input:
2525
an image array object
2626
single output:
27-
an image arrary object, without enforcing a downsteam receiver
27+
an image array object, without enforcing a downstream receiver
2828
2929
Besides, this operator also saves the image file in the given output folder.
3030
"""

monai/deploy/operators/clara_viz_operator.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class ClaraVizOperator(Operator):
3333
seg_image: Image object of the segmentation image derived from the input image.
3434
"""
3535

36-
def __init__(self, fragement: Fragment, *args, **kwargs):
36+
def __init__(self, fragment: Fragment, *args, **kwargs):
3737
"""Constructor of the operator.
3838
3939
Args:
@@ -43,7 +43,7 @@ def __init__(self, fragement: Fragment, *args, **kwargs):
4343
self.input_name_image = "image"
4444
self.input_name_seg_image = "seg_image"
4545

46-
super().__init__(fragement, *args, **kwargs)
46+
super().__init__(fragment, *args, **kwargs)
4747

4848
def setup(self, spec: OperatorSpec):
4949
spec.input(self.input_name_image)

monai/deploy/operators/dicom_encapsulated_pdf_writer_operator.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,12 @@ class DICOMEncapsulatedPDFWriterOperator(Operator):
4545
None
4646
4747
File output:
48-
Generaed DICOM instance file in the provided output folder.
48+
Generated DICOM instance file in the provided output folder.
4949
"""
5050

5151
# File extension for the generated DICOM Part 10 file.
5252
DCM_EXTENSION = ".dcm"
53-
# The default output folder for saveing the generated DICOM instance file.
53+
# The default output folder for saving the generated DICOM instance file.
5454
DEFAULT_OUTPUT_FOLDER = Path(os.getcwd()) / "output"
5555

5656
def __init__(
@@ -249,7 +249,7 @@ def _is_pdf_bytes(self, content: bytes):
249249
return True
250250

251251

252-
# Commenting out the following as pttype complains about the contructor for no reason
252+
# Commenting out the following as pttype complains about the constructor for no reason
253253
# def test(test_copy_tags: bool = True):
254254
# from monai.deploy.operators.dicom_data_loader_operator import DICOMDataLoaderOperator
255255
# from monai.deploy.operators.dicom_series_selector_operator import DICOMSeriesSelectorOperator

monai/deploy/operators/dicom_seg_writer_operator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ def __init__(
206206
Object encapsulating the description of each segment present in the segmentation.
207207
output_folder: Folder for file output, overridden by named input on compute.
208208
Defaults to current working dir's child folder, output.
209-
custom_tags: Optonal[Dict[str, str]], optional
209+
custom_tags: Optional[Dict[str, str]], optional
210210
Dictionary for setting custom DICOM tags using Keywords and str values only
211211
omit_empty_frames: bool, optional
212212
Whether to omit frames that contain no segmented pixels from the output segmentation.

monai/deploy/operators/dicom_text_sr_writer_operator.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ class DICOMTextSRWriterOperator(Operator):
4242
None
4343
4444
File output:
45-
Generaed DICOM instance file in the provided output folder.
45+
Generated DICOM instance file in the provided output folder.
4646
"""
4747

4848
# File extension for the generated DICOM Part 10 file.
4949
DCM_EXTENSION = ".dcm"
50-
# The default output folder for saveing the generated DICOM instance file.
50+
# The default output folder for saving the generated DICOM instance file.
5151
# DEFAULT_OUTPUT_FOLDER = Path(os.path.join(os.path.dirname(__file__))) / "output"
5252
DEFAULT_OUTPUT_FOLDER = Path.cwd() / "output"
5353

@@ -259,7 +259,7 @@ def write(self, content_text, dicom_series: Optional[DICOMSeries], output_dir: P
259259
self._logger.info(f"DICOM SOP instance saved in {file_path}")
260260

261261

262-
# Commenting out the following as pttype complains about the contructor for no reason
262+
# Commenting out the following as pttype complains about the constructor for no reason
263263
# def test(test_copy_tags: bool = True):
264264
# from monai.deploy.operators.dicom_data_loader_operator import DICOMDataLoaderOperator
265265
# from monai.deploy.operators.dicom_series_selector_operator import DICOMSeriesSelectorOperator

monai/deploy/operators/inference_operator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
class InferenceOperator(Operator):
1818
"""The base operator for operators that perform AI inference.
1919
20-
This operator preforms pre-transforms on a input image, inference with
20+
This operator performs pre-transforms on a input image, inference with
2121
a given model, post-transforms, and final results generation.
2222
"""
2323

monai/deploy/operators/monai_bundle_inference_operator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ def compute(self, op_input, op_output, context):
546546
# `context.models.get(model_name)` returns a model instance if exists.
547547
# If model_name is not specified and only one model exists, it returns that model.
548548

549-
# The models are loaded on contruction via the AppContext object in turn the model factory.
549+
# The models are loaded on construction via the AppContext object in turn the model factory.
550550
self._model_network = self.app_context.models.get(self._model_name) if self.app_context.models else None
551551

552552
if self._model_network:

monai/deploy/operators/monai_seg_inference_operator.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class InfererType(StrEnum):
5858
class MonaiSegInferenceOperator(InferenceOperator):
5959
"""This segmentation operator uses MONAI transforms and Sliding Window Inference.
6060
61-
This operator preforms pre-transforms on a input image, inference
61+
This operator performs pre-transforms on a input image, inference
6262
using a given model, and post-transforms. The segmentation image is saved
6363
as a named Image object in memory.
6464
@@ -241,7 +241,7 @@ def _convert_dicom_metadata_datatype(self, metadata: Dict):
241241
if not metadata:
242242
return metadata
243243

244-
# Try to convert data type for the well knowned attributes. Add more as needed.
244+
# Try to convert data type for the well known attributes. Add more as needed.
245245
if metadata.get("SeriesInstanceUID", None):
246246
try:
247247
metadata["SeriesInstanceUID"] = str(metadata["SeriesInstanceUID"])
@@ -313,6 +313,7 @@ def compute_impl(self, input_image, context):
313313
with torch.no_grad():
314314
for d in dataloader:
315315
images = d[self._input_dataset_key].to(device)
316+
self._logger.info(f"Input of {type(images)} shape: {images.shape}")
316317
if self._inferer == InfererType.SLIDING_WINDOW:
317318
d[self._pred_dataset_key] = sliding_window_inference(
318319
inputs=images,
@@ -331,7 +332,14 @@ def compute_impl(self, input_image, context):
331332
)
332333

333334
d = [post_transforms(i) for i in decollate_batch(d)]
334-
out_ndarray = d[0][self._pred_dataset_key].cpu().numpy()
335+
self._logger.info(f"Post transform length/batch size of output: {len(d)}")
336+
self._logger.info(
337+
f"Post transform pixel spacings of '{self._pred_dataset_key}' in the first output: {d[0][self._pred_dataset_key].pixdim}"
338+
)
339+
out_ndarray = d[0][self._pred_dataset_key].cpu().numpy() # Single output to numpy on CPU
340+
self._logger.info(
341+
f"Post transform '{self._pred_dataset_key}' of {type(out_ndarray)} shape: {out_ndarray.shape}"
342+
)
335343
# Need to squeeze out the channel dim fist
336344
out_ndarray = np.squeeze(out_ndarray, 0)
337345
# NOTE: The domain Image object simply contains a Arraylike obj as image as of now.
@@ -343,7 +351,9 @@ def compute_impl(self, input_image, context):
343351
# the resultant ndarray for the prediction image needs to be transposed back, so the
344352
# array index order is back to DHW, the same order as the in-memory input Image obj.
345353
out_ndarray = out_ndarray.T.astype(np.uint8)
346-
self._logger.info(f"Output Seg image numpy array shaped: {out_ndarray.shape}")
354+
self._logger.info(
355+
f"Output Seg image numpy array of type '{type(out_ndarray)}' shape: {out_ndarray.shape}"
356+
)
347357
self._logger.info(f"Output Seg image pixel max value: {np.amax(out_ndarray)}")
348358

349359
return Image(out_ndarray, input_img_metadata)

monai/deploy/operators/publisher_operator.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ class PublisherOperator(Operator):
2929
generates the render config file and the meta data file, then save all in the `publish` folder of the app.
3030
"""
3131

32-
# The default input folder for saveing the generated DICOM instance file.
32+
# The default input folder for saving the generated DICOM instance file.
3333
DEFAULT_INPUT_FOLDER = Path(getcwd()) / "input"
3434

35-
# The default output folder for saveing the generated DICOM instance file.
35+
# The default output folder for saving the generated DICOM instance file.
3636
DEFAULT_OUTPUT_FOLDER = Path(getcwd()) / "output"
3737

3838
def __init__(

monai/deploy/operators/stl_conversion_operator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class STLConversionOperator(Operator):
4141
"""Converts volumetric image to surface mesh in STL format.
4242
4343
If a file path is provided, the STL binary will be saved in the said output folder.
44-
This operator also save the STL file as bytes in memory, idenfied by the named output. Being optional,
44+
This operator also save the STL file as bytes in memory, identified by the named output. Being optional,
4545
this output does not require any downstream receiver.
4646
4747
Named inputs:

0 commit comments

Comments
 (0)