def test_from_named_components_with_separator_from_bytes(self): # If the names already include separator chars # a ValueError should be raised with pytest.raises(ValueError): PersonName.from_named_components( family_name_ideographic=b'\033$B;3ED\033(B^\033$BB@O:\033(B', encodings=[default_encoding, 'iso2022_jp'], )
def test_from_named_components(self): # Example from DICOM standard, part 5, sect 6.2.1.1 pn = PersonName.from_named_components(family_name='Adams', given_name='John Robert Quincy', name_prefix='Rev.', name_suffix='B.A. M.Div.') assert pn == 'Adams^John Robert Quincy^^Rev.^B.A. M.Div.' assert pn.family_name == 'Adams' assert pn.given_name == 'John Robert Quincy' assert pn.name_prefix == 'Rev.' assert pn.name_suffix == 'B.A. M.Div.'
def test_from_named_components_jp_from_unicode(self): # Example name from PS3.5-2008 section H p. 98 pn = PersonName.from_named_components( family_name='Yamada', given_name='Tarou', family_name_ideographic='山田', given_name_ideographic='太郎', family_name_phonetic='やまだ', given_name_phonetic='たろう', encodings=[default_encoding, 'iso2022_jp'], ) pn = pn.decode() assert ("Yamada", "Tarou") == (pn.family_name, pn.given_name) assert "山田^太郎" == pn.ideographic assert "やまだ^たろう" == pn.phonetic
def test_from_named_components_jp_from_bytes(self): # Example name from PS3.5-2008 section H p. 98 pn = PersonName.from_named_components( family_name='Yamada', given_name='Tarou', family_name_ideographic=b'\033$B;3ED\033(B', given_name_ideographic=b'\033$BB@O:\033(B', family_name_phonetic=b'\033$B$d$^$@\033(B', given_name_phonetic=b'\033$B$?$m$&\033(B', encodings=[default_encoding, 'iso2022_jp'], ) pn = pn.decode() assert ("Yamada", "Tarou") == (pn.family_name, pn.given_name) assert "山田^太郎" == pn.ideographic assert "やまだ^たろう" == pn.phonetic
def test_from_named_components_kr_from_unicode(self): # Example name from PS3.5-2008 section I.2 p. 108 pn = PersonName.from_named_components( family_name='Hong', given_name='Gildong', family_name_ideographic='洪', given_name_ideographic='吉洞', family_name_phonetic='홍', given_name_phonetic='길동', encodings=[default_encoding, 'euc_kr'], ) pn = pn.decode() assert ("Hong", "Gildong") == (pn.family_name, pn.given_name) assert "洪^吉洞" == pn.ideographic assert "홍^길동" == pn.phonetic
def test_from_named_components_kr_from_bytes(self): # Example name from PS3.5-2008 section I.2 p. 108 pn = PersonName.from_named_components( family_name='Hong', given_name='Gildong', family_name_ideographic=b'\033$)C\373\363', given_name_ideographic=b'\033$)C\321\316\324\327', family_name_phonetic=b'\033$)C\310\253', given_name_phonetic=b'\033$)C\261\346\265\277', encodings=[default_encoding, 'euc_kr'], ) pn = pn.decode() assert ("Hong", "Gildong") == (pn.family_name, pn.given_name) assert "洪^吉洞" == pn.ideographic assert "홍^길동" == pn.phonetic
def get_sr_dataset( self, roi_measurements: List[VolumetricROIMeasurementsAndQualitativeEvaluations], ct_datasets: List[Dataset], seg_dataset: Segmentation, series_number: int, series_description: str ): """Construct a Structured Report containing measurements and evaluations for one or more annotations. Depending on the command-line parameters, each SR document may contain measurements and evaluations for the annotation of a single nodule by a single reader, or in the case of "--composite", measurements and evaluations of one or more nodules, each annotated by one or more distinct readers. Parameters ---------- roi_measurements: List[highdicom.sr.VolumetricROIMeasurementsAndQualitativeEvaluations] List of measurement groups, each containing to the measurements and evaluations of a single nodule by a single reader, and referencing a single segment in a segmentation image. ct_datasets: List[pydicom.dataset.Dataset] List of CT datasets from which the segmentations were derived. seg_dataset: Segmentation Segmentation image referenced by the SR. series_number: int Series number of the newly created SR document. series_description: str Series description of the newly-created SR document. Returns ------- highdicom.sr.Comprehensive3DSR Structured Report document dataset using template TID 1500 containing measurements and evaluations for one or more nodules. """ # Be explicit about reader being anonymous anonymous_person_name = PersonName.from_named_components( given_name='anonymous', family_name='observer' ) observer_context = ObserverContext( observer_type=codes.DCM.Person, observer_identifying_attributes=PersonObserverIdentifyingAttributes( name=anonymous_person_name ) ) observation_context = ObservationContext( observer_person_context=observer_context ) measurement_report = MeasurementReport( observation_context=observation_context, procedure_reported=codes.LN.CTUnspecifiedBodyRegion, imaging_measurements=roi_measurements ) # Create the Structured Report instance sr_dcm = Comprehensive3DSR( evidence=ct_datasets + [seg_dataset], content=measurement_report[0], series_number=series_number, series_instance_uid=UID(), sop_instance_uid=UID(), instance_number=1, manufacturer='highdicom developers', is_complete=True, is_verified=True, verifying_observer_name=anonymous_person_name, verifying_organization='anonymous', series_description=series_description ) return sr_dcm
def get_segmentation_dataset( self, ct_datasets: List[Dataset], pixel_array: np.ndarray, seg_descs: List[SegmentDescription], series_number: int, series_description: str ): """Construct the SOP Instance dataset for a segmentation image. This method includes information common to all segmentation images, such as the manufacturer name and software version. Parameters ---------- ct_datasets: List[pydicom.dataset.Dataset] List of CT datasets from which the segmentations were derived. pixel_array: np.ndarray Pixel array of the segmentation masks seg_descs: List[SegmentDescription] Descriptions of each segment in the segmentation image. series_number: int Series number to apply to the newly created segmentation image. series_description: str Series description of the newly-created segmentation image. Returns ------- highdicom.seg.Segmentation Dataset for the newly-created Segmentation SOP Instance. """ anonymous_person_name = PersonName.from_named_components( given_name='anonymous', family_name='observer' ) seg_dcm = Segmentation( source_images=ct_datasets, pixel_array=pixel_array, segmentation_type=SegmentationTypeValues.BINARY, segment_descriptions=seg_descs, series_instance_uid=UID(), series_number=series_number, sop_instance_uid=UID(), instance_number=1, manufacturer="highdicom developers", manufacturer_model_name="highdicom", software_versions=f"{highdicom_version}", device_serial_number='1', content_description="Lung nodule segmentation", content_creator_name=anonymous_person_name, series_description=series_description ) # Add in some extra information seg_dcm.BodyPartExamined = "LUNG" seg_dcm.ClinicalTrialSeriesID = "Session1" seg_dcm.ClinicalTrialTimePointID = "1" seg_dcm.ClinicalTrialCoordinatingCenterName = "TCIA" seg_dcm.ContentLabel = "SEGMENTATION" return seg_dcm
def test_from_named_components_with_separator(self): # If the names already include separator chars # a ValueError should be raised with pytest.raises(ValueError): PersonName.from_named_components(given_name='Yamada^Tarou')