Quick Start: Grouping Motors with mb_creator#

The mb_creator() function from apstools.devices.motor_factory lets you quickly create an ophyd Device that groups any number of motors, either real or simulated, without writing a custom class.

Basic Usage#

Create an ophyd Device structure (such as an ophyd.MotorBundle) from a set of motor specifications.

1. Empty Device#

Create a device with no motors (just a container):

from apstools.devices import mb_creator

empty = mb_creator(name="empty")
empty
MB_Device(prefix='', name='empty', read_attrs=[], configuration_attrs=[])

2. Simulated Axes#

Create a device with simulated (SoftPositioner) axes by providing a list of names:

sim = mb_creator(name="sim", motors=["x", "y"])
sim.x
SoftPositioner(name='sim_x', parent='sim', settle_time=0.0, timeout=None, egu='', limits=(0, 0), source='computed')

3. Mixed Real and Simulated Motors#

Mix real (EpicsMotor) and simulated axes by using a dict and setting some to None:

combo = mb_creator(
    name="bundle",
    prefix="gp:",
    motors={
        "x": "m1",
        "y": "m2",
        "z": "m3",
        "roll": None,  # Simulated
        "pitch": None, # Simulated
        "yaw": None, # Simulated
    }
)
combo.x, combo.roll
(EpicsMotor(prefix='gp:m1', name='bundle_x', parent='bundle', settle_time=0.0, timeout=None, read_attrs=['user_readback', 'user_setpoint'], configuration_attrs=['user_offset', 'user_offset_dir', 'velocity', 'acceleration', 'motor_egu']),
 SoftPositioner(name='bundle_roll', parent='bundle', settle_time=0.0, timeout=None, egu='', limits=(0, 0), source='computed'))

4. Custom Labels#

Add custom labels to your device for organization or registry lookup:

labeled = mb_creator(
    name="labeled",
    motors={"x": "m1"},
    labels=["mygroup", "motors"]
)
labeled._ophyd_labels_
{'motors', 'mygroup'}

For more information: