def test_rule_precedence(): """Rules are applied in order of generality - most specific first. Verify""" # Some rules with a potentially ambivalent order rule_a = Rule(PrivateTags(), Remove()) # Remove all private tags rule_b = Rule(Tag(0x1301, 0x0000), Keep()) # but keep this private tag rule_c = Rule(RepeatingGroup("50xx,xxxx"), Hash()) # match all these rule_d = Rule(Tag(0x5002, 0x0002), Keep()) # but specifically remove this rule_e = Rule(SingleTag("PatientName"), Hash()) # and one regular rule rules = RuleSet(rules=[rule_a, rule_b, rule_c, rule_d, rule_e]) # now in all these cases, the most specific rule should be returned: assert rules.get_rule( DatEF(tag=(0x1301, 0x0000))) == rule_b # also matches a assert rules.get_rule( DatEF(tag=(0x5002, 0x0002))) == rule_d # also matches c assert rules.get_rule(DatEF(tag=(0x5002, 0x0001))) == rule_c assert rules.get_rule( DatEF(tag=(0x5001, 0x0001))) == rule_c # also matches a assert rules.get_rule(DatEF(tag=(0x0010, 0x0010))) == rule_e assert rules.get_rule(DatEF(tag="Modality")) is None # For rules with identical generality, just keep the order of input rule_1 = Rule(RepeatingGroup("50xx,xxxx"), Hash()) rule_2 = Rule(RepeatingGroup("xx10,xxxx"), Hash()) rules = RuleSet(rules=[rule_1, rule_2]) assert rules.get_rule( DatEF(tag=(0x5010, 0x0000))) == rule_1 # also matches a assert rules.get_rule( DatEF(tag=(0x5110, 0x0000))) == rule_2 # also matches a
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 some_rules() -> List[Rule]: """Different types of Rules""" return [ Rule(SingleTag("PatientName"), Hash()), Rule(RepeatingGroup("50xx,xxxx"), Remove()), Rule(PrivateTags(), Remove()), ]
def test_rule_set(): """Rule set should be able to find the proper rules for tags""" # some rules rule1 = Rule(SingleTag("PatientName"), Hash()) rule2 = Rule(RepeatingGroup("50xx,xxxx"), Remove()) rule3 = Rule(PrivateTags(), Remove()) rules = RuleSet(rules=[rule1, rule2, rule3]) assert rules.get_rule(DatEF(tag="PatientName")) == rule1 assert rules.get_rule( DatEF(tag="Modality")) is None # This rule is not defined assert rules.get_rule( DatEF(tag=(0x5000, 0x0001))) == rule2 # try a repeating rule assert (rules.get_rule(DatEF(tag=(0x1301, 0x0001))) == rule3 ) # try a private tag rule
def test_rule_set_remove(): # some rules rule1 = Rule(SingleTag("PatientName"), Hash()) rule2 = Rule(RepeatingGroup("50xx,xxxx"), Remove()) rule3 = Rule(PrivateTags(), Remove()) rules = RuleSet(rules=[rule1, rule2, rule3]) assert len(rules.as_dict()) == 3 rules.remove(rule3) assert len(rules.as_dict()) == 2 rules.remove(rule1) assert len(rules.as_dict()) == 1 with pytest.raises(KeyError): rules.remove(rule3) with pytest.raises(KeyError): rules.remove(rule1)
"""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 some_pid_rules(): return [ Rule(SingleTag("PatientID"), Hash()), Rule(SingleTag("PatientID"), Remove()), Rule(SingleTag("PatientID"), Keep()), ]