Plesty Documentation

Scaffold

plesty init experiment — the files it writes, and the split between settings, wiring and secrets.

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.