예제 #1
0
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
예제 #2
0
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
예제 #3
0
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)
예제 #4
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
예제 #5
0
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())
예제 #6
0
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"))
예제 #7
0
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"
예제 #8
0
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())
    ])
예제 #9
0
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
예제 #10
0
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}")
예제 #11
0
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}")
예제 #12
0
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)
예제 #13
0
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
예제 #14
0
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
예제 #15
0
def test_factory():
    """Check whether dataset factory actually generates datasets
    """
    generated = CTDatasetFactory()
    assert generated.SeriesDate == generated.AcquisitionDate
    assert CTDatasetFactory(AccessionNumber="1234").AccessionNumber == "1234"
예제 #16
0
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