def test_private_definition_strings(): """Just testing human readable input of private definition""" definition = SafePrivateDefinition(blocks=[ SafePrivateBlock( tags=[ "0023[SIEMENS MED SP DXMG WH AWS 1]10", "0023[SIEMENS MED SP DXMG WH AWS 1]11", "00b1[TestCreator]01", "00b1[TestCreator]02", ], criterion=lambda x: x.Modality == "CT", comment="Just some test tags", ), SafePrivateBlock( tags=["00b1[othercreator]11", "00b1[othercreator]12"], comment="Some more test tags, without a criterion", ), ]) # for a CT dataset all tags are considered safe assert len(definition.safe_identifiers(CTDatasetFactory())) == 6 # for a US dataset only the last block is considered safe assert len(definition.safe_identifiers( CTDatasetFactory(Modality="US"))) == 2
def a_dataset_with_transfer_syntax(): """Transfer Syntax is needed for interpreting PixelData. This is not recorded with CTDatasetFactory() """ dataset = CTDatasetFactory() dataset.file_meta = Dataset() dataset.file_meta.TransferSyntaxUID = ExplicitVRLittleEndian return dataset
def test_private_definition(a_ct_safe_private_definition): """Define some private elements that are safe for CT""" assert (len( a_ct_safe_private_definition.get_safe_private_tags( CTDatasetFactory())) == 4) assert (len( a_ct_safe_private_definition.get_safe_private_tags( CTDatasetFactory(Modality="US"))) == 0)
def test_private_definition_no_criterion(some_private_identifiers): """Without a criterion tags are always considered safe""" safe_private = SafePrivateBlock(tags=some_private_identifiers) assert len(safe_private.get_safe_private_tags(CTDatasetFactory())) == 4 assert len( safe_private.get_safe_private_tags( CTDatasetFactory(Modality="US"))) == 4
def test_process_pixel_data_exception(): """A suspicious dataset that cannot be cleaned should raise exception""" processor = PixelProcessor(location_list=PIILocationList([])) with pytest.raises(PixelDataProcessorException) as e: processor.clean_pixel_data(CTDatasetFactory(Modality="US")) assert "could not find any location to clean" in str(e.value) # but this should not raise exceptions because its not suspicious processor.clean_pixel_data(CTDatasetFactory())
def test_default_core(a_safe_private_definition): core = create_default_core( safe_private_definition=a_safe_private_definition) core.deidentify(CTDatasetFactory()) signature = extract_signature(deidentifier=core, dataset=CTDatasetFactory()) assert len(signature) == 108 with pytest.raises(DeidentificationException): # suspicious, but this type of dataset is not in a_safe_private_definition core.deidentify(CTDatasetFactory(Modality="US"))
def test_factory_random(fix_random_seed): """Test reproducibility of randomized tests Kind of a meta test as it tests pytest and factory instead of my own code. Still, I want to make sure this works""" dataset = CTDatasetFactory() assert str(dataset.PatientName) == "Vaessen^Maud"
def test_private_definition_string(some_private_identifier_strings): """For convenience you can also init a SafePrivateBlock using strings""" block = SafePrivateBlock(tags=some_private_identifier_strings) assert all([ isinstance(x, TagIdentifier) for x in block.get_safe_private_tags(CTDatasetFactory()) ])
def test_splitting_off_pixeldata(): original = CTDatasetFactory() copied, pixeldata = split_pixel_data(original) only_in_copied = [ copied[z] for z in {x.tag for x in copied} - {x.tag for x in original} ] only_in_original = [ original[z] for z in {x.tag for x in original} - {x.tag for x in copied} ] assert len(only_in_copied) == 0 # no new items should have been inserted assert only_in_original == [pixeldata] # make the copy does not contain any references to object from original def get_all_ids(dataset: Dataset) -> Set[int]: ids = set() for element in dataset: if element.VR == VRs.Sequence: ids = ids + get_all_ids(element) else: ids.add(id(element)) return ids assert not get_all_ids(original) & get_all_ids( copied) # intersection is empty
def generate_some_dicom_files(output_dir): output_dir.mkdir(parents=True, exist_ok=True) filenames = [f"dcmfile{x}" for x in range(5)] for filename in filenames: export(dataset=CTDatasetFactory(), path=output_dir / filename) print(f"Wrote {len(filenames)} files to {output_dir}")
def generate_file_with_specifics(output_path): """Generate a dicom file, set specific tags. All tags supported by pydicom can be set here""" export(dataset=CTDatasetFactory(PatientSex='M', PatientName='Smith^Harry', PatientIdentityRemoved='NO'), path=output_path) print(f"Wrote file to {output_path}")
def test_private_block_identifier(): dataset = CTDatasetFactory() element = dataset[(0x0075, 0x1000)] assert PrivateBlockTagIdentifier("0075,[RADBOUDUMCANONYMIZER]00").matches( element) assert not PrivateBlockTagIdentifier( "0075,[radboudumcanonymizer]00").matches(element) assert not PrivateBlockTagIdentifier( "0073,[RADBOUDUMCANONYMIZER]00").matches(element) assert not PrivateBlockTagIdentifier( "0075,[RADBOUDUMCANONYMIZER]01").matches(element)
def test_annotated_dataset_serialization(): """Annotated dataset should contain the dataset, annotations and a description""" dataset = CTDatasetFactory() annotated = AnnotatedDataset( dataset=dataset, annotations=[ MustNotChange(tag=Tag("PatientID"), explanation="PatientID contains essential info") ], description="a CT dataset with test annotations", ) as_dict = annotated.to_dict() loaded = AnnotatedDataset.from_dict(as_dict) assert annotated.annotations[0].explanation == loaded.annotations[ 0].explanation assert annotated.description == loaded.description assert annotated.dataset == loaded.dataset
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_factory(): """Check whether dataset factory actually generates datasets """ generated = CTDatasetFactory() assert generated.SeriesDate == generated.AcquisitionDate assert CTDatasetFactory(AccessionNumber="1234").AccessionNumber == "1234"
def test_signature_realistic_dataset(a_core): """Check with a realistic dataset. Nothing should crash""" deltas = extract_signature(a_core, CTDatasetFactory()) assert len([x for x in deltas if x.has_changed()]) == 19