cerr.viewer package

Visualization sub-package. Three interchangeable viewers share the same planC data model:

  • pycerr_napari - napari-based 2D/3D viewer and magicgui widgets.

  • pycerr_gui - PyQt5 desktop slice viewer (CERR-style), with contouring, registration QA, IMRTP/ROE launchers and a programmatic control API.

  • pycerr_nbviewer - ipywidgets + matplotlib viewer for Jupyter/Colab.

For backward compatibility the public napari API is also reachable directly on the package, e.g. cerr.viewer.showNapari(...); this is resolved lazily so that importing pycerr_gui / pycerr_nbviewer does not pull in napari.

Submodules

cerr.viewer.pycerr_napari module

pyCERR napari viewer.

napari-based visualization of scan, structure, dose and deformation vector fields, with the associated magicgui widgets (window/level, structure edit/create/export, registration QA mirror-scope, dose colorbar).

Entry points:

showNapari(planC, …) - open the napari viewer captureToFile(…) - render axial/sagittal/coronal screenshots to file

For Jupyter/Colab (no Qt/napari) use cerr.viewer.pycerr_nbviewer; for the PyQt desktop viewer use cerr.viewer.pycerr_gui.

cerr.viewer.pycerr_napari.initialize_image_window_widget() FunctionGui[source]

Creates a magicgui widget for adjusting the image contrast window.

Builds a GUI panel with a CT window preset dropdown and manual center/width fields. When the user clicks ‘Set’, the selected layer’s contrast limits are updated and the updated layer metadata is returned as a LayerDataTuple.

Returns:

The magicgui image_window widget ready to be docked in

a Napari viewer.

Return type:

FunctionGui

cerr.viewer.pycerr_napari.initialize_struct_edit_widget() FunctionGui[source]

Creates a magicgui widget for editing and saving structure masks.

Builds a GUI panel that lets the user pick a Labels layer and choose whether to overwrite the existing structure or save as a new one. On clicking ‘Save edits’, the updated mask is imported back into planC and the layer metadata is refreshed.

Returns:

The magicgui struct_save widget ready to be docked in

a Napari viewer.

Return type:

FunctionGui

cerr.viewer.pycerr_napari.get_scan_layers(gui)[source]

Filter Image layers based on the scan dataclass

cerr.viewer.pycerr_napari.initialize_struct_create_widget() FunctionGui[source]

Creates a magicgui widget for drawing a new structure on a scan.

Builds a GUI panel that lets the user pick an Image layer and supply a structure name. Clicking ‘Create’ adds a blank Labels layer sized to match the chosen scan, pre-configured with the next available structure color and associated planC metadata.

Returns:

The magicgui struct_add widget ready to be docked in

a Napari viewer.

Return type:

FunctionGui

cerr.viewer.pycerr_napari.getLabelsDict(vwr)[source]

Returns a mapping from display label strings to structure indices.

Iterates over all layers in the Napari viewer and collects those that are Labels layers with a saved structNum. Each key is a string of the form "<index>_<structureName>" and each value is the corresponding integer structure index in planC.

Parameters:

vwr (napari.Viewer) – The active Napari viewer whose layers are searched.

Returns:

Mapping of "<index>_<structureName>" strings to integer

structure indices.

Return type:

dict

cerr.viewer.pycerr_napari.getLabelsList(vwr)[source]

Returns a list of display label strings for all saved structures in the viewer.

Convenience wrapper around getLabelsDict() that returns only the keys (i.e. the "<index>_<structureName>" strings) as an ordered list.

Parameters:

vwr (napari.Viewer) – The active Napari viewer whose layers are searched.

Returns:

Ordered list of "<index>_<structureName>" label strings.

Return type:

list[str]

cerr.viewer.pycerr_napari.initialize_struct_export_widget(vwr) FunctionGui[source]

Creates a magicgui widget for exporting structures to DICOM or NIfTI.

Builds a GUI panel populated with the structures currently visible in the Napari viewer. The user can multi-select structures, choose an output format (DICOM RT-STRUCT or NIfTI), and specify an output file path. Clicking ‘Export’ writes the file to disk.

Parameters:

vwr (napari.Viewer) – The active Napari viewer used to enumerate available structure layers.

Returns:

The magicgui struct_export widget ready to be docked in

the Napari viewer.

Return type:

FunctionGui

cerr.viewer.pycerr_napari.checkerboard_indices(shape, tile_size, evenTiles=True)[source]

Generates row and column indices for a checkerboard pattern.

Parameters:
  • shape (tuple) – Shape of the 2D array (rows, cols).

  • tile_size (int) – Size of each square tile.

Returns:

Two lists, one for row indices and one for column indices.

Each list contains tuples of slice objects representing the indices for the checkerboard pattern.

Return type:

tuple

cerr.viewer.pycerr_napari.getRCSwithinScanExtents(r, c, s, numRows, numCols, numSlcs, offset, axNum)[source]

Computes a bounding box of voxel indices clamped to the scan volume.

Given a cursor position (r, c, s) and a half-size offset, computes a rectangular region around the cursor along the two in-plane axes determined by axNum, then clamps every edge to the valid index range of the volume.

Parameters:
  • r (int or float) – Row index of the cursor position.

  • c (int or float) – Column index of the cursor position.

  • s (int or float) – Slice index of the cursor position.

  • numRows (int) – Total number of rows in the scan volume.

  • numCols (int) – Total number of columns in the scan volume.

  • numSlcs (int) – Total number of slices in the scan volume.

  • offset (int) – Half-size of the bounding region in voxels.

  • axNum (int) – Axis perpendicular to the current viewing plane (0, 1, or 2).

Returns:

(rMin, rMax, cMin, cMax, sMin, sMax)

— the clamped bounding-box indices for rows, columns, and slices.

Return type:

tuple[int, int, int, int, int, int]

cerr.viewer.pycerr_napari.updateMirror(viewer, baseLayer, movLayer, mrrScpLayerBase, mrrScpLayerMov, mirrorLine, mirrorSize, displayType)[source]

Refreshes the mirror-scope overlay layers and border lines for registration QA.

Called on every cursor move event to re-extract cropped sub-volumes from the base and moving image layers at the current cursor position, resize/flip them according to displayType, write the result into the temporary mrrScpLayerBase / mrrScpLayerMov image layers, and redraw the mirrorLine shapes that mark the split boundary.

Parameters:
  • viewer (napari.Viewer) – The active Napari viewer.

  • baseLayer (napari.layers.Image) – The fixed/reference image layer.

  • movLayer (napari.layers.Image) – The moving/registered image layer.

  • mrrScpLayerBase (napari.layers.Image) – Temporary overlay layer for the cropped base image patch.

  • mrrScpLayerMov (napari.layers.Image) – Temporary overlay layer for the cropped moving image patch.

  • mirrorLine (napari.layers.Shapes) – Shapes layer used to draw the split boundary line.

  • mirrorSize (float) – Approximate radius of the mirror region in mm.

  • displayType (str) – One of 'Mirrorscope', 'Sidebyside', or 'AlternateGrid'.

Returns:

None

cerr.viewer.pycerr_napari.mirror_scope_callback(layer, event)[source]

Mouse-drag callback that drives the mirror-scope registration QA overlay.

Registered as a mouse_drag_callbacks handler on the mirror-scope image layers. On the initial click and on every subsequent drag event it reads the current cursor world-coordinate from the viewer, stores it in the layer metadata, and calls updateMirror() to refresh the cropped overlay patches and boundary lines.

Parameters:
  • layer (napari.layers.Image) – The mirror-scope image layer that received the mouse event. Its metadata dict must contain keys 'mirrorline', 'displayType', 'mirrorSize', 'viewer', 'baseLayer', 'movLayer', 'mrrScpLayerBase', and 'mrrScpLayerMov'.

  • event – The napari mouse event object (used as a generator via yield to distinguish click from drag).

Yields:

None

Yields control back to napari between the click and each move

event so the viewer can process intermediate frames.

Returns:

None

cerr.viewer.pycerr_napari.initialize_reg_qa_widget() FunctionGui[source]

Creates a magicgui widget for interactive registration quality-assurance overlays.

Builds a GUI panel with dropdowns for selecting a base image and a moving image from the Napari viewer, a display-type selector ('Mirrorscope', 'Sidebyside', 'AlternateGrid', 'Toggle', or '--- OFF ---'), and sliders for mirror size and image toggle opacity. The widget creates and manages the temporary 'Mirror-Scope-base', 'Mirror-Scope-mov', and 'Mirror-line' layers in the viewer and hooks up mirror_scope_callback() for interactive drag-to-compare.

Returns:

The magicgui mirror_scope widget ready to be docked in

the Napari viewer.

Return type:

FunctionGui

cerr.viewer.pycerr_napari.initialize_dose_select_widget() FunctionGui[source]

Creates a magicgui widget for selecting a dose layer in the Napari viewer.

Builds a minimal GUI panel with an Image layer picker labelled ‘Pick a Dose’. The widget auto-calls on change and returns the selected dose layer as a LayerDataTuple so that downstream widgets (e.g. the dose colorbar) can react to the selection.

Returns:

The magicgui dose_select widget ready to be docked in

the Napari viewer.

Return type:

FunctionGui

cerr.viewer.pycerr_napari.initialize_dose_colorbar_widget() FunctionGui[source]

Creates a matplotlib canvas widget used as a dose colorbar panel.

Constructs a narrow (1 x 10 inch) FigureCanvasQTAgg figure with a dark background style intended to be docked alongside the Napari viewer to display the dose colorbar.

Returns:

A Qt-compatible matplotlib canvas ready to be embedded

as a Napari dock widget.

Return type:

FigureCanvasQTAgg

cerr.viewer.pycerr_napari.initialize_dvf_colorbar_widget() FunctionGui[source]

Creates a matplotlib canvas widget used as a deformation vector field colorbar panel.

Constructs a narrow (1 x 10 inch) FigureCanvasQTAgg figure with a dark background style intended to be docked alongside the Napari viewer to display the DVF magnitude colorbar.

Returns:

A Qt-compatible matplotlib canvas ready to be embedded

as a Napari dock widget.

Return type:

FigureCanvasQTAgg

cerr.viewer.pycerr_napari.showNapari(planC, scan_nums=0, struct_nums=[], dose_nums=[], vectors_dict={}, displayMode='2d')[source]

Routine to display images in the Napari viewer. This routine requires a display (physical or virtual).

Parameters:
  • planC (cerr.plan_container.PlanC) – pyCERR’s plan container object

  • scan_nums (list or int) – scan indices to display from planC.scan

  • struct_nums (list or int) – structure indices to display from planC.structure

  • dose_nums (list or int) – dose indices to display from planC.dose

  • vectors_dict

    A dictionary whose fields are “vectors” and “features”. vectors must be an array of size nx2x3, where n is the number of vectors. The 1st element along the 2nd dimension contains (row,col,slc) representing the start co-ordinate The 2nd element along the 2nd dimension contains (yDeform,xDeform,zDeform) representing the lengths of vectors along y, x and z axis in CERR virtual coordinates. i.e. vectors[i,0,:] = [rStartV[i], cStartV[i], sStartV[i]]

    vectors[i,1,:] = [yDeformV[i], xDeformV[i], zDeformV[i]]

  • displayMode – ‘2d’: contours are displayed by labels layer ‘3d’ contours are displayed by surface layer.

Returns:

Napari Viewer object List[napari.layers.Image]: List of scan layers corresponding to input scan_nums List[napari.layers.Labels]: List of structure layers corresponding to input struct_nums List[napari.layers.Image]: List of dose layers corresponding to input dose_nums List[napari.layers.Vectors]: List containing DVF layer corresponding to input vector_dict

Return type:

napari.Viewer

cerr.viewer.pycerr_napari.captureToFile(planC, fileName, scanNums, strNums, doseNums, vectorDict, centerStr, dispOpts=[])[source]

Renders axial, sagittal, and coronal screenshots of a structure and saves them to a file.

Opens a Napari viewer via showNapari(), navigates to the slices with the largest cross-section of centerStr along each axis, captures screenshots, then saves all three views as a single image file using matplotlib.

