Interface Contracts
A contract here is a promise plesty-lib makes to the code built on it: what a class or function guarantees, and what a subclass must provide in return. Modules rely on these promises, so they change only with a new version number and a note in the changelog. Each entry below states the promise and links the page that shows how to use it.
Devices
BaseDeviceSyncModel, in plesty.lib.device.base_device_sync. Every device
inherits this class. It combines three independent parts, each a separate base class
(a mixin):
ConfigSystem, the parameters: declared, checked against their type and range (Parameter System);FunctionSystem, the operations: declared in code or in a JSON file (Function System);TelemetrySystem, a snapshot of the device’s state (status()) and optional callbacks on every read and write (Data & Metadata Schemas).
A subclass implements connect, disconnect, _write_, _query_,
check_errors and check_operatability. In return, write and query check the
value, log the call, convert the reply, and report it to the callbacks. A with
block connects and disconnects, and claims the instrument for this object while it
is open. See Base Device.
doc_model() returns a DeviceDocModel: everything a device declares, as data
rather than text. Its parameters are grouped, its operations listed, and the methods
every device has (standard_methods) are kept apart from the device’s own. Anything
that describes a device, such as generated documentation, the server’s describe
reply or a control panel, reads this instead of collecting the information itself.
See Base Device.
Solvers, in plesty.lib.solver. A CmdSolver turns a parameter into the command
that reads or writes it; an OpSolver turns an operation request into the
instrument’s reply. SCPISolver also runs any operation whose whole exchange is one
SCPI command and one value, taken from the command field of the operation’s
declaration, so such operations need no code. See
Command Solver.
CompositeDevice.call, in plesty.lib.device.composite_device. When a call to a
device on another computer times out, the client is rebuilt and the call tried
again, a limited number of times, before the last TimeoutError is raised. See
Resilient remote calls.
Preflight: checking that an instrument is really there before a measurement.
A connection’s TrafficManager.preflight(address) returns a Preflight result. A
device’s preflight() returns the same result as a plain dictionary without serial
numbers, so that its server can send it over the network. A composite’s
preflight() returns a Preflight with one part per device, each including what
that device’s server reported. On a Preflight, ready says whether everything
needed is there, summary() explains what is missing, and to_dict() gives the
result without serial numbers, for saving. See
Preflight: is the instrument actually there?.
Experiments
Experiment, Plan and the journal, in plesty.lib.experiment. build_plan()
returns a Plan of Steps, fixed once the run starts and identified by a
fingerprint of its content (a SHA-256 hash). Before any device is touched, run()
checks that every step names a public method of the experiment. Each step is
recorded in an append-only journal. run(resume=<run id>) skips the steps already
recorded and refuses to continue if the plan’s fingerprint has changed. teardown()
always runs, however the run ends. See
Experiment Framework.
Run control, in plesty.lib.experiment.control. A request written to the run
folder’s control.json (pause, resume, cancel, abort, or a note) takes effect at the
next boundary between two steps. Only an abort is also checked during a step, every
half second, and it interrupts the step. See
Asking a running measurement to pause or stop.
Result files, in plesty.lib.data.io. save_result writes the data file first,
and its description (ResultDocument, JSON) last. A description on disk therefore
means its data is complete. load_document reads a description without loading the
data; convert_to_hdf5 packs several results into one HDF5 file. See
Data & Metadata Schemas.
Analyzers and reports
Analyzer, in plesty.lib.analyzer. A subclass declares input_schema and
output_schema and implements one synchronous analyze(). Calling the analyzer
checks the inputs, fills in missing units and descriptions of the outputs from the
schema, and stamps every array and table in the outputs with its provenance: the
analyzer’s class, its package version, and its settings. An analyzer never imports a
device. See Analyzer Framework.
Report, in plesty.lib.report. A report is a list of text, tables and figures.
save() writes it as JSON; Report.load() reads it back and to_html() or
to_latex() renders it, without importing the analyzer that made it. See
Reports.
Viewing
Viz, RunData and Plot, in plesty.lib.monitor. Viz makes the viewer for
one experiment. RunData reads everything a run has saved, once, and every plot in
the viewer shares it. A plot is a title and a function draw(data) that returns what
to draw: Line, Scatter, Image, Scalar or Text. Viewing only reads the run
folder, so it cannot disturb the measurement. The older Monitor classes still work.
See Viewing a Run.
Shell and panels, in plesty.lib.ui. A Panel is anything that fits in a
sub-window; Shell is the main window that docks, floats and tabs them, remembers
their layout, and refreshes all of them on one timer. Colours and styles come from
packaged files, never from Python code. Only plesty.lib.ui.qt imports Qt. See
Shell Framework.
Tests every module runs
Contract pipelines, in plesty.lib.test. Each kind of module has a set of tests
that checks it keeps these contracts, without the instrument:
Pipeline |
For |
Checks |
Run by plesty-sdk as gate |
|---|---|---|---|
|
devices |
8 tests: the declarations are valid, every parameter and operation works against a simulated instrument, connecting and disconnecting, identity, errors |
|
|
experiments |
5 tests: the plan is the same every time, every step names a method, the plan survives saving and loading, the lifecycle methods are asynchronous |
|
|
analyzers |
5 tests: the schemas are valid, |
|
A gate is one of the checks plesty check, the checking command of plesty-sdk,
runs before a module may be published. What a simulated instrument cannot show, such
as the exact command format, a flaky connection or two devices sharing one computer,
is tested on the real instrument by FieldTestPipeline, over the network by
client_field_test, and for shared computers by field_test_concurrency. See
Testing.