diff --git a/docs/ann.rst b/docs/ann.rst index 8b0ca9d7..9c04013b 100644 --- a/docs/ann.rst +++ b/docs/ann.rst @@ -37,6 +37,9 @@ contains. The required metadata elements include: * An ``annotated_property_category`` and ``annotated_property_type`` (:class:`highdicom.sr.CodedConcept`), coded values (see :ref:`coding`) describing the category and specific structure that has been annotated. + See :dcm:`CID 7151 ` and + :dcm:`CID 8135 ` respectively for the associated + context groups. * A ``graphic_type`` (:class:`highdicom.ann.GraphicTypeValues`) indicating the "form" of the annotations. Permissible values are ``"ELLIPSE"``, ``"POINT"``, ``"POLYGON"``, ``"RECTANGLE"``, and ``"POLYLINE"``. diff --git a/docs/coding.rst b/docs/coding.rst index ba7a98f4..fe73bb47 100644 --- a/docs/coding.rst +++ b/docs/coding.rst @@ -127,12 +127,27 @@ hash to the same value if you use them within sets or as keys in dictionaries. For equality and hashing, two codes are considered equivalent if they have the same coding scheme, and value, regardless of how their meaning is represented. +Context Groups +-------------- + +Many places where codes are used in the standard are associated with a +`Context Group`. These are sets of codes determined to be suitable for a +particular purpose. Most are `extensible`, meaning you can choose codes +outside the context group if you wish. However, it is best practice to use +a code within the context group if a suitable code exists within it. + +Context groups are have an identifier called a `CID`. For example, :dcm:`CID +7150 ` is the context group containing codes to use +to describe segmented properties categories in a DICOM segmentation and +:dcm:`CID 7151 ` contains values for the more +specific segmented property types. Note that this second example includes other +CIDs recursively. + Finding Suitable Codes ---------------------- The `pydicom` code dictionary allows searching for concepts via simple string -matching. However, for more advanced searching it is generally advisable to -search the documentation for the coding scheme itself. +matching. You can also search with context groups. .. code-block:: python @@ -146,3 +161,24 @@ search the documentation for the coding scheme itself. print(codes.SCT.Liver) # Code(value='10200004', scheme_designator='SCT', meaning='Liver', scheme_version=None) + + # Search within a context group (e.g. CID7150) + print(codes.cid7150.dir()) + # ['AnatomicalStructure', + # 'BodySubstance', + # 'Function', + # 'MorphologicallyAbnormalStructure', + # 'PhysicalObject', + # 'SpatialAndRelationalConcept', + # 'Substance', + # 'Tissue'] + + # Check whether a code lies within a context group + print(codes.SCT.BodySubstance in codes.cid7150) + # True + +However, for more advanced searching it is generally advisable to search the +documentation for the coding scheme itself. This +`webpage `_ is a nice +interactive tool for searching the terms and Context Groups defined within +DICOM. diff --git a/docs/seg.rst b/docs/seg.rst index ce8592ad..5eb4bc87 100644 --- a/docs/seg.rst +++ b/docs/seg.rst @@ -67,11 +67,13 @@ description includes the following information: segment represents an anatomical structure, a tissue type, or an abnormality. This is passed as either a :class:`highdicom.sr.CodedConcept`, or a :class:`pydicom.sr.coding.Code` - object. + object. See + :dcm:`CID 7150 ` for the associated context group. - **Segmented Property Type**: Another coded value that more specifically describes the segmented region, as for example a kidney or tumor. This is passed as either a :class:`highdicom.sr.CodedConcept`, or a - :class:`pydicom.sr.coding.Code` object. + :class:`pydicom.sr.coding.Code` object. See + :dcm:`CID 7151 ` for the associated context group. - **Algorithm Type**: Whether the segment was produced by an automatic, semi-automatic, or manual algorithm. The valid values are contained within the enum :class:`highdicom.seg.SegmentAlgorithmTypeValues`. @@ -112,7 +114,7 @@ representing a liver that has been manually segmented. liver_description = hd.seg.SegmentDescription( segment_number=1, segment_label='liver', - segmented_property_category=codes.SCT.Organ, + segmented_property_category=codes.SCT.AnatomicalStructure, segmented_property_type=codes.SCT.Liver, algorithm_type=hd.seg.SegmentAlgorithmTypeValues.MANUAL, display_color=hd.color.CIELabColor.from_string('red'), @@ -244,7 +246,7 @@ everything else the same. liver_description = hd.seg.SegmentDescription( segment_number=1, segment_label='liver', - segmented_property_category=codes.SCT.Organ, + segmented_property_category=codes.SCT.AnatomicalStructure, segmented_property_type=codes.SCT.Liver, algorithm_type=hd.seg.SegmentAlgorithmTypeValues.MANUAL, ) @@ -321,7 +323,7 @@ example to use the labelmap segmentation type. liver_description = hd.seg.SegmentDescription( segment_number=1, segment_label='liver', - segmented_property_category=codes.SCT.Organ, + segmented_property_category=codes.SCT.AnatomicalStructure, segmented_property_type=codes.SCT.Liver, algorithm_type=hd.seg.SegmentAlgorithmTypeValues.MANUAL, ) @@ -387,7 +389,7 @@ segmentation type. liver_description = hd.seg.SegmentDescription( segment_number=1, segment_label='liver', - segmented_property_category=codes.SCT.Organ, + segmented_property_category=codes.SCT.AnatomicalStructure, segmented_property_type=codes.SCT.Liver, algorithm_type=hd.seg.SegmentAlgorithmTypeValues.MANUAL, ) @@ -475,7 +477,7 @@ always be present even if there is a single source frame. liver_description = hd.seg.SegmentDescription( segment_number=2, segment_label='liver', - segmented_property_category=codes.SCT.Organ, + segmented_property_category=codes.SCT.AnatomicalStructure, segmented_property_type=codes.SCT.Liver, algorithm_type=hd.seg.SegmentAlgorithmTypeValues.MANUAL, ) @@ -635,7 +637,7 @@ must have exactly one channel dimension with the descriptor being the liver_description = hd.seg.SegmentDescription( segment_number=1, segment_label='liver', - segmented_property_category=codes.SCT.Organ, + segmented_property_category=codes.SCT.AnatomicalStructure, segmented_property_type=codes.SCT.Liver, algorithm_type=hd.seg.SegmentAlgorithmTypeValues.MANUAL, ) @@ -734,7 +736,7 @@ For example: liver_description = hd.seg.SegmentDescription( segment_number=1, segment_label='liver', - segmented_property_category=codes.SCT.Organ, + segmented_property_category=codes.SCT.AnatomicalStructure, segmented_property_type=codes.SCT.Liver, algorithm_type=hd.seg.SegmentAlgorithmTypeValues.MANUAL, ) @@ -827,7 +829,7 @@ between the items of the ``source_images`` list and axis 0 of the segmentation liver_description = hd.seg.SegmentDescription( segment_number=1, segment_label='liver', - segmented_property_category=codes.SCT.Organ, + segmented_property_category=codes.SCT.AnatomicalStructure, segmented_property_type=codes.SCT.Liver, algorithm_type=hd.seg.SegmentAlgorithmTypeValues.MANUAL, ) @@ -1187,7 +1189,7 @@ representing a probabilistic segmentation of the liver. liver_description = hd.seg.SegmentDescription( segment_number=1, segment_label='liver', - segmented_property_category=codes.SCT.Organ, + segmented_property_category=codes.SCT.AnatomicalStructure, segmented_property_type=codes.SCT.Liver, algorithm_type=hd.seg.SegmentAlgorithmTypeValues.MANUAL, ) diff --git a/docs/volume.rst b/docs/volume.rst index ee9f99de..82df87ab 100644 --- a/docs/volume.rst +++ b/docs/volume.rst @@ -630,7 +630,7 @@ spatial metadata in the output object is correct. brain_description = hd.seg.SegmentDescription( segment_number=1, segment_label='brain', - segmented_property_category=codes.SCT.Organ, + segmented_property_category=codes.SCT.AnatomicalStructure, segmented_property_type=codes.SCT.Brain, algorithm_type=hd.seg.SegmentAlgorithmTypeValues.AUTOMATIC, algorithm_identification=algorithm_identification,