Parameters:
  • planC (cerr.plan_container.PlanC) – pyCERR’s plan container object.

  • fileName (str) – Output image file path (e.g. 'output.png').

  • scanNums (int or list[int]) – Scan index or indices to display.

  • strNums (int or list[int]) – Structure index or indices to display.

  • doseNums (int or list[int]) – Dose index or indices to display.

  • vectorDict (dict) – Deformation vector field dictionary passed to showNapari() (may be empty).

  • centerStr (int) – Index of the structure in planC.structure used to determine which slice to show in each view.

  • dispOpts (list or dict, optional) – Display options controlling opacity, windowing, and contour width for scan, structure, and dose layers. Defaults to [] (no overrides).

Returns:

None

cerr.viewer.pycerr_gui module

pyCERR Viewer GUI

A QT-based desktop viewer built on pyCERR.

Features (mirroring the classic CERR slice viewer):
  • Import DICOM directory / NIfTI scan, dose & structure files / planC pickle

  • Axial, sagittal and coronal linked views with slice sliders & mouse wheel

  • Pan (drag) and zoom (right-drag up/down) per view; double-click / R to reset

  • Right-click menu per view: choose the orientation (Axial/Sagittal/Coronal) plus the scan, dose & structures it displays (CERR-style per-axis View/ScanSet/DoseSet/StructSet selection)

  • Lock slices across matching views (View menu or L): windows showing the same orientation scroll together

  • View > Layout: one view, two side-by-side, one large + two stacked, three equal columns, or four equal views in a 2x2 grid

  • 3D view (default 4th window of the 2x2 layout, or right-click > View > 3D): shows the three orthogonal planes selected in the 2D views, textured with the scan and outlined in the plane-locator colors. GPU-accelerated via pyvista/VTK when installed (pip install pyvista pyvistaqt; falls back to matplotlib otherwise); rotate with left-drag, zoom with right-drag or wheel, pan with middle-drag. The planes are DRAGGABLE: grab one with the left button to scroll through slices - the linked 2D views follow live. Also shows structure surfaces (from the Structures checklist) and 30/50/70/90% isodose surfaces (from the Dose combo, colored by the dose colorbar)

  • Ruler tool per view (right-click > Draw Ruler): drag to measure distances in cm, CERR-style; toggle again to clear

  • Contouring tools (Tools > Contouring): CERR-style draw/erase of structure contours on the axial view - freehand, point-by-point polygon (line segments, right/double-click to close) and disk brush modes - with per-slice delete/copy, undo, and save back to planC via importStructureMask (new or edited structures)

  • Crosshairs linked across views (View menu or X to toggle)

  • Patient-orientation labels (L/R/A/P/S/I) at the edges of each 2D view and an orientation triad in the 3D view (View menu or O to toggle)

  • Multi-scan fusion: overlay any loaded scan with per-scan opacity & colormap

  • CT window/level presets (Soft Tissue, Lung, Bone, Brain, …) + manual W/L

  • Structure contour overlays with per-structure colors & visibility toggles, optional contour vertex dots (“Points”), adjustable contour line width, and double-click a structure to center all three views on it

  • Dose colorwash overlay with adjustable transparency, colorbar & dose units

  • Crosshair readout: position (cm), scan value (HU/SUV), dose (Gy)

  • DVH tool (cumulative dose-volume histograms, CERR-style)

  • Registration QA tool (Tools menu): compare a base and a moving scan via Mirrorscope (moving mirrored about a draggable line), Side-by-side, Alternate grid (checkerboard) and Toggle/blend (base-moving cross-fade slider) displays in every 2D view; each scan uses its own colormap

  • Tools menu launchers for the IMRTP GUI (beamlet dose calculation) and the ROE GUI (Radiotherapy Outcomes Explorer), sharing this viewer’s planC. IMRTP shows its computed dose in this viewer and draws beam’s-eye-view overlays (checked beams): the per-slice field cross-section in each 2D view (updates as you scroll) and the full field pyramid in the 3D view

Requirements:

pip install pyCERR PyQt5 matplotlib scipy – or add your local pyCERR checkout to sys.path (see PYCERR_PATH below).

