Skip to content

Commit 992a0d3

Browse files
author
Chris Bridge
committed
Implement SegmentDescription and Code
Signed-off-by: Chris Bridge <cbridge@partners.org>
2 parents c591e47 + 74add36 commit 992a0d3

File tree

1 file changed

+71
-2
lines changed

1 file changed

+71
-2
lines changed

monai/deploy/operators/dicom_seg_writer_operator.py

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@
1212
import os
1313
from pathlib import Path
1414
from random import randint
15-
from typing import TYPE_CHECKING, List, Union
15+
from typing import TYPE_CHECKING, List, NamedTuple, Optional, Sequence, Union
1616

1717
import numpy as np
18+
from typeguard import typechecked
1819

1920
from monai.deploy.utils.importutil import optional_import
2021
from monai.deploy.utils.version import get_sdk_semver
@@ -39,6 +40,74 @@
3940
from monai.deploy.core.domain.dicom_series_selection import StudySelectedSeries
4041

4142

43+
class Code(NamedTuple):
44+
"""Namedtuple for representation of a coded concept consisting of the
45+
actual code *value*, the coding *scheme designator*, the code *meaning*
46+
(and optionally the coding *scheme version*).
47+
"""
48+
value: str
49+
scheme_designator: str
50+
meaning: str
51+
scheme_version: Optional[str] = None
52+
53+
54+
class SegmentDescription:
55+
56+
@typechecked
57+
def __init__(
58+
self,
59+
segment_number: int,
60+
segment_label: str,
61+
segmented_property_category: Code,
62+
segmented_property_type: Code,
63+
algorithm_name: str,
64+
algorithm_version: str,
65+
algorithm_family: Code = codes.DCM.ArtificialIntelligence,
66+
tracking_uid: Optional[str] = None,
67+
tracking_id: Optional[str] = None,
68+
anatomic_regions: Optional[Sequence[Code]] = None,
69+
primary_anatomic_structures: Optional[Sequence[Code]] = None
70+
):
71+
self._segment_number = segment_number
72+
self._segment_label = segment_label
73+
self._segmented_property_category = pydicom_Code(*segmented_property_category)
74+
self._segmented_property_type = pydicom_Code(*segmented_property_type)
75+
self._tracking_id = tracking_id
76+
if anatomic_regions is not None:
77+
self._anatomic_regions = [pydicom_Code(*ar) for ar in anatomic_regions]
78+
else:
79+
self._anatomic_regions = None
80+
if primary_anatomic_structures is not None:
81+
self._primary_anatomic_structures = [pydicom_Code(*pas) for pas in primary_anatomic_structures]
82+
else:
83+
self._primary_anatomic_structures = None
84+
85+
# Generate a UID if one was not provided
86+
if tracking_id is not None and tracking_uid is None:
87+
tracking_uid = hd.UID()
88+
self._tracking_uid = tracking_uid
89+
90+
self._algorithm_identification = hd.AlgorithmIdentificationSequence(
91+
name=algorithm_name,
92+
family=algorithm_family,
93+
version=algorithm_version,
94+
)
95+
96+
def to_segment_description(self) -> hd.seg.SegmentDescription:
97+
return hd.seg.SegmentDescription(
98+
segment_number=self._segment_number,
99+
segment_label=self._segment_label,
100+
segmented_property_category=self._segment_label,
101+
segmented_property_type=self._segmented_property_type,
102+
algorithm_identification=self._algorithm_identification,
103+
algorithm_type="AUTOMATIC",
104+
tracking_uid=self._tracking_uid,
105+
tracking_id=self._tracking_id,
106+
anatomic_regions=self._anatomic_regions,
107+
primary_anatomic_structures=self._primary_anatomic_structures,
108+
)
109+
110+
42111
@md.input("seg_image", Image, IOType.IN_MEMORY)
43112
@md.input("study_selected_series_list", List[StudySelectedSeries], IOType.IN_MEMORY)
44113
@md.output("dicom_seg_instance", DataPath, IOType.DISK)
@@ -75,7 +144,7 @@ def __init__(self, segment_descriptions: List[SegmentDescription], *args, **kwar
75144
segmentation.
76145
"""
77146

78-
self._seg_descs = segment_descriptions
147+
self._seg_descs = [sd.to_segment_description() for sd in segment_descriptions]
79148

80149
def compute(self, op_input: InputContext, op_output: OutputContext, context: ExecutionContext):
81150
"""Performs computation for this operator and handles I/O.

0 commit comments

Comments
 (0)