refactor(panda-box): add pandaboxomny and refactor panda_box main integration

This commit is contained in:
x12sa
2026-02-27 13:22:44 +01:00
committed by appel_c
parent 91d15fdaf2
commit 3c0c0b3573
2 changed files with 113 additions and 10 deletions
+11 -10
View File
@@ -15,6 +15,7 @@ class PandaBoxCSAXS(PandaBox):
def on_init(self):
super().on_init()
self._acquisition_group = "burst"
self._timeout_on_completed = 10
def on_stage(self):
# TODO, adjust as seen fit.
@@ -31,19 +32,19 @@ class PandaBoxCSAXS(PandaBox):
"""On complete is called after the scan is complete. We need to wait for the capture to complete before we can disarm the PandaBox."""
def _check_capture_complete():
timeout = 10
captured = 0
start_time = time.monotonic_ns()
start_time = time.monotonic()
try:
while captured < self.scan_info.msg.num_points:
logger.debug(
f"Run with captured {captured} and expected points : {self.scan_info.msg.num_points}."
expected_points = int(self.scan_info.msg.num_points * 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.5)
if (time.monotonic_ns() - start_time) > timeout:
break
time.sleep(0.01)
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}")
finally:
self._disarm()
@@ -61,14 +62,14 @@ class PandaBoxCSAXS(PandaBox):
# )
# ret_status = status & status_panda_state
# self.cancel_on_stop(ret_status)
return ret_status
# return ret_status
if __name__ == "__main__":
import time
panda = PandaBoxCSAXS(
name="panda",
name="omny_panda",
host="omny-panda.psi.ch",
signal_alias={
"FMC_IN.VAL2.Value": "alias",
@@ -0,0 +1,102 @@
"""Module to integrate the PandaBox for cSAXS measurements."""
import time
from bec_lib.logger import bec_logger
from ophyd_devices import AsyncMultiSignal, StatusBase
from ophyd_devices.devices.panda_box.panda_box import PandaBox, PandaState
from pandablocks.responses import FrameData
logger = bec_logger.logger
class PandaBoxOMNY(PandaBox):
def on_init(self):
super().on_init()
self._acquisition_group = "burst"
self._timeout_on_completed = 10
def on_stage(self):
# TODO, adjust as seen fit.
# Adjust the acquisition group based on scan parameters if needed
if self.scan_info.msg.scan_type == "fly":
self._acquisition_group = "fly"
elif self.scan_info.msg.scan_type == "step":
if self.scan_info.msg.scan_parameters["frames_per_trigger"] == 1:
self._acquisition_group = "monitored"
else:
self._acquisition_group = "burst"
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."""
def _check_capture_complete():
captured = 0
start_time = time.monotonic()
try:
expected_points = int(self.scan_info.msg.num_points * 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:
raise TimeoutError(f"Pandabox {self.name} did not complete after {self._timeout_on_completed} with points captured {captured}/{expected_points}")
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
if __name__ == "__main__":
import time
panda = PandaBoxCSAXS(
name="omny_panda",
host="omny-panda.psi.ch",
signal_alias={
"FMC_IN.VAL2.Value": "alias",
"FMC_IN.VAL1.Min": "alias2",
"FMC_IN.VAL1.Max": "alias3",
"FMC_IN.VAL1.Mean": "alias4",
},
)
panda.on_connected()
status = StatusBase(obj=panda)
panda.add_status_callback(
status=status, success=[PandaState.DISARMED], failure=[PandaState.READY]
)
panda.stop()
status.wait(timeout=2)
panda.unstage()
logger.info(f"Panda connected")
ret = panda.stage()
logger.info(f"Panda staged")
ret = panda.pre_scan()
ret.wait(timeout=5)
logger.info(f"Panda pre scan done")
time.sleep(5)
panda.stop()
st = panda.complete()
st.wait(timeout=5)
logger.info(f"Measurement completed")
panda.unstage()
logger.info(f"Panda Unstaged")