After session with Klaus

This commit is contained in:
gac-x05la
2025-02-20 12:42:33 +01:00
parent 76cf6ac447
commit f15fd00712
3 changed files with 104 additions and 29 deletions

View File

@@ -13,7 +13,7 @@ import requests
import os
from ophyd import Signal, Component, Kind
from ophyd.status import SubscriptionStatus
from ophyd.status import SubscriptionStatus, Status
from websockets.sync.client import connect, ClientConnection
from websockets.exceptions import ConnectionClosedOK, ConnectionClosedError
@@ -41,6 +41,9 @@ class StdDaqMixin(CustomDeviceMixin):
# Fish out our configuration from scaninfo (via explicit or generic addressing)
# NOTE: Scans don't have to fully configure the device
d = {}
scan_parameters = self.parent.scaninfo.scan_msg.scan_parameters
std_daq_params = scan_parameters.get("std_daq_params")
if "kwargs" in self.parent.scaninfo.scan_msg.info:
scanargs = self.parent.scaninfo.scan_msg.info["kwargs"]
if "image_width" in scanargs and scanargs["image_width"] is not None:
@@ -88,6 +91,7 @@ class StdDaqMixin(CustomDeviceMixin):
if points_valid:
d["num_points_total"] = num_points
# Perform bluesky-style configuration
if len(d) > 0:
# Configure new run (will restart the stdDAQ)
@@ -97,7 +101,9 @@ class StdDaqMixin(CustomDeviceMixin):
sleep(0.5)
# Try to start a new run (reconnects)
self.parent.bluestage()
if std_daq_params.get("reconnect",True):
self.parent.bluestage()
# And start status monitoring
self._mon = Thread(target=self.monitor, daemon=True)
self._mon.start()
@@ -159,6 +165,7 @@ class StdDaqClient(PSIDeviceBase):
"state",
"bluestage",
"blueunstage",
"complete",
]
_wsclient = None
@@ -277,6 +284,8 @@ class StdDaqClient(PSIDeviceBase):
images (limited by the ringbuffer size and backend speed).
file_path: str, optional
File path to save the data, usually GPFS.
file_prefix: str, optional
File prefix to save the data [default = file].
image_width : int, optional
ROI size in the x-direction [pixels].
image_height : int, optional
@@ -299,6 +308,10 @@ class StdDaqClient(PSIDeviceBase):
# Run parameters
if "num_points_total" in d:
self.num_images.set(d["num_points_total"]).wait()
if "file_path" in d:
self.file_path.set(d["file_path"]).wait()
if "file_prefix" in d:
self.file_prefix.set(d["file_prefix"]).wait()
# Restart the DAQ if resolution changed
cfg = self.get_daq_config()
@@ -322,6 +335,15 @@ class StdDaqClient(PSIDeviceBase):
sleep(1)
self.get_daq_config(update=True)
# def configure(self, d:dict):
# if "num_points_total" in d:
# num_points = d.pop("num_points_total")
# self.num_images.set(num_points).wait()
# super().configure(d)
# self.set_daq_config()
# sleep(1)
# self.get_daq_config(update=True)
def bluestage(self):
"""Stages the stdDAQ
@@ -351,6 +373,7 @@ class StdDaqClient(PSIDeviceBase):
file_path = self.file_path.get()
num_images = self.num_images.get()
file_prefix = self.name
file_prefix = self.file_prefix.get()
print(file_prefix)
@@ -427,12 +450,18 @@ class StdDaqClient(PSIDeviceBase):
def complete(self) -> SubscriptionStatus:
"""Wait for current run. Must end in status 'file_saved'."""
# Return immediately if we're detached
# TODO: Maybe check for connection (not sure if it's better)
if self.state() in ["idle", "file_saved", "error"]:
status = Status(self)
status.set_finished()
return status
def is_running(*args, value, timestamp, **kwargs):
result = value in ["idle", "file_saved", "error"]
return result
status = SubscriptionStatus(self.runstatus, is_running, settle_time=0.5)
# status.set_finished()
return status
def get_daq_config(self, update=False) -> dict:

View File

@@ -4,6 +4,11 @@ import numpy as np
from bec_lib.device import DeviceBase
from bec_server.scan_server.scans import Acquire, AsyncFlyScanBase
from bec_lib import bec_logger
logger = bec_logger.logger
class AcquireDark(Acquire):
scan_name = "acquire_dark"
required_kwargs = ["exp_burst"]
@@ -295,6 +300,7 @@ class AcquireRefs(Acquire):
self.num_flats = num_flats
self.file_prefix_dark = file_prefix_dark
self.file_prefix_white = file_prefix_white
self.scan_parameters["std_daq_params"] = {"reconnect": False}
def scan_core(self):
@@ -308,11 +314,16 @@ class AcquireRefs(Acquire):
)
# to set signals on a device
yield from self.stubs.send_rpc_and_wait("gfdaq", "file_prefix.set", self.file_prefix_dark)
# yield from self.stubs.send_rpc_and_wait("gfdaq", "num_images.set", self.num_darks)
cameras = [cam.name for cam in self.device_manager.devices.get_devices_with_tags("camera") if cam.enabled]
for cam in cameras:
yield from self.stubs.send_rpc_and_wait(cam, "file_prefix.set", f"{self.file_prefix}_{cam}_dark")
yield from self.stubs.send_rpc_and_wait(cam, "num_images.set", self.num_darks)
yield from self.stubs.send_rpc_and_wait(cam, "bluestage") # rename to arm
darks = AcquireDark(
exp_burst=self.num_darks,
# file_prefix=self.file_prefix_dark,
device_manager=self.device_manager,
metadata=self.metadata,
instruction_handler=self.stubs._instruction_handler,
@@ -320,33 +331,52 @@ class AcquireRefs(Acquire):
)
yield from darks.scan_core()
yield from self.stubs.send_rpc_and_wait("gfdaq", "complete")
yield from self.stubs.send_rpc_and_wait("gfdaq", "unstage")
self.point_id = darks.point_id
status_sample_out_angle.wait()
# if self.num_flats:
# self.connector.send_client_info(
# f"Acquiring {self.num_flats} flat field images",
# show_asap=True,
# rid=self.metadata.get("RID"),
# )
# yield from self.stubs.send_rpc_and_wait("gfdaq", "file_prefix.set", self.file_prefix_white)
# yield from self.stubs.send_rpc_and_wait("gfdaq", "num_images.set", self.num_flats)
if self.num_flats:
self.connector.send_client_info(
f"Acquiring {self.num_flats} flat field images",
show_asap=True,
rid=self.metadata.get("RID"),
)
yield from self.stubs.send_rpc_and_wait("gfdaq", "file_prefix.set", self.file_prefix_white)
yield from self.stubs.send_rpc_and_wait("gfdaq", "num_images.set", self.num_flats)
yield from self.stubs.send_rpc_and_wait("gfdaq", "bluestage")
# flats = AcquireWhite(
# exp_burst=self.num_flats,
# #sample_position_out=self.sample_position_out,
# #sample_angle_out=self.sample_angle_out,
# #motor=self.motor,
# device_manager=self.device_manager,
# metadata=self.metadata,
# instruction_handler=self.stubs._instruction_handler,
# **self.caller_kwargs,
# )
# flats.point_id = self.point_id
# yield from flats.scan_core()
# self.point_id = flats.point_id
# ## TODO move sample in beam and do not wait
# ## TODO move rotation to angle and do not wait
logger.warning("Calling AcquireWhite")
flats = AcquireWhite(
exp_burst=self.num_flats,
#sample_position_out=self.sample_position_out,
#sample_angle_out=self.sample_angle_out,
#motor=self.motor,
device_manager=self.device_manager,
metadata=self.metadata,
instruction_handler=self.stubs._instruction_handler,
**self.caller_kwargs,
)
flats.point_id = self.point_id
yield from flats.scan_core()
logger.warning("Unstaging the DAQ")
yield from self.stubs.send_rpc_and_wait("gfdaq", "complete")
yield from self.stubs.send_rpc_and_wait("gfdaq", "unstage")
logger.warning("Completing the DAQ")
logger.warning("Finished the DAQ")
self.point_id = flats.point_id
## TODO move sample in beam and do not wait
## TODO move rotation to angle and do not wait
logger.warning("Done with scan_core")
class TutorialFlyScanContLine(AsyncFlyScanBase):

View File

@@ -546,4 +546,20 @@ class Measurement:
exp_time=self.exposure_time, exp_period=self.exposure_period, image_width=self.roix,
image_height=self.roiy, acq_mode='default', file_path=self.file_path, nr_writers=2, base_path=self.base_path,
file_prefix_dark=file_prefix_dark, file_prefix_white=file_prefix_white,
ddc_trigger=4, ddc_source0=1, **kwargs)
ddc_trigger=4, ddc_source0=1, **kwargs)
def start_preview(self, exposure_time=None, exposure_period=None,
preview_strategy='', preview_paramters=200, **kwargs):
"""
Start the camera in preview mode, no data will be written.
Parameters
----------
exposure_time : float, optional
"""
if exposure_time is None:
exposure_time = self.exposure_time
if exposure_period is None:
exposure_period = 50 # no need to go faster for a preview