Skip to main content

pyCERR - A Python-based Computational Environment for Radiological Research

pyCERR provides a convenient data structure for radiological imaging metadata and their associations: scans, segmentations, radiotherapy dose, treatment plans and deformable registrations for a patient are held together in a single container. Utilities are provided to extract, transform and organize this metadata, and to visualize the results of image processing.

On this foundation, pyCERR supports a wide range of applications in radiology and radiation oncology research:

  • Image analysis: IBSI-compliant radiomics and texture maps, PET SUV computation, DCE-MRI uptake features and optimal mass transport (urOMT) analysis
  • Segmentation: contouring, structure operations, consensus contours and auto-segmentation with pre-trained AI models
  • Registration: deformable image registration (plastimatch, ANTs) with tools for registration quality assurance
  • Dosimetry and outcomes: dose-volume histograms and metrics, gamma dose comparison, and normal tissue complication / tumor control probability models
  • Treatment planning: IMRT dose calculation and fluence optimization, including lattice radiotherapy
  • AI workflows: data preparation for model training and inference, on a workstation or in the cloud

Quick Start

Create a virtual environment with uv, install pyCERR with the desktop viewer, and launch Python:

uv venv --python 3.12
source .venv/bin/activate          # Windows: .venv\Scripts\activate
uv pip install "pycerr[viewer]"
python

In Python, load an example dataset and show it in the desktop viewer:

from cerr import plan_container as pc
from cerr.viewer.pycerr_gui import show
from cerr import datasets

dcmDir = datasets.fetch_sample_data('head_and_neck')   # local if present, else downloaded
planC = pc.loadDcmDir(dcmDir)
v = show(planC)

The desktop viewer needs the viewer extra. A plain pycerr install covers everything else, including the Jupyter viewer; see Install pyCERR.

Features

All data for a patient lives in a single PlanC container — scans, structures (segmentations), dose, treatment plans (beams) and deformations — defined in cerr.plan_container. Around it, pyCERR provides:

Data import / export

  • DICOM import of CT/MR/PT/US/NM scans plus RTSTRUCT, RTDOSE and RTPLAN — pc.loadDcmDir
  • NIfTI import/export of scans, segmentations and dose — pc.loadNiiScan / loadNiiStructure / loadNiiDose, .saveNii
  • Full-PlanC HDF5 serialization — pc.saveToH5 / pc.loadFromH5
  • DICOM RTSTRUCT export — cerr.dcm_export.rtstruct_iod

Segmentation & contours

  • Lazy polygon → binary-mask rasterization — cerr.contour.rasterseg.getStrMask
  • Import label maps / binary masks as structures — cerr.dataclasses.structure.importStructureMask

Radiomics (IBSI-compliant)

  • Scalar features: morphology, first-order, GLCM / GLRLM / GLSZM / GLDZM / NGTDM / NGLDM (IBSI-1)
  • Convolutional texture / filter-response maps: mean, LoG, Laws, Gabor, wavelet (IBSI-2)
  • cerr.radiomics.ibsi1.computeScalarFeatures, configured via JSON settings

Dosimetry & outcomes

  • Dose–volume histograms and metrics (Dx, Vx, MOHx, MOCx, mean dose) — cerr.dvh
  • Radiotherapy outcome models (NTCP/TCP: LKB, logistic, Cox, Appelt) — cerr.roe
  • IMRT planning / beamlet (influence-matrix) dose calculation — cerr.imrtp

Image processing

  • Deformable image registration via plastimatch / ANTs — cerr.registration
  • Resampling, intensity preprocessing and masking — cerr.utils
  • Semi-quantitative DCE-MRI features — cerr.mri_metrics
  • Helpers for AI model training / inference pipelines — cerr.utils.ai_pipeline

Visualization — three interchangeable viewers driven by the same planC (a PyQt5 CERR-style desktop GUI, a Jupyter/Colab notebook viewer, and napari 2D/3D); see visualize scan, dose and segmentation below.

Documentation

Install pyCERR

pyCERR is published on PyPI as pycerr and supports Python 3.9–3.13 (3.12 recommended). Install it into an isolated virtual environment. The steps below use uv; install it first if you don't have it (curl -LsSf https://astral.sh/uv/install.sh | sh on macOS/Linux, winget install --id=astral-sh.uv on Windows, or brew install uv).

1. Create and activate a virtual environment

uv venv --python 3.12              # creates .venv/, downloading Python 3.12 if needed
source .venv/bin/activate          # Windows: .venv\Scripts\activate

2. Install pyCERR with the extras you need

