Beispiel #1
0
 def test_find_content_items_filtered_by_value_type_relationship_type(self):
     items = find_content_items(
         self._sr_document,
         value_type=ValueTypeValues.CODE,
         relationship_type=RelationshipTypeValues.HAS_OBS_CONTEXT)
     assert len(items) == 2
     name_code_value_1 = items[0].ConceptNameCodeSequence[0].CodeValue
     assert name_code_value_1 == codes.DCM.ObserverType.value
     name_code_value_2 = items[1].ConceptNameCodeSequence[0].CodeValue
     assert name_code_value_2 == codes.DCM.ObserverType.value
Beispiel #2
0
 def test_find_content_items_filtered_by_relationship_type(self):
     items = find_content_items(
         self._sr_document,
         relationship_type=RelationshipTypeValues.HAS_OBS_CONTEXT)
     assert len(items) == 4
     name_code_value_1 = items[0].ConceptNameCodeSequence[0].CodeValue
     assert name_code_value_1 == codes.DCM.ObserverType.value
     name_code_value_2 = items[1].ConceptNameCodeSequence[0].CodeValue
     assert name_code_value_2 == codes.DCM.PersonObserverName.value
     name_code_value_3 = items[2].ConceptNameCodeSequence[0].CodeValue
     assert name_code_value_3 == codes.DCM.ObserverType.value
     name_code_value_4 = items[3].ConceptNameCodeSequence[0].CodeValue
     assert name_code_value_4 == codes.DCM.DeviceObserverUID.value
Beispiel #3
0
    def __init__(self,
                 evidence: Sequence[Dataset],
                 content: Dataset,
                 series_instance_uid: str,
                 series_number: int,
                 sop_instance_uid: str,
                 instance_number: int,
                 manufacturer: Optional[str] = None,
                 is_complete: bool = False,
                 is_final: bool = False,
                 is_verified: bool = False,
                 institution_name: Optional[str] = None,
                 institutional_department_name: Optional[str] = None,
                 verifying_observer_name: Optional[str] = None,
                 verifying_organization: Optional[str] = None,
                 performed_procedure_codes: Optional[Sequence[Union[
                     Code, CodedConcept]]] = None,
                 requested_procedures: Optional[Sequence[Dataset]] = None,
                 previous_versions: Optional[Sequence[Dataset]] = None,
                 record_evidence: bool = True,
                 **kwargs: Any) -> None:
        """
        Parameters
        ----------
        evidence: Sequence[pydicom.dataset.Dataset]
            Instances that are referenced in the content tree and from which
            the created SR document instance should inherit patient and study
            information
        content: pydicom.dataset.Dataset
            Root container content items that should be included in the
            SR document
        series_instance_uid: str
            Series Instance UID of the SR document series
        series_number: Union[int, None]
            Series Number of the SR document series
        sop_instance_uid: str
            SOP Instance UID that should be assigned to the SR document instance
        instance_number: int
            Number that should be assigned to this SR document instance
        manufacturer: str, optional
            Name of the manufacturer of the device that creates the SR document
            instance (in a research setting this is typically the same
            as `institution_name`)
        is_complete: bool, optional
            Whether the content is complete (default: ``False``)
        is_final: bool, optional
            Whether the report is the definitive means of communicating the
            findings (default: ``False``)
        is_verified: bool, optional
            Whether the report has been verified by an observer accountable
            for its content (default: ``False``)
        institution_name: str, optional
            Name of the institution of the person or device that creates the
            SR document instance
        institutional_department_name: str, optional
            Name of the department of the person or device that creates the
            SR document instance
        verifying_observer_name: Union[str, None], optional
            Name of the person that verfied the SR document
            (required if `is_verified`)
        verifying_organization: str, optional
            Name of the organization that verfied the SR document
            (required if `is_verified`)
        performed_procedure_codes: List[highdicom.sr.coding.CodedConcept], optional
            Codes of the performed procedures that resulted in the SR document
        requested_procedures: List[pydicom.dataset.Dataset]
            Requested procedures that are being fullfilled by creation of the
            SR document
        previous_versions: List[pydicom.dataset.Dataset], optional
            Instances representing previous versions of the SR document
        record_evidence: bool, optional
            Whether provided `evidence` should be recorded, i.e. included
            in Current Requested Procedure Evidence Sequence or Pertinent
            Other Evidence Sequence (default: ``True``)
        **kwargs: Any, optional
            Additional keyword arguments that will be passed to the constructor
            of `highdicom.base.SOPClass`

        Note
        ----
        Each dataset in `evidence` must be part of the same study.

        """  # noqa: E501
        super().__init__(
            evidence=evidence,
            content=content,
            series_instance_uid=series_instance_uid,
            series_number=series_number,
            sop_instance_uid=sop_instance_uid,
            sop_class_uid=ComprehensiveSRStorage,
            instance_number=instance_number,
            manufacturer=manufacturer,
            is_complete=is_complete,
            is_final=is_final,
            is_verified=is_verified,
            institution_name=institution_name,
            institutional_department_name=institutional_department_name,
            verifying_observer_name=verifying_observer_name,
            verifying_organization=verifying_organization,
            performed_procedure_codes=performed_procedure_codes,
            requested_procedures=requested_procedures,
            previous_versions=previous_versions,
            record_evidence=record_evidence,
            **kwargs)
        unsopported_content = find_content_items(
            content, value_type=ValueTypeValues.SCOORD3D, recursive=True)
        if len(unsopported_content) > 0:
            raise ValueError(
                'Comprehensive SR does not support content items with '
                'SCOORD3D value type.')
