feat(flomni): rt_positions prints the average of the per-point standard deviations (sample vs FZP during the exposures) to the BEC CLI at the end of each scan; no ZeroDivisionError when no point was read
CI for csaxs_bec / test (push) Successful in 4m18s

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QnSJvqxh9oDbshx8qXgeiX
This commit is contained in:
Mirko HollerandClaude Opus 5.5 committed 2026-10-26 10:59:15 +01:00
1 parent 81d9e9eec0
commit 68ea8235e6
2 files changed
+38 -4

No files matched your search

+21 -4
View File
@@ -877,11 +877,28 @@ class RtFlomniFlyer(Device):
status.set_finished()
self.progress.put(value=read_counter, max_value=number_of_positions_planned, done=True)
logger.info(
"Flomni statistics: Average of all standard deviations: x"
f" {self.average_stdeviations_x_st_fzp/read_counter*1000:.1f}, y"
f" {self.average_stdeviations_y_st_fzp/read_counter*1000:.1f}"
self._report_statistics(read_counter)
def _report_statistics(self, read_counter: int):
"""At the end of a scan: mean of the per-point standard deviations (sample vs FZP during each exposure,
RT_sampler) to the device-server log and to the BEC command line (Mirko 2026-10-26)."""
if read_counter == 0:
logger.info("Flomni statistics: no scan points read, no average of the standard deviations")
return
msg = (
"flOMNI scan statistics: average of the standard deviations during the exposures"
f" ({read_counter} points, sample vs FZP): x"
f" {self.average_stdeviations_x_st_fzp/read_counter*1000:.1f} nm, y"
f" {self.average_stdeviations_y_st_fzp/read_counter*1000:.1f} nm"
)
logger.info(msg)
try:
self.controller.device_manager.connector.send_client_info(
msg, scope="flomni_scan_statistics", show_asap=True
)
except Exception as exc: # pylint: disable=broad-except
# the statistics are information only: never fail the readout for them
logger.warning(f"Flomni statistics not sent to the client: {exc}")
def _get_signals_from_table(self, return_table) -> dict:
self.average_stdeviations_x_st_fzp += float(return_table[4])
+17
View File
@@ -4,6 +4,7 @@ import pytest
from ophyd_devices.tests.utils import SocketMock
from csaxs_bec.devices.omny.rt import RtFlomniController, RtFlomniMotor
from csaxs_bec.devices.omny.rt.rt_flomni_ophyd import RtFlomniFlyer
from csaxs_bec.devices.omny.rt.rt_ophyd import RtError
@@ -98,3 +99,19 @@ def test_feedback_enable_without_reset_raises(rt_flomni):
rt_flomni.feedback_enable_without_reset()
laser_tracker_on.assert_called_once()
assert mock.call(b"l3\n") in rt_flomni.sock.put.mock_calls
def test_flyer_reports_average_stdev_to_the_client(rt_flomni):
flyer = RtFlomniFlyer(name="rt_positions", socket_cls=SocketMock, device_manager=rt_flomni.device_manager)
flyer.controller = rt_flomni
for row in (["0", "0", "1", "1", "0.002", "2", "2", "0.001", "0", "0"],
["1", "0", "1", "1", "0.004", "2", "2", "0.003", "0", "0"]):
flyer._get_signals_from_table(row)
flyer._report_statistics(2)
send = rt_flomni.device_manager.connector.send_client_info
msg = send.call_args.args[0]
assert "x 3.0 nm, y 2.0 nm" in msg and "2 points" in msg
assert send.call_args.kwargs["show_asap"] is True
send.reset_mock()
flyer._report_statistics(0) # no points: nothing sent, no ZeroDivisionError
send.assert_not_called()