plesty.lib.monitor.viz

The command line that watches a run — an experiment supplies only its panels.

Everything about watching is the same for every experiment: which run (the newest, or --run), where the share is mounted, live or replayed, in a window or rendered offscreen to a video, recorded or not. What differs is which record key means what. Viz owns the former; the experiment writes one function for the latter and is done:

from plesty.common_monitors import SpectrumMonitor, WaterfallMonitor
from plesty.common_monitors.spectrum import spectrum_mapper
from plesty.lib.monitor import Viz
from plesty.lib.ui import MonitorPanel

viz = Viz("Polarization PL", experiment="pol_pl")

@viz.panels
def panels(run):
    spectra = spectrum_mapper("data_file", locate=run.local, row_key="hwp_deg")
    yield MonitorPanel(SpectrumMonitor(run.source(spectra), name="spectrum"), weight=3)
    yield MonitorPanel(WaterfallMonitor(run.source(spectra), name="map"), weight=3)

if __name__ == "__main__":
    sys.exit(viz.main())
python -m plesty.pol_pl.viz monitor                 # follow the newest run live
python -m plesty.pol_pl.viz monitor --replay 2      # replay a stored run, 2 rows/refresh
python -m plesty.pol_pl.viz render --run <run-id>   # <run-id>.mp4, no window needed

The panels function receives a Run and yields Panel objects in docking order. run.source(mapper) is already live or replayed as the subcommand decided — one call per view: a source hands each record out once, so two views on one source would split the rows between them (a mapper is freely shared) — run.local joins a recorded path to this machine’s shared disk, and run.config is the frozen configuration — enough to decide which panels a run gets. This module imports no toolkit until Viz.main() runs, so --help and the parser work on a headless host.

Attributes

PanelsFunc

_TEXT

Exceptions

VizNotAvailable

Raised when an experiment's viewer cannot be loaded in this environment.

Classes

Viz

The monitor / render command line over one experiment's panels.

Functions

_text(→ dict[str, Any])

Return the command-line text catalog (loaded once from the assets).

load_viz(→ Viz)

Return the Viz an experiment's viewer module declares.

Module Contents

plesty.lib.monitor.viz.PanelsFunc
plesty.lib.monitor.viz._TEXT: dict[str, Any] | None = None
plesty.lib.monitor.viz._text() → dict[str, Any]

Return the command-line text catalog (loaded once from the assets).

Return type:

dict[str, Any]

exception plesty.lib.monitor.viz.VizNotAvailable

Bases: RuntimeError

Raised when an experiment’s viewer cannot be loaded in this environment.

Initialize self. See help(type(self)) for accurate signature.

plesty.lib.monitor.viz.load_viz(module: str) → Viz

Return the Viz an experiment’s viewer module declares.

A host application — a console managing several experiments — embeds an experiment’s own views by importing its viewer here and calling Viz.view(). That works exactly when the module is installed alongside the host, which is the condition, and the honest failure when it is not: the host then opens the viewer as its own process instead.

The module is expected to hold exactly one Viz at module level, which is how every viewer is written — viz = Viz("…") beside the panels function it decorates.

Parameters:

module (str) – Import path of the viewer, plesty.pol_pl.viz.

Returns:

The viewer’s Viz.

Raises:

VizNotAvailable – If the module cannot be imported here — usually because the experiment is not installed in this environment — or does not declare exactly one Viz.

Return type:

Viz

class plesty.lib.monitor.viz.Viz(title: str, *, experiment: str | Sequence[str] | None = None, run_root: str | pathlib.Path | None = None, reads: plesty.lib.monitor.data.Reader | None = None)

The monitor / render command line over one experiment’s panels.

Describe the experiment whose runs are watched.

Parameters:
  • title (str) – Human title of the experiment, shown in the window title and the command-line description.

  • experiment (Union[str, Sequence[str], None]) – The experiment name(s) whose runs to look for when --run is not given — a name or several (an experiment that was renamed still owns its old runs). None takes the newest run of any experiment.

  • run_root (Optional[str | pathlib.Path]) – Where runs are looked for — the experiment’s root, under the shared point (PLESTY_DATA) when relative; None takes the shared point itself, and runs without one. --run-root overrides per call.

  • reads (Optional[plesty.lib.monitor.data.Reader]) – Expands one committed row into the columns the plots want — a record names a spectrum file rather than carrying the array, so something has to turn the path into numbers. One per viewer, cached per row, so a map and a fit of the same sweep load each spectrum once between them. An experiment whose records hold their own numbers omits it.

