diff --git a/csaxs_bec/devices/panda_box/panda_line_trigger.py b/csaxs_bec/devices/panda_box/panda_line_trigger.py index 5cf85a09..6bd4a9e4 100644 --- a/csaxs_bec/devices/panda_box/panda_line_trigger.py +++ b/csaxs_bec/devices/panda_box/panda_line_trigger.py @@ -163,6 +163,7 @@ class PandaLineTrigger(Device): self.trigger_edge = trigger_edge self._pulse_params = None # parameters written to the PULSE blocks self._dropped_at_arm = 0 # DROPPED is only zeroed by ENABLE, which is never toggled + self._ignored_reported = 0 # ignored edges since arm() already logged self.device_manager = device_manager super().__init__(prefix, name=name, **kwargs) @@ -359,6 +360,7 @@ class PandaLineTrigger(Device): self.panda.set(f"{counter}.ENABLE", "ZERO") self.panda.set(f"{counter}.ENABLE", "ONE") self._dropped_at_arm = int(self.panda.get(f"{self.DETECTOR_PULSE}.DROPPED")) + self._ignored_reported = 0 self.panda.set(f"{gate}.FORCE_SET", "") def disarm(self) -> None: @@ -415,9 +417,15 @@ class PandaLineTrigger(Device): f"{self.name}: expected {n_lines} line(s) with {n_lines * n_pulses} pulses," f" got {status['lines']} with {status['pulses']}." ) - if status["triggers"] != status["lines"]: - logger.warning( - f"{self.name}: {status['triggers'] - status['lines']} trigger edge(s) ignored" - f" (edge while a line was running or while not armed): {status}." + # Ignored edges are harmless (lines and pulses are checked above): typically encoder + # noise at the PSO window entry, one extra edge per line while the line runs. Log only + # the new ones, as info, so a scan does not print a growing warning after each line. + ignored = status["triggers"] - status["lines"] + if ignored > self._ignored_reported: + logger.info( + f"{self.name}: {ignored - self._ignored_reported} trigger edge(s) ignored in" + f" line {n_lines} (edge while a line was running or while not armed)," + f" {ignored} since arm." ) + self._ignored_reported = ignored return status diff --git a/tests/tests_devices/test_panda_line_trigger.py b/tests/tests_devices/test_panda_line_trigger.py index 65edee41..95feadef 100644 --- a/tests/tests_devices/test_panda_line_trigger.py +++ b/tests/tests_devices/test_panda_line_trigger.py @@ -274,3 +274,26 @@ def test_user_access_names_not_protected_by_bec(device_cls): module, name = device_cls.rsplit(".", 1) cls = getattr(importlib.import_module(module), name) assert not set(cls.USER_ACCESS) & set(get_protected_class_methods()) + + +def test_ignored_edges_logged_once_per_line_as_info(trigger): + from unittest import mock + + from csaxs_bec.devices.panda_box import panda_line_trigger + + trigger.configure_line(5, exp_time=0.01) + trigger.arm() + with mock.patch.object(panda_line_trigger, "logger") as logger: + for n_lines in (1, 2): + trigger.soft_line_trigger() + trigger.panda.busy = True + trigger.soft_line_trigger() # entry noise during the line + trigger.panda.busy = False + trigger.wait_lines_done(n_lines, timeout=1) + trigger.soft_line_trigger() + trigger.wait_lines_done(3, timeout=1) # clean line: nothing logged + logger.warning.assert_not_called() + messages = [call.args[0] for call in logger.info.call_args_list] + assert len(messages) == 2 + assert "1 trigger edge(s) ignored in line 1" in messages[0] + assert "1 trigger edge(s) ignored in line 2" in messages[1] and "2 since arm" in messages[1]