uv pip install pycerr                      # core: I/O, radiomics, DVH, registration, Jupyter viewer
uv pip install "pycerr[viewer]"            # + PyQt5 desktop viewer (pycerr_gui), ROE and IMRTP GUIs
uv pip install "pycerr[viewer,napari]"     # + napari 2D/3D viewer
Extra Adds Needed for
(none) core dependencies, ipywidgets Python API, headless/batch processing, containers, cerr.viewer.pycerr_nbviewer (Jupyter / Colab)
viewer PyQt5, pyvista, pyvistaqt cerr.viewer.pycerr_gui desktop viewer (incl. 3D view), ROE and IMRTP GUIs
napari napari[all], napari-animation cerr.viewer.pycerr_napari
ants antspyx ANTs-based registration, cerr.registration.ants_reg
gpu cupy-cuda13x and NVIDIA CUDA 13 runtime wheels optional GPU acceleration of the urOMT solver

Extras can be combined, e.g. uv pip install "pycerr[viewer,napari,ants]". The viewer extra is not in the base install because PyQt5 has no aarch64 Linux wheel; on arm64 Linux (ARM servers, Apple Silicon Docker images) install plain pycerr. Launching pycerr_gui without the extra raises an ImportError naming the install command.

AI segmentation models (cerr.ai_models) additionally need model_installer, which is distributed from GitHub only:

uv pip install "model_installer @ git+https://github.com/cerr/model_installer.git"

Install the latest development version

uv pip install "pycerr[viewer] @ git+https://github.com/cerr/pyCERR.git@main"

or, to work on pyCERR itself, clone the repository and make an editable install:

git clone https://github.com/cerr/pyCERR.git
cd pyCERR
uv venv --python 3.12
source .venv/bin/activate
uv pip install -e ".[viewer,napari]" pytest

Jupyter

Install JupyterLab in the same environment to run the example notebooks:

uv pip install jupyterlab
jupyter lab

In Google Colab, install with !pip install pycerr (the notebook viewer needs no extra).

Example Notebooks

Example notebooks are hosted at https://github.com/cerr/pyCERR-Notebooks/. Clone this repository to use notebooks as a starting point.

git clone https://github.com/cerr/pyCERR-Notebooks.git

Example snippets

Run Python from the virtual environment created above and try out the following code samples.

Import modules for planC and viewer

import numpy as np
from cerr import plan_container as pc
from cerr.viewer import pycerr_gui           # desktop viewer (pycerr_gui.show, ...); needs pycerr[viewer]

Read DICOM directory contents to planC

dcmDir = r"\\path\to\Data\dicom\directory"
planC = pc.loadDcmDir(dcmDir)

Read NifTi scan to planC

scanNiiFileName = r"\\path\to\Data\scan.nii.gz"
planC = pc.loadNiiScan(scanNiiFileName, imageType = "CT SCAN")

Read NifTi scan in a specified orientation to planC

planC = pc.loadNiiScan(scanNiiFileName, imageType = "CT SCAN", direction='LPS')   # 3-letter orientation code, e.g. 'LPS', 'RAS'

Read NifTi scan and append to an existing planC

planC = pc.loadNiiScan(scanNiiFileName, imageType = "CT SCAN", direction='LPS', initplanC=planC)

Read NifTi segmentation to planC

structNiiFileName = r"\\path\to\Data\structure.nii.gz"
assocScanNum = 0
labelDict = {'GTV_P': 1, 'GTV_N': 2}    # structure name -> label value
planC = pc.loadNiiStructure(structNiiFileName, assocScanNum, planC, labelDict)

Export Structures to DICOM

from cerr.dcm_export import rtstruct_iod

structDcmFileName = r"\\path\to\Data\structure.dcm"
structNums = [0,2,3]
exportOpts = {'seriesDescription': "Exported by pyCERR"}
rtstruct_iod.create(structNums,structDcmFileName,planC,exportOpts)

Export Scan, Structure and Dose to NifTi

scanNiiFileName = r"\\path\to\Data\scan.nii.gz"
scanNum = 0
planC.scan[scanNum].saveNii(scanNiiFileName)

structNiiFileName = r"\\path\to\Data\structure.nii.gz"
structNum = 0
planC.structure[structNum].saveNii(structNiiFileName, planC)    

doseNiiFileName = r"\\path\to\Data\dose.nii.gz"
doseNum = 0
planC.dose[doseNum].saveNii(doseNiiFileName)

visualize scan, dose and segmentation

pyCERR ships three interchangeable viewers under the cerr.viewer sub-package, all driven by the same planC:

Viewer Module Install Best for
PyQt5 desktop cerr.viewer.pycerr_gui (show) pycerr[viewer] CERR-style slice viewer: contouring, registration QA, IMRTP/ROE, scripting API
notebook cerr.viewer.pycerr_nbviewer (showNB) pycerr Jupyter / JupyterLab / VS Code / Google Colab
napari 2D/3D cerr.viewer.pycerr_napari (showNapari) pycerr[napari] quick interactive review, 3D rendering

