This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Experiment editing

The Experiment lifecycle, parameters, timing and scans.

An experiment is a Python class derived from Experiment. The framework calls a small number of well-defined hooks, and provides the parameter and device model around them.

Lifecycle

StageWhat happens
build()Declare parameters and devices; called once per instance
run()Execute one repetition of the experiment
_start_run() / _end_run()Framework bookkeeping around each run, including data markers
close()Release devices and clients

Do not perform hardware work in build(): it may run while the user is editing parameters. Put all timed operations in run().

Parameters

Parameters are declared with typed values such as NumberValue, BoolValue, StringCombo, IntegerValue and ListValue. Each value carries metadata used by the GUI and by the scan engine:

  • unit and display multiplier;
  • minimum/maximum and step;
  • whether the value is persisted;
  • the list of allowed values for combos.

The same metadata drives the desktop parameter panel, the web dashboard and scan validation, so a scan cannot silently use an invalid value.

Timing

delay(seconds) advances the sequence clock. realtime() and the DAC/TTL attribute descriptors schedule outputs on the real-time controller. The experiment code describes what happens; the selected backend decides how to realise it on FPGA, ADwin or a simulated controller.

Keep hardware interactions inside run() and avoid Python-level busy loops. The runtime is designed so that a long analysis or GUI operation cannot block the timing path.

Scans and repetitions

A scan is a list of parameter values, optionally multi-dimensional, with an execution order (including randomised and snake orders). The queue turns a scan into individual task descriptions, each with the same parameter schema. Results are stored with the scan definition so the data remains self-describing.

Errors and cleanup

An exception in run() aborts the current run, executes framework cleanup, and marks the task failed. close() is called even after failures. Device leases and property clients are released deterministically; long-running experiments should rely on this cleanup rather than on process exit.