Beispiel #1
0
def _check_is_anonymised_dataset_file_and_dir(
    ds, tmp_path, anon_is_expected=True, ignore_private_tags=False
):
    temp_filepath = str(tmp_path / "test.dcm")

    try:
        create.set_default_transfer_syntax(ds)

        ds.file_meta = TEST_FILE_META
        ds.save_as(temp_filepath, write_like_original=False)

        if anon_is_expected:
            assert is_anonymised_dataset(ds, ignore_private_tags)
            assert is_anonymised_file(temp_filepath, ignore_private_tags)
            assert is_anonymised_directory(tmp_path, ignore_private_tags)
        else:
            assert not is_anonymised_dataset(ds, ignore_private_tags)
            assert not is_anonymised_file(temp_filepath, ignore_private_tags)
            assert not is_anonymised_directory(tmp_path, ignore_private_tags)
    finally:
        remove_file(temp_filepath)
Beispiel #2
0
def test_anonymise_dataset_and_all_is_anonymised_functions(tmp_path):

    # Create dataset with one instance of every identifying keyword and
    # run basic anonymisation tests
    ds = pydicom.dataset.Dataset()
    for keyword in IDENTIFYING_KEYWORDS:
        # Ignore file meta elements for now
        tag = hex(pydicom.datadict.tag_for_keyword(keyword))
        if pydicom.tag.Tag(tag).group == 0x0002:
            continue

        value = _get_non_anonymous_replacement_value(keyword)
        setattr(ds, keyword, value)

    _check_is_anonymised_dataset_file_and_dir(ds, tmp_path, anon_is_expected=False)

    ds_anon = anonymise_dataset(ds)
    _check_is_anonymised_dataset_file_and_dir(ds_anon, tmp_path, anon_is_expected=True)

    # Test the anonymisation and check functions for each identifying
    # element individually.
    for elem in ds_anon.iterall():

        # TODO: AffectedSOPInstanceUID and RequestedSOPInstanceUID
        # are not writing to file. Investigate when UID anonymisation is
        # implemented.
        if elem.keyword in ("AffectedSOPInstanceUID", "RequestedSOPInstanceUID"):
            continue

        ds_single_non_anon_value = deepcopy(ds_anon)
        setattr(
            ds_single_non_anon_value,
            elem.keyword,
            _get_non_anonymous_replacement_value(elem.keyword),
        )
        _check_is_anonymised_dataset_file_and_dir(
            ds_single_non_anon_value, tmp_path, anon_is_expected=False
        )
        ds_single_anon = anonymise_dataset(ds_single_non_anon_value)
        _check_is_anonymised_dataset_file_and_dir(
            ds_single_anon, tmp_path, anon_is_expected=True
        )

    # Test correct handling of private tags
    ds_anon.add(pydicom.dataset.DataElement(0x0043102B, "SS", [4, 4, 0, 0]))
    _check_is_anonymised_dataset_file_and_dir(
        ds_anon, tmp_path, anon_is_expected=False, ignore_private_tags=False
    )
    _check_is_anonymised_dataset_file_and_dir(
        ds_anon, tmp_path, anon_is_expected=True, ignore_private_tags=True
    )

    ds_anon.remove_private_tags()
    _check_is_anonymised_dataset_file_and_dir(
        ds_anon, tmp_path, anon_is_expected=True, ignore_private_tags=False
    )

    # Test blank anonymisation
    # # Sanity check
    _check_is_anonymised_dataset_file_and_dir(ds, tmp_path, anon_is_expected=False)

    ds_anon_blank = anonymise_dataset(ds, replace_values=False)
    _check_is_anonymised_dataset_file_and_dir(
        ds_anon_blank, tmp_path, anon_is_expected=True
    )

    # Test handling of unknown tags by removing PatientName from
    # baseline dict
    patient_name_tag = pydicom.datadict.tag_for_keyword("PatientName")

    try:
        patient_name = get_baseline_dicom_dict().pop(patient_name_tag)

        with pytest.raises(ValueError) as e_info:
            anonymise_dataset(ds)
        assert str(e_info.value).count(
            "At least one of the non-private tags "
            "within your DICOM file is not within "
            "PyMedPhys's copy of the DICOM dictionary."
        )

        ds_anon_delete_unknown = anonymise_dataset(ds, delete_unknown_tags=True)
        _check_is_anonymised_dataset_file_and_dir(
            ds_anon_delete_unknown, tmp_path, anon_is_expected=True
        )
        with pytest.raises(AttributeError) as e_info:
            ds_anon_delete_unknown.PatientName  # pylint: disable = pointless-statement
        assert str(e_info.value).count(
            "'Dataset' object has no attribute " "'PatientName'"
        )

        ds_anon_ignore_unknown = anonymise_dataset(ds, delete_unknown_tags=False)
        _check_is_anonymised_dataset_file_and_dir(
            ds_anon_ignore_unknown, tmp_path, anon_is_expected=True
        )
        assert patient_name_tag in ds_anon_ignore_unknown

    finally:
        get_baseline_dicom_dict().setdefault(patient_name_tag, patient_name)

    # Test copy_dataset=False:
    anonymise_dataset(ds, copy_dataset=False)
    assert is_anonymised_dataset(ds)
