Write Devices for Blueapi#
See also
Home of Plans and Devices for information about where device code usually lives.
Format#
See also
Dodal for many more examples
Devices are made using the dodal style available through factory functions like this:
from my_facility_devices import MyTypeOfDetector
def my_detector(name: str) -> MyTypeOfDetector:
return MyTypeOfDetector(name, {"other_config": "foo"})
The return type annotation -> MyTypeOfDetector
is required as blueapi uses it to determine that this function creates a device. Meaning you can have a Python file where only some functions create devices and they will be automatically picked up. Similarly, these functions can be organized per-preference into files.
The device is created via a function rather than a global to preserve side-effect-free imports. Each device must have its own factory function.
How to Configure Detectors to Write Files#
Note
This is an absolute requirement to write data onto the Diamond Filesystem. This decorator must be used every time a new data collection is intended to begin. For an example, see below.
Dodal defines a decorator, @attach_data_session_metadata_decorator()
, for configuring ophyd-async
detectors to write data to a common location.
@attach_metadata
def ophyd_async_snapshot(
detectors: List[Readable],
metadata: Optional[dict[str, Any]] = None,
) -> MsgGenerator:
Configures a number of devices, which may be Ophyd-Async detectors and require
knowledge of where to write their files, then takes a snapshot with them.
Args:
detectors (List[Readable]): Devices, maybe including Ophyd-Async detectors.
Returns:
MsgGenerator: Plan
Yields:
Iterator[MsgGenerator]: Bluesky messages
yield from count(detectors, 1, metadata or {})
def repeated_snapshot(
detectors: List[Readable],
metadata: Optional[dict[str, Any]] = None,
) -> MsgGenerator:
Configures a number of devices, which may be Ophyd-Async detectors and require
knowledge of where to write their files, then takes multiple snapshot with them.
Args:
detectors (List[Readable]): Devices, maybe including Ophyd-Async detectors.
Returns:
MsgGenerator: Plan
Yields:
Iterator[MsgGenerator]: Bluesky messages
@attach_metadata
def inner_function():
yield from count(detectors, 1, metadata or {})
for _ in range(5):
yield from inner_function()