def description(self): """Return the DICOM dictionary name for the element.""" if self.tag.is_private: name = "Private tag data" # default if hasattr(self, 'private_creator'): try: # If have name from private dictionary, use it, but # but put in square brackets so is differentiated, # and clear that cannot access it by name name = private_dictionary_description( self.tag, self.private_creator) name = "[%s]" % (name) except KeyError: pass elif self.tag.elem >> 8 == 0: name = "Private Creator" elif dictionary_has_tag(self.tag) or repeater_has_tag(self.tag): name = dictionary_description(self.tag) # implied Group Length dicom versions < 3 elif self.tag.element == 0: name = "Group Length" else: name = "" return name
def priorfix_RemoveIllegalTags(ds: Dataset, parent_kw: str, log: list) -> bool: tags_to_be_removed = [] fixed = False for k, a in ds.items(): try: a = ds[k] except KeyError as err: if not k.is_private: if not Dictionary.dictionary_has_tag(k): ttaagg = validate_vr.tag2str(a.tag) eerr = mesgtext_cc.ErrorInfo( "General Fix - tag {} in {}is not a standard dicom tag" .format(ttaagg, parent_kw), 'fixed by removing the attribute') log.append(eerr.getWholeMessage()) tags_to_be_removed.append(a.tag) continue if type(a.value) == Sequence: for item in a.value: fixed = fixed or priorfix_RemoveIllegalTags( item, a.keyword, log) elif type(a.value) == Dataset: fixed = fixed or priorfix_RemoveIllegalTags( a.value, a.keyword, log) for tg in tags_to_be_removed: del ds[tg] return fixed
def description(self): """Return the DICOM dictionary name for the element.""" if dictionary_has_tag(self.tag) or repeater_has_tag(self.tag): name = dictionary_description(self.tag) elif self.tag.is_private: name = "Private tag data" # default if hasattr(self, 'private_creator'): try: # If have name from private dictionary, use it, but # but put in square brackets so is differentiated, # and clear that cannot access it by name name = private_dictionary_description( self.tag, self.private_creator) name = "[%s]" % (name) except KeyError: pass elif self.tag.elem >> 8 == 0: name = "Private Creator" # implied Group Length dicom versions < 3 elif self.tag.element == 0: name = "Group Length" else: name = "" return name
def tag2str(ttag: BaseTag): if Dictionary.dictionary_has_tag(ttag): desc = Dictionary.dictionary_description(ttag) vr = Dictionary.dictionary_VR(ttag) txt = "->{}:{}".format(desc, vr) else: txt = '' msg = "(0x{:0>4x}, 0x{:0>4x})".format(ttag.group, ttag.element, txt) return msg
def keyword(self) -> str: """Return the element's keyword (if known) as :class:`str`. For officially registered DICOM Data Elements this will be the *Keyword* as given in :dcm:`Table 6-1<part06/chapter_6.html#table_6-1>`. For private or unknown elements this will return an empty string ``''``. """ if dictionary_has_tag(self.tag): return dictionary_keyword(self.tag) return ''
def is_retired(self) -> bool: """Return the element's retired status as :class:`bool`. For officially registered DICOM Data Elements this will be ``True`` if the retired status as given in the DICOM Standard, Part 6, :dcm:`Table 6-1<part06/chapter_6.html#table_6-1>` is 'RET'. For private or unknown elements this will always be ``False``. """ if dictionary_has_tag(self.tag): return dictionary_is_retired(self.tag) return False
def name(self) -> str: """Return the DICOM dictionary name for the element as :class:`str`. Returns ------- str * For officially registered DICOM Data Elements this will be the *Name* as given in :dcm:`Table 6-1<part06/chapter_6.html#table_6-1>`. * For private elements known to *pydicom* this will be the *Name* in the format ``'[name]'``. * For unknown private elements this will be ``'Private tag data'``. * Otherwise returns an empty string ``''``. """ if self.tag.is_private: if self.private_creator: try: # If have name from private dictionary, use it, but # but put in square brackets so is differentiated, # and clear that cannot access it by name name = private_dictionary_description( self.tag, self.private_creator) return f"[{name}]" except KeyError: pass elif self.tag.element >> 8 == 0: return "Private Creator" return "Private tag data" # default if dictionary_has_tag(self.tag) or repeater_has_tag(self.tag): return dictionary_description(self.tag) # implied Group Length dicom versions < 3 if self.tag.element == 0: return "Group Length" return ""
def test_dict_has_tag(self): """Test dictionary_has_tag""" self.assertTrue(dictionary_has_tag(0x00100010)) self.assertFalse(dictionary_has_tag(0x11110010))
def test_dict_has_tag(self): """Test dictionary_has_tag""" assert dictionary_has_tag(0x00100010) assert not dictionary_has_tag(0x11110010)
def is_retired(self): """The data_element's retired status""" if dictionary_has_tag(self.tag): return dictionary_is_retired(self.tag) else: return False
def is_retired(self): """The element's retired status.""" if dictionary_has_tag(self.tag): return dictionary_is_retired(self.tag) else: return False
def keyword(self): """Return the element's keyword (if known) as :class:`str`.""" if dictionary_has_tag(self.tag): return dictionary_keyword(self.tag) else: return ''
def is_retired(self): """Return the element's retired status as :class:`bool`.""" if dictionary_has_tag(self.tag): return dictionary_is_retired(self.tag) else: return False
def message_to_primitive(self): """ Convert the current DIMSE Message object to a DIMSE service parameters primitive Returns ------- primitive : pynetdicom.DIMSEparameters DIMSE service primitive The primitive generated from the current DIMSE Message """ cls_type_name = self.__class__.__name__ if 'C_ECHO' in cls_type_name: primitive = C_ECHO_ServiceParameters() elif 'C_STORE' in cls_type_name: primitive = C_STORE_ServiceParameters() elif 'C_FIND' in cls_type_name: primitive = C_FIND_ServiceParameters() elif 'C_GET' in cls_type_name: primitive = C_GET_ServiceParameters() elif 'C_MOVE' in cls_type_name: primitive = C_MOVE_ServiceParameters() elif 'N_EVENT' in cls_type_name: primitive = N_EVENT_REPORT_ServiceParameters() elif 'N_GET' in cls_type_name: primitive = N_GET_ServiceParameters() elif 'N_SET' in cls_type_name: primitive = N_SET_ServiceParameters() elif 'N_ACTION' in cls_type_name: primitive = N_ACTION_ServiceParameters() elif 'N_CREATE' in cls_type_name: primitive = N_CREATE_ServiceParameters() elif 'N_DELETE' in cls_type_name: primitive = N_DELETE_ServiceParameters() ## Command Set # For each parameter in the primitive, set the appropriate value # from the Message's Command Set for elem in self.command_set: if dictionary_has_tag(elem.tag): elem_name = dictionary_keyword(elem.tag) else: elem_name = elem.name.replace(' ', '') if hasattr(primitive, elem_name): try: setattr(primitive, elem_name, self.command_set.__getattr__(elem_name)) except: logger.error('DIMSE failed to convert message to primitive') ## Datasets if cls_type_name == 'C_STORE_RQ': setattr(primitive, 'DataSet', self.data_set) elif cls_type_name in ['C_FIND_RQ', 'C_FIND_RSP', 'C_GET_RQ', 'C_GET_RSP', 'C_MOVE_RQ', 'C_MOVE_RSP']: setattr(primitive, 'Identifier', self.data_set) elif cls_type_name == 'N_EVENT_REPORT_RQ': setattr(primitive, 'EventInformation', self.data_set) elif cls_type_name == 'N_EVENT_REPORT_RSP': setattr(primitive, 'EventReply', self.data_set) elif cls_type_name in ['N_GET_RSP', 'N_SET_RSP', 'N_CREATE_RQ', 'N_CREATE_RSP']: setattr(primitive, 'AttributeList', self.data_set) elif cls_type_name == 'N_SET_RQ': setattr(primitive, 'ModificationList', self.data_set) elif cls_type_name == 'N_ACTION_RQ': setattr(primitive, 'ActionInformation', self.data_set) elif cls_type_name == 'N_ACTION_RSP': setattr(primitive, 'ActionReply', self.data_set) return primitive
def primitive_to_message(self, primitive): """ Convert a DIMSE service parameters primitive to the current DIMSE message object Parameters ---------- primitive : pynetdicom.DIMSEparameters DIMSE service parameter The primitive to convert to the current DIMSE Message object """ ## Command Set for elem in self.command_set: # Use the short version of the element names as these should # match the parameter names in the primitive # # Nope, there's no guarantee that this will be the case # I think I'll add a keyword parameter to the pydicom Element # class and push upstream # elem_name = elem.keyword # # In the meantime we can add a workaround if dictionary_has_tag(elem.tag): elem_name = dictionary_keyword(elem.tag) else: elem_name = elem.name.replace(' ', '') # Old method if elem_name in primitive.__dict__.keys(): if primitive.__dict__[elem_name] is not None: elem.value = primitive.__dict__[elem_name] else: del self.command_set[elem.tag] # New method elif hasattr(primitive, elem_name): # If value hasn't been set for a parameter then delete # the corresponding element attr = getattr(primitive, elem_name) if attr is not None: elem.value = attr else: del self.command_set[elem.tag] # Theres a one-to-one relationship in the message_type dict, so invert # it for convenience rev_type = {} for value in message_type.keys(): rev_type[message_type[value]] = value cls_type_name = self.__class__.__name__.replace('_', '-') self.command_set.CommandField = rev_type[cls_type_name] ## Data Set # Default to no Data Set self.data_set = BytesIO() self.command_set.CommandDataSetType = 0x0101 # These message types should (except for C-FIND-RSP) always have # a Data Set cls_type_name = self.__class__.__name__ if cls_type_name == 'C_STORE_RQ': self.data_set = primitive.DataSet self.command_set.CommandDataSetType = 0x0001 elif cls_type_name in ['C_FIND_RQ', 'C_GET_RQ', 'C_GET_RSP', 'C_MOVE_RQ', 'C_MOVE_RSP']: self.data_set = primitive.Identifier self.command_set.CommandDataSetType = 0x0001 # C-FIND-RSP only has a Data Set when the Status is pending (0x0001) elif cls_type_name == 'C_FIND_RSP' and \ self.command_set.Status in [0xFF00, 0xFF01]: self.data_set = primitive.Identifier self.command_set.CommandDataSetType = 0x0001 elif cls_type_name == 'N_EVENT_REPORT_RQ': self.data_set = primitive.EventInformation self.command_set.CommandDataSetType = 0x0001 elif cls_type_name == 'N_EVENT_REPORT_RSP': self.data_set = primitive.EventReply self.command_set.CommandDataSetType = 0x0001 elif cls_type_name in ['N_GET_RSP', 'N_SET_RSP', 'N_CREATE_RQ', 'N_CREATE_RSP']: self.data_set = primitive.AttributeList self.command_set.CommandDataSetType = 0x0001 elif cls_type_name == 'N_SET_RQ': self.data_set = primitive.ModificationList self.command_set.CommandDataSetType = 0x0001 elif cls_type_name == 'N_ACTION_RQ': self.data_set = primitive.ActionInformation self.command_set.CommandDataSetType = 0x0001 elif cls_type_name == 'N_ACTION_RSP': self.data_set = primitive.ActionReply self.command_set.CommandDataSetType = 0x0001 elif cls_type_name in ['C_ECHO_RQ', 'C_ECHO_RSP', 'N_DELETE_RQ', 'C_STORE_RSP', 'C_CANCEL_RQ', 'N_DELETE_RSP', 'C_FIND_RSP']: pass else: logger.error("DIMSE - Can't convert primitive to message for " "unknown message type '%s'" %cls_type_name) # Set the Command Set length self._set_command_group_length()
def keyword(self): """The element's keyword (if known).""" if dictionary_has_tag(self.tag): return dictionary_keyword(self.tag) else: return ''
def test_dict_has_tag(self): """Test dictionary_has_tag""" assert dictionary_has_tag(0x00100010) assert not dictionary_has_tag(0x11110010) assert dictionary_has_tag("PatientName") assert not dictionary_has_tag("PatientMane")
def keyword(self): """The data_element's keyword (if known)""" if dictionary_has_tag(self.tag): return dictionary_keyword(self.tag) else: return ''