Run:

python pycerr_gui.py [optional: path to DICOM directory]

cerr.viewer.pycerr_gui.cerr_get_cmap(_name)[source]
cerr.viewer.pycerr_gui.cerr_get_lut(_name, n=256)[source]
cerr.viewer.pycerr_gui.ascending(coords, arr, axis)[source]

Return coords sorted ascending and array flipped along axis to match.

class cerr.viewer.pycerr_gui.SliceView(*args: Any, **kwargs: Any)[source]

Bases: QWidget

sliceChanged

alias of str

cursorMoved

alias of str

viewReset

alias of str

contextRequested

alias of str

rulerChanged

alias of str

strokeFinished

alias of str

brushStroke

alias of str

brushDone

alias of str

crosshairDragged

alias of str

CLICK_PX = 6
property is3d
property uses_vtk
set_projection(to3d)[source]

Swap between the 2D matplotlib canvas and the 3D display. The 3D display is a GPU-accelerated pyvista/VTK widget when available, else a matplotlib Axes3D fallback.

cancel_polygon()[source]
clear_draw_artists()[source]

Remove transient contouring previews (polygon, brush cursor).

reset_view()[source]

Clear pan/zoom and ask the main window to re-render at full extent.

ruler_length()[source]

In-plane length of the current ruler in cm (data units are cm).

redraw_ruler()[source]

Recreate ruler artists after the axes were cleared (refresh).

clear_ruler()[source]
set_range(nslices, current)[source]
class cerr.viewer.pycerr_gui.DoseColorbarWidget(*args: Any, **kwargs: Any)[source]

Bases: QWidget

GRAB_PX = 9
TOP = 16
BOT = 16
setDose(doseMax)[source]
paintEvent(_event)[source]
mousePressEvent(ev)[source]
contextMenuEvent(ev)[source]
mouseMoveEvent(ev)[source]
mouseReleaseEvent(_ev)[source]
mouseDoubleClickEvent(_ev)[source]
class cerr.viewer.pycerr_gui.PyCerrViewer(*args: Any, **kwargs: Any)[source]

Bases: QMainWindow

setPlanC(planC)[source]

Attach an existing pyCERR plan container and display it.

getPlanC()[source]

Return the current (possibly updated) plan container.

display_dose(doseNum)[source]

Refresh from planC and show dose doseNum (called by IMRTP).

setBeams(beams)[source]

Display IMRTP beam overlays (2D + 3D). beams is a list of {“polylines”: [Nx3 arrays], “color”: (r, g, b)} dicts; [] clears.

set_scan(scanNum)[source]

Select the base scan (index into planC.scan).

set_dose(doseNum)[source]

Select the displayed dose; doseNum < 0 (or None) hides dose.

set_dose_alpha(alpha)[source]

Dose colorwash opacity, 0..1.

set_window_level(center, width)[source]

Manual window center/width for the base scan.

set_window_preset(name)[source]

Apply a named CT window preset (see CT_WINDOW_PRESETS).

set_scan_colormap(name)[source]
set_scan_opacity(alpha)[source]
set_orientation(winId, orientation)[source]

Set which orientation a window (A/B/C/D) displays (or VIEW_3D).

set_slice(orientation, k)[source]

Move the window showing orientation to slice index k.

set_structures_visible(which)[source]

Show structures: ‘all’, ‘none’, or a list of structure indices.

goto_structure(strNum)[source]

Center all views on a structure’s center of mass.

set_crosshairs(on)[source]
set_orientation_labels(on)[source]
set_structure_dots(on)[source]
set_contour_linewidth(width)[source]
set_lock_views(on)[source]
save_screenshot(path, target='window', dpi=150)[source]

Save a screenshot to path (PNG by file extension).

target:

“window” - the whole GUI window “views” - just the panel of view windows “A”/”B”/”C”/”D” - a single view window (2D figure or 3D render) an orientation (“Axial”/”Sagittal”/”Coronal”/”3D”) - that view “3d” - the 3D view (whichever window shows it)

Returns the path written.

start_reg_qa(base=None, moving=None, mode='Mirrorscope', size=None, base_frac=None)[source]

