Instrument Configuration

This page describes the procedure for defining the beamline configuration. Haven contains definitions for many Ophyd and Ophyd-async devices, however Haven needs a beamline configuration file to know which specific devices are needed for each beamline.

These files should be listed in the environmental variable HAVEN_CONFIG_FILES as a semi-colon separated list (e.g. export HAVEN_CONFIG_FILES=$HOME/bluesky/iconfig.toml:/local/bluesky/iconfig_extra.toml).

Then the devices defined in these files can be loaded in python:

from haven import beamline
await beamline.load()

Once the beamline has been loaded, the devices are available using an Ophyd registry attached to the beamline object. For example, beamline.registry["austin"] would return an Ophyd device instance named “austin”, and beamline.registry.findall("ion_chambers") would return all devices with the “ion_chambers” Ophyd label.

Motivation

Haven’s goal is to provide support for all of the spectroscopy beamlines. However, each beamline is different, and these differences are managed by a set of configuration files, similar to the .ini files used in the old LabView applications. To keep the complexity of these configuration files manageable, Haven gets much of the needed information from the IOCs directly.

The job of processing the configuration files is handled by the Instrument class. This class keeps track of the configuration file schema, as well as the resulting devices.

Haven/Firefly should always load without a specific configuration file, but will probably not do anything useful.

Device Definitions

The beamline instrument loader can either instantiate ophyd devices directly, or using factory functions.

Simple Devices

Each device class has an entry in the :py:object:`~haven.instrument.beamline` loader. To create a new device, add a table to the configuration file for each device instance to create. The keys in the table should correspond to arguments passed to the device’s __init__() method.

Typically, the key for the table is the joined-lower version of the class name. For example, an instance of the HighHeatLoadMirror device class would be added to the configuration file as:

[[ high_heat_load_mirror ]]
name = "ORM1"
prefix = "255ida:ORM1:"
bendable = false

The instrument loader will then create a new device as HighHeatLoadMirror(name="ORM1", prefix="255ida:", bendable=False).

The resulting device can then be retrieved from the beamline instrument registry: beamline.registry["ORM1"].

Note

The Ophyd registry allows looking up devices by Ophyd label. E.g. beamline.registry.findall("ion_chambers") will retrieve all devices with “ion_chambers” in its labels.

The instrument loader itself does not handle labels. In most cases, reasonable defaults should be set by the device’s __init__() methods, however for more control the device table could also contain the labels key, with the beamline then being responsible for ensuring these labels are correct.

For example, the following device would be accesible by registry['I0'] and registry.findall("detectors"), but not by registry.findall(["ion_chambers"])

[[ ion_chamber ]]
name = "I0"
...
labels = ["detectors"]

Factory Functions

Devices can be created using functions instead of Device classes. The general idea is the same. For each factory function, the instrument loader will look for tables with arguments to this function, typically derived from the joined-lower name for the factory. For example, the function:

def make_area_detector(name: str, prefix: str, ad_version: str = "4.3") -> Device:
     ...

could have an entry in the configuration file:

[[ area_detector ]]
name = "sim_det"

These factory functions should return either a new Device, or a iterable of new devices.

Checking Configuration

If Haven is installed with pip, the command haven_config can be used to read configuration variables as they will be seen by Haven:

$ haven_config beamline
{'hardware_is_present': False, 'name': 'SPC Beamline (sector unknown)'}
$ haven_config beamline.hardware_is_present
False

Example Configuration

Below is an example of a configuration that can be re-used for new device support or beamline setup.

If a feature is added to Haven that would benefit from beamline-specific configuration, an example of its use should be added to src/haven/iconfig_testing.toml.