Plesty Documentation

Live Views

How a measurement is watched while it runs — three pieces, only one of which knows what the measurement means, and why watching cannot disturb it.

A sweep that takes an hour and is only looked at afterwards is an hour spent finding out the sample drifted at row 12. The point of watching a measurement is to find out early — and the point of the design below is that watching costs the measurement nothing.

Three views of one polarization sweep, updating together as it runs: the spectrum just acquired, every spectrum so far stacked into a map, and the excitation power against plate angle. All three are reading the same file the experiment is writing — nothing was added to the measurement to make this possible.

Three separate views, one run, no coordination between them. That is the whole of what the design below buys, and the rest of this page is why it costs the measurement nothing.

Three pieces

Answers Who writes it
Source What has appeared since I last asked? The library
Monitor What should be drawn for this row? You — the only part that knows what the measurement means
Renderer Where does it go? The library — a window, a video, or nothing at all in a test

Splitting it three ways is what lets one view work everywhere. A monitor never mentions a toolkit, so the same class runs in a window, in a test, or in a script rendering an MP4 on a headless machine. And because it is fed rows rather than reading files, it does not care whether they arrive live or are read back from a run that finished last week.

A monitor declares the channels it consumes, declares what it draws, and projects one onto the other. That is the whole obligation — a schema and two methods. Everything else is base machinery.

The record file is the stream

There is no subscription to set up, no port, and no callback the experiment has to register. The run is already writing records.jsonl, one line per completed step, and a line appears only once its step is fully persisted. A source tails that file by byte offset.

Three consequences follow, and together they are the reason this design was chosen over a broadcast:

  • Attach whenever you like. A source opened halfway through a run reads the file from the beginning, so its first poll delivers every row already written. Nothing that happened before you looked is lost.
  • Watching costs the run nothing. The source only reads. The experiment does not know it is being watched, keeps no connections, serializes nothing, and behaves identically whether ten views are open or none.
  • A finished run is watched exactly like a live one. Same file, same code. A finished measurement is a live one that stopped arriving.

A broadcast design would fail all three: a late subscriber misses what was sent before it connected, the producer does work per subscriber, and replaying a stored run becomes a second code path.

The mapper is where the experiment lives

A record carries everything its step measured; a view declares the few channels it draws. Something has to project one onto the other, and that something is a mapper — a plain function handed one record, returning the channels a monitor declared, or None to drop the row.

The library refuses a frame carrying channels the monitor never declared, rather than quietly keeping the ones it recognises. That strictness is the point: a renamed column becomes an error on the first row instead of a plot that keeps drawing, half-empty, until someone notices during analysis.

Keeping the mapper outside the monitor is also what makes views reusable. A spectrum view that declares wavelength and counts serves any spectroscopy bench; only the mapper knows that this experiment calls its sweep axis hwp_deg. Views general enough to outgrow one experiment live in plesty-common-monitors — worth looking at before writing a new one.

Read next

  • The Monitor — write one, against a real run, in about twenty minutes.
  • The Viewer — three views docked in one window, and the same run rendered to a video on a headless machine.
  • Runs & Data — the file the views are reading, and why a line in it is a commit.