Beispiel #4
0
 def test_find_content_items_filtered_by_name(self):
     items = find_content_items(self._sr_document,
                                name=codes.DCM.ProcedureReported)
     assert len(items) == 1
     name_code_value = items[0].ConceptNameCodeSequence[0].CodeValue
     assert name_code_value == codes.DCM.ProcedureReported.value
Beispiel #5
0
 def test_find_content_items(self):
     items = find_content_items(self._sr_document)
     assert len(items) == 8
Beispiel #6
0
 def test_find_content_items_filter_by_relationship_type_recursively(self):
     items = find_content_items(
         self._sr_document,
         relationship_type=RelationshipTypeValues.CONTAINS,
         recursive=True)
     assert len(items) == 6
Beispiel #7
0
 def test_find_content_items_filter_by_value_type_recursively_1(self):
     items = find_content_items(self._sr_document,
                                value_type=ValueTypeValues.CODE,
                                recursive=True)
     assert len(items) == 9
Beispiel #8
0
 def test_find_content_items_filter_by_name_recursively(self):
     items = find_content_items(self._sr_document,
                                name=codes.DCM.TrackingUniqueIdentifier,
                                recursive=True)
     assert len(items) == 2
Beispiel #9
0
 def test_find_content_items_recursively(self):
     items = find_content_items(self._sr_document, recursive=True)
     assert len(items) == 20
Beispiel #10
0
 def test_find_content_items_filtered_by_value_type(self):
     items = find_content_items(self._sr_document,
                                value_type=ValueTypeValues.UIDREF)
     assert len(items) == 1
     name_code_value = items[0].ConceptNameCodeSequence[0].CodeValue
     assert name_code_value == codes.DCM.DeviceObserverUID.value
Beispiel #11
0
    def _collect_evidence(
            self, evidence: Sequence[Dataset],
            content: Dataset) -> Tuple[List[Dataset], List[Dataset]]:
        """Collect evidence for the SR document.

        Any `evidence` that is referenced in `content` via IMAGE or
        COMPOSITE content items will be grouped together for inclusion in the
        Current Requested Procedure Evidence Sequence and all remaining
        evidence will be grouped for potential inclusion in the Pertinent Other
        Evidence Sequence.

        Parameters
        ----------
        evidence: List[pydicom.dataset.Dataset]
            Metadata of instances that serve as evidence for the SR document
            content
        content: pydicom.dataset.Dataset
            SR document content

        Returns
        -------
        Tuple[List[pydicom.dataset.Dataset], List[pydicom.dataset.Dataset]]
            Items of the Current Requested Procedure Evidence Sequence and the
            Pertinent Other Evidence Sequence

        Raises
        ------
        ValueError
            When a SOP instance is referenced in `content` but not provided as
            `evidence`

        """  # noqa
        references = find_content_items(content,
                                        value_type=ValueTypeValues.IMAGE,
                                        recursive=True)
        references += find_content_items(content,
                                         value_type=ValueTypeValues.COMPOSITE,
                                         recursive=True)
        ref_uids = set([
            ref.ReferencedSOPSequence[0].ReferencedSOPInstanceUID
            for ref in references
        ])
        evd_uids = set()
        ref_group: Mapping[Tuple[str, str], List[Dataset]] = defaultdict(list)
        unref_group: Mapping[Tuple[str, str],
                             List[Dataset]] = defaultdict(list)
        for evd in evidence:
            if evd.SOPInstanceUID in evd_uids:
                # Skip potential duplicates
                continue
            evd_item = Dataset()
            evd_item.ReferencedSOPClassUID = evd.SOPClassUID
            evd_item.ReferencedSOPInstanceUID = evd.SOPInstanceUID
            key = (evd.StudyInstanceUID, evd.SeriesInstanceUID)
            if evd.SOPInstanceUID in ref_uids:
                ref_group[key].append(evd_item)
            else:
                unref_group[key].append(evd_item)
            evd_uids.add(evd.SOPInstanceUID)
        if not (ref_uids.issubset(evd_uids)):
            missing_uids = ref_uids.difference(evd_uids)
            raise ValueError(
                'No evidence was provided for the following SOP instances, '
                'which are referenced in the document content: "{}"'.format(
                    '", "'.join(missing_uids)))

        ref_items = self._create_references(ref_group)
        unref_items = self._create_references(unref_group)
        return (ref_items, unref_items)