title
experiment = None
run_root = None
reads = None
plots: list[plesty.lib.monitor.plots.Plot] = []
_panels: PanelsFunc | None = None
add_plot(plot: plesty.lib.monitor.plots.Plot) → plesty.lib.monitor.plots.Plot

Add plot to the window; returns it.

Parameters:

plot (plesty.lib.monitor.plots.Plot) – A Plot.

Returns:

The plot, so a caller can keep a reference to one it will poke.

Return type:

plesty.lib.monitor.plots.Plot

plot(title: str = '', *, name: str = '', weight: float | None = None) → Callable[[plesty.lib.monitor.plots.DrawFunc], plesty.lib.monitor.plots.DrawFunc]

Add a plot written as a function. Use as a decorator.

@viz.plot("Spectrum")
def spectrum(data):
    row = data.latest
    return [Line(row["wavelength"], row["counts"])]

The function is called on every tick with the run’s RunData and returns drawables. It is handed the whole store rather than declared channels, so a plot that starts wanting one more field needs no second declaration to keep in step.

Parameters:
  • title (str) – What the view is called; defaults to the function’s name.

  • name (str) – Layout key, so an arrangement survives a rename of the title; defaults to the title.

  • weight (Optional[float]) – Relative size when the panels are first laid out.

Returns:

The decorator, which returns the function unchanged so it stays callable and testable on its own.

Return type:

Callable[[plesty.lib.monitor.plots.DrawFunc], plesty.lib.monitor.plots.DrawFunc]

panels(func: PanelsFunc) → PanelsFunc

Register a function that turns a Run into panels directly.

Superseded by plot(), and kept for viewers written against the older shape. A viewer that registers plots does not need this; one that registers both shows the panels and then the plots.

Parameters:

func (PanelsFunc)

Return type:

PanelsFunc

data(run: plesty.lib.experiment.runs.Run) → plesty.lib.monitor.data.RunData

Return the store this viewer’s plots read.

Parameters:

run (plesty.lib.experiment.runs.Run) – The run to read.

Returns:

A RunData over it, carrying this viewer’s reads.

Return type:

plesty.lib.monitor.data.RunData

build_parser() → argparse.ArgumentParser

Return the argument parser: shared options plus the two subcommands.

Return type:

argparse.ArgumentParser

view(run: plesty.lib.experiment.runs.Run, *, interval_ms: int = 500, remember_layout: bool = True, title: str | None = None) → Any

Compose this experiment’s panels over run, without showing them.

This is the whole of what an experiment’s viewer is: the panels its panels() function yields, docked together and ticking. What is done with the result is the caller’s business — main() gives it a window of its own, and a host application puts the same object in a layout, because a shell is a widget before it is a window.

So an experiment writes its views once and they are embeddable wherever the module can be imported, with no second composition to keep in step and nothing serialized between them. A console that does not have the module installed cannot call this at all, and opens the window instead — that is the only difference between the two.

Parameters:
  • run (plesty.lib.experiment.runs.Run) – The run to watch.

  • interval_ms (int) – How often the panels are pumped.

  • remember_layout (bool) – Restore and save the arrangement. A host that embeds the view usually says False: the arrangement of a pane inside another window is not the arrangement of the experiment’s own window.

  • title (Optional[str]) – Window title and layout key; None names the experiment and the run.

Returns:

A Shell holding the panels, not yet started — the caller calls start() when it is in place.

Raises:
  • RuntimeError – If the viewer declares neither plots nor panels.

  • ValueError – If nothing came of them; an empty view says less than the reason it is empty.

Return type:

Any

resolve_run(args: argparse.Namespace) → plesty.lib.experiment.runs.Run

Return the Run the arguments name, configured for the subcommand.

Raises:

SystemExit – If no run exists yet — a viewer opened before its experiment is a mistake worth naming, not an empty window.

Parameters:

args (argparse.Namespace)

Return type:

plesty.lib.experiment.runs.Run

main(argv: Sequence[str] | None = None) → int

Run the command line and return the exit code.

Parameters:

argv (Optional[Sequence[str]]) – Argument list; None uses sys.argv.

Raises:
  • RuntimeError – If no panels function was registered.

  • SystemExit – If no run exists, or the panels function yields nothing.

Return type:

int