Running the Experiment

Installation

git clone https://gitlab.com/plesty/hub/experiments/plesty-pow-pl.git
cd plesty-pow-pl
uv sync

Deployment: setup.yaml and .env

setup.yaml says what the run is made of: the bench that serves the wave-plate stage (hwp), the spectrometer (spec) and the powermeter (pm), and the package each runs. It names no lab — every value is a variable, set in .env (copy .env.example):

  • LOCAL_DATA — where this machine sees the shared data disk;

  • BENCH_OPTICS_DATA, BENCH_OPTICS_HOST, BENCH_OPTICS_TOKEN — that bench’s view of the same disk, where its bench agent listens, and its token.

The bench gives the run each device’s address (HWP_ADDRESS, SPEC_ADDRESS, PM_ADDRESS) and gives the spectrometer DEVICE_DATA_PATH, its own view of the disk. Against servers started without a bench, set the three addresses and PLESTY_DATA in .env by hand.

Every run goes to <PLESTY_DATA>/pow-pl/<run_id> (or under --run-root), and its spectra to pow-pl/<run_id>/raw/spec under the spectrometer’s bench folder on the Plesty share (platform-a/pow-pl/<run_id>/raw/spec), named <sample>_<qd>_hwp<angle>deg_exp<ms>ms_<HHMMSS>.spe — for example D104-C_QD01_hwp004.00deg_exp500ms_143512.spe. The time keeps a retaken row from meeting the name of its failed attempt; nothing in a name is a space.

Start, watch, resume

# Preview the plan without touching devices
uv run python -m plesty.pow_pl --dry-run

# Run (checkpoints under <PLESTY_DATA>/pow-pl/<run_id>/)
uv run python -m plesty.pow_pl --config config/default.yaml

# Resume an interrupted run at the exact angle it stopped
uv run python -m plesty.pow_pl --resume <run_id>

Every completed row is persisted immediately, so an interruption loses at most the row in flight. The plan is frozen with the run: resuming with a changed configuration is refused rather than silently measuring something else.

What the console shows

The run logs every phase to the console and to logs/pow_pl_<timestamp>.log: the config summary, the rig connect (Connecting hwp @ tcp://… (timeout 5000 ms) …, Connected hwp @ tcp://… in 0.4 s, PowPlRig ready in 1.2 s: hwp=…, spec=…, pm=…), the run id and run dir with the step count, homing, and then per row: Step 12/47 qd[QD-01]-hwp[022.00] (measure_row), the stage move (HWP -> 22.00 deg, HWP settled at 22.0000 deg after 1.1 s), the acquisition (Acquiring 1 frame(s) x 1.00 s + power …, Acquired in 2.3 s: <frame>, power … uW) and Row 11/46 done in 3.4 s: ….

When a device server is not there

The start is a preflight (plesty-lib connect_rig): every server must answer within connect_deadline_s (10 s) and be the device its slot requires (requires in config.yaml — a wrong port connects fine but is not the stage). On a failure the run does not start; you are told which device, at which address, from which .env variable, and asked:

The rig is not ready — 1 device(s) failed the preflight:
  - pm: Sub-device 'pm' unreachable at tcp://127.0.0.1:5557 after 10.1 s: …
      address tcp://127.0.0.1:5557 (from PM_ADDRESS in .env / the environment)
Check that the pm server(s) are running and that PM_ADDRESS point at them
(a wrong port connects fine but is not the expected device).
[r] retry (after fixing .env or starting the server)  [a] abort  [s] continue without pm
>

r rebuilds the rig (start the server or fix .env first), a aborts, s — offered only when the powermeter is the failing device — runs spectra-only (the powermeter block is dropped from the run, so the rows carry no power column; a --resume of a run planned with power will refuse that). Without a terminal (a service, CI) nothing waits: the diagnosis is logged and the process exits with RigNotReadyError.

The HWP angle is verified

The K10CR1 server answers a move only once the stage has physically stopped (plesty-k10cr1#2), so the angle it reports is the angle the row is measured at and is stored as hwp_reported_deg. set_hwp checks it against the target (position_tolerance_deg, 0.01°): a mismatch re-issues the move once, a second mismatch fails the step — it is then retried by the run’s retry ladder rather than recorded at a wrong angle.