Enterprise-grade medical-imaging pipeline: ingest, de-identify, convert, and QC DICOM for 3D Slicer and ITK-SNAP.
Project description
dicom-forge
An enterprise-grade medical-imaging pipeline that prepares DICOM for 3D Slicer and ITK-SNAP.
dicom-forge takes a folder of DICOM, de-identifies it, runs quality control,
and converts it into the formats clinical-research viewers load natively — NIfTI
(.nii.gz), NRRD (.nrrd), and Slicer's segmentation format (.seg.nrrd). Every run
produces a serialisable audit record.
It is the headless core of a two-repo system; its companion,
slicer-forge, wraps it in a 3D Slicer
extension GUI.
Why this exists
Real imaging pipelines separate a testable, headless core from a thin GUI.
3D Slicer itself is built this way: ITK/VTK do the work, the GUI is a shell on top.
dicom-forge is that core — so the logic is unit-tested in CI without needing
Slicer installed, and the same code runs from the command line, from Python, or
inside Slicer's Python console.
Features
- Ingestion — recursive DICOM discovery, series grouping, geometry-aware slice ordering (handles oblique acquisitions), rescale-slope/intercept applied (CT in HU).
- De-identification — three escalating levels modelled on the DICOM PS3.15 Basic
Profile, with deterministic salted-hash pseudonymisation of
PatientID. - Quality control — slice count, geometry consistency, slice-spacing regularity, and intensity statistics, split into blocking errors vs. non-blocking warnings.
- Conversion — geometry-preserving export to NIfTI / NRRD via SimpleITK (the ITK core shared with Slicer & ITK-SNAP).
- Segmentation — write Slicer-native
.seg.nrrdlabel maps with named, coloured segments. - Typed & validated — Pydantic models everywhere,
py.typed, strict mypy. - Two interfaces — a Rich CLI (
dicomforge) and a clean Python API.
Installation
pip install dicom-anvil # core (ingest, de-id, QC)
pip install "dicom-anvil[convert]" # + SimpleITK/pynrrd/nibabel for conversion
Names: the package installs as
dicom-anvil(the PyPI namedicom-forgewas already taken) and imports asdicomforge; the repository staysdicom-forge.
The conversion stack (SimpleITK et al.) is an optional extra so the core stays lightweight and CI-friendly. Calling a conversion function without it raises a clear
MissingDependencyErrortelling you exactly what to install.
Quick start
Command line
# List the series in a folder
dicomforge inspect ./study
# Run QC and print a report
dicomforge qc ./study
# Full pipeline: de-identify -> QC -> convert to Slicer NRRD
dicomforge convert ./study ./out/patient01 --format nrrd --deid-level moderate
Python
from dicomforge import run_pipeline, PipelineConfig, OutputFormat
result = run_pipeline(
"./study",
"./out/patient01",
config=PipelineConfig(output_format=OutputFormat.NRRD),
)
print(result.qc.passed) # True / False
print(result.conversion.output_path) # ./out/patient01.nrrd
print(result.model_dump_json(indent=2)) # full audit record
Pipeline order (and why it matters)
ingest ──> de-identify ──> QC ──> convert
De-identification runs before conversion, so any file written to disk is already free of direct identifiers. De-id is performed in memory — your source DICOM is never modified.
⚠️ De-identification is risk reduction, not a legal guarantee. Burned-in pixel annotations and private vendor tags can still carry PHI. Always review output before releasing it outside a controlled environment.
Development
python -m venv .venv && . .venv/Scripts/activate # Windows
pip install -e ".[dev,convert]"
pytest # run the suite (synthetic DICOM, no real data needed)
ruff check . && mypy # lint + type-check
License
PolyForm Noncommercial License 1.0.0 © Angela Hudson
Noncommercial use — personal, research, educational, and other noncommercial purposes as defined by the license — is free. Any commercial use requires a separate license from the copyright holder. See LICENSE for the full terms, or open an issue to ask about commercial licensing.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dicom_anvil-0.1.0.tar.gz.
File metadata
- Download URL: dicom_anvil-0.1.0.tar.gz
- Upload date:
- Size: 32.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cf0ad9ca7f8acb72824c0e2694662fa237c6b8924db6421cb243f4205ff8cac9
|
|
| MD5 |
ec1361e162fda68660a1383b9f62ca32
|
|
| BLAKE2b-256 |
cb6ceb67b7963484da41e60b54d0ec65569d5deea633a75fccadf9f7a06c257c
|
Provenance
The following attestation bundles were made for dicom_anvil-0.1.0.tar.gz:
Publisher:
release.yml on DaCameraGirl/dicom-forge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dicom_anvil-0.1.0.tar.gz -
Subject digest:
cf0ad9ca7f8acb72824c0e2694662fa237c6b8924db6421cb243f4205ff8cac9 - Sigstore transparency entry: 1844280858
- Sigstore integration time:
-
Permalink:
DaCameraGirl/dicom-forge@fea5339b69c7d6852fa362e6692ac6cd51a0c897 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/DaCameraGirl
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@fea5339b69c7d6852fa362e6692ac6cd51a0c897 -
Trigger Event:
push
-
Statement type:
File details
Details for the file dicom_anvil-0.1.0-py3-none-any.whl.
File metadata
- Download URL: dicom_anvil-0.1.0-py3-none-any.whl
- Upload date:
- Size: 28.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
76179365a0fbaf373145850ddd1fc2ee49af74ab18d17d135eaf5b50c478578c
|
|
| MD5 |
22f25403516ff528a2ee605ad2aeaf65
|
|
| BLAKE2b-256 |
60eaa951e8302f8ee2283f424c1cb7b4d4f6a63be3763c88667a3c18be11a529
|
Provenance
The following attestation bundles were made for dicom_anvil-0.1.0-py3-none-any.whl:
Publisher:
release.yml on DaCameraGirl/dicom-forge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dicom_anvil-0.1.0-py3-none-any.whl -
Subject digest:
76179365a0fbaf373145850ddd1fc2ee49af74ab18d17d135eaf5b50c478578c - Sigstore transparency entry: 1844281050
- Sigstore integration time:
-
Permalink:
DaCameraGirl/dicom-forge@fea5339b69c7d6852fa362e6692ac6cd51a0c897 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/DaCameraGirl
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@fea5339b69c7d6852fa362e6692ac6cd51a0c897 -
Trigger Event:
push
-
Statement type: