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
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:
1 parent
81d9e9eec0
commit
68ea8235e6
2 files changed
+38
-4
No files matched your search
@@ -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])
|
||||
|
||||
@@ -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()
|
||||
Reference in new issue
Block a user