Beispiel #3
0
def test_anonymised_dataset_with_nested_name():
    nested_name = dicom_dataset_from_dict(
        {"OverrideSequence": [{"OperatorsName": "George"}]}
    )

    assert not is_anonymised_dataset(nested_name)
Beispiel #4
0
def test_anonymise_cli(tmp_path):

    temp_filepath = str(tmp_path / "test.dcm")
    try:
        copyfile(TEST_FILEPATH, temp_filepath)
        temp_anon_filepath = str(tmp_path / TEST_ANON_BASENAME)
        # Basic file anonymisation
        assert not is_anonymised_file(temp_filepath)
        assert not exists(temp_anon_filepath)

        anon_file_command = "pymedphys dicom anonymise".split() + [temp_filepath]
        try:
            subprocess.check_call(anon_file_command)
            assert is_anonymised_file(temp_anon_filepath)
            assert exists(temp_filepath)
        finally:
            remove_file(temp_anon_filepath)

        # File anonymisation - preserve filenames
        assert not is_anonymised_file(temp_filepath)

        expected_anon_filepath = label_dicom_filepath_as_anonymised(temp_filepath)
        assert not exists(expected_anon_filepath)

        anon_file_pres_command = "pymedphys dicom anonymise -f".split() + [
            temp_filepath
        ]
        try:
            subprocess.check_call(anon_file_pres_command)
            assert is_anonymised_file(expected_anon_filepath)
            assert exists(temp_filepath)
        finally:
            remove_file(expected_anon_filepath)

        # File anonymisation - clear values
        assert not is_anonymised_file(temp_filepath)
        assert not exists(temp_anon_filepath)

        temp_cleared_anon_filepath = str(tmp_path / TEST_ANON_BASENAME)

        anon_file_clear_command = "pymedphys dicom anonymise -c".split() + [
            temp_filepath
        ]
        try:
            subprocess.check_call(anon_file_clear_command)
            assert is_anonymised_file(temp_cleared_anon_filepath)
            assert pydicom.dcmread(temp_cleared_anon_filepath).PatientName == ""
            assert exists(temp_filepath)
        finally:
            remove_file(temp_cleared_anon_filepath)

        # File anonymisation - leave keywords unchanged
        assert not is_anonymised_file(temp_filepath)
        assert not exists(temp_anon_filepath)

        anon_file_keep_command = (
            "pymedphys dicom anonymise".split()
            + [temp_filepath]
            + "-k PatientName".split()
        )
        try:
            subprocess.check_call(anon_file_keep_command)
            assert not is_anonymised_file(temp_anon_filepath)
            ds = pydicom.dcmread(temp_anon_filepath)
            ds.PatientName = "Anonymous"
            assert is_anonymised_dataset(ds)
            assert exists(temp_filepath)
        finally:
            remove_file(temp_anon_filepath)

        # File anonymisation - private tag handling
        assert not is_anonymised_file(temp_filepath)
        assert not exists(temp_anon_filepath)

        anon_file_private_command = "pymedphys dicom anonymise -p".split() + [
            temp_filepath
        ]
        try:
            subprocess.check_call(anon_file_private_command)
            assert not is_anonymised_file(temp_anon_filepath)
            assert is_anonymised_file(temp_anon_filepath, ignore_private_tags=True)
            assert exists(temp_filepath)
        finally:
            remove_file(temp_anon_filepath)

        # TODO: File anonymisation - unknown tag handling
        # # Calling a subprocess reloads BASELINE_DICOM_DICT...

        # Basic dir anonymisation
        assert not is_anonymised_directory(tmp_path)
        assert not exists(temp_anon_filepath)

        anon_dir_command = "pymedphys dicom anonymise".split() + [str(tmp_path)]
        try:
            subprocess.check_call(anon_dir_command)
            assert is_anonymised_file(temp_anon_filepath)
            assert exists(temp_filepath)
        finally:
            remove_file(temp_anon_filepath)
    finally:
        remove_file(temp_filepath)
Beispiel #5
0
def test_anonymised_dataset_with_empty_patient_sex():
    blank_sex_ds = dicom_dataset_from_dict({"PatientSex": None})
    assert is_anonymised_dataset(blank_sex_ds)
    hardcode_replace_ds = anonymise_dataset(blank_sex_ds)
    assert hardcode_replace_ds["PatientSex"].value is None