Skip to content

API — nefi.viz

Generated by scripts/gen_api_docs.py — do not edit by hand. Index

nefi.viz

nefi.viz — figures, animations, dashboards and shareable reports for neural-field inversion.

nefi.viz.fields

Field viewers: 1-D lines, 2-D images, 3-D slices / mosaics / projections / voxels, and the standard reconstruction figure :func:compare_fields (GT | measurement | reconstruction(s) | signed error, metrics in the panel titles).

class Comparison(name: str | None, label: str, tag: str, g: np.ndarray | None, items: list[tuple[str, np.ndarray]], mets: dict[str, dict[str, float]], spec: CmapSpec, domain...

Everything a comparison layout needs (resolved by :func:compare_fields).

  • gt_title(self) -> str
  • lims(self) -> tuple[float, float]
  • recon_title(self, lab: str, n_metrics: int = 2) -> str

def add_colorbar(fig: Any, mappable: Any, axes: Any, label: str | None = None, nticks: int = 4, shrink: float = 0.85, location: str | None = None, pad: float = 0.015) -> Any

Thin colorbar attached to one axes or a list of axes (constrained-layout friendly); location="bottom" puts it below (e.g. next to 3-D axes, whose tick labels constrained layout does not see).

def anomaly_background(a: Any) -> float

Background level of a field: its median (the bulk value for localized anomalies).

def anomaly_centroid(vol: Any, *, mask: Any = None, background: float | None = None, level: float = 0.5) -> tuple[int, ...]

Grid index of the centroid of the dominant anomaly of a 2-D / 3-D field.

def anomaly_levels(gt: Any, *, background: float | None = None, fraction: float = 0.5, min_share: float = 0.2) -> list[float]

Contour levels outlining the anomalies of a ground truth: background ± fraction × the largest deviation on each side (a side whose deviation is below min_share of the other is skipped, so a positive-only source map gets one level and a signed map two).

def as_complex(a: np.ndarray, stacked: str | None = None) -> np.ndarray

Combine a stacked real/imag pair (stacked="first": shape (2, ...); "last": (..., 2)) into a complex array; other arrays are returned unchanged.

def axis_coords(n: int, domain: Any = None, dim: int = 0) -> np.ndarray

Cell-center coordinates of axis dim (physical if domain is given).

def compare_fields(gt: Any, recons: Any, measurement: Any = None, *, kind: str = 'auto', field: str | None = None, quantity: str | None = None, metrics: Any = 'auto', error: b...

The standard reconstruction figure: measurement | GT | reconstruction(s) | extra panels.

def default_metrics(kind: str) -> dict[str, Callable]

PSNR + relative error (1-D), PSNR + SSIM (2-D / 3-D) from :mod:nefi.metrics.basic.

def depth_mosaic(vol: Any, *, field: str | None = None, axis: int = -1, slices: Sequence[int] | None = None, n_slices: int = 8, ncols: int | None = None, domain: Any = None,...

Depth-slice mosaic of a 3-D field with one shared color scale (NeFTY Fig. 4 style).

def detect_kind(x: Any, kind: str = 'auto') -> str

"1d" | "2d" | "3d" | "complex" from the dimensionality / dtype of x.

def draw_contour(ax: Axes, mask: Any, extent: tuple[float, float, float, float], color: str | None = None, level: float = 0.5)

Outline of a 2-D mask (e.g. a defect / support) on an image panel.

def draw_levels(ax: Axes, arr: Any, levels: Sequence[float], extent: tuple[float, float, float, float], *, style: str = 'gt', origin: str = 'lower', color: str | None = Non...

Iso-lines of a 2-D array (field convention a[x, y]) on an image panel.

def draw_peaks(ax: Axes, idx: np.ndarray, shape: Sequence[int], extent: tuple[float, float, float, float], style: str = 'gt')

Overlay peak markers: "gt" hollow white circles, "recon" aqua crosses.

def field_metrics(pred: Any, gt: Any, metrics: Mapping[str, Callable] | str | None = 'auto') -> dict[str, float]

Metrics of pred against gt (failures become nan, never exceptions).

def image_extent(shape: Sequence[int], domain: Any = None, dims: tuple[int, int] = (0, 1)) -> tuple[float, float, float, float]

imshow extent (x0, x1, y0, y1) of a 2-D slice: physical when domain (a :class:~nefi.domain.Domain or an extent list) is given, pixel indices otherwise.

def image_panels(images: Mapping[str, Any], *, field: str | None = None, spec: CmapSpec | str | None = None, shared: bool = True, ncols: int | None = None, peaks: bool = Fal...

Grid of 2-D panels {label: image} with one shared color scale (default).

def line_profile(a: np.ndarray, center: Sequence[int], axis: int) -> np.ndarray

Values of a along axis through the grid point center.

def match_shape(a: np.ndarray, shape: Sequence[int]) -> np.ndarray

Resample a to shape (area / linear, cell-centered) when the shapes differ.

def metrics_label(metrics: Mapping[str, Any] | None, max_items: int = 2) -> str

"PSNR 24.1 dB · SSIM 0.912" from a metrics dict (first max_items entries).

def orthoslices(vol: Any, *, field: str | None = None, index: Sequence[int] | None = None, domain: Any = None, spec: CmapSpec | str | None = None, title: str | None = None,...

Three orthogonal slices through index (default: the most anomalous voxel, i.e. the largest difference from the median — typically inside a defect).

def panel_set(panels: Any = None, error: bool = True) -> tuple[str, ...]

Normalize compare_fields(panels=...): None → measurement, GT, reconstruction and the signed error; a string names the extra panel ("overlay" → measurement, GT, reconstruction, overlay); a sequence lists the panels (any of :data:PANELS).

def peak_indices(img: Any, threshold: float = 0.05) -> np.ndarray

(k, 2) integer (i, j) indices of 3×3 local maxima above threshold · max.

def plot_complex(x: Any, *, field: str | None = None, domain: Any = None, title: str | None = None, complex_stack: str | None = None, dark: bool | None = None) -> Figure

Magnitude (magma) and phase (twilight on [-π, π]) of a complex 1-D / 2-D field (3-D: representative slice).

def plot_field(x: Any, *, field: str | None = None, kind: str = 'auto', ax: Axes | None = None, domain: Any = None, title: str | None = None, colorbar: bool = True, peaks:...

Draw one field: line (1-D), image (2-D), depth mosaic (3-D; the representative slice when ax is given) or magnitude + phase (complex).

def plot_line(ax: Axes, y: Any, *, x: Any = None, domain: Any = None, label: str | None = None, color: str | None = None, style: str = 'recon', **kw: Any)

One 1-D field on an axes. style: "gt" (ink, dashed), "recon" (series color, solid), "data" (muted dots).

def projections(vol: Any, *, field: str | None = None, mode: str = 'auto', domain: Any = None, spec: CmapSpec | str | None = None, title: str | None = None, colorbar: bool ...

Max / min / mean projections of a 3-D field along each axis.

def representative_slice(vol: np.ndarray, axis: int = -1) -> int

Index of the slice with the largest in-slice variance (ties → the middle slice).

def resolve_field(obj: Any, field: str | None = None) -> tuple[np.ndarray, str | None]

Array of one field from a tensor, a :class:~nefi.solve.Result, a fields dict or a :class:~nefi.measurement.Measurement.

def select_slices(n: int, n_slices: int) -> list[int]

n_slices evenly spaced indices in [0, n) (all of them if n <= n_slices).

def show_image(ax: Axes, img: Any, *, spec: CmapSpec | str | None = None, name: str | None = None, vmin: float | None = None, vmax: float | None = None, extent: tuple[floa...

Draw a 2-D array as an image panel.

def squeeze_field(a: np.ndarray) -> np.ndarray

Drop singleton dims ((1, 64, 64) → (64, 64)) but keep at least 1-D.

def take_slice(vol: np.ndarray, index: int, axis: int = -1) -> np.ndarray

2-D slice vol[..., index] along axis (remaining dims keep their order).

def to_numpy(x: Any) -> np.ndarray

Tensor / array / list → numpy (float64 for real data, complex128 for complex data).

def voxel_threshold(a: np.ndarray, mode: str = 'auto', background: float | None = None, fraction: float = 0.5) -> tuple[str, float]

(mode, threshold) of a voxel view: the anomaly side ("below" / "above" the background, the side of the larger deviation for mode="auto") and the level fraction of the way from the background (default: the median) to that extreme.

def voxel_view(vol: Any, *, field: str | None = None, threshold: float | None = None, mode: str = 'auto', max_points: int = 4000, domain: Any = None, ax: Axes | None = Non...

Isosurface-free 3-D view: scatter of thresholded voxels, colored by value.

nefi.viz.hints

Display hints: how an instance wants its measurement and its fields drawn.

def apply_transform(a: np.ndarray, transform: Any, *, domain: Any = None, instance: Any = None) -> np.ndarray

Apply a display transform to one array (returns a new array; the input is unchanged).

def compare_extras(hints: Mapping[str, Any] | None, ndim: int) -> tuple[str, ...]

Extra panels of the gallery's compare figure: the compare_panel hint, else ("overlay",) for 3-D fields and ("error",) otherwise.

def field_hint(hints: Mapping[str, Any] | None, key: str, field: str | None) -> Any

Value of a field-level hint for field: a plain value applies to every field, a mapping {field: value} only to the fields it names ("*" = default).

def instance_hints(instance: Any = None, hints: Mapping[str, Any] | None = None) -> dict

Display hints for instance (:data:INSTANCE_HINTS < instance.viz_hints < explicit hints).

def transform_is_magnitude(transform: Any) -> bool

True for transforms whose result is a non-negative magnitude (abs, gradients).

def transform_name(transform: Any) -> str | None

Canonical name of a transform spec (None for the identity).

def transform_note(transform: Any) -> str

Short text for panel titles ("mean removed", "log₁₀", ...); "" = identity.

def volume_axis(hints: Mapping[str, Any] | None, default: int = -1) -> int

The volume_axis hint (slicing axis of 3-D fields), default when absent.

nefi.viz.interactive

Interactive 3-D viewer: drag-to-rotate isosurfaces, voxels and slices in the browser.

def asset_bytes() -> int

Size of :func:assets_html in bytes (shared by every viewer of a page).

def assets_html() -> str

The viewer's <style> and <script> — include once per page.

def auto_stretch(extent: Sequence[Sequence[float]], axis: int = -1) -> float

Depth stretch of thin slabs (as the static voxel views): physical (1) unless the volume axis is shorter than 35 % of the largest lateral side, then stretched to 35 %.

def decode_mesh(entry: Mapping[str, Any], shape: Sequence[int]) -> tuple[np.ndarray, np.ndarray]

(vertices (V, 3), faces (F, 3)) of a mesh entry (mirror of the JS decodeMesh).

def decode_volume(entry: Mapping[str, Any], shape: Sequence[int]) -> np.ndarray

The values the viewer decodes from a payload volume (mirror of the JS decode).

def downsample(a: np.ndarray, max_side: int = 64) -> np.ndarray

Area-average a so no side exceeds max_side (unchanged when it already fits).

def encode_mesh(verts: np.ndarray, faces: np.ndarray, shape: Sequence[int], **meta: Any) -> dict[str, Any]

A mesh entry: vertices (grid index coordinates in [-0.5, n - 0.5]) as uint16 over each axis, faces as uint16 (≤ 65535 vertices) or uint32; meta (level, side, rule) is kept.

def entry_viewer_inputs(entry: Any) -> tuple[dict[str, np.ndarray], dict[str, Any]]

(volumes, options) of a 3-D gallery entry: GT and reconstruction on the GT grid (the instance's display hints applied, :func:~nefi.viz.multiphysics.tile_data) — with an edge refinement GT | smooth | refined (or the refused candidate, labelled) —, the instance's IoU rule as the GT threshold, the anomaly centroid, the volume_transform hint.

def normalize_kind(kind: Any) -> str | None

"canvas" / "plotly" / None (off) from True, False, None or a name ("none", "off", "js", "vanilla", ...).

def normalize_mode(mode: str) -> str

One of :data:MODES (aliases: "isosurface", "points+slice", "both", ...).

def payload_levels(payload: Mapping[str, Any]) -> list[dict[str, Any]]

Levels, counts and IoU / Dice at the payload's defaults, recomputed from the decoded values like the browser does (tests and tools).

def plotly_cdn_tag() -> str

The <script src=…> tag of the plotly.js CDN build matching the installed plotly.

def plotly_volume_html(volumes: Any, *, extent: Any = None, threshold: Any = None, cmap: Any = None, title: str | None = None, height: int = 420, standalone: bool = False, field: ...

Isosurfaces with plotly.graph_objects.Isosurface (one scene per volume, cameras synchronized): the GT at its threshold rule, reconstructions at their level_rule level.

def quantize(a: np.ndarray, bits: int = 8, rules: Sequence[Mapping[str, Any]] = ()) -> tuple[dict[str, Any], np.ndarray]

Quantize a volume to bits-bit codes lo + q · step (the top code is NaN when the volume has NaNs); codes are nudged so each rule in rules selects exactly the voxels it selects in a (relative rules use a's own max / min, embedded as peak / trough). Returns (entry, decoded) — the JSON entry and the values the viewer sees.

def save_volume_viewer(path: str | Path, volumes: Any, *, kind: str = 'canvas', **kw: Any) -> Path

Write a standalone viewer page (kind="plotly": the CDN-backed plotly page).

def standalone_page(body: str, title: str, subtitle: str | None = None) -> str

A whole HTML document (report stylesheet, light / dark) around body.

def viewer_cmap(spec: CmapSpec) -> str

The viewer's colormap for a spec: the same name when implemented (_r variants included), else by kind (diverging → RdBu_r, cyclic → twilight, viridis).

def viewer_fragment(payload: Mapping[str, Any], *, height: int = 420, include_assets: bool = True, element_id: str | None = None) -> str

HTML fragment of one viewer: the (optional) assets, a <div> with a unique id, the JSON payload in a <script type="application/json"> and a one-line mount script.

def viewer_fragment_from_file(path: str | Path, *, height: int = 420, include_assets: bool = True, include_plotlyjs: bool = True) -> str

The report fragment of a viewer.json written by :func:write_entry_viewer (fresh element ids; the canvas assets / the plotly CDN tag only when asked — once per page).

def viewer_payload(volumes: Any, *, extent: Any = None, threshold: Any = None, mode: str = 'voxels', cmap: Any = None, title: str | None = None, field: str | None = None, labe...

The JSON payload of a viewer (see :func:volume_viewer_html for the arguments).

def viewer_size_bytes(volumes: Any, *, include_assets: bool = False, **kw: Any) -> int

Bytes a viewer adds to a page: the fragment of volumes (or of a ready payload), without the shared script / stylesheet unless include_assets.

def volume_viewer_html(volumes: Any, *, extent: Any = None, threshold: Any = None, mode: str = 'voxels', cmap: Any = None, title: str | None = None, height: int = 420, standalone:...

HTML of an interactive 3-D viewer of one or two volumes (same camera).

def write_entry_viewer(entry: Any, out_dir: str | Path, *, kind: str = 'canvas') -> dict[str, Any]

Write the viewer of a 3-D gallery entry: <name>/viewer.json (what reports embed) and <name>/viewer.html (a standalone page). Returns the manifest info (paths relative to out_dir, sizes in bytes, grid, rule, default levels and IoU / Dice).

nefi.viz.isosurface

Isosurfaces of 3-D fields: threshold rules, volume-matched iso-levels, display transforms, marching-cubes meshes and the shaded static renderings of gallery_3d.png / voxels.png.

def auto_rule(reference: Any) -> dict[str, Any]

Half-way from the reference's background (median) to its extreme on the anomaly side — the rule of the static voxel views (:func:~nefi.viz.fields.voxel_threshold).

def contour_levels(gt: Any, fractions: Sequence[float] = (0.25, 0.5, 0.75)) -> list[float]

Levels at fractions of the GT contrast, from its background (median) toward its extreme on the anomaly side.

def depth_exaggeration(shape: Sequence[int], domain: Any = None, factor: float = 0.6) -> float

Stretch of the depth axis of 3-D panels: max(1, factor · lateral / depth) (thin slabs stay readable; the axis label says ×k).

def draw_isosurfaces(axes: Sequence[Axes], entries: Sequence[tuple[str, np.ndarray, float, str]], *, domain: Any = None, colors: Sequence[str] | None = None, elev: float = 24.0,...

Shaded isosurfaces, one per projection="3d" axes, with one camera and one box.

def draw_level_contours(axes: Sequence[Axes], gt: np.ndarray, recon: np.ndarray, *, center: Sequence[int] | None = None, axis: int = -1, levels: Sequence[float] | None = None, frac...

Multi-level contours of GT (solid) and reconstruction (dashed) on the central slices.

def gaussian_smooth(a: Any, sigma: float) -> np.ndarray

Separable Gaussian smoothing (radius ⌈3σ⌉, replicated edges), σ in voxels.

def has_marching_cubes() -> bool

True when skimage.measure.marching_cubes is importable.

def hinted_transform(hints: Mapping[str, Any] | None, field: str | None = None) -> Any

The volume_transform display hint for field (a spec, or {field: spec} with "*" as default), normalized by :func:transform_spec.

def iou_dice(a: Any, b: Any) -> tuple[float, float]

(IoU, Dice) of two boolean masks (NaN when both are empty).

def iso_compare(gt: Any, recons: Any = None, *, field: str | None = None, rule: Any = None, how: str = 'matched', instance: Any = None, domain: Any = None, transform: Any =...

GT and reconstruction(s) as shaded isosurfaces with matched levels, plus contours.

def iso_levels(gt: Any, recon: Any, rule: Any = None, *, manual: float | None = None) -> dict[str, Any]

The GT level and the reconstruction's fixed / volume-matched / Otsu (/ manual) levels, with the voxel count, IoU and Dice of each reconstruction set against the GT set.

def iso_mesh(values: Any, level: float, side: str = 'above', *, max_faces: int = 20000, step_size: int | None = None) -> tuple[np.ndarray, np.ndarray] | None

Marching-cubes isosurface enclosing the voxels past level on side.

def iso_titles(label: str, levels: Mapping[str, Any], how: str = 'matched', name: str | None = None) -> tuple[str, str]

Two-line panel titles of a GT / reconstruction isosurface pair: level and rule, voxels or IoU / Dice (with the IoU at the GT threshold for comparison).

def level_rule(value: float, side: str, source: str = '') -> dict[str, Any]

An absolute rule v > value (side="above") or v < value.

def matched_level(values: Any, side: str, count: float) -> float

The volume-matched level: count voxels of values lie past it on side.

def normalize_rule(threshold: Any, reference: Any = None) -> dict[str, Any]

A threshold rule from None (automatic, :func:auto_rule), a number (side of the reference's larger deviation), (side, value) or a mapping.

def otsu_level(values: Any, bins: int = 256) -> float

Otsu's threshold: the histogram split (bins bins over [min, max]) maximizing the between-class variance — the middle of the maximizing splits when an empty gap between the classes makes several of them tie.

def recon_level(values: Any, rule: Mapping[str, Any], how: str, *, gt_count: int, manual: float | None = None) -> float

The level of a reconstruction under a level rule (:data:LEVEL_RULES).

def rule_level(rule: Mapping[str, Any], values: Any = None, *, peak: float | None = None, trough: float | None = None) -> float

The threshold of rule in data units for one volume (relative rules use the volume's own peak / trough: its max / min unless given).

def select_mask(values: Any, rule: Mapping[str, Any], *, peak: float | None = None, trough: float | None = None) -> np.ndarray

Voxels selected by a threshold rule (NaN never selected).

def surface_colors(n: int, dark: bool | None = None) -> list[str]

Isosurface colours: the ground truth neutral, reconstructions the categorical slots.

def transform_label(spec: Any) -> str

"display: smooth σ=1" (empty for no transform) — used in every title.

def transform_spec(spec: Any) -> dict[str, Any] | None

Normalize a volume display transform: None / "none" → None; a name of :data:VOLUME_TRANSFORMS (aliases: gaussian, unsharp, tv, bilateral, …); a mapping {"name": ..., <parameters>}; or (name, {parameters}).

def volume_transform(a: Any, spec: Any) -> np.ndarray

Apply a display transform (:func:transform_spec) to a volume; returns a new array.

def voxel_rule(instance: Any = None, reference: Any = None, *, hints: Mapping[str, Any] | None = None, field: str | None = None) -> dict[str, Any]

The GT threshold rule of voxel / isosurface views: the instance's IoU rule.

nefi.viz.measurement

Measurement viewers: spectra, time-series frames, sinograms, receiver traces, k-space masks, signals, sparse point observations — and :func:plot_fit (data vs prediction vs residual with the noise floor).

class MeasurementView(layout: str, kind: str, data: np.ndarray, label: str, spec: CmapSpec, mask: np.ndarray | None = None, points: tuple[np.ndarray, np.ndarray, np.ndarray] | No...

A single-panel representation of a measurement.

def detect_layout(data: Any, meta: Mapping | None = None, field_shape: Sequence[int] | None = None, mask: Any = None) -> str

Guess the measurement layout (see the module table) from shape, dtype and metadata.

def draw_measurement(ax: Axes, measurement: Any, *, field_shape: Sequence[int] | None = None, instance: Any = None, layout: str = 'auto', title: str | None = None, colorbar: boo...

Draw the compact view of a measurement into ax and return the view used (arguments as in :func:measurement_view; axes=True keeps ticks and axis labels).

def measurement_view(measurement: Any, *, field_shape: Sequence[int] | None = None, instance: Any = None, layout: str = 'auto', reduce: str | int | None = None, source: int | No...

Compact single-panel view of a measurement (used by tiles and :func:compare_fields).

def plot_fit(pred: Any, measurement: Any, *, noise_std: float | None = None, layout: str = 'auto', field_shape: Sequence[int] | None = None, instance: Any = None, domain...

Data vs prediction vs residual, with the noise floor.

def plot_frames(data: Any, *, times: Sequence[float] | None = None, n_frames: int = 5, pixels: Sequence[tuple[int, int]] | None = None, shared: bool = False, loglog: bool |...

Time-series frames (n_t, H, W) (NeFTY thermograms): a strip of frames (geometric time spacing) and per-pixel decay curves.

def plot_kspace(mask: Any, data: Any = None, *, shift: bool = True, title: str | None = None, dark: bool | None = None) -> Figure

k-space sampling mask (and the log-magnitude of the sampled data, if given).

def plot_measurement(measurement: Any, *, layout: str = 'auto', field_shape: Sequence[int] | None = None, instance: Any = None, domain: Any = None, hints: Mapping[str, Any] | No...

Full view of a measurement, dispatched on its layout (see the module table).

def plot_signal(data: Any, *, x: Any = None, mask: Any = None, noise_std: float | None = None, title: str | None = None, xlabel: str = 'sample', dark: bool | None = None) -...

A 1-D measurement (signal or sensor vector) with an optional ±σ band.

def plot_sinogram(data: Any, *, angles: Sequence[float] | None = None, detector: Sequence[float] | None = None, n_profiles: int = 3, mask: Any = None, title: str | None = Non...

Sinogram (n_views, n_detectors): image (angle vertical, detector horizontal) and a few projection profiles.

def plot_spectra(data: Any, *, freqs: Sequence[float] | None = None, n_slices: int = 3, n_pixels: int = 3, domain: Any = None, title: str | None = None, xlabel: str = 'frequ...

Spectral stacks (n_freq, H, W) (NeTMY): the noise map Σ_ω S(ω, r), a few frequency slices on a shared scale, and pixel spectra (mean ± std, brightest pixels).

def plot_traces(data: Any, *, source: int | None = None, dt: float | None = None, t0: float = 0.0, mode: str = 'both', max_traces: int = 48, clip: float = 99.0, title: str ...

Receiver traces (n_src, n_rec, n_t) of one source: image gather (time downwards, RdBu_r centred) and/or a wiggle plot with filled positive lobes.

def residual_stats(pred: Any, measurement: Any, noise_std: float | None = None) -> dict[str, float | None]

Data-fit summary: rmse (masked), noise_std, chi = RMSE/σ (≈ 1 when the fit reaches the noise floor, Morozov) and the relative residual ‖r‖ / ‖y‖.

def resolve_layout(data: Any, meta: Mapping | None, field_shape: Sequence[int] | None, mask: Any, hints: Mapping[str, Any] | None = None) -> str

Layout from meta["layout"], then instance hints, then :func:detect_layout.

def stack_axis(shape: Sequence[int], field_shape: Sequence[int] | None, hints: Mapping[str, Any] | None) -> int

Slice axis of a 3-D matrix / sinogram measurement (e.g. (n_views, n_det, n_z)).

def unpack(measurement: Any) -> tuple[np.ndarray, np.ndarray | None, dict, float | None]

(data, mask, meta, noise_std) from a :class:~nefi.measurement.Measurement, a tensor or an array.

nefi.viz.multiphysics

The multi-physics gallery: one smoke run per registered instance, one compact tile per physical system (GT | measurement | reconstruction, headline metric and wall-clock), a single overview figure, per-instance figures and a JSON manifest.

class GalleryEntry(name: str, status: str = 'pending', description: str = '', scene_class: str | None = None, smoke: str | None = None, config: dict[str, Any] = <factory>, bud...

Manifest entry of one physical system (JSON-serializable except run).

  • headline(self) -> tuple[str, float] | None — (metric, value) shown on the tile.
  • ok (property)
  • to_dict(self) -> dict[str, Any]

class GalleryManifest(...)

The JSON manifest (a dict) plus the in-memory :class:GalleryEntry list (.entries, with .run artifacts when keep_runs=True).

class GalleryRun(instance: Any, info: dict[str, Any], gt: dict[str, Any] | None, measurement: Any, problem: Any, result: Any, stage_snapshots: Any = None, field_snapshots: A...

In-memory artifacts of one gallery run (not serialized).

class TileData(name: str | None, label: str, note: str, g: np.ndarray | None, rec: np.ndarray, mask: np.ndarray | None, spec: Any, hints: dict[str, Any], domain: Any)

The arrays a tile shows (after the instance's display hints).

  • titles(self) -> tuple[str, str]
  • volume (property)

def display_field(run: GalleryRun, result: Any, td: TileData) -> np.ndarray

result's primary field as the tile shows it: on the GT grid, complex → magnitude, the instance's field_transform applied (like :func:tile_data's reconstruction).

def draw_tile(container: Any, entry: GalleryEntry)

Draw one tile (GT | measurement | reconstruction) into a figure or sub-figure.

def draw_volume_block(container: Any, entry: GalleryEntry, *, n_slices: int = 8)

One system of gallery_3d.png: larger GT and reconstruction depth mosaics (GT outlined on the reconstruction), multi-level contours of GT (solid) and reconstruction (dashed) on the central slice and the depth cross-section, and shaded isosurfaces — the GT at its threshold rule (the instance's IoU rule), the reconstruction at the volume-matched level (as many voxels as the GT; same camera; levels, IoU and Dice in the titles, with the IoU at the GT's own threshold for comparison). A volume_transform display hint is applied to the reconstruction's contours and isosurface and named in the titles.

def draw_volume_tile(container: Any, entry: GalleryEntry, *, n_slices: int = 6)

The gallery row of a 3-D system (full overview width).

def entry_rule(run: GalleryRun, td: TileData | None = None) -> dict[str, Any]

The GT threshold rule of a 3-D gallery run: the instance's IoU rule (:func:~nefi.viz.isosurface.voxel_rule) — or, after a display transform of the field, half-way from the GT background to its extreme.

Report sections of a gallery: overview + summary table, the 3-D systems (:func:volume_section), then one section per system.

def has_refined(entry: GalleryEntry) -> bool

True when the entry carries a refined (or refused-candidate) field to draw.

def instance_figures(entry: GalleryEntry, out_dir: str | Path, *, formats: Sequence[str] = ('png',), dpi: float = 130, max_kb: float | None = 300, animate: bool = False, dark: b...

Write the standard figures of one gallery entry into out_dir/<name>/.

def is_volume_entry(entry: GalleryEntry) -> bool

True for a successful entry whose primary field has three (non-singleton) dimensions.

def iso_rows(manifest: Mapping[str, Any]) -> list[dict[str, Any]]

One row per 3-D system: the reconstruction's level, IoU and Dice at the GT threshold and at the volume-matched level (and Otsu's IoU) — from the manifest's iso entries.

def iso_summary(entry: GalleryEntry) -> dict[str, Any]

Level-set comparison of a 3-D entry (raw fields, no display transform): the GT threshold rule and, for the reconstruction, the level, voxel count, IoU and Dice at the GT threshold (fixed), at the volume-matched level and at Otsu's level (:func:~nefi.viz.isosurface.iso_levels); refined: the same for the refined field. {} without a ground truth.

def meta_mask(measurement: Any, shape: Sequence[int]) -> np.ndarray | None

A field-shaped mask from measurement.meta (:data:MASK_KEYS), else None.

def physics_gallery(instances: Any = None, budget_scale: float = 0.15, device: str = 'auto', out_dir: str | Path = 'runs/gallery', *, seed: int = 0, smoke: bool = True, max_ste...

Run every available instance at a small budget and draw the multi-physics gallery.

def physics_overview(entries: Sequence[GalleryEntry], *, ncols: int = 3, title: str | None = None, dark: bool | None = None) -> Figure

One figure with a tile per physical system (failed systems show their error).

def physics_volumes(entries: Sequence[GalleryEntry], *, n_slices: int = 8, title: str | None = None, dark: bool | None = None) -> Figure | None

gallery_3d.png: one block per 3-D system (larger depth mosaics of GT and reconstruction, contrast contours and side-by-side isosurfaces at matched levels, :func:draw_volume_block); None when no entry is volumetric.

def refine_entry(entry: GalleryEntry) -> dict[str, Any]

Edge refinement of a 3-D gallery entry (nefi.solve.refine_run_output, see docs/refinement.md); never raises.

def refine_line(refine: Mapping[str, Any], width: int | None = None) -> str

"refined ✓ IoU 0.59 → 0.82 · Edge-F1 0.42 → 1 · χ 1.15 → 1.10" (tile titles).

def refine_rows(manifest: Mapping[str, Any]) -> list[dict[str, Any]]

One row per refined 3-D system: verdict, mode, data fit, IoU and Edge-F1 before → after, the refined field's volume-matched IoU and the cost — from the manifest's refine.

def refined_view(run: GalleryRun, td: TileData) -> tuple[np.ndarray, str] | None

(array, label) of the "refined" column of a 3-D run (None without refinement): "refined", or "refined — refused" for the refused candidate (the smooth result is kept).

def run_instance_smoke(spec: Any, *, budget_scale: float = 0.15, device: str = 'auto', seed: int = 0, smoke: bool = True, max_steps: int | None = 1500, min_steps: int = 20, time_b...

Generate → invert → evaluate one instance at a demo budget; never raises.

def summary_rows(entries: Sequence[GalleryEntry]) -> list[dict[str, Any]]

One table row per system: status, scene, grid, steps, timings, headline metrics.

def tile_data(run: GalleryRun) -> TileData

Primary field of a gallery run (GT and reconstruction on the GT grid), with the instance's field_transform / field_label / field_cmap hints applied; complex fields are shown by magnitude.

def tile_figure(entry: GalleryEntry, dark: bool | None = None) -> Figure

A stand-alone figure with one tile (a full-width row for 3-D systems).

def tile_title(entry: GalleryEntry) -> str

name + a second line with the headline metric (the smooth result's), wall-clock and steps + (3-D systems with refine) a third line: the refinement's verdict, IoU and Edge-F1 before → after and the data fit χ before → after (:func:refine_line).

def volume_block_figure(entry: GalleryEntry, *, n_slices: int = 8, dark: bool | None = None) -> Figure

One 3-D system's block of gallery_3d.png as its own figure (<name>/block3d.png: the static row shown above the system's interactive viewer in reports).

def volume_extras(entry: GalleryEntry, out_dir: str | Path, kind: str | None = 'canvas', *, formats: Sequence[str] = ('png',), dpi: float = 130, max_kb: float | None = 300)

3-D extras of a gallery entry: the level-set comparison (entry.iso) and, with an interactive kind, the static row <name>/block3d.png plus the viewer files (entry.viewer, :func:~nefi.viz.interactive.write_entry_viewer). Never raises.

def volume_section(manifest: Mapping[str, Any], out_dir: str | Path, *, interactive: bool = True, height: int = 420) -> Any

The "3-D systems" report section: with interactive and viewer files, one subsection per 3-D system — its static row (block3d.png) and right under it the interactive viewer (script and stylesheet included once) — else gallery_3d.png; the level table (:func:iso_rows) either way. None without 3-D systems.

nefi.viz.performance

Performance dashboards: per-step time, scaling with grid size, memory by gradient mode, wall-clock breakdowns and benchmark tables with confidence intervals.

def aggregate(rows: Any, metric: str, by: str = 'method', group: str | None = None, ci: float = 0.95) -> list[dict[str, Any]]

Mean ± CI of metric per by (and group) over rows without errors.

def collect_performance(instances: Any = None, device: Any = 'auto', steps: int = 20, *, warmup: int = 3, stage: int = -1, smoke: bool = True, overrides: Mapping[str, Mapping[str, ...

Profile the optimization step of several instances (rows for the plots above).

def collect_scaling(instance: Any, sizes: Sequence[Any], *, key: str | None = None, device: Any = 'auto', steps: int = 10, warmup: int = 2, stage: int = -1, smoke: bool = True,...

Profile one instance at several sizes (rows for :func:plot_scaling).

def load_profiles(source: Any = 'runs/_perf') -> list[dict[str, Any]]

Rows of tools/profile_instance.py --json files.

def load_rows(source: Any) -> list[dict[str, Any]]

Rows from a list of dicts, a BenchmarkResult / RuntimeTable (.rows), a dict with rows (benchmark.json) or entries (gallery manifest.json), or a path to a .json / .csv file or a directory containing one of them.

def loglog_slope(x: Sequence[float], y: Sequence[float]) -> float

Least-squares slope of log y vs log x (nan with < 2 positive points).

def normalize_row(r: Mapping[str, Any]) -> dict[str, Any]

Harmonize aliases and derive n / ms_per_step / fwd_ms where possible.

def plot_bench_table(rows: Any, metric: str, *, by: str = 'method', group: str | None = 'class', ci: float = 0.95, higher_is_better: bool | None = None, title: str | None = None...

Mean ± confidence interval of metric per method (dots with CI whiskers), one small multiple per scene class.

def plot_memory(rows: Any, *, by: str = 'shape', hue: str = 'mode', value: str = 'auto', title: str | None = None, dark: bool | None = None) -> Figure

Memory per gradient mode (e.g. adjoint vs autograd vs checkpoint) and grid size.

def plot_scaling(rows: Any, *, x: str = 'n', y: Sequence[str] = ('ms_per_step', 'memory'), by: str = 'instance', fit: bool = True, reference: bool = True, title: str | None ...

Step time and memory vs grid size, log-log, with fitted slopes (O(N^slope)).

def plot_speedup(rows: Any, *, title: str | None = None, dark: bool | None = None) -> Figure

Per-instance "speedup vs eager" bars (log axis, 1× = eager, value at every tip).

def plot_step_time(rows: Any, *, value: str = 'ms_per_step', by: str = 'instance', hue: str = 'device', split: bool = True, log: bool | str = 'auto', shapes: bool = True, titl...

Per-step time per instance (horizontal bars, value at every bar tip).

def plot_wallclock_breakdown(results: Any, *, labels: Sequence[str] | None = None, title: str | None = None, dark: bool | None = None) -> Figure

Stacked horizontal bars of where the wall-clock went, one bar per run.

def profile_problem(problem: Any, stage: Any, *, device: Any = 'auto', steps: int = 20, warmup: int = 3, saved_tensors: bool = True) -> dict[str, Any]

Time optimization steps of one curriculum stage (forward / backward / optimizer split).

def profile_speedups(rows: Any) -> list[dict[str, Any]]

Speedup of every accelerated profile over plain eager execution.

def profile_variant(row: Mapping[str, Any]) -> str

"eager" for a plain solver-loop profile, else a short label of its switches ("compile=step", "autocast=bf16", "solver=chebyshev · jacobi_iters=13", ...).

def shape_label(shape: Any) -> str

"64×64×16" from a shape list / string.

nefi.viz.qualitative

Qualitative comparison figures: the scenes × methods grid of a paper, failure-mode panels and a one-call baselines panel.

def axis_excess(err: np.ndarray) -> float

Cross / streak-artifact indicator of an error map.

def baselines_panel(instance: Any, measurement: Any = None, gt: Mapping[str, Any] | None = None, methods: Any = None, budget_scale: float = 0.1, *, device: str = 'cpu', seed: i...

Run the instance's method and its baselines() at a small budget and draw the grid.

def failure_modes(gt: Any, recons: Any, *, field: str | None = None, support_threshold: float = 0.05, dilate: int = 1, spectrum: bool = True, title: str | None = None, dark: ...

Residual maps that expose failure modes, one row per method.

def failure_stats(pred: Any, gt: Any, *, support_threshold: float = 0.05, dilate: int = 1) -> dict[str, float]

Failure-mode numbers of a reconstruction.

def method_grid(rows: Sequence[Mapping[str, Any]], row_labels: Sequence[str] | None = None, col_labels: Sequence[str] | None = None, *, field: str | None = None, gt_key: st...

The classic qualitative figure: scenes (rows) × methods (columns).

def run_methods(instance: Any, measurement: Any = None, gt: Mapping[str, Any] | None = None, methods: Any = None, budget_scale: float = 0.1, *, device: str = 'cpu', seed: i...

Run the instance's own method and baselines on one measurement at a small budget.

nefi.viz.report

Shareable reports: one self-contained HTML file (figures embedded as base64, metrics and timing tables, config hash, environment) or a Markdown page with relative image links.

class Section(title: str, text: str = '', images: list[Any] = <factory>, table: Sequence[Mapping[str, Any]] | None = None, columns: Sequence[str] | None = None, html: str...

One report section.

def environment_info(device: Any = None) -> dict[str, Any]

Versions, platform and accelerator info for reproducibility sections.

def fmt_value(v: Any, precision: int = 4) -> str

Compact cell text: numbers to precision significant digits, NaN/None → —.

def html_report(out_dir: str | Path, title: str, sections: Sequence[Section | Mapping[str, Any]], *, filename: str = 'index.html', subtitle: str | None = None, config_hash:...

Write a self-contained HTML report and return its path.

def html_table(rows: Sequence[Mapping[str, Any]], columns: Sequence[str] | None = None, precision: int = 4) -> str

HTML table (numbers right-aligned, tabular figures; status cells get a ✓ / ✗ glyph).

def markdown_report(out_dir: str | Path, title: str, sections: Sequence[Section | Mapping[str, Any]], *, filename: str = 'report.md', subtitle: str | None = None, config_hash: ...

Write a Markdown report (relative image links; figures objects are saved next to it).

def markdown_table(rows: Sequence[Mapping[str, Any]], columns: Sequence[str] | None = None, precision: int = 4) -> str

GitHub-flavoured markdown table.

def slug(text: str) -> str

URL-fragment slug of a heading.

def write_json(path: str | Path, obj: Any) -> Path

JSON writer tolerant of tensors, tuples, paths and non-finite floats.

nefi.viz.style

House style for nefi figures: palette, per-quantity colormaps, rc settings, sizes, saving.

class CmapSpec(cmap: str, kind: str = 'sequential', quantity: str = 'generic')

A colormap choice: matplotlib name, kind and the quantity it was chosen for.

  • centered (property)

class Theme(name: str, surface: str, page: str, ink: str, ink2: str, muted: str, grid: str, axis: str, bad: str, palette: tuple[str, ...])

Surface / ink tokens and the categorical palette of one color mode.

  • color(self, i: int) -> str — Categorical slot i (0-based).

def blank_axes(ax: Axes, frame: bool = True)

Hide ticks and tick labels of an image panel; keep a hairline frame (frame=True) so panels whose values sit at the surface color (diverging midpoint) keep visible edges.

def close_figure(fig: Figure)

Close a figure if it is managed by pyplot (never imports pyplot itself).

def cmap_for(name: str | None = None, data: Any = None, quantity: str | None = None) -> CmapSpec

Choose the colormap for a field.

def color_limits(arrays: Sequence[Any] | Any, spec: CmapSpec | None = None, robust: float | None = None) -> tuple[float, float]

Shared (vmin, vmax) of one or several arrays for a colormap spec.

def current_context() -> str

Active size context ("paper", "notebook" or "talk").

def figsize(ncols: int = 1, nrows: int = 1, *, panel: tuple[float, float] | None = None, cbar: bool | int = False, title: bool = False, context: str | None = None, max_...

Figure size (inches) for a grid of nrows × ncols panels.

def figure_to_png_bytes(fig: Figure, dpi: float = 110) -> bytes

Render a figure to PNG bytes (for embedding).

def format_metric(name: str, value: Any, precision: int = 3) -> str

Compact name value label for panel titles (PSNR 24.1 dB, SSIM 0.912).

def get_cmap(spec: CmapSpec | str, dark: bool | None = None)

matplotlib colormap for a spec, with the theme's color for masked (NaN) pixels.

def grid_on(ax: Axes, axis: str = 'y')

Hairline solid gridlines on axis ("x", "y" or "both"), below the data.

def is_signed(data: Any, min_fraction: float = 0.1) -> bool

True when data has a genuine negative and positive part (min < 0 < max beyond noise).

def message_axes(ax: Axes, text: str, title: str | None = None, error: bool = False)

Replace an axes by a centered text message (missing data, failed run).

def new_figure(nrows: int = 1, ncols: int = 1, *, figsize: tuple[float, float] | None = None, squeeze: bool = False, layout: str | None = 'constrained', **subplots_kw: Any...

A pyplot-free figure (safe on headless servers) and its axes grid.

def note(ax: Axes, text: str, loc: str = 'upper left', fontsize: float | None = None)

Small secondary-ink annotation inside an axes.

def palette(dark: bool | None = None) -> tuple[str, ...]

The eight categorical colors of the active (or requested) theme.

def panel_size(context: str | None = None) -> tuple[float, float]

Default (width, height) of one image panel in inches.

def paper_figsize(columns: int = 1, aspect: float = 0.75) -> tuple[float, float]

Journal figure size: one or two columns wide, height = aspect × width.

def plain_log_ticks(ax: Axes, axis: str = 'both')

Readable ticks on log axes spanning fewer than two decades: 1-2-5 steps printed as plain numbers (20, 50) instead of 2×10¹ or no label at all.

def primary_metric(metrics: Mapping[str, Any] | None) -> tuple[str, float] | None

The headline (name, value) of a metrics dict (PSNR > SSIM > HF1 > rel.err > ...).

def quantity_of(name: str | None) -> str | None

Physical quantity guessed from a field name ("rho" → "density") or None.

def savefig(fig: Figure, path: str | Path, formats: Sequence[str] = ('png',), dpi: float = 130, *, close: bool = True, max_kb: float | None = 300, min_dpi: float = 55) ...

Save a figure as PNG and optionally SVG / PDF (parent directories are created).

def series_colors(n: int, dark: bool | None = None) -> list[str]

Colors for n series in slot order. More than eight series must be folded first.

def set_default_style(dark: bool = False, context: str = 'notebook')

Process-wide default theme / context used when no :func:use_style block is active.

def spec_from_hint(value: Any, data: Any = None, quantity: str | None = None) -> CmapSpec | None

A colormap from a display hint (measurement_cmap / field_cmap).

def style_rc(dark: bool | None = None, context: str | None = None) -> dict[str, Any]

matplotlib rcParams of the house style for a theme and size context.

def styled(dark: bool | None = None) -> Iterator[Theme]

Apply the house style for one plotting call.

def theme(dark: bool | None = None) -> Theme

The active theme (dark=None) or the light / dark theme explicitly.

def use_style(dark: bool = False, context: str = 'notebook', **rc: Any) -> Iterator[Theme]

Context manager applying the house style (light or dark) and size context.

nefi.viz.training

Training-dynamics figures: loss history with stage boundaries and the annealing schedule, per-stage summaries, the coarse→fine multiscale view and snapshot animations.

class StageSnapshots(names: Sequence[str] | None = None)

Keep detached CPU copies of every field at the end of each curriculum stage.

  • on_stage_end(self, solver: Any, stage_idx: int, stage: Any, info: dict)
  • on_step(self, solver: Any, state: Any)

def animate_snapshots(snapshots: Any, path: str | Path, *, gt: Any = None, result: Any = None, field: str | None = None, fps: float = 8.0, max_frames: int = 40, dpi: float = 72, ...

Animate field snapshots (GIF, or MP4 when ffmpeg is available).

def history_arrays(history: Any, stage_results: Sequence[Mapping] | None = None) -> dict[str, np.ndarray]

Per-step numpy columns of Result.history (or a history dict), all of equal length.

def loss_keys(arrays: Mapping[str, np.ndarray]) -> list[str]

Loss-valued columns (everything but bookkeeping), in history order.

def plot_history(result: Any, *, keys: Sequence[str] | None = None, noise_floor: float | None = None, noise_std: float | None = None, logy: bool | str = 'auto', show_progres...

Loss history with curriculum stage boundaries, annealing windows, β/K and LR panels.

def plot_multiscale(result: Any, snapshots: Any = None, *, gt: Any = None, field: str | None = None, history: bool = True, title: str | None = None, dark: bool | None = None) -...

Coarse→fine view of a multiscale curriculum.

def plot_stage_summary(result: Any, *, title: str | None = None, dark: bool | None = None) -> Figure

Per-stage bars: steps, wall-clock seconds (ms/step at the bar tip) and final data loss.

def snapshot_list(snapshots: Any, field: str | None = None) -> list[tuple[int, np.ndarray]]

[(global_step, array)] from a :class:~nefi.solve.callbacks.FieldSnapshots / :class:StageSnapshots callback, their .snapshots list, (step, tensor) pairs or bare tensors.

nefi.viz.volume

3-D field views: depth mosaics, cross-sections through the anomaly, projections and voxel comparisons — the building blocks of the 3-D layout of :func:~nefi.viz.compare_fields, the gallery's 3-D rows and gallery_3d.png.

class Outline(vol: np.ndarray, levels: list[float], mask: bool = False)

What is outlined on reconstruction panels: a GT mask (level 0.5) or the GT anomaly level set (:func:~nefi.viz.fields.anomaly_levels).

  • of(gt: Any = None, mask: Any = None) -> Outline | None
  • projection(self, axis: int, mode: str, max_fraction: float = 0.2) -> np.ndarray | None — The outlined quantity projected along axis — None for mean projections and for extended anomalies (covering more than max_fraction of the projection, e.g. a skull or a filament network), whose projected outline would only add clutter.
  • section(self, center: Sequence[int], which: int, axis: int) -> np.ndarray
  • slice(self, k: int, axis: int) -> np.ndarray

def anomaly_summary(vol: Any, mask: Any = None) -> dict[str, Any]

Centroid, background and projection side of a volume (for titles and reports).

def compare_volume(ctx: Comparison) -> Figure

The 3-D layout of :func:~nefi.viz.compare_fields.

def depth_label(k: int, n: int, axis: int, domain: Any = None, compact: bool = False) -> str

"z = 0.417" (physical, with a domain) or "z 3/6" (1-based slice number).

def draw_projection(ax: Axes, vol: np.ndarray, *, axis: int = -1, mode: str = 'auto', reference: Any = None, spec: CmapSpec, vmin: float | None = None, vmax: float | None = Non...

A min / max / mean projection along the volume axis (auto: the anomaly side of reference), outlined with the GT footprint when outline is given.

def draw_sections(axes: Sequence[Axes], vol: np.ndarray, center: Sequence[int], *, axis: int = -1, spec: CmapSpec, vmin: float, vmax: float, domain: Any = None, outline: Outl...

The two depth cross-sections through center (x–z and y–z for axis=-1), depth pointing down, a + at the centroid; outlines as in :func:draw_slices. square draws them in square boxes (the depth axis is stretched to the slice size, so thin slabs stay readable next to the mosaic).

def draw_slices(axes: Sequence[Axes], vol: np.ndarray, idx: Sequence[int], *, axis: int = -1, spec: CmapSpec, vmin: float, vmax: float, domain: Any = None, outline: Outline...

Depth slices idx of vol into axes (shared colour limits).

def draw_voxels(axes: Sequence[Axes], entries: Sequence[tuple[str, np.ndarray]], *, name: str | None = None, reference: np.ndarray | None = None, threshold: float | None = ...

Thresholded voxels of every entry into projection="3d" axes with one threshold (from reference, default the first entry), one colour scale and one camera; titles give the voxel count and the IoU with the reference voxel set. Returns the first scatter (for a shared colorbar) or None.

def label_inside(ax: Axes, text: str, loc: str = 'upper left')

A small white label with a dark halo inside an image panel (depth of a mosaic slice).

def mosaic_shape(k: int, max_cols: int | None = None) -> tuple[int, int]

(rows, cols) of a mosaic of k slices: one row up to 3, 2×2 for 4, two rows up to 8, then square-ish.

def mosaic_slices(n: int, max_slices: int = 6) -> list[int]

Up to max_slices evenly spaced slice indices along an axis of length n.

def project(vol: np.ndarray, axis: int = -1, mode: str = 'auto', reference: Any = None) -> tuple[np.ndarray, str]

Projection along axis: "max", "min", "mean" or "auto" (the anomaly side of reference — default vol — :func:projection_mode). Returns (array, mode).

def projection_mode(ref: Any, background: float | None = None) -> str

"min" when the anomalies of ref lie below the background (low-diffusivity defects), "max" otherwise (sources, absorbers, densities).

def section(vol: np.ndarray, center: Sequence[int], which: int, axis: int = -1) -> tuple[np.ndarray, int, int]

Cross-section containing the volume axis through center.

def section_extent(shape: Sequence[int], domain: Any, lateral: int, depth: int) -> tuple[float, float, float, float]

imshow extent of a cross-section drawn with origin="upper" (depth grows down).

def voxel_compare(gt: Any, recons: Any = None, *, field: str | None = None, threshold: float | None = None, mode: str = 'auto', domain: Any = None, elev: float = 24.0, azim: ...

Ground truth and reconstruction(s) as thresholded voxels, side by side.

def voxel_sets(g: np.ndarray, a: np.ndarray, mode: str, threshold: float) -> tuple[int, float]

(voxels of a past the threshold, IoU with the GT voxel set).