This commit is contained in:
2025-09-04 08:54:43 +02:00
parent 7914105863
commit 5e817e7e9b

View File

@@ -5,6 +5,7 @@ from __future__ import annotations
import enum
import threading
import time
import traceback
from typing import TYPE_CHECKING
import numpy as np
@@ -174,22 +175,29 @@ class Pilatus(PSIDeviceBase, ADBase):
def _poll_array_data(self):
while not self._poll_thread_stop_event.wait(1 / self._poll_rate):
logger.debug("Polling Pilatus array data for preview...")
value = self.image1.array_data.get()
if value is None:
continue
width = self.image1.array_size.width.get()
height = self.image1.array_size.height.get()
# Geometry correction for the image
data = np.reshape(value, (height, width))
last_image: DevicePreviewMessage = self.preview.get()
if last_image is not None:
if np.array_equal(data, last_image.data):
try:
value = self.image1.array_data.get()
if value is None:
continue
width = self.image1.array_size.width.get()
height = self.image1.array_size.height.get()
# Geometry correction for the image
data = np.reshape(value, (height, width))
last_image: DevicePreviewMessage = self.preview.get()
if last_image is None:
return
elif np.array_equal(data, last_image.data):
# No update if image is the same, ~2.5ms on 2400x2400 image (6M)
logger.debug(
f"Pilatus preview image for {self.name} is the same as last one, not updating."
)
return
self.preview.put(data)
except Exception: # pylint: disable=broad-except
content = traceback.format_exc()
logger.error(
f"Error while polling array data for preview of {self.name}: {content}"
)
########################################
# Beamline Specific Implementations #
@@ -221,6 +229,7 @@ class Pilatus(PSIDeviceBase, ADBase):
self.hdf.capture.put(0)
self.cam.trigger_mode.set(TRIGGERMODE.MULT_TRIGGER.value).wait(5)
self.cam.image_file_tmot.set(60).wait(5)
self.hdf.file_write_mode.set(FILEWRITEMODE.STREAM.value).wait(5)
self.hdf.file_template.set("%s%s").wait(5)
self.hdf.auto_save.set(1).wait(5)
@@ -257,7 +266,7 @@ class Pilatus(PSIDeviceBase, ADBase):
# Camera settings
self.cam.num_exposures.set(1).wait(5)
self.cam.num_images.set(n_images).wait(5)
self.cam.acquire_time.set(detector_exp_time).wait(5)
self.cam.acquire_time.set(exp_time).wait(5) # let's try this
self.cam.acquire_period.set(PILATUS_ACQUIRE_TIME).wait(5)
self.filter_number.set(0).wait(5)
# HDF5 settings
@@ -324,6 +333,7 @@ class Pilatus(PSIDeviceBase, ADBase):
else:
status_hdf = CompareStatus(self.hdf.capture, ACQUIREMODE.DONE.value)
status_cam = CompareStatus(self.cam.acquire, ACQUIREMODE.DONE.value)
status_cam_server =
num_images = self.scan_info.msg.num_points * self.scan_info.msg.scan_parameters.get(
"frames_per_trigger", 1
)
@@ -336,19 +346,6 @@ class Pilatus(PSIDeviceBase, ADBase):
self.cancel_on_stop(status)
return status
def _on_failure_callback(self, status: DeviceStatus | AndStatusWithList):
"""
This is a best effort cleanup procedure for the Pilatus backend.
It seems as if the CamServer is likely to crash, and needs a restart
if an acquisition is interrupted pre-dominantly and not properly stopped.
So we attach it to any status object during the acquisition.
Args:
status (DeviceStatus | AndStatusWithList): The status object to check.
"""
if not status.success:
status.device.on_stop()
def on_kickoff(self) -> None:
"""Called to kickoff a device for a fly scan. Has to be called explicitly."""