PyQt5 desktop viewer

from cerr.viewer import pycerr_gui
viewer = pycerr_gui.show(planC)            # opens the CERR-style desktop GUI
# ... or launch empty and drag-and-drop a DICOM directory / NIfTI file in.
# The viewer exposes a scripting API (set_scan/set_dose/goto_structure,
# registration-QA setup, DVH export, save_screenshot, ...); see
# cerr/viewer/API_pycerr_gui.md for the full reference.

Notebook viewer (Jupyter / Colab)

from cerr.viewer import pycerr_nbviewer
viewer = pycerr_nbviewer.showNB(planC, scan_nums=[0], struct_nums=strNumList,
                                 dose_nums=[0])

napari viewer

from cerr.viewer import pycerr_napari
scanNumList = [0]
doseNumList = [0]
numStructs = len(planC.structure)
strNumList = np.arange(numStructs)
displayMode = '2d' # '2d' or '3d'
vectDict = {}
viewer, scan_layer, struct_layer, dose_layer, dvf_layer = \
               pycerr_napari.showNapari(planC, scan_nums=scanNumList, struct_nums=strNumList,\
	       dose_nums=doseNumList, vectors_dict=vectDict, displayMode = '2d')

Compute DVH-based metrics

from cerr import dvh
structNum = 0
doseNum = 0
dosesV, volsV, isErr = dvh.getDVH(structNum, doseNum, planC)
binWidth = 0.025
doseBinsV,volHistV = dvh.doseHist(dosesV, volsV, binWidth)
percent = 70
dvh.MOHx(doseBinsV,volHistV,percent)

Compute radiomics

import os
from cerr import datasets
from cerr.radiomics import ibsi1

scanNum = 0
structNum = 0
# JSON settings file: resampling, intensity discretization and feature classes.
# A sample is shipped with pyCERR; copy and edit it for your own analysis.
settingsFile = os.path.join(os.path.dirname(datasets.__file__),
                            'radiomics_settings', 'original_settings.json')
featDict, diagDict = ibsi1.computeScalarFeatures(scanNum, structNum, settingsFile, planC)
# featDict maps feature names to values (IBSI-1: shape, first-order, GLCM, GLRLM, GLSZM, ...)

Compute texture

import os
from cerr import datasets
from cerr.radiomics import texture_utils

scanNum = 0
structNum = 0
# JSON settings file for a convolutional filter (IBSI-2). Samples shipped with pyCERR:
# mean_filter.json, LoG_filter.json, Rot_inv_laws_energy_filter.json, gabor_filter.json
settingsFile = os.path.join(os.path.dirname(datasets.__file__),
                            'convolutional_filter_settings', 'LoG_filter.json')
planC = texture_utils.generateTextureMapFromPlanC(planC, scanNum, structNum, settingsFile)
# The texture map is added as a new scan, cropped around the structure
textureScanNum = len(planC.scan) - 1
texture3M = planC.scan[textureScanNum].getScanArray()

Metadata

Release files for pycerr 2.3.0

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

Source distribution (sdist)

Source distribution for pycerr 2.3.0
File Size Uploaded
pycerr-2.3.0.tar.gz 25.8 MB Details

Built distribution (wheel)

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

Total release size: 51.7 MB

Release files / pycerr-2.3.0.tar.gz

Download URL pycerr-2.3.0.tar.gz
Size 25.8 MB
Tags Source
SHA-256 checksum
How to use checksums
332fe28366a8f5a7db20f2e542e2601312c9ddee6532d969315b05f43191c761
BLAKE2b-256 checksum
How to use checksums
110f71ca344c5b4fef29b8623158cf649648f739084c7577c3545839ac61dd65
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 9, 2026.

Transparency log

Release files / pycerr-2.3.0-py3-none-any.whl

Download URL pycerr-2.3.0-py3-none-any.whl
Size 25.9 MB
Tags Python 3
SHA-256 checksum
How to use checksums
92211e0bb64b4a2c17f2fb7b5d27978d560d755315ef1a8d16cc954822b19fbb
BLAKE2b-256 checksum
How to use checksums
395b599eba4d198f4f06ed94653f885ad1e0f863a5f27a20e9a7ebca9bfd1f56
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 9, 2026.

Transparency log

Release history Release notifications | RSS feed

2.3.3

2 release files

2.3.2

2 release files

2.3.1

2 release files

This release

2.3.0 This release

2 release files

2.2.3

2 release files

2.2.2

2 release files

2.2.1

2 release files

2.2.0

2 release files

2.1.0

2 release files

2.0.0

2 release files

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