The Run’s Data: RunData

Every plot function receives one argument, data: a RunData holding every row the run has saved so far, where a row is one step’s record (see How plesty-lib runs a measurement). Viz creates it and refreshes it; a plot only asks it questions. The layers of a viewer shows where it sits.

One store for all plots

RunData reads the run’s rows once and keeps them, and every plot of the viewer gets the same RunData. A spectrum, a map of all spectra and a fit of the same scan therefore read the run’s file once between them, and each sees every row. At each refresh, only the rows added since the last one are read.

What it answers

Call

Gives

data.latest

the newest row, whichever step wrote it; None before the first

data.last("counts")

the newest row that has a counts field; None if there is none yet

data.rows

every row so far, as a list of dictionaries

data.column("hwp_deg")

one field across all rows, as an array

data.stack("counts")

a field that holds an array in each row, stacked into a 2-D array, one row per record

data.where(qd="QD-02")

only the rows whose field has that value, as a RunData again

data.config

the settings the run’s plan was built from

data.provenance

which versions of which packages produced the run

data.status()

the run’s state and step counts (see Reading a Run)

latest or last. Not every step of a plan saves the same kind of row. A scan might save a spectrum per angle and then one row with a fit, so the newest row is the fit, and a plot of the spectra wants data.last("counts").

column or stack. column is for a field with one value per row. For a field that holds a whole array per row, such as a spectrum, it raises an error naming stack, which is what that field needs.

reads: rows that name a file

A device that produces large files saves them itself, and its row holds only the file’s path (see Data on a Shared Disk). To plot the numbers inside, give the viewer a reads function. It receives a row and the run, and returns the extra fields to add to that row:

from plesty.lib.data import SpectrumData
from plesty.lib.monitor import Viz


def read_spectrum(row, run):
    """Turn the file a row names into the fields the plots want."""
    if "data_file" not in row:
        return {}
    spectrum = SpectrumData.load(run.local(row["data_file"]))
    counts = spectrum.intensity.reshape(-1, spectrum.intensity.shape[-1]).sum(axis=0)
    return {"wavelength": spectrum.wavelength, "counts": counts}


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

run.local() turns the recorded path into a path on this computer. reads is called once per row and its answer kept, so each file is loaded once however many plots use it. If it fails, for example on a file that is still being written, that row simply lacks the extra fields; the viewer goes on.

An experiment whose rows hold their own numbers needs no reads.