def verifyType3(ds: Dataset, module: str, element: str, verbose: bool, log: list, fix_trivials: bool, multiplicityMin: uint32, multiplicityMax: uint32) -> bool: # Type 3 - Optional Data Element not_exists = False reason = "" if element in ds: elem = ds[element] else: not_exists = True # this is optional err_vr = False err_vm = False # do not check emptiness if not not_exists: if not verifyVR(elem, module, element, verbose, log): reason = "Error - T<{}> {}" reason = reason.format(ErrorType.Type3VR.value, MMsgDC("BadValueRepresentation")) err_vr = True else: if not verifyVM(elem, module, element, verbose, log, multiplicityMin, multiplicityMax, "source"): reason = "Error - T<{}> {}" reason = reason.format(ErrorType.Type3VM.value, MMsgDC("BadAttributeValueMultiplicity")) err_vm = True if len(reason) != 0: ViolationMessage(reason, MMsgDC("Type3"), module, element, log, verbose) else: ValidMessage(MMsgDC("Type3"), module, element, log, verbose) return len(reason) == 0
def verifyNotZero(elem: DataElement, verbose: bool, log: list, which: int, warningNotError: bool) -> bool: success = True if elem.is_empty: return True val = elem.value vm = elem.VM if type(val) == MultiValue: if which == -1: candidate = val else: if which >= vm: return False else: candidate = [val[which]] else: if which >= 1: return False else: candidate = [val] for i, count in zip(candidate, range(0, len(candidate))): if not isPydicomNumeric(i): log.append("{} {} <{}>".format( EMsgDC("TriedToVerifyNotZeroForNonNumericAttribute"), MMsgDC("ForAttribute"), elem.description())) return False if i == 0: log.append("{} {} {} {} <{}>".format( (WMsgDC("ZeroValue") if warningNotError else EMsgDC("ZeroValue")), MMsgDC("ForValue"), (count + 1), MMsgDC("OfAttribute"), elem.description())) success = False return success
def LogElementAndModule(module: str, element: str) -> str: mesg = "" if len(element) != 0: mesg += MMsgDC("Element") + " = <{}> ".format(element) if len(module) != 0: mesg += MMsgDC("Module") + " = <{}> ".format(module) return mesg
def verifyVM(elem: DataElement, module: str, element: str, verbose: bool, log: list, multiplicityMin: uint32, multiplicityMax: uint32, specifiedSource=""): ttag = elem.tag current_vm = elem.VM vm = dictionary_VM(ttag) if multiplicityMax == 0 and multiplicityMin == 0: [dictmin, has_min_factor, dictmax, has_max_factor] = getVM_min_max(vm) source = MMsgDC("Dictionary") else: dictmin = multiplicityMin dictmax = multiplicityMax has_min_factor = False has_max_factor = False source = specifiedSource if len(specifiedSource) > 0 else MMsgDC( "ModuleDefinition") min_err = False max_err = False if has_min_factor: min_err = (current_vm % dictmin == 0) else: min_err = current_vm < dictmin if has_max_factor: max_err = (current_vm % dictmax == 0) else: max_err = current_vm > dictmin message = "" err = min_err and max_err if err: mssg = "{} {} vm is {} ({}".format( EMsgDC("BadAttributeValueMultiplicity"), vm, current_vm, dictmin) if (dictmin != dictmax or not has_max_factor or not has_min_factor): if not has_max_factor and dictmax == 0xFFFFFFFF: mssg += "-n" elif has_max_factor and dictmax > 1: mssg += "-{}n".format(dictmax) elif has_max_factor and dictmax == 1: mssg += "-n".format(dictmax) else: mssg += "-{}".format(dictmax) mssg += " {} {})".format(MMsgDC("RequiredBy"), source) if len(element) != 0: mssg += MMsgDC("Element") + "=<" + element + ">" if len(module) != 0: mssg += MMsgDC("Module") + "=<" + module + ">" log.append(mssg) return not err
def verifyVR(elem: DataElement, module: str, element: str, verbose: bool, log: list, fix_trivial=False): # tag = getTag(); # if (tag.isPrivateTag()) : # return True v = elem.value try: vrd = dictionary_VR(elem.tag) except BaseException as err: print(err) mssg = EMsgDC("NoSuchElementInDictionary") + " " if len(element) != 0: mssg += MMsgDC("Element") + "=<" + element + ">" if len(module) != 0: mssg += MMsgDC("Module") + "=<" + module + ">" log.append(mssg) return False vre = elem.VR vrds = [] vre_equlas_vrd = False if len(vrd) > 2 and len(vre) == 2: vrds = vrd.split(' or ') for dic_vr in vrds: if dic_vr == vre: vre_equlas_vrd = True break else: vre_equlas_vrd = (vre == vrd) if not vre_equlas_vrd and not(vrd == "OX" and vre == "OB" or vre == "OW") \ and not(vrd == "XS" and vre == "US" or vre == "SS") \ and not(vrd == "XO" and vre == "US" or vre == "SS" or vre == "OW") \ and not(vrd == "XL" and vre == "UL" or vre == "SL"): mssg = EMsgDC("BadValueRepresentation") \ + " " + vre + " (" + vrd + " " + MMsgDC("Required") + ")" # print(vrds,'<-->' ,vrd,'<-->', vre, '<-->', elem) if len(element) != 0: mssg += MMsgDC("Element") + "=<" + element + ">" if len(module) != 0: mssg += MMsgDC("Module") + "=<" + module + ">" log.append(mssg) if fix_trivial: elem.VR = vrd mssg += " :fixed: by changing the vr" return False else: return True
def verifyType2C(ds: Dataset, module: str, element: str, verbose: bool, log: list, fix_trivials: bool, condition_function, mbpo: bool, parent_ds: Dataset, root_ds: Dataset, multiplicityMin: uint32, multiplicityMax: uint32) -> bool: # Type 2C - Conditional Data Element (May be Empty) err_not_exists = False err_vr = False err_vm = False reason = "" if condition_function == 0: conditionNotSatisfied = True else: conditionNotSatisfied = not condition_function(ds, parent_ds, root_ds) if element in ds: elem = ds[element] else: if not conditionNotSatisfied: reason = "Error - T<{}> {}" reason = reason.format(ErrorType.Type2CAbsent.value, MMsgDC("MissingAttribute")) err_not_exists = True if not err_not_exists: if condition_function != 0 and conditionNotSatisfied and not mbpo: reason = "Error - T<{}> {}" reason = reason.format( ErrorType.Type2CPresent.value, MMsgDC( "AttributePresentWhenConditionUnsatisfiedWithoutMayBePresentOtherwise" )) if fix_trivials: tmp = ErrorInfo(reason + "{} {}", fix_by_removing(ds, element)) reason = tmp.getWholeMessage() if elem.is_empty: if not verifyVR(elem, module, element, verbose, log): reason = "Error - T<{}> {}" reason = reason.format(ErrorType.Type2CVR.value, MMsgDC("BadValueRepresentation")) err_vr = True else: if not verifyVM(elem, module, element, verbose, log, multiplicityMin, multiplicityMax, "source"): reason = "Error - T<{}> {}" reason = reason.format( ErrorType.Type2CVM.value, MMsgDC("BadAttributeValueMultiplicity")) err_vm = True if len(reason) != 0: if fix_trivials: ViolationMessage(reason, MMsgDC("Type2C"), module, element, log, verbose, True) else: ViolationMessage(reason, MMsgDC("Type2C"), module, element, log, verbose) else: ValidMessage(MMsgDC("Type2C"), module, element, log, verbose) return len(reason) == 0
def verifyEnumValues(elem: DataElement, str_val: dict, verbose: bool, log: list, which: int) -> bool: success = True val = elem.value vm = elem.VM if type(val) == MultiValue: if which == -1: candidate = val else: if which >= vm: return False else: candidate = [val[which]] else: if which >= 1: return False else: candidate = [val] for i, count in zip(candidate, range(0, len(candidate))): converted_i = i if type(i) == DSfloat or \ type(i) == DSdecimal or type(i) == IS: converted_i = str(i) elif type(i) == str: converted_i = i else: log.append( EMsgDC("TriedToVerifyEnumeratedValueForNonStringAttribute") + \ MMsgDC("ForAttribute") + " <" + elem.description() + ">") return False if converted_i in str_val: if verbose: log.append( MMsgDC("RecognizedEnumeratedValue") \ + " <" + i + "> " + MMsgDC("Is") + " <" + str_val[i] \ + "> " + MMsgDC("ForValue") + " {}".format(count + 1) \ + " " + MMsgDC("OfAttribute") + " <" \ + elem.description() + ">") else: msg = "{} <{}> {} {} {} {}".format( EMsgDC("UnrecognizedEnumeratedValue"), i, MMsgDC("ForValue"), count + 1, MMsgDC("OfAttribute"), elem.description()) log.append(msg) success = False return success
def verifyEnumValues_uint16(elem: DataElement, bin_method, verbose: bool, log: list, which: int) -> bool: success = True val = elem.value vm = elem.VM if type(val) == MultiValue: if which == -1: candidate = val else: if which >= vm: return False else: candidate = [val[which]] else: if which >= 1: return False else: candidate = [val] for i, count in zip(candidate, range(0, len(candidate))): if not isPydicomNumeric(i): log.append( EMsgDC("TriedToVerifyEnumeratedValueForNonNumericAttribute") + \ MMsgDC("ForAttribute") + " <" + elem.description() + ">") try: int_input = uint16(i) output = bin_method(int_input) except: output = [] if len(output) == 0: msg = "{} <{}> {} {} {} {} {}".format( EMsgDC("UnrecognizedEnumeratedValue"), i, MMsgDC("ForValue"), count + 1, MMsgDC("OfAttribute"), elem.description(), bin_method.__name__) log.append(msg) success = False else: if verbose: log.append( MMsgDC("RecognizedEnumeratedValue") \ + " <{}> ".format(i) + MMsgDC("Is") + " <" + output \ + "> " + MMsgDC("ForValue") + " {}".format(count + 1) \ + " " + MMsgDC("OfAttribute") + " <" \ + elem.description() + ">") return success
def verifyType2(ds: Dataset, module: str, element: str, verbose: bool, log: list, fix_trivials: bool, multiplicityMin: uint32, multiplicityMax: uint32) -> bool: # Type 2 - Required Data Element (May be Empty) err_vr = False err_vm = False err_not_exists = False reason = "" if element in ds: elem = ds[element] else: reason = "Error - T<{}> {}" reason = reason.format(ErrorType.Type2.value, MMsgDC("MissingAttribute")) err_not_exists = True if fix_trivials: # add an empty attrib tmp = ErrorInfo(reason + "{} {}", fix_ByAddingEmptyAttrib(ds, element)) reason = tmp.getWholeMessage() if not err_not_exists: # do not check emptiness if not elem.is_empty: if not verifyVR(elem, module, element, verbose, log): reason = "Error - T<{}> {}" reason = reason.format(ErrorType.Type2VR.value, MMsgDC("BadValueRepresentation")) err_vr = True else: if not verifyVM(elem, module, element, verbose, log, multiplicityMin, multiplicityMax): reason = "Error - T<{}> {}" reason = reason.format( ErrorType.Type2VM.value, MMsgDC("BadAttributeValueMultiplicity")) err_vm = True if len(reason) != 0: if fix_trivials: ViolationMessage(reason, MMsgDC("Type2"), module, element, log, verbose, True) else: ViolationMessage(reason, MMsgDC("Type2"), module, element, log, verbose) else: ValidMessage(MMsgDC("Type2"), module, element, log, verbose) return len(reason) == 0
def verifyDefinedTerms(elem: DataElement, str_val: dict, verbose: bool, log: list, which: int) -> bool: val = elem.value vm = elem.VM if type(val) == MultiValue: if which == -1: candidate = val else: if which >= vm: return False else: candidate = [val[which]] else: if which >= 1: return False else: candidate = [val] for i, count in zip(candidate, range(0, len(candidate))): if type(i) != str: log.append( EMsgDC("TriedToVerifyDefinedTermsForNonStringAttribute") + \ MMsgDC("ForAttribute") + " <" + elem.description() + ">") return False if i in str_val: if verbose: log.append( MMsgDC("RecognizedDefinedTerms") \ + " <" + i + "> " + MMsgDC("Is") + " <" + str_val[i] \ + "> " + MMsgDC("ForValue") + " {}".format(count + 1) \ + " " + MMsgDC("OfAttribute") + " <" \ + elem.description() + ">") else: msg = "{} <{}> {} {} {} {}".format( WMsgDC("UnrecognizedDefinedTerm"), i, MMsgDC("ForValue"), count + 1, MMsgDC("OfAttribute"), elem.description()) log.append(msg) return True return False
def verifyRequired(ds: Dataset, module: str, element: str, verbose: bool, log: list, fix_trivials: bool, multiplicityMin: uint32, multiplicityMax: uint32) -> bool: # Normalized Required Data Element err_vr = False err_vm = False err_empty = False err_not_exists = False reason = "" if element in ds: elem = ds[element] else: reason = "Error - T<{}> {}" reason = reason.format(ErrorType.Required.value, MMsgDC("MissingAttribute")) err_not_exists = True if not err_not_exists: if elem.is_empty(): reason = "Error - T<{}> {}" reason = reason.format(ErrorType.RequiredEmpty.value, MMsgDC("EmptyAttribute")) err_empty = True if not verifyVR(elem, module, element, verbose, log): reason = "Error - T<{}> {}" reason = reason.format(ErrorType.RequiredVR.value, MMsgDC("BadValueRepresentation")) err_vr = True else: if not verifyVM(elem, module, element, verbose, log, multiplicityMin, multiplicityMax, "source"): reason = "Error - T<{}> {}" reason = reason.format(ErrorType.RequiredVM.value, MMsgDC("BadAttributeValueMultiplicity")) err_vm = True if len(reason) != 0: ViolationMessage(reason, MMsgDC("NormalizedRequired"), module, element, log, verbose) else: ValidMessage(MMsgDC("NormalizedRequired"), module, element, log, verbose) return len(reason) == 0
def verifyEnumValues_tag(elem: DataElement, tag_method, verbose: bool, log: list, which: int) -> bool: # I think group and element for all values of multivalue attribs is the same. I should ask this? success = True val = elem.value vm = elem.VM g = uint16(elem.tag.group) e = uint16(elem.tag.elemnt) output = tag_method(g, e) if len(output) == 0: msg = "{} <({},{})> {} {} {}".format( EMsgDC("UnrecognizedEnumeratedValue"), g, e, MMsgDC("ForValue"), MMsgDC("OfAttribute"), elem.description()) log.append(msg) success = False else: if verbose: log.append( MMsgDC("RecognizedEnumeratedValue") \ + " <" + "({},{})".format(g, e) + "> " + MMsgDC( "Is") + " <" + output \ + "> " + MMsgDC("ForValue") + val \ + " " + MMsgDC("OfAttribute") + " <" \ + elem.description() + ">") # if which == -1: # candidate = val # else: # if which >= vm: # return False # else: # candidate = val[which] # for i in candidate: # if type(i) != int: # return False # output = tag_method(uint16(elem.tag.group), uint16(elem.tag.elemnt)) # if len(output) == 0: # print("Unrecognized defined term for {}".format(elem.keyword)) # success = False # else: # print("print sth if verbose") return success
def verifyType3C(ds: Dataset, module: str, element: str, verbose: bool, log: list, fix_trivials: bool, condition_function, mbpo: bool, parent_ds: Dataset, root_ds: Dataset, multiplicityMin: uint32, multiplicityMax: uint32) -> bool: # Type 3C - Conditional and Optional Data Element (May be Empty or Absent) reason = "" not_exists = False if condition_function == 0: conditionNotSatisfied = True else: conditionNotSatisfied = not condition_function(ds, parent_ds, root_ds) if element in ds: elem = ds[element] else: not_exists = True if not not_exists: if not conditionNotSatisfied: WarningMessage(MMsgDC("Unexpected"), MMsgDC("Type3C"), module, element, log, verbose) err_vr = False err_vm = False if not verifyVR(elem, module, element, verbose, log, fix_trivials): reason = "Error - T<{}> {}".format( ErrorType.Type3CVR.value, MMsgDC("BadValueRepresentation")) err_vr = True else: if not verifyVM(elem, module, element, verbose, log, multiplicityMin, multiplicityMax, "source"): reason = "Error - T<{}> {}" reason = reason.format(ErrorType.Type3CVM.value, MMsgDC("BadAttributeValueMultiplicity")) err_vm = True if len(reason) != 0: ViolationMessage(reason, MMsgDC("Type3C"), module, element, log, verbose) else: ValidMessage(MMsgDC("Type3C"), module, element, log, verbose) return len(reason) == 0
def ValidMessage(elementtype: str, module: str, element: str, log: list, verbose: bool): if verbose: mesg = "{} - {} {}".format(MMsgDC("ValidElement"), elementtype, LogElementAndModule(module, element))