def test_reject_kogsps_fail(dataset): """Datasets that should be rejected""" with pytest.raises(DeidentificationException): Core(profile=Profile(rule_sets=[]), bouncers=[RejectKOGSPS()]).deidentify( dataset )
def create_default_core( safe_private_definition: SafePrivateDefinition = None, location_list: PIILocationList = None, ) -> Core: """A default deidentification core with the following profile: * basic_profile * clean_descriptors * retain_patient_characteristics * retain_device_id * retain_safe_private Parameters ---------- safe_private_definition: SafePrivateDefinition, optional Which private tags are safe to keep. Defaults to keeping none location_list: PIILocationList, optional Definition of where to remove burnt in information from images. Defaults to simply rejecting all datasets that might have burnt in information """ sets = get_dicom_rule_sets(safe_private_definition) profile = Profile( # Choose which rule sets to use name="idiscore default profile", rule_sets=[ sets.basic_profile, sets.clean_descriptors, sets.retain_patient_characteristics, sets.retain_device_id, sets.retain_safe_private, ], ) return create_core(profile=profile, location_list=location_list,)
def test_reject_non_standard(): a_core = Core(profile=Profile(rule_sets=[]), bouncers=[RejectNonStandardDicom()]) # this should not raise anything a_core.deidentify(quick_dataset(SOPClassUID="1.2.840.10008")) with pytest.raises(DeidentificationException): a_core.deidentify(quick_dataset(SOPClassUID="123"))
def test_core_description(): """Human readable answer to the question 'what does this deidentifier do?'""" sets = DICOMRuleSets() profile = Profile(rule_sets=[ sets.basic_profile, sets.clean_descriptors, sets.clean_graphics, sets.retain_modified_dates, sets.retain_safe_private, ]) final_set = profile.flatten() assert len(final_set.rules) == 442 core = Core(profile=profile, bouncers=[RejectKOGSPS]) test = core.description() print(test)
def test_realistic_profile(): """Run a file through a profile that has several options""" sets = DICOMRuleSets() profile = Profile(rule_sets=[ sets.basic_profile, sets.clean_descriptors, sets.clean_graphics, sets.retain_modified_dates, sets.retain_safe_private, ]) final_set = profile.flatten() assert len(final_set.rules) == 442 core = Core(profile=profile) dataset = CTDatasetFactory() original = deepcopy(dataset) deidentified = core.deidentify(dataset) assert original.PatientID != deidentified.PatientID
def test_profile_flatten(some_pid_rules): """A profile can have multiple rule sets, but with flatten you should end up with one rule per DICOM tag """ hash_name = Rule(SingleTag("PatientName"), Hash()) # initial set set1 = RuleSet(rules=[some_pid_rules[0], hash_name]) # set with a different rule for PatientID set2 = RuleSet( rules=[some_pid_rules[1], Rule(SingleTag("Modality"), Remove())]) profile = Profile(rule_sets=[set1, set2]) # The PatientID rule of set2 should be chosen when flattening assert some_pid_rules[1] in profile.flatten().rules assert some_pid_rules[0] not in profile.flatten().rules # if another set is added, the rules from this should overrule earlier set3 = RuleSet(name="another set", rules=[some_pid_rules[2]]) assert some_pid_rules[2] in profile.flatten( additional_rule_sets=[set3]).rules # but any original rule that was not overwritten should still be present assert hash_name in profile.flatten(additional_rule_sets=[set3]).rules
def test_core_deidentify_safe_private(a_dataset, a_safe_private_definition): """Private elements marked as safe should not be removed by Clean()""" assert Tag("00b10010") in a_dataset # a private creator tag assert Tag("00b11001") in a_dataset # and a private tag # A core instance that should clean() private tags, but one tag is deemed safe ruleset = RuleSet( [Rule(PrivateTags(), Clean(safe_private=a_safe_private_definition))]) core = Core(profile=Profile([ruleset])) # One tag should be kept deltas = extract_signature(deidentifier=core, dataset=a_dataset) assert {x.tag: x for x in deltas}[Tag("00b10010")].status == "REMOVED" assert {x.tag: x for x in deltas}[Tag("00b11001")].status == "UNCHANGED" # but only so long as dataset has modality = CT a_dataset.Modality = "US" deltas = extract_signature(deidentifier=core, dataset=a_dataset) assert {x.tag: x for x in deltas}[Tag("00b10010")].status == "REMOVED" assert {x.tag: x for x in deltas}[Tag("00b11001")].status == "REMOVED"
"""You can set your own rules for specific DICOM tags. Be aware that this might mean the deidentification is no longer DICOM-complient """ import pydicom from idiscore.core import Core, Profile from idiscore.defaults import get_dicom_rule_sets from idiscore.identifiers import RepeatingGroup, SingleTag from idiscore.operators import Hash, Remove from idiscore.rules import Rule, RuleSet # Custom rules that will hash the patient name and remove all curve data my_ruleset = RuleSet( rules=[ Rule(SingleTag("PatientName"), Hash()), Rule(RepeatingGroup("50xx,xxxx"), Remove()), ], name="My Custom RuleSet", ) sets = get_dicom_rule_sets() # Contains official DICOM deidentification rules profile = Profile( # add custom rules to basic profile rule_sets=[sets.basic_profile, my_ruleset]) core = Core(profile) # Create an deidentification core # read a DICOM dataset from file and write to another core.deidentify(pydicom.read("my_file.dcm")).save_as("deidentified.dcm")
def test_reject_kogsps_pass(dataset): """Datasets that should be passed""" # should not raise exceptions assert Core(profile=Profile(rule_sets=[]), bouncers=[RejectKOGSPS()]).deidentify( dataset )
def a_core_with_some_rules(some_rules) -> Core: """Core instance with a three-rule profile""" return Core(profile=Profile([RuleSet(some_rules)]))
"""Basic example of deidentifying a single file""" import pydicom from idiscore.core import Core, Profile from idiscore.defaults import get_dicom_rule_sets sets = get_dicom_rule_sets() # Contains official DICOM deidentification rules profile = Profile( # Choose which rule sets to use rule_sets=[ sets.basic_profile, sets.retain_modified_dates, sets.retain_device_id ]) core = Core(profile) # Create an deidentification core # read a DICOM dataset from file and write to another core.deidentify(pydicom.read("my_file.dcm")).save_as("deidentified.dcm")