fix(aerotech): calibrate returns string keys so the scan does not hang
CI for csaxs_bec / test (push) Successful in 3m36s

calibrate() returned {channel: offset} with integer keys. The scan server cannot
decode an RPC reply with integer map keys (msgpack strict_map_key), so the
calibrate status never completed and aerotech_cont_grid waited forever in
pre_scan. Now {"enc<channel>": offset}; new test round-trips the RPC return
values of the capture device through the BEC serializer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
This commit is contained in:
x01dcandClaude Opus 5.5 committed 2026-10-29 12:59:53 +01:00
1 parent e79314c77f
commit aa49276d8d
2 files changed
+22 -4

No files matched your search

+6 -2
View File
@@ -890,12 +890,16 @@ class A3200PositionCapture(PSIDeviceBase):
frames_per_trigger = getattr(frames, "frames_per_trigger", 1) if frames else 1
self._correlation_group = "monitored" if frames_per_trigger == 1 else "burst_group"
def calibrate(self) -> dict[int, float]:
def calibrate(self) -> dict[str, float]:
"""
Determine the offset between encoder counts and program position of each channel:
one capture triggered by a software PSO fire with the axes at rest.
Fires the PSO output once: the line trigger receiver (DDG) must not be armed.
Returns the offsets by signal name (enc<channel>). String keys: the return value
of an RPC call is sent with msgpack, which rejects integer map keys, and the scan
would wait forever for the call to finish.
"""
channels = sorted(self.channels)
self.controller.dataacq_arm(
@@ -910,7 +914,7 @@ class A3200PositionCapture(PSIDeviceBase):
axis = self.channels[ch]
position = self.controller.get_position(axis)
self._offsets[ch] = position - counts / self.controller.counts_per_unit(axis)
return dict(self._offsets)
return {f"enc{ch}": offset for ch, offset in self._offsets.items()}
def arm(self, n_triggers: int) -> None:
"""Arm the capture of the next n_triggers trigger edges (start of the array)."""
+16 -2
View File
@@ -305,8 +305,22 @@ def test_line_trigger_needs_pso_input():
def test_capture_calibration_removes_counter_offset():
_, _, capture = _capture_setup()
offsets = capture.calibrate()
assert offsets[6] == pytest.approx(-777 / 20000)
assert offsets[2] == pytest.approx(55 / 10000)
assert offsets["enc6"] == pytest.approx(-777 / 20000)
assert offsets["enc2"] == pytest.approx(55 / 10000)
def test_capture_rpc_returns_survive_msgpack():
# an RPC return value that msgpack cannot decode leaves the scan waiting forever
from bec_lib.serialization import MsgpackSerialization
x, _, capture = _capture_setup()
returns = [capture.calibrate()]
x.move(-1.0, wait=True)
capture.arm(5)
x.move(1.0, wait=True)
returns.append(capture.read_line())
for value in returns:
assert MsgpackSerialization.loads(MsgpackSerialization.dumps(value)) == value
def test_capture_line_publishes_positions():