refactor: cleanup docs and logs for most relevant devices

This commit is contained in:
2026-03-02 08:23:02 +01:00
parent e9fd9084b8
commit 05a1e3d8be
6 changed files with 32 additions and 47 deletions

View File

@@ -309,7 +309,11 @@ class DDG1(PSIDeviceBase, DelayGeneratorCSAXS):
# Shutter opens without delay at t0, closes after exp_time * burst_count + 2ms (self._shutter_to_open_delay)
self.set_delay_pairs(channel="cd", delay=0, width=shutter_width)
self.set_delay_pairs(channel="gh", delay=self._shutter_to_open_delay, width=(shutter_width-self._shutter_to_open_delay))
self.set_delay_pairs(
channel="gh",
delay=self._shutter_to_open_delay,
width=(shutter_width - self._shutter_to_open_delay),
)
# Trigger extra pulse for MCS OR gate
# f = e + 1us
@@ -520,7 +524,6 @@ class DDG1(PSIDeviceBase, DelayGeneratorCSAXS):
- Return the status object to BEC which will automatically resolve once the status register has
the END_OF_BURST bit set. The callback of the status object will also stop the polling loop.
"""
overall_start = time.time()
self._stop_polling()
# NOTE If the trigger source is not SINGLE_SHOT, the DDG is triggered by an external source
@@ -559,7 +562,6 @@ class DDG1(PSIDeviceBase, DelayGeneratorCSAXS):
# Send trigger
self.trigger_shot.put(1, use_complete=True)
self.cancel_on_stop(status)
logger.info(f"Configured ddg in {time.time()-overall_start}")
return status
def on_stop(self) -> None:

View File

@@ -261,7 +261,6 @@ class MCSCardCSAXS(PSIDeviceBase, MCSCard):
**kwargs: Additional keyword arguments from the subscription, including 'obj' (the EpicsSignalRO instance).
"""
with self._rlock:
logger.info(f"Received update on mcs card {self.name}")
if self._omit_mca_callbacks.is_set():
return # Suppress callbacks when erasing all channels
self._mca_counter_index += 1
@@ -293,9 +292,6 @@ class MCSCardCSAXS(PSIDeviceBase, MCSCard):
)
# Once we have received all channels, push data to BEC and reset for next accumulation
logger.info(
f"Received update for {attr_name}, index {self._mca_counter_index}/{self.NUM_MCA_CHANNELS}"
)
if len(self._current_data) == self.NUM_MCA_CHANNELS:
logger.debug(
f"Current data index {self._current_data_index} complete, pushing to BEC."
@@ -398,11 +394,12 @@ class MCSCardCSAXS(PSIDeviceBase, MCSCard):
# NOTE Make sure that the signal that omits mca callbacks is cleared
self._omit_mca_callbacks.clear()
logger.info(f"MCS Card {self.name} on_stage completed in {time.time() - start_time:.3f}s.")
# For a fly scan we need to start the mcs card ourselves
if self.scan_info.msg.scan_type == "fly":
self.erase_start.put(1)
logger.info(f"MCS Card {self.name} on_stage completed in {time.time() - start_time:.3f}s.")
def on_prescan(self) -> None | StatusBase:
"""
This method is called after on_stage and before the scan starts. For the MCS card, we need to make sure

View File

@@ -132,7 +132,6 @@ class Eiger(PSIDeviceBase):
if data is None:
logger.error(f"Received image message on device {self.name} without data.")
return
logger.info(f"Received preview image on device {self.name}")
self.preview_image.put(data)
# pylint: disable=missing-function-docstring

View File

@@ -3,14 +3,18 @@
import time
from bec_lib.logger import bec_logger
from ophyd_devices import AsyncMultiSignal, StatusBase
from ophyd_devices import StatusBase
from ophyd_devices.devices.panda_box.panda_box import PandaBox, PandaState
from pandablocks.responses import FrameData
logger = bec_logger.logger
class PandaBoxCSAXS(PandaBox):
"""
PandaBox integration for cSAXS. This class implements cSAXS specific logic for the PandaBox integration.
TODO: This logic is not yet mapped to any existing hardware. Adapt Docstring once the hardware is defined and integrated.
"""
def on_init(self):
super().on_init()
@@ -18,6 +22,7 @@ class PandaBoxCSAXS(PandaBox):
self._timeout_on_completed = 10
def on_stage(self):
start_time = time.time()
super().on_stage()
# TODO, adjust as seen fit.
# Adjust the acquisition group based on scan parameters if needed
@@ -29,6 +34,8 @@ class PandaBoxCSAXS(PandaBox):
else:
self._acquisition_group = "burst"
logger.info(f"PandaBox {self.name} on_stage completed in {time.time() - start_time:.3f}s.")
def on_complete(self):
"""On complete is called after the scan is complete. We need to wait for the capture to complete before we can disarm the PandaBox."""
@@ -41,12 +48,13 @@ class PandaBoxCSAXS(PandaBox):
* self.scan_info.msg.scan_parameters.get("frames_per_trigger", 1)
)
while captured < expected_points:
logger.info(
f"Run with captured {captured} and expected points : {expected_points}."
)
ret = self.send_raw("*PCAP.CAPTURED?")
captured = int(ret[0].split("=")[-1])
time.sleep(0.01)
if (time.monotonic() - start_time) > self._timeout_on_completed / 2:
logger.info(
f"Waiting for capture on device {self.name} to complete: captured {captured}/{expected_points} points."
)
if (time.monotonic() - start_time) > self._timeout_on_completed:
raise TimeoutError(
f"Pandabox {self.name} did not complete after {self._timeout_on_completed} with points captured {captured}/{expected_points}"
@@ -54,21 +62,9 @@ class PandaBoxCSAXS(PandaBox):
finally:
self._disarm()
_check_capture_complete()
# NOTE: This utility class allows to submit a blocking function to a thread and return a status object
# that can be awaited for. This allows for asynchronous waiting for the capture to complete without blocking
# the main duty cycle of the device server. The device server knows how to handle the status object (future)
# and will wait for it to complete.
# status = self.task_handler.submit_task(_check_capture_complete, run=True)
# status_panda_state = StatusBase(obj=self)
# self.add_status_callback(
# status, success=[PandaState.END, PandaState.DISARMED], failure=[PandaState.READY]
# )
# ret_status = status & status_panda_state
# self.cancel_on_stop(ret_status)
# return ret_status
status_captured = self.task_handler.submit_task(_check_capture_complete, run=True)
self.cancel_on_stop(status_captured)
return status_captured
if __name__ == "__main__":

View File

@@ -10,6 +10,7 @@ logger = bec_logger.logger
class PandaBoxOMNY(PandaBox):
"""PandaBox integration for OMNY. This class implements OMNY specific logic for the PandaBox integration."""
def on_init(self):
super().on_init()
@@ -17,6 +18,7 @@ class PandaBoxOMNY(PandaBox):
self._timeout_on_completed = 10
def on_stage(self):
start_time = time.time()
super().on_stage()
# TODO, adjust as seen fit.
# Adjust the acquisition group based on scan parameters if needed
@@ -28,6 +30,8 @@ class PandaBoxOMNY(PandaBox):
else:
self._acquisition_group = "burst"
logger.info(f"PandaBox {self.name} on_stage completed in {time.time() - start_time:.3f}s.")
def on_complete(self):
"""On complete is called after the scan is complete. We need to wait for the capture to complete before we can disarm the PandaBox."""
@@ -40,12 +44,13 @@ class PandaBoxOMNY(PandaBox):
* self.scan_info.msg.scan_parameters.get("frames_per_trigger", 1)
)
while captured < expected_points:
logger.info(
f"Run with captured {captured} and expected points : {expected_points}."
)
ret = self.send_raw("*PCAP.CAPTURED?")
captured = int(ret[0].split("=")[-1])
time.sleep(0.01)
if (time.monotonic() - start_time) > self._timeout_on_completed / 2:
logger.info(
f"Waiting for capture on device {self.name} to complete: captured {captured}/{expected_points} points."
)
if (time.monotonic() - start_time) > self._timeout_on_completed:
raise TimeoutError(
f"Pandabox {self.name} did not complete after {self._timeout_on_completed} with points captured {captured}/{expected_points}"
@@ -57,20 +62,6 @@ class PandaBoxOMNY(PandaBox):
self.cancel_on_stop(status_captured)
return status_captured
# NOTE: This utility class allows to submit a blocking function to a thread and return a status object
# that can be awaited for. This allows for asynchronous waiting for the capture to complete without blocking
# the main duty cycle of the device server. The device server knows how to handle the status object (future)
# and will wait for it to complete.
# status = self.task_handler.submit_task(_check_capture_complete, run=True)
# status_panda_state = StatusBase(obj=self)
# self.add_status_callback(
# status, success=[PandaState.END, PandaState.DISARMED], failure=[PandaState.READY]
# )
# ret_status = status & status_panda_state
# self.cancel_on_stop(ret_status)
# return ret_status
if __name__ == "__main__":
import time

View File

@@ -1,4 +1,4 @@
""" Module with JungfrauJochTestScan class. """
"""Module with JungfrauJochTestScan class."""
from bec_lib import bec_logger
from bec_server.scan_server.scans import AsyncFlyScanBase, ScanAbortion