plesty.lib.experiment.runs
How a run is named, laid out, found, and read back.
Experiment writes runs; this
module is the other side — the one place that spells out the run-directory
convention so viewers, analyzers, and command lines never re-derive it:
<run_root>/<name>_<YYYYmmdd-HHMMSS>/ # run id = experiment name + start time
├── plan.json # frozen schedule + config
├── journal.jsonl # events; run_started carries the data paths
├── records.jsonl # one line per completed step: its result
└── data/step_NNNN.npy # blobs the records reference, if any
Device-written blobs (spectrometer frames, camera images) never cross the
network: they land on a shared disk under <data_dir>/<run_id>/raw, where
data_dir is the share as the acquiring host sees it. A machine reading
the run sees the same share under its own mount, so every path in a record
is translated through the pair (data_dir, data_mount). Both come from
one environment convention — PLESTY_DATA_DIR and PLESTY_DATA_MOUNT —
and the run journals the spelling it was written with, so a viewer on any
machine needs at most its own mount.
run = Run(latest_run("/mnt/share", name="pol_pl"))
run.config["powermeter"] # the frozen configuration
run.status()["state"] # "running" / "completed" / ...
run.local(record["data_file"]) # host path → path on this machine
Attributes
Classes
Read access to one run directory: plan, journal, records, data paths. |
Functions
|
Return the run id for experiment name started at when (now by default). |
|
Split a run id into its experiment name and start time. |
|
Return the run directories under run_root, oldest first. |
|
Return the most recently started run under run_root. |
|
Join path parts in the spelling of root's operating system. |
|
Translate a path the acquiring host reported into this machine's mount. |
Module Contents
- plesty.lib.experiment.runs.BLOB_SUBDIR = 'data'
- plesty.lib.experiment.runs.RECORDS_FILE = 'records.jsonl'
- plesty.lib.experiment.runs.DATA_DIR_VAR = 'PLESTY_DATA_DIR'
- plesty.lib.experiment.runs.DATA_MOUNT_VAR = 'PLESTY_DATA_MOUNT'
- plesty.lib.experiment.runs.PLAN_FILE = 'plan.json'
- plesty.lib.experiment.runs.JOURNAL_FILE = 'journal.jsonl'
- plesty.lib.experiment.runs.RAW_SUBDIR = 'raw'
- plesty.lib.experiment.runs.RUN_ID_TIME_FORMAT = '%Y%m%d-%H%M%S'
- plesty.lib.experiment.runs.run_id(name: str, when: datetime.datetime | None = None) str
Return the run id for experiment name started at when (now by default).
- Parameters:
name (str)
when (Optional[datetime.datetime])
- Return type:
str
- plesty.lib.experiment.runs.parse_run_id(text: str) tuple[str, datetime.datetime] | None
Split a run id into its experiment name and start time.
- Parameters:
text (str) – A directory name.
- Returns:
(name, started), orNonewhen text is not a run id — the name may itself contain underscores, so the split is at the last one.- Return type:
Optional[tuple[str, datetime.datetime]]
- plesty.lib.experiment.runs.list_runs(run_root: str | pathlib.Path, name: str | Sequence[str] | None = None) list[pathlib.Path]
Return the run directories under run_root, oldest first.
- Parameters:
run_root (str | pathlib.Path) – The directory runs are created in.
name (Union[str, Sequence[str], None]) – Keep only runs of this experiment name (or any of several — an experiment that was renamed still owns its old runs).
Nonekeeps every run.
- Return type:
list[pathlib.Path]
- plesty.lib.experiment.runs.latest_run(run_root: str | pathlib.Path, name: str | Sequence[str] | None = None) pathlib.Path
Return the most recently started run under run_root.
- Raises:
FileNotFoundError – If there is no such run yet — a viewer opened before its experiment is a mistake worth naming.
- Parameters:
run_root (str | pathlib.Path)
name (Union[str, Sequence[str], None])
- Return type:
pathlib.Path
- plesty.lib.experiment.runs.host_join(root: str, *parts: str) str
Join path parts in the spelling of root’s operating system.
A data directory is spelled the way the acquiring host spells it, which is not necessarily this machine’s convention —
G:\RAWDATAfrom a Linux viewer must still becomeG:\RAWDATA\run\raw.- Parameters:
root (str)
parts (str)
- Return type:
str
- plesty.lib.experiment.runs.to_local(host_path: str, data_dir: str, mount: str) pathlib.Path
Translate a path the acquiring host reported into this machine’s mount.
- Parameters:
host_path (str) – The path as the acquiring host spelled it, e.g.
G:\RAWDATA\pol_pl_20260805-091909\raw\frame.spe.data_dir (str) – The shared root as that host sees it.
mount (str) – The same root as this machine sees it.
- Raises:
ValueError – If host_path lies outside data_dir — a path from another rig or a stale configuration, which would otherwise resolve to a plausible-looking wrong file.
- Return type:
pathlib.Path
- class plesty.lib.experiment.runs.Run(run_dir: str | pathlib.Path, *, mount: str | None = None, data_dir: str | None = None, replay_rows: int = 0)
Read access to one run directory: plan, journal, records, data paths.
Nothing here writes. The plan is read once; the journal is replayed on each
status()because a run under way keeps appending to it.Attach to a run directory.
- Parameters:
run_dir (str | pathlib.Path) – The run directory.
mount (Optional[str]) – This machine’s view of the shared data root;
NonetakesPLESTY_DATA_MOUNTfrom the environment, then the mount journaled by the machine that ran the experiment (only when that directory exists here).data_dir (Optional[str]) – The shared root as the acquiring host sees it — only for runs that did not record it themselves.
replay_rows (int) – How
source()hands records out —0follows the run live,nrations a stored run n records per poll.
- path
- replay_rows = 0
- _mount = None
- _data_dir = None
- _plan: plesty.lib.experiment.schedule.Plan | None = None
- _started: dict[str, Any] | None = None
- sources: list[Any] = []
- property id: str
The run id (the directory name).
- Return type:
str
- property name: str | None
The experiment name the run id carries, if it parses as one.
- Return type:
Optional[str]
- property started: datetime.datetime | None
The start time the run id carries, if it parses as one.
- Return type:
Optional[datetime.datetime]
- property plan: plesty.lib.experiment.schedule.Plan
The frozen plan (loaded once).
- Return type:
- property config: dict[str, Any]
The frozen configuration;
{}when the plan is unreadable.- Return type:
dict[str, Any]
- property journal: plesty.lib.experiment.journal.Journal
The run’s journal.
- Return type:
- status() dict[str, Any]
The run status by journal replay (see
Journal.status()).- Return type:
dict[str, Any]
- records() Iterable[dict[str, Any]]
Iterate the committed step records, oldest first.
- Return type:
Iterable[dict[str, Any]]
- _run_started() dict[str, Any]
- Return type:
dict[str, Any]
- property data_dir: str | None
The shared root as the acquiring host sees it.
Journaled by the run; falls back to the plan’s top-level
data_dirfor runs written before the journal carried it, then to thedata_dirgiven at construction.- Return type:
Optional[str]
- property raw_dir: str | None
Where the run’s device-written blobs went, in the host’s spelling.
- Return type:
Optional[str]
- property data_mount: str | None
The shared root as this machine sees it (see the class docstring).
- Return type:
Optional[str]
- local(host_path: str) pathlib.Path
Return host_path (as a record spells it) as a path on this machine.
Untranslated when the run has no data root or this machine has no mount for it — the case of a viewer on the acquiring host itself.
- Parameters:
host_path (str)
- Return type:
pathlib.Path
- source(mapper: plesty.lib.monitor.sources.FrameMapper | None = None) plesty.lib.monitor.sources.RunSource | plesty.lib.monitor.sources.ReplaySource
Return a source over this run’s records — live or replayed.
A
RunSourcewhenreplay_rowsis 0, else aReplaySourcehanding out that many records per poll. Every source made here is kept insources.Make one source per consumer: a source hands each record out once, so two views polling the same source would each see half the rows. The mapper is what they share.
- Parameters:
mapper (Optional[plesty.lib.monitor.sources.FrameMapper])
- Return type:
Union[plesty.lib.monitor.sources.RunSource, plesty.lib.monitor.sources.ReplaySource]
- property exhausted: bool
Whether every source made here has handed out its last record.
Live sources never are (the next record may still be coming); a run without sources counts as exhausted so a watcher does not wait forever.
- Return type:
bool
- __repr__() str
Return
Run('<path>').- Return type:
str