def test_decode(self): """ Check decoding an assoc_rq produces the correct user information """ pdu = A_ASSOCIATE_AC() pdu.decode(a_associate_ac) user_info = pdu.variable_items[2] assert user_info.item_type == 0x50 assert user_info.item_length == 58 assert len(user_info) == 62 assert isinstance(user_info.user_data, list) # Test user items for item in user_info.user_data: # Maximum PDU Length (required) if isinstance(item, MaximumLengthSubItem): assert item.maximum_length_received == 16384 assert user_info.maximum_length == 16384 # Implementation Class UID (required) elif isinstance(item, ImplementationClassUIDSubItem): assert item.item_type == 0x52 assert item.item_length == 27 assert item.implementation_class_uid == UID( '1.2.276.0.7230010.3.0.3.6.0') assert isinstance(item.item_type, int) assert isinstance(item.item_length, int) assert isinstance(item.implementation_class_uid, UID) # Implementation Version Name (optional) elif isinstance(item, ImplementationVersionNameSubItem): assert item.item_type == 0x55 assert item.item_length == 15 assert item.implementation_version_name == b'OFFIS_DCMTK_360' assert isinstance(item.item_type, int) assert isinstance(item.item_length, int) assert isinstance(item.implementation_version_name, bytes)
def test_decode(self): """Check decoding an assoc_rq produces the correct user information.""" pdu = A_ASSOCIATE_RQ() pdu.decode(a_associate_rq) user_info = pdu.variable_items[2] assert user_info.item_type == 0x50 assert user_info.item_length == 62 assert len(user_info) == 66 assert isinstance(user_info.user_data, list) # Test user items for item in user_info.user_data: # Maximum PDU Length (required) if isinstance(item, MaximumLengthSubItem): assert item.maximum_length_received == 16382 assert user_info.maximum_length == 16382 # Implementation Class UID (required) elif isinstance(item, ImplementationClassUIDSubItem): assert item.item_type == 0x52 assert item.item_length == 32 assert item.implementation_class_uid == UID( '1.2.826.0.1.3680043.9.3811.0.9.0') assert isinstance(item.item_type, int) assert isinstance(item.item_length, int) assert isinstance(item.implementation_class_uid, UID) # Implementation Version Name (optional) elif isinstance(item, ImplementationVersionNameSubItem): assert item.item_type == 0x55 assert item.item_length == 14 assert item.implementation_version_name == b'PYNETDICOM_090' assert isinstance(item.item_type, int) assert isinstance(item.item_length, int) assert isinstance(item.implementation_version_name, bytes)
def test_transfer_syntax(self): """Test transfer syntax setter""" pc = PresentationContext(1) pc.TransferSyntax = ['1.2.840.10008.1.2'] self.assertEqual(pc.TransferSyntax[0], UID('1.2.840.10008.1.2')) self.assertTrue(isinstance(pc.TransferSyntax[0], UID)) pc.TransferSyntax = [b'1.2.840.10008.1.2.1'] self.assertEqual(pc.TransferSyntax[0], UID('1.2.840.10008.1.2.1')) self.assertTrue(isinstance(pc.TransferSyntax[0], UID)) pc.TransferSyntax = [UID('1.2.840.10008.1.2.2')] self.assertEqual(pc.TransferSyntax[0], UID('1.2.840.10008.1.2.2')) self.assertTrue(isinstance(pc.TransferSyntax[0], UID)) with self.assertRaises(TypeError): pc.TransferSyntax = UID('1.4.1') pc.TransferSyntax = ['1.4.1.', '1.2.840.10008.1.2'] self.assertEqual(pc.TransferSyntax[0], UID('1.2.840.10008.1.2'))
def test_transfer_syntax_good_uid(self): """ Check AE initialisation produces valid transfer syntaxes """ ae = AE(scu_sop_class=['1.2.840.10008.1.1'], transfer_syntax=['1.2.840.10008.1.2']) self.assertTrue(ae.transfer_syntaxes == [UID('1.2.840.10008.1.2')]) ae = AE(scu_sop_class=['1.2.840.10008.1.1'], transfer_syntax=['1.2.840.10008.1.2', '1.2.840.10008.1.1']) self.assertTrue(ae.transfer_syntaxes == [UID('1.2.840.10008.1.2')]) ae = AE(scu_sop_class=['1.2.840.10008.1.1'], transfer_syntax=['1.2.840.10008.1.2', '1.2.840.10008.1.2.2']) self.assertTrue(ae.transfer_syntaxes == [UID('1.2.840.10008.1.2'), UID('1.2.840.10008.1.2.2')]) ae = AE(scu_sop_class=['1.2.840.10008.1.1'], transfer_syntax=[UID('1.2.840.10008.1.2')]) self.assertTrue(ae.transfer_syntaxes == [UID('1.2.840.10008.1.2')]) ae = AE(scu_sop_class=['1.2.840.10008.1.1'], transfer_syntax=[ImplicitVRLittleEndian]) self.assertTrue(ae.transfer_syntaxes == [UID('1.2.840.10008.1.2')])
def _convert(self, val: Any) -> Any: """Convert `val` to an appropriate type for the element's VR.""" # If the value is bytes and has a VR that can only be encoded # using the default character repertoire, convert it to a string if self.VR in DEFAULT_CHARSET_VR and isinstance(val, bytes): val = val.decode() if self.VR == VR_.IS: return pydicom.valuerep.IS(val, self.validation_mode) if self.VR == VR_.DA and config.datetime_conversion: return pydicom.valuerep.DA(val, validation_mode=self.validation_mode) if self.VR == VR_.DS: return pydicom.valuerep.DS(val, False, self.validation_mode) if self.VR == VR_.DT and config.datetime_conversion: return pydicom.valuerep.DT(val, validation_mode=self.validation_mode) if self.VR == VR_.TM and config.datetime_conversion: return pydicom.valuerep.TM(val, validation_mode=self.validation_mode) if self.VR == VR_.UI: return UID(val, self.validation_mode) if val is not None else None if self.VR == VR_.PN: return PersonName(val, validation_mode=self.validation_mode) if self.VR == VR_.AT and (val == 0 or val): return val if isinstance(val, BaseTag) else Tag(val) self.validate(val) return val
def test_transfer_syntax(self): """Test transfer syntax setter""" pc = PresentationContext(1) pc.TransferSyntax = ['1.2.840.10008.1.2'] assert pc.TransferSyntax[0] == UID('1.2.840.10008.1.2') assert isinstance(pc.TransferSyntax[0], UID) pc.TransferSyntax = [b'1.2.840.10008.1.2.1'] assert pc.TransferSyntax[0] == UID('1.2.840.10008.1.2.1') assert isinstance(pc.TransferSyntax[0], UID) pc.TransferSyntax = [UID('1.2.840.10008.1.2.2')] assert pc.TransferSyntax[0] == UID('1.2.840.10008.1.2.2') assert isinstance(pc.TransferSyntax[0], UID) with pytest.raises(TypeError): pc.TransferSyntax = UID('1.4.1') pc.TransferSyntax = ['1.4.1.', '1.2.840.10008.1.2'] assert pc.TransferSyntax[0] == UID('1.2.840.10008.1.2')
def test_wrap_encode_uid(self): """Test PDU._wrap_encode_uid().""" pdu = PDU() uid = UID('1.2.840.10008.1.1') out = pdu._wrap_encode_uid(uid) assert out == b'1.2.840.10008.1.1'
def testCompareNone(self): """UID: comparing against None give False...""" # From issue 96 uid = UID('1.2.3') self.assertNotEqual(uid, None, "Comparison to a number returned True")
logging.basicConfig(filename='pynetdicom.log', filemode='w', format='%(name)s - %(levelname)s - %(message)s') LOGGER = logging.getLogger('pynetdicom') LOGGER.setLevel(logging.DEBUG) #AEs & IP scu_ae = os.environ.get('AE_TITLE') dest_ae = os.environ.get('DEST_AE') dest_ip = os.environ.get('DEST_IP') print(scu_ae, dest_ae, dest_ip) ae = AE(ae_title=scu_ae) # this uid is for secondary image capture uid = UID('1.2.840.10008.5.1.4.1.1.7') ae.add_requested_context(uid) ds = dcmread('tester2.dcm') # work in progress, still not working with PACS assoc = ae.associate(dest_ip, 5000, ae_title=dest_ae) if assoc.is_established: print('Associated') status = assoc.send_c_store(ds) if status: print('C-STORE request status: 0x{0:04x}'.format(status.Status)) else: print('Connection timed out, was aborted or received invalid resposne')
def test_is_private(self): """Test the is_private property""" uid = UID('1.2.840.10008.1.2') private_uid = UID('1.2.840.10009.1.2') self.assertTrue(private_uid.is_private) self.assertFalse(uid.is_private)
def testCompareNotEqualByName(self): """UID: comparing not equal by name...""" # from Issue 121 ct_image_storage = UID('1.2.840.10008.5.1.4.1.1.2') msg = "UID not equal comparison by name was not correct" self.assertFalse(ct_image_storage != 'CT Image Storage', msg)
def test_sop_classes_good_uid(self): """ Check AE initialisation produces valid supported SOP classes """ # scu_sop_class ae = AE(scu_sop_class=['1.2.840.10008.1.1', '1.2.840.10008.1.1.1']) self.assertTrue(ae.scu_supported_sop == [UID('1.2.840.10008.1.1'), UID('1.2.840.10008.1.1.1')]) ae = AE(scu_sop_class=[UID('1.2.840.10008.1.1')]) self.assertTrue(ae.scu_supported_sop == [UID('1.2.840.10008.1.1')]) ae = AE(scu_sop_class=[VerificationSOPClass]) self.assertTrue(ae.scu_supported_sop == [UID('1.2.840.10008.1.1')]) ae = AE(scu_sop_class=[1, VerificationSOPClass, 3]) self.assertTrue(ae.scu_supported_sop == [UID('1.2.840.10008.1.1')]) # scp_sop_class ae = AE(scp_sop_class=['1.2.840.10008.1.1', '1.2.840.10008.1.1.1']) self.assertTrue(ae.scp_supported_sop == [UID('1.2.840.10008.1.1'), UID('1.2.840.10008.1.1.1')]) ae = AE(scp_sop_class=[UID('1.2.840.10008.1.1')]) self.assertTrue(ae.scp_supported_sop == [UID('1.2.840.10008.1.1')]) ae = AE(scp_sop_class=[VerificationSOPClass]) self.assertTrue(ae.scp_supported_sop == [UID('1.2.840.10008.1.1')]) ae = AE(scp_sop_class=[1, VerificationSOPClass, 3]) self.assertTrue(ae.scp_supported_sop == [UID('1.2.840.10008.1.1')])
def setup(self): self.enc = Encoder(UID('1.2.3'))
def test_string(self): """Check the string output.""" primitive = ImplementationClassUIDNotification() primitive.implementation_class_uid = UID( '1.2.826.0.1.3680043.9.3811.0.9.0') assert '1.2.826.0.1.3680043.9.3811.0.9.0' in primitive.__str__()
def test_assignment_and_exceptions(self): """ Check incorrect types/values for properties raise exceptions """ primitive = SOPClassCommonExtendedNegotiation() ## Check assignment # SOP Class UID reference_uid = UID('1.2.840.10008.5.1.4.1.1.2') primitive.sop_class_uid = b'1.2.840.10008.5.1.4.1.1.2' assert primitive.sop_class_uid == reference_uid primitive.sop_class_uid = 'abc' assert primitive.sop_class_uid == 'abc' primitive.sop_class_uid = '1.2.840.10008.5.1.4.1.1.2' assert primitive.sop_class_uid == reference_uid primitive.sop_class_uid = UID('1.2.840.10008.5.1.4.1.1.2') assert primitive.sop_class_uid == reference_uid # Service Class UID primitive.service_class_uid = b'1.2.840.10008.5.1.4.1.1.2' assert primitive.service_class_uid == reference_uid primitive.service_class_uid = 'abc' assert primitive.service_class_uid == 'abc' primitive.service_class_uid = '1.2.840.10008.5.1.4.1.1.2' assert primitive.service_class_uid == reference_uid primitive.service_class_uid = UID('1.2.840.10008.5.1.4.1.1.2') assert primitive.service_class_uid == reference_uid # Related General SOP Class Identification ref_list = [ UID('1.2.840.10008.5.1.4.1.1.2'), UID('1.2.840.10008.5.1.4.1.1.3'), UID('1.2.840.10008.5.1.4.1.1.4') ] uid_list = [] uid_list.append(b'1.2.840.10008.5.1.4.1.1.2') uid_list.append('1.2.840.10008.5.1.4.1.1.3') uid_list.append(UID('1.2.840.10008.5.1.4.1.1.4')) primitive.related_general_sop_class_identification = uid_list assert primitive.related_general_sop_class_identification == ref_list primitive.related_general_sop_class_identification = ['abc'] assert primitive.related_general_sop_class_identification == ['abc'] with pytest.raises(TypeError): primitive.related_general_sop_class_identification = 'test' ## Check exceptions # SOP Class UID with pytest.raises(TypeError): primitive.sop_class_uid = 10 with pytest.raises(TypeError): primitive.sop_class_uid = 45.2 # Service Class UID with pytest.raises(TypeError): primitive.service_class_uid = 10 with pytest.raises(TypeError): primitive.service_class_uid = 45.2 # Related General SOP Class Identification with pytest.raises(TypeError): primitive.related_general_sop_class_identification = [10] with pytest.raises(TypeError): primitive.related_general_sop_class_identification = [45.2] # No value set primitive = SOPClassCommonExtendedNegotiation() with pytest.raises(ValueError): item = primitive.from_primitive() primitive.sop_class_uid = b'1.2.840.10008.5.1.4.1.1.2' with pytest.raises(ValueError): item = primitive.from_primitive() primitive = SOPClassCommonExtendedNegotiation() primitive.service_class_uid = b'1.2.840.10008.5.1.4.1.1.2' with pytest.raises(ValueError): item = primitive.from_primitive()
Set module shortcuts and globals """ from pydicom.uid import UID version = ['0', '9', '1'] __version__ = '.'.join(version) # Encoded as SH, 16 bytes maximum # TODO: UPPER_CASE, change to PYNETDICOM_IMPLEMENTATION_VERSION pynetdicom_version = 'PYNETDICOM3_' + ''.join(version) assert 1 <= len(pynetdicom_version) <= 16 # UID prefix provided by https://www.medicalconnections.co.uk/Free_UID # Encoded as UI, 64 bytes maximum # TODO: UPPER_CASE, change to PYNETDICOM_UID_PREFIX pynetdicom_uid_prefix = '1.2.826.0.1.3680043.9.3811.' # TODO: UPPER_CASE, change to PYNETDICOM_IMPLEMENTATION_UID pynetdicom_implementation_uid = UID(pynetdicom_uid_prefix + '.'.join(version)) assert pynetdicom_implementation_uid.is_valid import logging from pynetdicom3.applicationentity import ApplicationEntity as AE from pynetdicom3.association import Association from pynetdicom3.acse import ACSEServiceProvider as ACSE from pynetdicom3.dimse import DIMSEServiceProvider as DIMSE from pynetdicom3.dul import DULServiceProvider as DUL from pynetdicom3.sop_class import STORAGE_CLASS_LIST as StorageSOPClassList from pynetdicom3.sop_class import QR_CLASS_LIST as QueryRetrieveSOPClassList from pynetdicom3.sop_class import VerificationSOPClass
def apply_color_lut(arr, ds=None, palette=None): """Apply a color palette lookup table to `arr`. .. versionadded:: 1.4 If (0028,1201-1203) *Palette Color Lookup Table Data* are missing then (0028,1221-1223) *Segmented Palette Color Lookup Table Data* must be present and vice versa. The presence of (0028,1204) *Alpha Palette Color Lookup Table Data* or (0028,1224) *Alpha Segmented Palette Color Lookup Table Data* is optional. Use of this function with the :dcm:`Enhanced Palette Color Lookup Table Module<part03/sect_C.7.6.23.html>` or :dcm:`Supplemental Palette Color LUT Module<part03/sect_C.7.6.19.html>` is not currently supported. Parameters ---------- arr : numpy.ndarray The pixel data to apply the color palette to. ds : dataset.Dataset, optional Required if `palette` is not supplied. A :class:`~pydicom.dataset.Dataset` containing a suitable :dcm:`Image Pixel<part03/sect_C.7.6.3.html>` or :dcm:`Palette Color Lookup Table<part03/sect_C.7.9.html>` Module. palette : str or uid.UID, optional Required if `ds` is not supplied. The name of one of the :dcm:`well-known<part06/chapter_B.html>` color palettes defined by the DICOM Standard. One of: ``'HOT_IRON'``, ``'PET'``, ``'HOT_METAL_BLUE'``, ``'PET_20_STEP'``, ``'SPRING'``, ``'SUMMER'``, ``'FALL'``, ``'WINTER'`` or the corresponding well-known (0008,0018) *SOP Instance UID*. Returns ------- numpy.ndarray The RGB or RGBA pixel data as an array of ``np.uint8`` or ``np.uint16`` values, depending on the 3rd value of (0028,1201) *Red Palette Color Lookup Table Descriptor*. References ---------- * :dcm:`Image Pixel Module<part03/sect_C.7.6.3.html>` * :dcm:`Supplemental Palette Color LUT Module<part03/sect_C.7.6.19.html>` * :dcm:`Enhanced Palette Color LUT Module<part03/sect_C.7.6.23.html>` * :dcm:`Palette Colour LUT Module<part03/sect_C.7.9.html>` * :dcm:`Supplemental Palette Color LUTs <part03/sect_C.8.16.2.html#sect_C.8.16.2.1.1.1>` """ # Note: input value (IV) is the stored pixel value in `arr` # LUTs[IV] -> [R, G, B] values at the IV pixel location in `arr` if not ds and not palette: raise ValueError("Either 'ds' or 'palette' is required") if palette: # Well-known palettes are all 8-bits per entry datasets = { '1.2.840.10008.1.5.1': 'hotiron.dcm', '1.2.840.10008.1.5.2': 'pet.dcm', '1.2.840.10008.1.5.3': 'hotmetalblue.dcm', '1.2.840.10008.1.5.4': 'pet20step.dcm', '1.2.840.10008.1.5.5': 'spring.dcm', '1.2.840.10008.1.5.6': 'summer.dcm', '1.2.840.10008.1.5.7': 'fall.dcm', '1.2.840.10008.1.5.8': 'winter.dcm', } if not UID(palette).is_valid: try: uids = { 'HOT_IRON': '1.2.840.10008.1.5.1', 'PET': '1.2.840.10008.1.5.2', 'HOT_METAL_BLUE': '1.2.840.10008.1.5.3', 'PET_20_STEP': '1.2.840.10008.1.5.4', 'SPRING': '1.2.840.10008.1.5.5', 'SUMMER': '1.2.840.10008.1.5.6', 'FALL': '1.2.840.10008.1.5.8', 'WINTER': '1.2.840.10008.1.5.7', } palette = uids[palette] except KeyError: raise ValueError("Unknown palette '{}'".format(palette)) try: from pydicom import dcmread fname = datasets[palette] ds = dcmread(get_palette_files(fname)[0]) except KeyError: raise ValueError("Unknown palette '{}'".format(palette)) # C.8.16.2.1.1.1: Supplemental Palette Color LUT # TODO: Requires greyscale visualisation pipeline if getattr(ds, 'PixelPresentation', None) in ['MIXED', 'COLOR']: raise ValueError( "Use of this function with the Supplemental Palette Color Lookup " "Table Module is not currently supported" ) # All channels are supposed to be identical lut_desc = ds.RedPaletteColorLookupTableDescriptor # A value of 0 = 2^16 entries nr_entries = lut_desc[0] or 2**16 # May be negative if Pixel Representation is 1 first_map = lut_desc[1] # Actual bit depth may be larger (8 bit entries in 16 bits allocated) nominal_depth = lut_desc[2] dtype = np.dtype('uint{:.0f}'.format(nominal_depth)) luts = [] if 'RedPaletteColorLookupTableData' in ds: # LUT Data is described by PS3.3, C.7.6.3.1.6 r_lut = ds.RedPaletteColorLookupTableData g_lut = ds.GreenPaletteColorLookupTableData b_lut = ds.BluePaletteColorLookupTableData a_lut = getattr(ds, 'AlphaPaletteColorLookupTableData', None) actual_depth = len(r_lut) / nr_entries * 8 dtype = np.dtype('uint{:.0f}'.format(actual_depth)) for lut in [ii for ii in [r_lut, g_lut, b_lut, a_lut] if ii]: luts.append(np.frombuffer(lut, dtype=dtype)) elif 'SegmentedRedPaletteColorLookupTableData' in ds: # Segmented LUT Data is described by PS3.3, C.7.9.2 r_lut = ds.SegmentedRedPaletteColorLookupTableData g_lut = ds.SegmentedGreenPaletteColorLookupTableData b_lut = ds.SegmentedBluePaletteColorLookupTableData a_lut = getattr(ds, 'SegmentedAlphaPaletteColorLookupTableData', None) endianness = '<' if ds.is_little_endian else '>' byte_depth = nominal_depth // 8 fmt = 'B' if byte_depth == 1 else 'H' actual_depth = nominal_depth for seg in [ii for ii in [r_lut, g_lut, b_lut, a_lut] if ii]: len_seg = len(seg) // byte_depth s_fmt = endianness + str(len_seg) + fmt lut = _expand_segmented_lut(unpack(s_fmt, seg), s_fmt) luts.append(np.asarray(lut, dtype=dtype)) else: raise ValueError("No suitable Palette Color Lookup Table Module found") if actual_depth not in [8, 16]: raise ValueError( "The bit depth of the LUT data '{:.1f}' is invalid (only 8 or 16 " "bits per entry allowed)".format(actual_depth) ) lut_lengths = [len(ii) for ii in luts] if not all(ii == lut_lengths[0] for ii in lut_lengths[1:]): raise ValueError("LUT data must be the same length") # IVs < `first_map` get set to first LUT entry (i.e. index 0) clipped_iv = np.zeros(arr.shape, dtype=dtype) # IVs >= `first_map` are mapped by the Palette Color LUTs # `first_map` may be negative, positive or 0 mapped_pixels = arr >= first_map clipped_iv[mapped_pixels] = arr[mapped_pixels] - first_map # IVs > number of entries get set to last entry np.clip(clipped_iv, 0, nr_entries - 1, out=clipped_iv) # Output array may be RGB or RGBA out = np.empty(list(arr.shape) + [len(luts)], dtype=dtype) for ii, lut in enumerate(luts): out[..., ii] = lut[clipped_iv] return out
# Get a list of all the class members of the current module members = inspect.getmembers(sys.modules[__name__], lambda mbr: isinstance(mbr, str)) for obj in members: if hasattr(obj[1], "service_class") and obj[1] == uid: return cast(SOPClass, obj[1]) sop_class = SOPClass(uid) sop_class._service_class = ServiceClass return sop_class # Well-known SOP Instance UIDs for the supported Service Classes DisplaySystemInstance = UID("1.2.840.10008.5.1.1.40.1") """``1.2.840.10008.5.1.1.40.1`` .. versionadded:: 1.5 """ PrinterConfigurationRetrievalInstance = UID("1.2.840.10008.5.1.1.17.376") """``1.2.840.10008.5.1.1.17.376`` .. versionadded:: 1.5 """ PrinterInstance = UID("1.2.840.10008.5.1.1.17") """``1.2.840.10008.5.1.1.17`` .. versionadded:: 1.5 """ ProceduralEventLoggingInstance = UID("1.2.840.10008.1.40.1")
def test_presentation_context_abstract(self): """Check the presentation context generation abstract syntax""" ## SCU SOP Classes # str -> UID ae = AE(scu_sop_class=['1.1'], transfer_syntax=['1.2.840.10008.1.2']) ab_syn = ae.presentation_contexts_scu[0].AbstractSyntax self.assertEqual(ab_syn, UID('1.1')) self.assertTrue(isinstance(ab_syn, UID)) # UID no change ae = AE(scu_sop_class=[UID('1.2')], transfer_syntax=['1.2.840.10008.1.2']) ab_syn = ae.presentation_contexts_scu[0].AbstractSyntax self.assertEqual(ab_syn, UID('1.2')) self.assertTrue(isinstance(ab_syn, UID)) # sop_class -> UID ae = AE(scu_sop_class=[VerificationSOPClass], transfer_syntax=['1.2.840.10008.1.2']) ab_syn = ae.presentation_contexts_scu[0].AbstractSyntax self.assertEqual(ab_syn, UID('1.2.840.10008.1.1')) self.assertTrue(isinstance(ab_syn, UID)) # bytes -> UID ae = AE(scu_sop_class=[b'1.3'], transfer_syntax=['1.2.840.10008.1.2']) ab_syn = ae.presentation_contexts_scu[0].AbstractSyntax self.assertEqual(ab_syn, UID('1.3')) self.assertTrue(isinstance(ab_syn, UID)) # If not str, bytes, UID, serviceclass raise with self.assertRaises(TypeError): ae = AE(scu_sop_class=[12345], transfer_syntax=['1.2.840.10008.1.2']) # If not valid UID raise with self.assertRaises(TypeError): ae = AE(scu_sop_class=['1.3.'], transfer_syntax=['1.2.840.10008.1.2']) ## SCP SOP Classes # str -> UID ae = AE(scp_sop_class=['1.1'], transfer_syntax=['1.2.840.10008.1.2']) ab_syn = ae.presentation_contexts_scp[0].AbstractSyntax self.assertEqual(ab_syn, UID('1.1')) self.assertTrue(isinstance(ab_syn, UID)) # UID no change ae = AE(scp_sop_class=[UID('1.2')], transfer_syntax=['1.2.840.10008.1.2']) ab_syn = ae.presentation_contexts_scp[0].AbstractSyntax self.assertEqual(ab_syn, UID('1.2')) self.assertTrue(isinstance(ab_syn, UID)) # sop_class -> UID ae = AE(scp_sop_class=[VerificationSOPClass], transfer_syntax=['1.2.840.10008.1.2']) ab_syn = ae.presentation_contexts_scp[0].AbstractSyntax self.assertEqual(ab_syn, UID('1.2.840.10008.1.1')) self.assertTrue(isinstance(ab_syn, UID)) # bytes -> UID ae = AE(scp_sop_class=[b'1.3'], transfer_syntax=['1.2.840.10008.1.2']) ab_syn = ae.presentation_contexts_scp[0].AbstractSyntax self.assertEqual(ab_syn, UID('1.3')) self.assertTrue(isinstance(ab_syn, UID)) # If not str, bytes, UID, serviceclass raise with self.assertRaises(TypeError): ae = AE(scp_sop_class=[12345], transfer_syntax=['1.2.840.10008.1.2']) # If not valid UID raise with self.assertRaises(TypeError): ae = AE(scp_sop_class=['1.3.'], transfer_syntax=['1.2.840.10008.1.2'])
def test_inequality(self): """Test that UID.__ne__ works with private UIDs.""" assert not self.uid != UID('9.9.999.90009.1.2') assert not self.uid != '9.9.999.90009.1.2' assert self.uid != UID('9.9.999.90009.1.3') assert self.uid != '9.9.999.90009.1.3'
def test_raises(self): """Test raises exception if not a str type""" with pytest.raises(TypeError): UID(1234)
def setup_class(self): """Set default UID""" self.uid = UID('9.9.999.90009.1.2')
def build_context(abstract_syntax, transfer_syntax=None): """Return a PresentationContext built from the `abstract_syntax`. Parameters ---------- abstract_syntax : str or UID or sop_class.SOPClass The UID or SOPClass instance to use as the abstract syntax. transfer_syntax : str/UID or list of str/UID The transfer syntax UID(s) to use (default: [Implicit VR Little Endian, Explicit VR Little Endian, Implicit VR Big Endian]) Examples -------- Specifying a presentation context with the default transfer syntaxes >>> from pynetdicom import build_context >>> context = build_context('1.2.840.10008.1.1') >>> print(context) Abstract Syntax: Verification SOP Class Transfer Syntax(es): =Implicit VR Little Endian =Explicit VR Little Endian =Explicit VR Big Endian Specifying the abstract syntax using a pynetdicom SOPClass instance and a single transfer syntax >>> from pynetdicom import build_context >>> from pynetdicom.sop_class import VerificationSOPClass >>> context = build_context(VerificationSOPClass, '1.2.840.10008.1.2') >>> print(context) Abstract Syntax: Verification SOP Class Transfer Syntax(es): =Implicit VR Little Endian Specifying multiple transfer syntaxes >>> from pydicom.uid import UID >>> from pynetdicom import build_context >>> context = build_context(UID('1.2.840.10008.1.1'), ['1.2.840.10008.1.2', ... '1.2.840.10008.1.2.4.50']) >>> print(context) Abstract Syntax: Verification SOP Class Transfer Syntax(es): =Implicit VR Little Endian =JPEG Baseline (Process 1) Returns ------- presentation.PresentationContext """ if transfer_syntax is None: transfer_syntax = DEFAULT_TRANSFER_SYNTAXES abstract_syntax = UID(abstract_syntax) # Allow single transfer syntax values for convenience if isinstance(transfer_syntax, str): transfer_syntax = [transfer_syntax] context = PresentationContext() context.abstract_syntax = abstract_syntax context.transfer_syntax = transfer_syntax return context
def setup_class(self): """Set default UID""" self.uid = UID('1.2.840.10008.1.2')
from pydicom.uid import UID from ._version import __version__, __version_info__ # UID prefix provided by https://www.medicalconnections.co.uk/Free_UID # Encoded as UI, 64 bytes maximum PYNETDICOM_UID_PREFIX = '1.2.826.0.1.3680043.9.3811.' # Encoded as SH, 16 bytes maximum PYNETDICOM_IMPLEMENTATION_VERSION = ( 'PYNETDICOM_' + ''.join([str(ii) for ii in __version_info__['release']])) assert 1 <= len(PYNETDICOM_IMPLEMENTATION_VERSION) <= 16 PYNETDICOM_IMPLEMENTATION_UID = UID( PYNETDICOM_UID_PREFIX + '.'.join([str(ii) for ii in __version_info__['release']])) assert PYNETDICOM_IMPLEMENTATION_UID.is_valid import logging # Convenience imports from pynetdicom import events as evt from pynetdicom.ae import ApplicationEntity as AE from pynetdicom.association import Association from pynetdicom.presentation import ( build_context, build_role, DEFAULT_TRANSFER_SYNTAXES, VerificationPresentationContexts, StoragePresentationContexts,
def test_assignment(self): """Check assignment works correctly""" assoc = A_ASSOCIATE() with pytest.raises(AttributeError): assoc.mode = "test value" with pytest.raises(AttributeError): assoc.presentation_requirements = "test value2" with pytest.raises(AttributeError): assoc.session_requirements = "test value3" assoc.application_context_name = None assert assoc.application_context_name is None assoc.application_context_name = "1.2.840.10008.3.1.1.1" assert assoc.application_context_name == UID("1.2.840.10008.3.1.1.1") assoc.application_context_name = b"1.2.840.10008.3.1.1.1" assert assoc.application_context_name == UID("1.2.840.10008.3.1.1.1") assoc.application_context_name = UID("1.2.840.10008.3.1.1.1") assert assoc.application_context_name == UID("1.2.840.10008.3.1.1.1") msg = "'Calling AE Title' must be str, not 'NoneType'" with pytest.raises(TypeError, match=msg): assoc.calling_ae_title = None assoc.calling_ae_title = "ABCDEF1234567890" assert assoc.calling_ae_title == "ABCDEF1234567890" msg = "'Called AE Title' must be str, not 'NoneType'" with pytest.raises(TypeError, match=msg): assoc.called_ae_title = None assert assoc.responding_ae_title == assoc.called_ae_title assoc.called_ae_title = "1234567890ABCDEF" assert assoc.called_ae_title == "1234567890ABCDEF" assert assoc.responding_ae_title == assoc.called_ae_title max_length = MaximumLengthNotification() max_length.maximum_length_received = 31222 assoc.user_information.append(max_length) assert assoc.user_information[0].maximum_length_received == 31222 assoc.user_information = ["a", max_length] assert assoc.user_information == [max_length] assoc.result = None assert assoc.result is None assoc.result = 0 assoc.result = 1 assert assoc.result == 1 assoc.result = 2 assert assoc.result == 2 assoc.result_source = None assert assoc.result_source is None assoc.result_source = 1 assert assoc.result_source == 1 assoc.result_source = 2 assert assoc.result_source == 2 assoc.result_source = 3 assert assoc.result_source == 3 assoc.diagnostic = None assert assoc.diagnostic is None assoc.diagnostic = 1 assert assoc.diagnostic == 1 assoc.diagnostic = 2 assert assoc.diagnostic == 2 assoc.diagnostic = 3 assert assoc.diagnostic == 3 assoc.diagnostic = 7 assert assoc.diagnostic == 7 assoc.calling_presentation_address = None assert assoc.calling_presentation_address is None assoc.calling_presentation_address = ("10.40.94.43", 105) assert assoc.calling_presentation_address == ("10.40.94.43", 105) assoc.called_presentation_address = None assert assoc.called_presentation_address is None assoc.called_presentation_address = ("10.40.94.44", 106) assert assoc.called_presentation_address == ("10.40.94.44", 106) pc = PresentationContext() pc.context_id = 1 assoc.presentation_context_definition_list = [pc] assert assoc.presentation_context_definition_list == [pc] assoc.presentation_context_definition_list = ["a", pc] assert assoc.presentation_context_definition_list == [pc] assoc.presentation_context_definition_results_list = [pc] assert assoc.presentation_context_definition_results_list == [pc] assoc.presentation_context_definition_results_list = ["a", pc] assert assoc.presentation_context_definition_results_list == [pc] assoc = A_ASSOCIATE() # No maximum_length_received set assert assoc.maximum_length_received is None # No MaximumLengthNotification present assoc.maximum_length_received = 31223 assert assoc.user_information[0].maximum_length_received == 31223 assert assoc.maximum_length_received == 31223 # MaximumLengthNotification already present assoc.maximum_length_received = 31224 assert assoc.maximum_length_received == 31224 # No ImplementationClassUIDNotification present assoc.implementation_class_uid = "1.1.2.3.4" assert assoc.user_information[1].implementation_class_uid == UID("1.1.2.3.4") assert assoc.implementation_class_uid == UID("1.1.2.3.4") # ImplementationClassUIDNotification already present assoc.implementation_class_uid = "1.1.2.3.4" assert assoc.implementation_class_uid == UID("1.1.2.3.4")
def test_assignment_and_exceptions(self): """ Check incorrect types/values for properties raise exceptions """ primitive = SCP_SCU_RoleSelectionNegotiation() ## Check assignment # SOP Class UID reference_uid = UID('1.2.840.10008.5.1.4.1.1.2') primitive.sop_class_uid = b'1.2.840.10008.5.1.4.1.1.2' assert primitive.sop_class_uid == reference_uid primitive.sop_class_uid = '1.2.840.10008.5.1.4.1.1.2' assert primitive.sop_class_uid == reference_uid primitive.sop_class_uid = UID('1.2.840.10008.5.1.4.1.1.2') assert primitive.sop_class_uid == reference_uid # SCP Role primitive.scp_role = False assert primitive.scp_role is False # SCU Role primitive.scu_role = True assert primitive.scu_role is True ## Check exceptions with pytest.raises(TypeError): primitive.sop_class_uid = 10 with pytest.raises(TypeError): primitive.sop_class_uid = 45.2 with pytest.raises(TypeError): primitive.scp_role = 1 with pytest.raises(TypeError): primitive.scp_role = 'abc' with pytest.raises(TypeError): primitive.scu_role = 1 with pytest.raises(TypeError): primitive.scu_role = 'abc' # No value set primitive = SCP_SCU_RoleSelectionNegotiation() with pytest.raises(ValueError): item = primitive.from_primitive() primitive.sop_class_uid = b'1.2.840.10008.5.1.4.1.1.2' with pytest.raises(ValueError): item = primitive.from_primitive() primitive.scp_role = False with pytest.raises(ValueError): item = primitive.from_primitive() primitive = SCP_SCU_RoleSelectionNegotiation() primitive.sop_class_uid = b'1.2.840.10008.5.1.4.1.1.2' primitive.scu_role = True item = primitive.from_primitive() assert item.scu_role assert not item.scp_role primitive = SCP_SCU_RoleSelectionNegotiation() primitive.scp_role = True primitive.scu_role = True with pytest.raises(ValueError): item = primitive.from_primitive()
def test_validate_uid_conformance_true(self, uid, is_valid): _config.ENFORCE_UID_CONFORMANCE = True assert validate_uid(UID(uid)) == is_valid[0]
def test_assignment(self): """ Check assignment works correctly """ assoc = A_ASSOCIATE() with pytest.raises(AttributeError): assoc.mode = "test value" with pytest.raises(AttributeError): assoc.presentation_requirements = "test value2" with pytest.raises(AttributeError): assoc.session_requirements = "test value3" assoc.application_context_name = "1.2.840.10008.3.1.1.1" assert assoc.application_context_name == UID('1.2.840.10008.3.1.1.1') assoc.application_context_name = b"1.2.840.10008.3.1.1.1" assert assoc.application_context_name == UID('1.2.840.10008.3.1.1.1') assoc.application_context_name = UID("1.2.840.10008.3.1.1.1") assert assoc.application_context_name == UID('1.2.840.10008.3.1.1.1') assoc.calling_ae_title = 'ABCD1234ABCD12345' assert assoc.calling_ae_title == b'ABCD1234ABCD1234' assoc.called_ae_title = 'ABCD1234ABCD12345' assert assoc.called_ae_title == b'ABCD1234ABCD1234' assert assoc.responding_ae_title == b'ABCD1234ABCD1234' max_length = MaximumLengthNotification() max_length.maximum_length_received = 31222 assoc.user_information.append(max_length) assert assoc.user_information[0].maximum_length_received == 31222 assoc.user_information = ['a', max_length] assert assoc.user_information == [max_length] assoc.result = 0 assert assoc.result == 0 assoc.result = 1 assert assoc.result == 1 assoc.result = 2 assert assoc.result == 2 assoc.result_source = 1 assert assoc.result_source == 1 assoc.result_source = 2 assert assoc.result_source == 2 assoc.result_source = 3 assert assoc.result_source == 3 assoc.diagnostic = 1 assert assoc.diagnostic == 1 assoc.diagnostic = 2 assert assoc.diagnostic == 2 assoc.diagnostic = 3 assert assoc.diagnostic == 3 assoc.diagnostic = 7 assert assoc.diagnostic == 7 assoc.calling_presentation_address = ('10.40.94.43', 105) assert assoc.calling_presentation_address == ('10.40.94.43', 105) assoc.called_presentation_address = ('10.40.94.44', 106) assert assoc.called_presentation_address == ('10.40.94.44', 106) pc = PresentationContext() pc.context_id = 1 assoc.presentation_context_definition_list = [pc] assert assoc.presentation_context_definition_list == [pc] assoc.presentation_context_definition_list = ['a', pc] assert assoc.presentation_context_definition_list == [pc] assoc.presentation_context_definition_results_list = [pc] assert assoc.presentation_context_definition_results_list == [pc] assoc.presentation_context_definition_results_list = ['a', pc] assert assoc.presentation_context_definition_results_list == [pc] assoc = A_ASSOCIATE() # No maximum_length_received set assert assoc.maximum_length_received is None # No MaximumLengthNotification present assoc.maximum_length_received = 31223 assert assoc.user_information[0].maximum_length_received == 31223 assert assoc.maximum_length_received == 31223 # MaximumLengthNotification already present assoc.maximum_length_received = 31224 assert assoc.maximum_length_received == 31224 # No ImplementationClassUIDNotification present assoc.implementation_class_uid = '1.1.2.3.4' assert assoc.user_information[1].implementation_class_uid == UID( '1.1.2.3.4') assert assoc.implementation_class_uid == UID('1.1.2.3.4') # ImplementationClassUIDNotification already present assoc.implementation_class_uid = '1.1.2.3.4' assert assoc.implementation_class_uid == UID('1.1.2.3.4')
def test_validate_uid_conformance_false(self, uid, is_valid): _config.ENFORCE_UID_CONFORMANCE = False assert validate_uid(UID(uid)) == is_valid[1]