Ejemplo n.º 1
0
def test_anonymise_directory(tmp_path):
    temp_filepath = tmp_path / "test.dcm"
    temp_anon_filepath = label_dicom_filepath_as_anonymised(temp_filepath)
    try:
        copyfile(TEST_FILEPATH, temp_filepath)
        assert not is_anonymised_directory(tmp_path)

        # Test file deletion
        anonymise_directory(
            tmp_path, delete_original_files=False, anonymise_filenames=False
        )
        # # File should be anonymised but not dir, since original file
        # # is still present.
        assert is_anonymised_file(temp_anon_filepath)
        assert exists(temp_filepath)
        assert not is_anonymised_directory(tmp_path)

        remove_file(temp_anon_filepath)
        anonymise_directory(
            tmp_path, delete_original_files=True, anonymise_filenames=False
        )
        # # File and dir should be anonymised since original file should
        # # have been deleted.
        assert is_anonymised_file(temp_anon_filepath)
        assert not exists(temp_filepath)
        assert is_anonymised_directory(tmp_path)

    finally:
        remove_file(temp_anon_filepath)
Ejemplo n.º 2
0
def _test_pseudonymise_cli_for_file(tmp_path, test_file_path):

    temp_filepath = pjoin(tmp_path, "test.dcm")
    try:
        logging.info("CLI test on %s", test_file_path)

        copyfile(test_file_path, temp_filepath)

        # Basic file pseudonymisation
        # Initially, just make sure it exits with zero and doesn't fail to generate output
        assert not is_anonymised_file(temp_filepath)

        # need the SOP Instance UID and SOP Class name to figure out the destination file name
        # but will also be using the dataset to do some comparisons.
        ds_input: pydicom.FileDataset = pydicom.dcmread(temp_filepath,
                                                        force=True)

        pseudo_sop_instance_uid = pseudonymisation_api.pseudonymisation_dispatch[
            "UI"](ds_input.SOPInstanceUID)

        sop_class_uid: pydicom.dataelem.DataElement = ds_input.SOPClassUID

        mode_prefix = DICOM_SOP_CLASS_NAMES_MODE_PREFIXES[
            sop_class_uid.name  # pylint: disable = no-member
        ]
        temp_anon_filepath = pjoin(
            tmp_path,
            "{}.{}_Anonymised.dcm".format(mode_prefix,
                                          pseudo_sop_instance_uid),
        )
        assert not exists(temp_anon_filepath)

        anon_file_command = "pymedphys --verbose experimental dicom anonymise --pseudo".split(
        ) + [temp_filepath]
        logging.info("Command line: %s", anon_file_command)
        try:
            subprocess.check_call(anon_file_command)
            assert exists(temp_anon_filepath)
            # assert is_anonymised_file(temp_anon_filepath)
            assert exists(temp_filepath)

            ds_pseudo = pydicom.dcmread(temp_anon_filepath, force=True)
            assert ds_input["PatientID"].value != ds_pseudo["PatientID"].value
        finally:
            remove_file(temp_anon_filepath)

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

        anon_dir_command = "pymedphys --verbose experimental dicom anonymise --pseudo".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)
Ejemplo n.º 3
0
def test_anonymise_file():
    assert not is_anonymised_file(TEST_FILEPATH)
    temp_basename = "{}_{}.dcm".format(".".join(TEST_FILEPATH.split(".")[:-1]),
                                       uuid4())

    temp_filepath = pjoin(dirname(TEST_FILEPATH), temp_basename)
    anon_private_filepath = ""
    anon_filepath_orig = ""
    anon_filepath_pres = ""

    try:
        # Private tag handling
        anon_private_filepath = anonymise_file(TEST_FILEPATH,
                                               delete_private_tags=False)
        assert not is_anonymised_file(anon_private_filepath,
                                      ignore_private_tags=False)
        assert is_anonymised_file(anon_private_filepath,
                                  ignore_private_tags=True)

        anon_private_filepath = anonymise_file(TEST_FILEPATH,
                                               delete_private_tags=True)
        assert is_anonymised_file(anon_private_filepath,
                                  ignore_private_tags=False)

        # Filename is anonymised?
        assert basename(anon_private_filepath) == TEST_ANON_BASENAME

        # Deletion of original file
        copyfile(TEST_FILEPATH, temp_filepath)

        anon_filepath_orig = anonymise_file(temp_filepath,
                                            delete_original_file=True)
        assert is_anonymised_file(anon_filepath_orig)
        assert not exists(temp_filepath)

        # Preservation of filename if desired
        expected_filepath = "{}_Anonymised.dcm".format(".".join(
            TEST_FILEPATH.split(".")[:-1]))
        anon_filepath_pres = anonymise_file(TEST_FILEPATH,
                                            anonymise_filename=False)
        assert anon_filepath_pres == expected_filepath

    finally:
        remove_file(temp_filepath)
        remove_file(anon_private_filepath)
        remove_file(anon_filepath_orig)
        remove_file(anon_filepath_pres)
