plesty -d plesty-demo-pow-pl init experiment --name demo_pow_pl
cd plesty-demo-pow-pl && uv sync
plesty-demo-pow-pl/
├── plesty/demo_pow_pl/
│ ├── __main__.py the command line: the rig, the settings it takes, how it is built
│ └── experiment.py the experiment: its plan and its step methods
├── config/default.yaml the settings a run starts from
├── setup.yaml which instruments it uses, and which bench runs each
├── .env.example addresses, tokens and the shared disk — copied to .env, never committed
├── tests/ the contract tests gate e1 runs
└── pyproject.toml module_type = "experiment"
Three files hold three kinds of value, and keeping them apart is what lets the same module run in any lab:
| File | Holds | Committed |
|---|---|---|
config/*.yaml |
settings — the angles, the averaging; frozen into each run's plan | yes |
setup.yaml |
wiring — each instrument and the bench it runs on, as variable names | yes |
.env |
places and secrets — addresses, tokens, where this PC sees the shared disk | never |
The command line is already there
__main__.py builds the command line with ExperimentCLI, the same for every
experiment:
uv run python -m plesty.demo_pow_pl --dry-run # print the plan, connect nothing
uv run python -m plesty.demo_pow_pl # run with config/default.yaml
uv run python -m plesty.demo_pow_pl -c other.yaml # another settings file
uv run python -m plesty.demo_pow_pl --resume <run> # continue a stopped run
uv run python -m plesty.demo_pow_pl --manifest # what it declares, as JSON
The manifest is every setting the experiment takes, with type, unit and
description — PLESTY Bench builds its settings form from it, and gate e3
checks that it and config/*.yaml agree. So a setting is added in two places:
SCHEMA in __main__.py, and the YAML file. The scaffold's example setting
is points; replace it with this measurement's four:
SCHEMA = {
"default": [
ConfigParameter(
"start_deg",
default=0.0,
dtype=float,
unit="deg",
min_value=0.0,
max_value=360.0,
description="First half-wave-plate angle.",
),
ConfigParameter(
"stop_deg",
default=180.0,
dtype=float,
unit="deg",
min_value=0.0,
max_value=360.0,
description="Last half-wave-plate angle.",
),
ConfigParameter(
"step_deg",
default=2.0,
dtype=float,
unit="deg",
min_value=0.1,
max_value=90.0,
description="Angle between two rows.",
),
ConfigParameter(
"averaging",
default=10,
dtype=int,
unit="",
min_value=1,
max_value=3000,
description="Power readings averaged per row.",
),
],
}
# config/default.yaml
start_deg: 0.0
stop_deg: 180.0
step_deg: 2.0
averaging: 10
The recording covers exactly this grid, so every row replays a spectrum that
was really measured. The mocks answer per angle, so another grid works too —
step_deg: 5 gives a coarser map of the same measurement.
Next: The Rig.