Open and configure the registration QA tool programmatically.

base/moving: scan indices; mode: ‘Mirrorscope’|’Sidebyside’| ‘AlternateGrid’|’Toggle’; size: mirror-box/tile size (cm); base_frac: Toggle-mode base weight (0..1). Returns the RegQaDialog.

stop_reg_qa()[source]

Close the registration QA tool if open.

compute_dvh(doseNum=None, structNums=None, num_bins=400)[source]

Compute cumulative DVHs. Returns (doseAxis_Gy, {name: volPct}), each structure interpolated onto a shared dose axis (0..global max).

export_dvh(path, doseNum=None, structNums=None, num_bins=400)[source]

Compute cumulative DVHs and write them to a CSV (wide format: Dose(Gy), <struct>, …). Returns (doseAxis, {name: volPct}).

closeEvent(event)[source]
import_dicom(path=None)[source]
dragEnterEvent(event)[source]
dragMoveEvent(event)[source]
dropEvent(event)[source]
load_path(path)[source]

Load a dropped/opened path: a DICOM directory, a NIfTI file (.nii/.nii.gz - scan, or dose/structure by name heuristic when a scan is loaded), a single DICOM file (its folder is imported), or a .pkl plan container.

import_nii_scan()[source]
import_nii_dose()[source]
import_nii_struct()[source]
open_pkl()[source]
save_pkl()[source]
after_load(keep_view=False)[source]

Refresh combo boxes / lists after planC changes.

on_scan_changed(idx)[source]
on_dose_changed(idx)[source]
on_alpha(val)[source]
on_scan_cmap(name)[source]
on_scan_alpha(val)[source]
on_preset(name)[source]
on_manual_wl(*_)[source]
on_slice_changed(winId, val)[source]
on_lock_toggled(on)[source]
on_crosshair_toggled(on)[source]
on_orientation_toggled(on)[source]
reset_all_views()[source]
set_layout(name)[source]

Switch the arrangement of view windows (View > Layout).

on_ruler_changed(orient)[source]
on_cursor_moved(winId, xd, yd)[source]
on_struct_dots(on)[source]
on_struct_linewidth(val)[source]
on_struct_double_click(item)[source]

Center all views on the double-clicked structure’s centroid.

goto_struct_center(strNum)[source]

Navigate the three orthogonal views to the structure’s center of mass (its isocenter slice in each plane).

refresh_views(only=None)[source]
on_crosshair_dragged(winId, xdata, ydata, dragV, dragH)[source]

Dragging a crosshair line in one view scrolls the perpendicular views to the dragged in-plane location.

show_dvh_dialog()[source]
show_contour_dialog()[source]

Open the CERR-style contouring tools (draw on the axial view).

show_reg_dialog()[source]

Open the registration QA tool (Mirrorscope / Side-by-side / Alternate grid / Toggle), cf. the napari QA modes in cerr.viewer.

show_imrtp_gui()[source]

Open the IMRTP beamlet-dose GUI (cerr.imrtp.imrtp_gui) non-blocking.

show_roe_gui()[source]

Open the ROE outcomes-explorer GUI (cerr.roe.roe_gui) non-blocking.

show_about()[source]
class cerr.viewer.pycerr_gui.DvhDialog(*args: Any, **kwargs: Any)[source]

Bases: QDialog

plot()[source]
class cerr.viewer.pycerr_gui.ContourDialog(*args: Any, **kwargs: Any)[source]

Bases: QDialog

NEW_ITEM = '<New structure>'
delete_slice()[source]
copy_adjacent(offset)[source]

Replace the current slice mask with the superior(+1)/inferior(-1) neighbor’s (CERR’s copy sup/inf).

undo()[source]
save()[source]
closeEvent(event)[source]
class cerr.viewer.pycerr_gui.RegQaDialog(*args: Any, **kwargs: Any)[source]

Bases: QDialog

MODES = ('Mirrorscope', 'Sidebyside', 'AlternateGrid', 'Toggle')
mode()[source]
configure(base=None, moving=None, mode=None, size=None, base_frac=None)[source]

