pytweezer.coordinators.base module¶
Generic Coordinator base class for composite devices.
A coordinator is an extra RPC target on a composite device server (see
pytweezer/servers/device_server.py’s _make_composite) that holds direct
references to that server’s device backends. Because the backends are ordinary
Python objects in the same process, a coordinator drives them with plain method
calls: a camera frame handed to a DAC never touches a socket and is never
serialized. That is the whole point of the composite — a step that would cost an
RPC round trip per device becomes an attribute lookup.
Subclasses reach their backends through self.targets, keyed by role — each
sub-config’s "role" value, defaulting to its device name:
class MyLoop(Coordinator):
def step(self):
frame = self.targets["camera"].acquire_single_frame()
self.targets["dac"].set_voltage("Dev1/ao0", frame.mean())
Roles exist so a coordinator asks for "camera" while the device it gets is
called "Rb Feedback Cam" in config and served under that name to RPC clients.
One coordinator class therefore works across rigs whose devices are named
differently.
Point the composite’s "coordinator" config key at the subclass as a
"module.path:ClassName" string; build_spec imports and constructs it as
cls(roles, conf).
Three constraints on subclasses:
Every public method is a synchronous RPC method and stalls the whole server for its duration. The sipyco server is single-threaded asyncio and runs a plain
deftarget method inline on the event loop, so while a coordinator method runs, no target on that server — camera, DAC, or coordinator — answers anything. Keep methods bounded; a batch method should take an iteration count rather than free-running.Return values cross a PYON boundary. Return plain types, dicts, lists and numpy arrays; never exception objects or backend handles. Returning a camera frame reintroduces the serialization cost the coordinator exists to avoid.
Do not define
__call__.sipyco.pc_rpc.Servertreats a callable target as a per-connection factory and invokes it instead of serving it.
- class pytweezer.coordinators.base.Coordinator(targets, conf)[source]¶
Bases:
objectBase for an in-process device coordinator.
targetsmaps role to backend object;confis the composite device’s config entry.