Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

Isocenter

DOI PyPI License

De-identify a DICOM cohort without touching the source files, and hand compliance a report that names anything the run could not do.

Isocenter is a Python library for indexing, de-identifying, and exporting DICOM datasets at cohort scale. It builds a SQLite metadata index and a pixel/waveform sidecar beside a read-only source tree, applies your de-identification profile and pixel redaction rules to an in-memory object graph, grades its own output, and writes clean copies to a new directory as DICOM or PhysioNet WFDB.

You have a cohort of studies and a protocol an IRB approved. You need to hand a de-identified copy to a collaborator, a registry, or a model, and to hand your compliance reviewer a record of what was removed, what stayed because the protocol allowed it, and anything the run lost on the way. Isocenter is the library your script imports to do that. There is no command-line tool: the Python API is the whole interface.

Documentation: https://kvnlng.github.io/Isocenter/

What it refuses to do

  • Modify a source file. Ingest reads; anonymize and redact change an in-memory graph. Until export(), the session writes only the store, isocenter.log and files you ask for (a configuration, a key, a report, a manifest or a cohort table). export() writes copies to a directory you name, so a crashed or abandoned run leaves the originals as they were. The store (<name>.db and <name>_pixels.bin) holds the original identifiers and pixels, so keep it where PHI may live.
  • Grade a lossy export PASS. Every step that can lose data writes an audit row, and the compliance report reads those rows. A cohort that lost a file, a private tag, a waveform group, or a pixel frame grades REVIEW_REQUIRED and names the loss. An export that attempted instances and wrote none of them raises ExportError; a partial export returns what it wrote, with an ERROR row for each failure.
  • Pass through pixels it could not decode. If a compressed frame cannot be decompressed, because of a missing codec or a stream the decoder rejects, the export fails on that instance rather than copying bytes it never inspected.
  • Advertise a Python version it does not test. The suite runs on all four supported versions, including the free-threaded 3.14t build, at every release, and 3.12 and 3.14t must pass before anything is uploaded. The PyPI classifiers list only those.

What it does

  • De-identification against the DICOM PS3.15 Annex E Basic Profile table, edition 2026c. A profile decides which tags go, are emptied, are replaced, or are date-shifted; a field your protocol permits stays. Nested sequences are scanned, not only the top level. Date jitter is deterministic per patient within a project, so intervals survive. UIDs are replaced consistently, so references between exported files still resolve (a UID in a private tag is not replaced yet: #765).
  • Machine-specific pixel redaction. Redaction zones are keyed by device, because the same model burns identifiers into the same place every time. An optional OCR pass finds where the text lands, and CTP DicomPixelAnonymizer.script rules import directly.
  • Reversible anonymization, if you choose it. Original identities can be encrypted under a key into the Encrypted Attributes Sequence (0400,0500) before anonymization, and recovered later by whoever holds the key.
  • A persistent session. A Patient → Study → Series → Instance graph over a SQLite index and a pixel sidecar, so a 10,000-instance cohort reopens without rescanning and a job can be paused and resumed. Every action is written to an audit log.
  • A compliance report with a PASS or REVIEW_REQUIRED grade, every exception listed, and a signature block for the reviewer.
  • Waveforms. DICOM waveform IODs (ECG, hemodynamic) export as PhysioNet WFDB records, with an annotation bridge to Murmur Studio.

Install

Isocenter needs Python 3.12 or later on Linux or macOS. The storage layer's locks use fcntl, so it does not import on Windows; there, use WSL or a Linux container.

pip install isocenter

Release candidates: pip install --pre isocenter.

python -c "import isocenter; print(isocenter.__version__)"

The OCR and NLP extras, and what each needs, are on the installation page.

Example

Put some DICOM files in input/ and run:

from isocenter import Session

# Worker processes are started by spawn, so a script needs this guard.
if __name__ == "__main__":
    with Session("my_project.db") as session:   # the session store
        session.ingest("input")                  # reads; never writes the source
        report = session.audit()                 # findings under the default policy
        session.anonymize(report)                # in memory
        summary = session.export("export_clean")
        print(len(summary.written_uids), "files written")
        session.generate_report("compliance_report.md")

With no configuration loaded, the default policy is the Basic Profile table (648 tag rules), with Study Date jittered, Patient's Sex and Age kept, and private tags removed. export_clean/ holds one Subject_ANON_… folder per patient written. An image the default lossless JPEG 2000 cannot hold (32-bit samples, for example) is not written: its ERROR row says so and names use_compression=False. The Executive Summary of compliance_report.md opens with the grade. The Quick Start adds a configuration, redaction, reversible anonymization and a verify step, and the tutorials run each step on files bundled with pydicom.

Burned-in text

Machines burn identifiers into the pixels, and the same model tends to burn them in the same place every time. Isocenter finds that text by OCR and blanks it with redaction zones you write per device. The OCR guide covers both.

5b. Zone Discovery

discover_redaction_zones() OCRs a random sample of one machine's instances and returns a DiscoveryResult of where text was found, so you can write zones from what the data does rather than from one screenshot. The scan needs the ocr extra (pip install "isocenter[ocr]") and the tesseract binary; without either it raises OcrUnavailableError naming what is missing.

result = session.discover_redaction_zones("SN-12345", sample_size=50, min_confidence=80.0)

# Suggested zones, in the [y1, y2, x1, x2] form the redaction config takes.
for zone in result.to_zones(min_occurrence=0.25):
    print(zone["type"], zone["zone"], zone["examples"])

to_zones() clusters the candidates, and keeps only clusters seen in at least min_occurrence of the sampled instances: a name in one frame out of fifty is noise, one in forty is the overlay. Working on a DiscoveryResult needs no extra:

>>> from isocenter.discovery import DiscoveryCandidate, DiscoveryResult
>>> result = DiscoveryResult([
...     DiscoveryCandidate("SMITH^JOHN", 92.0, [10, 8, 60, 12], 0, "NAME_PATTERN"),
...     DiscoveryCandidate("MERCY GENERAL", 88.0, [200, 180, 50, 10], 1, "PROPER_NOUN"),
... ], n_sources=2)
>>> list(result.to_dataframe().columns)
['text', 'confidence', 'box', 'source_index', 'classification']
>>> result.get_density_matrix(bins=(2, 2))
[[1, 0], [0, 1]]
>>> result.to_zones(min_occurrence=0.5)
[{'zone': [8, 20, 10, 70], 'type': 'LIKELY_NAME', 'occurrence': 0.5, 'confidence': 92.0, 'examples': ['SMITH^JOHN']}, {'zone': [180, 190, 200, 250], 'type': 'PROPER_NOUN', 'occurrence': 0.5, 'confidence': 88.0, 'examples': ['MERCY GENERAL']}]

filter(), to_zones() and to_dataframe() are frozen for 1.x; get_density_matrix() is documented but internal (API stability). get_density_matrix() is not an image-space heatmap. It bins each box's centre into a grid normalised by the largest box origin among the candidates, not by the image's Rows and Columns, so two scans are not comparable to each other or to the image. Take coordinates from to_zones() or from each candidate's box.

Writing the zones

Zones go in the configuration file, under the machine they belong to:

machines:
  - serial_number: "DEV12345"
    model_name: "UltraSound Pro"
    redaction_zones:
      - [0, 50, 0, 800] # [row_start, row_end, col_start, col_end]

Documentation

Citing Isocenter

If Isocenter's de-identification is part of how a dataset was prepared, it belongs in the methods section rather than the acknowledgements. Use GitHub's Cite this repository button, which reads CITATION.cff.

Each release is archived on Zenodo. Cite the concept DOI, 10.5281/zenodo.22104298, which always resolves to the latest version, so the citation follows the work. If you need to record the exact version used, name it in the text (Isocenter v1.0.0) and leave the DOI pointing at the concept record.

Isocenter is the upstream half of a pair: it builds and de-identifies the corpus that Murmur Studio (10.5281/zenodo.21077528) reviews. Work that used both should cite both.

License

Apache-2.0. See LICENSE and NOTICE.

Releases up to and including 0.9.2 were published under the GNU Affero General Public License v3.0 or later and remain available under it; the change is not retroactive.

Contact

Bug reports and questions about documented behaviour go to GitHub Issues; they are answered there, in public, for free. Never post patient data, or anything taken from it, in an issue. If an export still carries something it should have removed or replaced, or lets someone recover an identity or a real date, report it privately, as the security policy describes.

Help beyond bug reports and questions is available as paid consulting: configuring a de-identification profile for a protocol, integrating Isocenter into a pipeline, reviewing a run's report before it goes to a reviewer, or a feature your study needs sooner than the roadmap. Write to support@isocenter.net with what you need, and use the same address for anything that should not be public.

Metadata

Release files for isocenter 1.0.0rc12

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for isocenter 1.0.0rc12
File Size Uploaded
isocenter-1.0.0rc12.tar.gz 2.6 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for isocenter 1.0.0rc12
File Interpreter ABI Platform
isocenter-1.0.0rc12-py3-none-any.whl Python 3 none any Details

Total release size: 3.3 MB

Release files / isocenter-1.0.0rc12.tar.gz

Download URL isocenter-1.0.0rc12.tar.gz
Size 2.6 MB
Tags Source
SHA-256 checksum
How to use checksums
482e90a90ec25c165799786993a69d635cfc74456a01a621fcff84bcd7eab131
BLAKE2b-256 checksum
How to use checksums
eb7186b1d76d8aec45e911d23ae6e8aa722e0639293ad35a6569bcaa0bec23ff
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release files / isocenter-1.0.0rc12-py3-none-any.whl

Download URL isocenter-1.0.0rc12-py3-none-any.whl
Size 728.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4a5a6fffbf7329bf4f127254865ce451625dfa6ba6c9344f5f36eb6621917126
BLAKE2b-256 checksum
How to use checksums
0333be085c762b819f035296d25d91d38a90e44cc91a62c60b021493f258b8d2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page