Programmatically set base/moving scans, display mode, mirror-box / tile size (cm) and toggle blend fraction (base weight, 0..1).

sync_base(idx)[source]

Reflect the viewer’s active scan as the QA base (no feedback loop).

compose_slice(winId, img, hV, vV)[source]

Composite RGB image of base+moving for one view slice, each scan rendered with its own colormap. None falls back to normal display.

draw_guides(view)[source]

Side-by-side: a vertical split line. Mirrorscope: the square lens box and its center mirror line.

closeEvent(event)[source]
cerr.viewer.pycerr_gui.launch(planC=None, dicomDir=None)[source]

Open the viewer with an existing planC and BLOCK until it is closed.

Anything imported or modified in the GUI (scans, structures, doses) is reflected in the returned plan container.

Example

import cerr.plan_container as pc from pycerr_gui import launch

planC = pc.loadDcmDir(r”C:/data/pat1”) planC = launch(planC) # interact, then close the window print(len(planC.structure)) # includes anything added in the GUI

Parameters:
  • planC – optional cerr.plan_container.PlanC to display on startup.

  • dicomDir – optional DICOM directory to import on startup.

Returns:

the updated plan container.

Return type:

cerr.plan_container.PlanC

cerr.viewer.pycerr_gui.show(planC=None)[source]

Open the viewer WITHOUT blocking and return the viewer object.

Intended for interactive sessions (IPython/Jupyter: run %gui qt first). The viewer keeps a live handle to the plan container:

viewer = show(planC) # … interact with the GUI … planC = viewer.planC # always the current state viewer.setPlanC(otherPlanC) # swap plans programmatically viewer.refresh_views() # redraw after external planC edits

Returns:

the viewer window (access .planC for current state).

Return type:

PyCerrViewer

cerr.viewer.pycerr_gui.capture(planC, out_path, target='window', setup=None, size=(1480, 920))[source]

Render planC in the viewer and save a screenshot to out_path, without requiring manual interaction. Returns the path written.

setup is an optional callable setup(viewer) that drives the scripting API before the screenshot is taken, e.g.:

from cerr.viewer.pycerr_gui import capture
def prep(v):
    v.set_layout("grid")
    v.set_window_preset("Lung")
    v.set_dose(0); v.set_dose_alpha(0.4)
    v.goto_structure(0)
capture(planC, "shot.png", target="window", setup=prep)

For headless/batch use, set the Qt platform to offscreen first (os.environ['QT_QPA_PLATFORM'] = 'offscreen') - note the pyvista 3D view needs a real GL context, so 2D targets are most reliable headless.

cerr.viewer.pycerr_gui.main()[source]

cerr.viewer.pycerr_nbviewer module

pyCERR Notebook Viewer

A notebook/Colab-friendly version of the pyCERR Viewer GUI (pycerr_gui.py).

The PyQt5 desktop GUI cannot run on a headless server (no display). This module provides the same functionality with ipywidgets + matplotlib, which renders natively inside Jupyter, JupyterLab, VS Code notebooks and Google Colab.

Features (matching the desktop viewer where it makes sense in a notebook):
  • Axial / sagittal / coronal views with slice sliders

  • CT window presets + manual center/width

  • Base-scan colormap + opacity

  • Structure contour overlays: per-structure toggles & DICOM colors, All/None, adjustable contour line width, vertex dots (“Alaly dots”), and a “Center” button to jump all views to a structure’s center of mass

  • Patient-orientation labels (L/R/A/P/S/I)

  • Dose colorwash with alpha, all 21 CERR colormaps (cerr_colormaps.py)

  • Colorbar (colormap) range + dose display range controls with a live, standalone colorbar (range sliders replace the desktop’s draggable markers)

  • Cumulative DVH tool (cerr.dvh) + CSV export

  • Programmatic control API (set_scan/set_dose/goto_structure/… ) mirroring the desktop pycerr_gui, plus save_screenshot() and export_dvh()

  • Live planC access: viewer.planC

Desktop-only features that don’t map to a static notebook (3D VTK view, interactive contouring, IMRTP beams, drag interactions, registration QA) are not included here; use the Qt viewer (pycerr_gui.py) for those.

