refactor(eiger): add file event signal
This commit is contained in:
@@ -59,7 +59,9 @@ from jfjoch_client.models.dataset_settings import DatasetSettings
|
|||||||
from jfjoch_client.models.detector_selection import DetectorSelection
|
from jfjoch_client.models.detector_selection import DetectorSelection
|
||||||
from jfjoch_client.models.detector_settings import DetectorSettings
|
from jfjoch_client.models.detector_settings import DetectorSettings
|
||||||
from jfjoch_client.models.detector_timing import DetectorTiming
|
from jfjoch_client.models.detector_timing import DetectorTiming
|
||||||
|
from ophyd import Component as Cpt
|
||||||
from ophyd import DeviceStatus
|
from ophyd import DeviceStatus
|
||||||
|
from ophyd_devices import FileEventSignal, PreviewSignal
|
||||||
from ophyd_devices.interfaces.base_classes.psi_device_base import PSIDeviceBase
|
from ophyd_devices.interfaces.base_classes.psi_device_base import PSIDeviceBase
|
||||||
|
|
||||||
from csaxs_bec.devices.jungfraujoch.jungfrau_joch_client import (
|
from csaxs_bec.devices.jungfraujoch.jungfrau_joch_client import (
|
||||||
@@ -88,6 +90,8 @@ class Eiger(PSIDeviceBase):
|
|||||||
|
|
||||||
USER_ACCESS = ["detector_distance", "beam_center"]
|
USER_ACCESS = ["detector_distance", "beam_center"]
|
||||||
|
|
||||||
|
file_event = Cpt(FileEventSignal, name="file_event")
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
name: str,
|
name: str,
|
||||||
@@ -218,11 +222,15 @@ class Eiger(PSIDeviceBase):
|
|||||||
# Set acquisition parameter
|
# Set acquisition parameter
|
||||||
ntrigger = int(scan_msg.num_points * scan_msg.scan_parameters["frames_per_trigger"])
|
ntrigger = int(scan_msg.num_points * scan_msg.scan_parameters["frames_per_trigger"])
|
||||||
# Fetch file path
|
# Fetch file path
|
||||||
self._full_path = get_full_path(
|
self._full_path = get_full_path(scan_msg, name=f"{self.name}_master")
|
||||||
scan_msg, name=self.name
|
# JFJ adds _master.h5 automatically
|
||||||
) # We can discuss if this should be used with name..
|
path = os.path.relpath(self._full_path, start="/sls/x12sa/data").rstrip("_master.h5")
|
||||||
# Get Path from Broker
|
self.file_event.put(
|
||||||
# Fetch basepath from JFJ broker config
|
file_path=self._full_path,
|
||||||
|
done=False,
|
||||||
|
successful=False,
|
||||||
|
hinted_h5_entries={"data": "entry/data/data"},
|
||||||
|
)
|
||||||
path = os.path.relpath(self._full_path, start="/sls/x12sa/data")
|
path = os.path.relpath(self._full_path, start="/sls/x12sa/data")
|
||||||
data_settings = DatasetSettings(
|
data_settings = DatasetSettings(
|
||||||
image_time_us=int(frame_time_us * 1e6), # This is currently ignored
|
image_time_us=int(frame_time_us * 1e6), # This is currently ignored
|
||||||
@@ -239,6 +247,11 @@ class Eiger(PSIDeviceBase):
|
|||||||
self.jfj_client.start(settings=data_settings)
|
self.jfj_client.start(settings=data_settings)
|
||||||
start_call_returns = time.time() - start_time - prep_time
|
start_call_returns = time.time() - start_time - prep_time
|
||||||
logger.info(f"Start Rest call from JFJ took {start_call_returns:.2f}s")
|
logger.info(f"Start Rest call from JFJ took {start_call_returns:.2f}s")
|
||||||
|
sleep_time = 0.5
|
||||||
|
time.sleep(sleep_time)
|
||||||
|
logger.info(
|
||||||
|
f"Eiger {self.name} staged and ready for acquisition; with additional sleep of {sleep_time:.2f}s"
|
||||||
|
)
|
||||||
|
|
||||||
def on_unstage(self) -> DeviceStatus:
|
def on_unstage(self) -> DeviceStatus:
|
||||||
"""Called while unstaging the device."""
|
"""Called while unstaging the device."""
|
||||||
@@ -249,6 +262,15 @@ class Eiger(PSIDeviceBase):
|
|||||||
def on_trigger(self) -> DeviceStatus:
|
def on_trigger(self) -> DeviceStatus:
|
||||||
"""Called when the device is triggered."""
|
"""Called when the device is triggered."""
|
||||||
|
|
||||||
|
def _file_event_callback(self, status: DeviceStatus) -> None:
|
||||||
|
"""Callback to update the file_event signal when the acquisition is done."""
|
||||||
|
self.file_event.put(
|
||||||
|
file_path=self._full_path,
|
||||||
|
done=True,
|
||||||
|
successful=status.success,
|
||||||
|
hinted_h5_entries={"data": "entry/data/data"},
|
||||||
|
)
|
||||||
|
|
||||||
def on_complete(self) -> DeviceStatus:
|
def on_complete(self) -> DeviceStatus:
|
||||||
"""Called to inquire if a device has completed a scans."""
|
"""Called to inquire if a device has completed a scans."""
|
||||||
|
|
||||||
@@ -257,6 +279,7 @@ class Eiger(PSIDeviceBase):
|
|||||||
for _ in range(timeout):
|
for _ in range(timeout):
|
||||||
try:
|
try:
|
||||||
self.jfj_client.wait_till_done(timeout=1, _request_timeout=5)
|
self.jfj_client.wait_till_done(timeout=1, _request_timeout=5)
|
||||||
|
|
||||||
except (
|
except (
|
||||||
JungfrauJochClientError
|
JungfrauJochClientError
|
||||||
): # Means that timeout was triggered, and not _request_timeout
|
): # Means that timeout was triggered, and not _request_timeout
|
||||||
@@ -267,9 +290,13 @@ class Eiger(PSIDeviceBase):
|
|||||||
except Exception as e: # This should actually never occur..
|
except Exception as e: # This should actually never occur..
|
||||||
raise ValueError(f"Error in complete for {self.name}, exception: {e}") from e
|
raise ValueError(f"Error in complete for {self.name}, exception: {e}") from e
|
||||||
else:
|
else:
|
||||||
|
# How can I check if the aquisition was successful?
|
||||||
|
# If not successfull, we have to raise an error here!
|
||||||
|
# For instance if packages were lost..
|
||||||
break
|
break
|
||||||
|
|
||||||
status = self.task_handler.submit_task(wait_for_complete, run=True)
|
status = self.task_handler.submit_task(wait_for_complete, run=True)
|
||||||
|
status.add_callback(self._file_event_callback)
|
||||||
self.cancel_on_stop(status)
|
self.cancel_on_stop(status)
|
||||||
return status
|
return status
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user