Ejemplo n.º 4
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)
Ejemplo n.º 5
0
def test_alternative_identifying_keywords():
    alternative_keyword_list = copy.copy(get_default_identifying_keywords())
    alternative_keyword_list.append("SOPInstanceUID")
    test_file_path = get_treatment_record_test_file_path()
    ds_test = pydicom.dcmread(test_file_path, force=True)
    with tempfile.TemporaryDirectory() as output_directory:
        anon_private_filepath = anonymise_file(
            test_file_path,
            output_filepath=output_directory,
            delete_private_tags=True,
            identifying_keywords=alternative_keyword_list,
        )
        ds_anon = pydicom.dcmread(anon_private_filepath, force=True)

        assert is_anonymised_file(anon_private_filepath, ignore_private_tags=False)
        assert ds_test["SOPInstanceUID"].value != ds_anon["SOPInstanceUID"].value
Ejemplo n.º 6
0
def _test_pseudonymise_file_at_path(
    test_file_path, test_identifying_keywords=None, test_replacement_strategy=None
):
    assert not is_anonymised_file(test_file_path)
    if test_identifying_keywords is None:
        identifying_keywords_for_pseudo = (
            pseudonymisation_api.get_default_pseudonymisation_keywords()
        )
        logging.info("Using pseudonymisation keywords")
    else:
        identifying_keywords_for_pseudo = test_identifying_keywords
    if test_replacement_strategy is None:
        replacement_strategy = pseudonymisation_api.pseudonymisation_dispatch
        logging.info("Using pseudonymisation strategy")
    else:
        replacement_strategy = test_replacement_strategy

    with tempfile.TemporaryDirectory() as output_directory:
        pseudonymised_file_path = anonymise_file(
            dicom_filepath=test_file_path,
            output_filepath=output_directory,
            delete_original_file=False,
            anonymise_filename=True,
            replace_values=True,
            # keywords_to_leave_unchanged=None,
            delete_private_tags=True,
            delete_unknown_tags=True,
            replacement_strategy=replacement_strategy,
            identifying_keywords=identifying_keywords_for_pseudo,
        )
        # debug print + Assert to force the print
        # print("Pseudonymised file at: ", pseudonymised_file_path)
        # assert False
        assert exists(pseudonymised_file_path)
        ds_input = pydicom.dcmread(test_file_path, force=True)
        ds_pseudo = pydicom.dcmread(pseudonymised_file_path, force=True)
        # simplistic stand-in to make sure *something* is happening
        assert ds_input["PatientID"].value != ds_pseudo["PatientID"].value
        # make sure that we are not accidentally using the hardcode replacement approach
        assert ds_pseudo["PatientID"].value not in ["", "Anonymous"]
Ejemplo n.º 7
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)
Ejemplo n.º 8
0
def test_anonymise_directory(tmp_path):
    temp_filepath = tmp_path / "test.dcm"
    temp_anon_filepath = label_dicom_filepath_as_anonymised(temp_filepath)

    temp_record_filepath = tmp_path / "test_record.dcm"
    temp_anon_record_filepath = label_dicom_filepath_as_anonymised(temp_record_filepath)

    try:
        copyfile(get_rtplan_test_file_path(), temp_filepath)
        assert not is_anonymised_directory(tmp_path)

        # Test file deletion
        anon_path_list = anonymise_directory(
            tmp_path, delete_original_files=False, anonymise_filenames=False
        )
        # # File should be anonymised but not dir, since original file
        # # is still present.
        assert is_anonymised_file(temp_anon_filepath)
        assert exists(temp_filepath)
        assert not is_anonymised_directory(tmp_path)
        assert anon_path_list is not None
        assert anon_path_list[0] == temp_anon_filepath

        remove_file(temp_anon_filepath)
        anon_path_list = anonymise_directory(
            tmp_path, delete_original_files=True, anonymise_filenames=False
        )
        # # File and dir should be anonymised since original file should
        # # have been deleted.
        assert is_anonymised_file(temp_anon_filepath)
        assert not exists(temp_filepath)
        assert is_anonymised_directory(tmp_path)
        assert anon_path_list[0] == temp_anon_filepath

        # Test fail fast vs. fail at last
        # if the function fails fast, the specified removal
        # will not take place
        # if the function does not fail fail, the specified
        # removal will take place
        logging.warning("Testing fail fast")
        remove_file(temp_anon_filepath)
        copyfile(get_rtplan_test_file_path(), temp_filepath)
        copyfile(get_treatment_record_test_file_path(), temp_record_filepath)
        ds_record = pydicom.dcmread(temp_record_filepath, force=True)
        # deliberately add a DICOM element that is not in the current
        # dictionary
        ds_record.add_new([0x300A, 0x9999], "FL", [1.0, 1.0])
        pydicom.dcmwrite(temp_record_filepath, ds_record)
        with pytest.raises((KeyError, ValueError)):
            anon_path_list = anonymise_directory(
                tmp_path,
                delete_original_files=True,
                anonymise_filenames=False,
                fail_fast=True,
            )
            logging.warning(anon_path_list)
            assert exists(temp_filepath)

        with pytest.raises((KeyError, ValueError)):
            anon_path_list = anonymise_directory(
                tmp_path,
                delete_original_files=True,
                anonymise_filenames=False,
                fail_fast=False,
            )
            logging.warning(anon_path_list)
            assert not exists(temp_filepath)

    finally:
        remove_file(temp_anon_filepath)
        remove_file(temp_anon_record_filepath)