Usage in a notebook (e.g. Google Colab):

!pip install pyCERR ipywidgets # upload pycerr_nbviewer.py and cerr_colormaps.py next to your notebook

import cerr.plan_container as pc from pycerr_nbviewer import showNB

planC = pc.loadDcmDir(“/content/dicom_dir”) viewer = showNB(planC) # interactive viewer appears in the cell

# later, in any cell – planC reflects everything done in/through the viewer: planC = viewer.planC

cerr.viewer.pycerr_nbviewer.cerr_get_cmap(_name)[source]
class cerr.viewer.pycerr_nbviewer.NbViewer(planC, scanNum=0, figWidth=13.0, autoDisplay=True)[source]

Bases: object

CERR-style slice viewer for Jupyter/Colab. Access .planC at any time.

render_figure()[source]

Build and return the matplotlib figure of the three views.

set_scan(scanNum)[source]
set_window_level(center, width)[source]
set_window_preset(name)[source]
set_scan_colormap(name)[source]
set_scan_opacity(alpha)[source]
set_dose(doseNum)[source]
set_dose_alpha(alpha)[source]
set_dose_colormap(name)[source]
set_structures_visible(which)[source]
set_structure_dots(on)[source]
set_contour_linewidth(width)[source]
set_crosshairs(on)[source]
set_orientation_labels(on)[source]
set_slice(orientation, k)[source]
goto_structure(strNum)[source]

Center the three views on a structure’s center of mass.

compute_dvh(doseNum=None, structNums=None, num_bins=400)[source]

Cumulative DVHs -> (doseAxis_Gy, {name: volPct}), each interpolated onto a shared 0..max dose axis.

export_dvh(path, doseNum=None, structNums=None, num_bins=400)[source]

Compute cumulative DVHs and write a wide CSV (Dose(Gy), <struct>…).

save_screenshot(path, dpi=150)[source]

Render the current three-view figure and save it to file.

setPlanC(planC)[source]

Swap in a different plan container and rebuild the UI state.

getPlanC()[source]
refresh()[source]

Redraw after external edits to planC (e.g. importStructureMask).

cerr.viewer.pycerr_nbviewer.showNB(planC, scanNum=0, figWidth=13.0, *, scan_nums=None, struct_nums=None, structNums=None, dose_nums=None, doseNum=None, windowPreset=None, windowCenter=None, windowWidth=None, **_ignored)[source]

Display the notebook viewer for planC and return the viewer object.

The returned object keeps a live handle: viewer.planC is always current, and viewer.refresh() redraws after you modify planC from other cells.

Optional keyword arguments set the initial state and provide backward compatibility with the removed showMplNb / the showNapari signatures: scan_nums/scanNum, struct_nums/structNums (visible structures), dose_nums/doseNum, and windowPreset or windowCenter + windowWidth. List-valued scan/dose use the first element; unrecognised keywords are ignored.

cerr.viewer.cerr_colormaps module

CERR dose colormaps, ported from MATLAB CERR (CERRColorMap.m / weatherMap.m), github.com/cerr/CERR (LGPL/GPL). Matrix maps parsed verbatim; procedural maps (starinterp, hotcold, copper, red/green/blue/yellow, fireice) reimplemented.

cerr.viewer.cerr_colormaps.get_cmap(name)[source]

Return a matplotlib ListedColormap for a CERR colormap name.

cerr.viewer.cerr_colormaps.get_lut(name, n=256)[source]

Return an (n,3) uint8 lookup table for a CERR colormap name.

Module contents

pyCERR viewer sub-package.

Modules:

pycerr_napari - napari-based viewer + widgets (showNapari, captureToFile) pycerr_gui - PyQt5 desktop viewer (PyCerrViewer, show, launch, capture) pycerr_nbviewer - Jupyter/Colab viewer (NbViewer, showNB)

For backward compatibility, the public napari API is also reachable directly on the package, e.g. cerr.viewer.showNapari(...). This is resolved lazily so that importing cerr.viewer.pycerr_gui / cerr.viewer.pycerr_nbviewer does not pull in napari.