def get_anonymous_replacement_value(keyword, current_value=None, replacement_strategy=None): """Get an appropriate anonymisation value for a DICOM element based on its value representation (VR) Parameters ---------- keyword: text string that is the pydicom name for the DICOM attribute/element current_value: optional, the value that is currently assigned to the element replacement_strategy: optional, a dispatch dictionary whose keys are the text representation of the VR of the element, and whose values are function references that take the current value of the element. Returns ------- A value that is a suitable replacement for the element whose attributes are identified by the keyword TODO ---- Address VR of CS to ensure DICOM conformance and if possible, interoperability CS typically implies a defined set of values, or in some cases, a strict enumeration of values and replacement with a value that is not in a defined set will often break interoperability. Replacement with a value that is not in an enumerated set breaks DICOM conformance. """ vr = get_baseline_keyword_vr_dict()[keyword] if vr == "CS": # An example, although this exact code breaks unit tests because # the unit tests are expecting the CS hardcoded replacement string "ANON" # if keyword == "PatientSex": # replacement_value = "O" # or one can replace with an empty string because PatientSex is typically type 2 # else: logging.warning( "Keyword %s has Value Representation CS and may require special processing to avoid breaking DICOM conformance or interoperability", keyword, ) # elif ... if replacement_strategy is None: replacement_strategy = strategy.ANONYMISATION_HARDCODE_DISPATCH try: replacement_value = replacement_strategy[vr](current_value) except KeyError: logging.error( "Unable to anonymise %s with VR %s, current value is %s", keyword, vr, current_value, ) raise return replacement_value
def _anonymise_tags(ds_anon, keywords_to_anonymise, replace_values): """Anonymise all desired DICOM elements. """ for keyword in keywords_to_anonymise: if hasattr(ds_anon, keyword): if replace_values: replacement_value = get_anonymous_replacement_value(keyword) else: if get_baseline_keyword_vr_dict()[keyword] in ("OB", "OW"): replacement_value = (0).to_bytes(2, "little") else: replacement_value = "" setattr(ds_anon, keyword, replacement_value) return ds_anon
def anonymise_tags(ds_anon, keywords_to_anonymise, replace_values, replacement_strategy=None): """Anonymise all desired DICOM elements. """ if not replace_values and replacement_strategy is not None: logging.warning( "Conflicting approach to anonymisation specified, a replacement strategy was specified in addition to a directive" "to eliminate values rather than replace them. Adhering to directive to eliminate values" ) for keyword in keywords_to_anonymise: if hasattr(ds_anon, keyword): if replace_values: if ds_anon[keyword].value in ("", None, []): logging.debug( "%s has value of empty list, None or empty string, no need to modify to anonymise", keyword, ) continue replacement_value = get_anonymous_replacement_value( keyword, current_value=ds_anon[keyword].value, replacement_strategy=replacement_strategy, ) else: if get_baseline_keyword_vr_dict()[keyword] in ("OB", "OW"): replacement_value = (0).to_bytes(2, "little") else: replacement_value = "" setattr(ds_anon, keyword, replacement_value) remaining_seq_only_list = [ x for x in ds_anon if (x.VR == "SQ" and x.name not in keywords_to_anonymise) ] for seq in remaining_seq_only_list: for seq_item in seq.value: anonymise_tags( seq_item, keywords_to_anonymise, replace_values, replacement_strategy=replacement_strategy, ) return ds_anon
def _anonymise_tags(ds_anon, keywords_to_anonymise, replace_values): """Anonymise all desired DICOM elements. """ for keyword in keywords_to_anonymise: if hasattr(ds_anon, keyword): if replace_values: replacement_value = get_anonymous_replacement_value(keyword) else: if get_baseline_keyword_vr_dict()[keyword] in ("OB", "OW"): replacement_value = (0).to_bytes(2, "little") else: replacement_value = "" setattr(ds_anon, keyword, replacement_value) remaining_seq_only_list = [ x for x in ds_anon if (x.VR == "SQ" and x.name not in keywords_to_anonymise) ] for seq in remaining_seq_only_list: for seq_item in seq.value: _anonymise_tags(seq_item, keywords_to_anonymise, replace_values) return ds_anon
def get_anonymous_replacement_value(keyword): """Get an appropriate dummy anonymisation value for a DICOM element based on its value representation (VR) """ vr = get_baseline_keyword_vr_dict()[keyword] return get_vr_anonymous_replacement_value_dict()[vr]