Pseudonymisation Tool#

This is the legacy experimental interface. Read its limitations in DICOM de-identification before sharing output.

Warning

Experimental pseudonymisation hashes UIDs and some numeric values without a secret key. Anyone who holds the original UIDs can re-link records, and anyone can recover small-range values such as patient weight from the output alone by hashing every plausible value. It shifts every patient’s dates by the same offset. Its output keeps the original file preamble and the original SOP Instance UID in the File Meta Information. Its functions emit a PseudonymisationLimitationWarning describing these limitations; this is not a deprecation. pseudonymisation_dispatch is a dictionary, so it emits no warning itself; pymedphys.dicom.anonymise(), which applies it in the example below, emits an AnonymisationLimitationWarning. Review the output before sharing it.

Summary#

Pseudonymisation provides a list of identifying keywords that includes UIDs and an anonymisation strategy that utilises SHA3_256 to hash text which is then encoded as base64, or for UIDs, converted to an integer appended to the PyMedPhys Org Root. Dates are shifted consistently and ages are jittered. The list of identifying keywords and the anonymisation strategy are passed in to the (non-experimental) anonymisation module/functions.

API#

pymedphys.experimental.pseudonymisation.pseudonymise(dicom_input, output_path=None)#

Convenient API to pseudonymisation. Elements whose tags are not in the pydicom dictionary will be deleted PatientSex will not be modified/pseudonymised For finer control, pass this module’s strategy and keywords to pymedphys.dicom.anonymise instead

Parameters:
  • dicom_input (pydicom.dataset.Dataset | str | pathlib.Path) – Either a dataset, a path to a file or a path to a directory

  • output_path (str | pathlib.Path, optional) – For a file input, provide a file path with a directory component. Its parent directory is used, but the filename is generated from the pseudonymised dataset. For a directory input, this is the destination directory. If None, output is written alongside the input. Ignored for a Dataset input, which returns a new dataset without saving it. Defaults to None.

Returns:

if the dicom_input was a dataset, return the pseudonymised dataset if the dicom input was a file, return the path to the pseudonymised file. if the dicom input was a directory, return the list of successfully anonymised files, and return that instead of None

Return type:

pydicom.dataset.Dataset | str | list of str

pymedphys.experimental.pseudonymisation.get_default_pseudonymisation_keywords()#
pymedphys.experimental.pseudonymisation.is_valid_strategy_for_keywords(identifying_keywords=None, replacement_strategy=None)#
class pymedphys.experimental.pseudonymisation.PseudonymisationLimitationWarning[source]#

Experimental pseudonymisation has known security limitations.

This is not a deprecation warning. No replacement is available yet, so experimental pseudonymisation is not scheduled for removal.

pseudonymisation.pseudonymisation_dispatch strategy, i.e. dictionary of VR and function references for anonymisation to achieve pseudonymisation#

Example#

For an in-memory dataset, the return value is the pseudonymised dataset; output_path does not save it. Save the returned dataset explicitly:

import pydicom
from pymedphys.experimental import pseudonymisation

ds_input = pydicom.dcmread("input.dcm")
ds_pseudo = pseudonymisation.pseudonymise(ds_input)
ds_pseudo.save_as("output.dcm")

For a file input, pass a file path with a directory component. The parent directory is used, but the filename is replaced with one generated from the pseudonymised dataset; use the returned path to locate the file. For a directory input, output_path is the destination directory:

output_file = pseudonymisation.pseudonymise(
    "input.dcm", output_path="output/example.dcm"
)
output_files = pseudonymisation.pseudonymise(
    "input_directory", output_path="output_directory"
)

For finer control, pass this module’s replacement strategy and identifying keywords to pymedphys.dicom.anonymise(). The following reproduces pseudonymise for a dataset; adjust the arguments as required:

import pymedphys.dicom

ds_pseudo = pymedphys.dicom.anonymise(
    ds_input,
    keywords_to_leave_unchanged=["PatientSex"],
    delete_unknown_tags=True,
    replacement_strategy=pseudonymisation.pseudonymisation_dispatch,
    identifying_keywords=pseudonymisation.get_default_pseudonymisation_keywords(),
)