Found out stdDAQ filename problem
This commit is contained in:
@@ -102,7 +102,7 @@ es1_psod:
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: monitored
|
||||
softwareTrigger: true
|
||||
softwareTrigger: false
|
||||
|
||||
|
||||
es1_ddaq:
|
||||
@@ -133,22 +133,22 @@ es1_ddaq:
|
||||
# softwareTrigger: true
|
||||
|
||||
|
||||
gfcam:
|
||||
description: GigaFrost camera client
|
||||
deviceClass: tomcat_bec.devices.GigaFrostCamera
|
||||
deviceConfig:
|
||||
prefix: 'X02DA-CAM-GF2:'
|
||||
backend_url: 'http://sls-daq-001:8080'
|
||||
auto_soft_enable: true
|
||||
deviceTags:
|
||||
- camera
|
||||
- trigger
|
||||
- gfcam
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: monitored
|
||||
softwareTrigger: true
|
||||
# gfcam:
|
||||
# description: GigaFrost camera client
|
||||
# deviceClass: tomcat_bec.devices.GigaFrostCamera
|
||||
# deviceConfig:
|
||||
# prefix: 'X02DA-CAM-GF2:'
|
||||
# backend_url: 'http://sls-daq-001:8080'
|
||||
# auto_soft_enable: true
|
||||
# deviceTags:
|
||||
# - camera
|
||||
# - trigger
|
||||
# - gfcam
|
||||
# enabled: true
|
||||
# onFailure: buffer
|
||||
# readOnly: false
|
||||
# readoutPriority: monitored
|
||||
# softwareTrigger: true
|
||||
|
||||
|
||||
# gfcam:
|
||||
@@ -202,30 +202,11 @@ gfcam:
|
||||
# softwareTrigger: false
|
||||
|
||||
|
||||
pcocam:
|
||||
description: PCO.edge camera client
|
||||
deviceClass: tomcat_bec.devices.PcoEdge5M
|
||||
deviceConfig:
|
||||
prefix: 'X02DA-CCDCAM2:'
|
||||
deviceTags:
|
||||
- camera
|
||||
- trigger
|
||||
- pcocam
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: monitored
|
||||
softwareTrigger: true
|
||||
|
||||
|
||||
# pcocam:
|
||||
# description: PCO.edge camera client
|
||||
# deviceClass: tomcat_bec.devices.PcoEdge5M
|
||||
# deviceConfig:
|
||||
# prefix: 'X02DA-CCDCAM2:'
|
||||
# std_daq_live: 'tcp://129.129.95.111:20010'
|
||||
# std_daq_ws: 'ws://129.129.95.111:8081'
|
||||
# std_daq_rest: 'http://129.129.95.111:5010'
|
||||
# deviceTags:
|
||||
# - camera
|
||||
# - trigger
|
||||
@@ -236,6 +217,25 @@ pcocam:
|
||||
# readoutPriority: monitored
|
||||
# softwareTrigger: true
|
||||
|
||||
|
||||
pcocam:
|
||||
description: PCO.edge camera client
|
||||
deviceClass: tomcat_bec.devices.PcoEdge5M
|
||||
deviceConfig:
|
||||
prefix: 'X02DA-CCDCAM2:'
|
||||
std_daq_live: 'tcp://129.129.95.111:20010'
|
||||
std_daq_ws: 'ws://129.129.95.111:8081'
|
||||
std_daq_rest: 'http://129.129.95.111:5010'
|
||||
deviceTags:
|
||||
- camera
|
||||
- trigger
|
||||
- pcocam
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: monitored
|
||||
softwareTrigger: true
|
||||
|
||||
# pcodaq:
|
||||
# description: GigaFrost stdDAQ client
|
||||
# deviceClass: tomcat_bec.devices.StdDaqClient
|
||||
|
||||
@@ -199,7 +199,7 @@ class GigaFrostCamera(PSIDeviceBase, GigaFrostBase):
|
||||
supplied signal. Use external enable instead, that works!
|
||||
"""
|
||||
|
||||
if acq_mode == "default":
|
||||
if acq_mode in ["default", "step"]:
|
||||
# NOTE: Software trigger via softEnable (actually works)
|
||||
# Trigger parameters
|
||||
self.fix_nframes_mode = "start"
|
||||
@@ -630,14 +630,11 @@ class GigaFrostCamera(PSIDeviceBase, GigaFrostBase):
|
||||
and self.trigger_mode == "auto"
|
||||
and self.enable_mode == "soft"
|
||||
):
|
||||
t_start = time()
|
||||
# BEC teststand operation mode: posedge of SoftEnable if Started
|
||||
self.soft_enable.set(0).wait()
|
||||
self.soft_enable.set(1).wait()
|
||||
|
||||
logger.info(f"Elapsed: {time()-t_start}")
|
||||
|
||||
if self.acquire_block.get():
|
||||
if self.acquire_block.get() or self.backend is None:
|
||||
wait_time = 0.2 + 0.001 * self.num_exposures.value * max(
|
||||
self.acquire_time.value, self.acquire_period.value
|
||||
)
|
||||
|
||||
@@ -59,7 +59,6 @@ class PcoEdge5M(PSIDeviceBase, PcoEdgeBase):
|
||||
USER_ACCESS = [
|
||||
"complete",
|
||||
"backend",
|
||||
# "acq_done",
|
||||
"live_preview",
|
||||
"arm",
|
||||
"disarm",
|
||||
@@ -125,6 +124,8 @@ class PcoEdge5M(PSIDeviceBase, PcoEdgeBase):
|
||||
*'FIFO buffer' for continous streaming
|
||||
data_format : str
|
||||
Usually set to 'ZEROMQ'
|
||||
acq_mode : str
|
||||
Store mode and data format according to preconfigured settings
|
||||
"""
|
||||
if self.state not in ("IDLE"):
|
||||
raise RuntimeError(f"Can't change configuration from state {self.state}")
|
||||
@@ -149,6 +150,10 @@ class PcoEdge5M(PSIDeviceBase, PcoEdgeBase):
|
||||
if "data_format" in d:
|
||||
self.file_format.set(d["data_format"]).wait()
|
||||
|
||||
# If a pre-configured acquisition mode is specified, set it
|
||||
if "acq_mode" in d:
|
||||
self.set_acquisition_mode(d["acq_mode"])
|
||||
|
||||
# State machine
|
||||
# Initial: BUSY and SET both low
|
||||
# 0. Write 1 to SET_PARAM
|
||||
@@ -165,6 +170,19 @@ class PcoEdge5M(PSIDeviceBase, PcoEdgeBase):
|
||||
self.set_param.set(1).wait()
|
||||
status.wait()
|
||||
|
||||
def set_acquisition_mode(self, acq_mode):
|
||||
"""Set acquisition mode
|
||||
|
||||
Utility function to quickly select between pre-configured and tested
|
||||
acquisition modes.
|
||||
"""
|
||||
if acq_mode in ["default", "step"]:
|
||||
# NOTE: Trigger duration requires a consumer
|
||||
self.bufferStoreMode.set("Recorder").wait()
|
||||
# self.file_format.set("ZEROMQ").wait()
|
||||
else:
|
||||
raise RuntimeError(f"Unsupported acquisition mode: {acq_mode}")
|
||||
|
||||
def arm(self):
|
||||
"""Bluesky style stage: arm the detector"""
|
||||
logger.warning("Staging PCO")
|
||||
@@ -206,6 +224,7 @@ class PcoEdge5M(PSIDeviceBase, PcoEdgeBase):
|
||||
|
||||
def _on_preview_update(self, img: np.ndarray, header: dict):
|
||||
"""Send preview stream and update frame index counter"""
|
||||
# FIXME: There's also a recorded images counter provided by the stdDAQ writer
|
||||
self.num_images_counter.put(header["frame"], force=True)
|
||||
self._run_subs(sub_type=self.SUB_DEVICE_MONITOR_2D, obj=self, value=img)
|
||||
|
||||
@@ -251,8 +270,6 @@ class PcoEdge5M(PSIDeviceBase, PcoEdgeBase):
|
||||
}
|
||||
|
||||
d = {}
|
||||
if "exp_burst" in scan_args and scan_args["exp_burst"] is not None:
|
||||
d["exposure_num_burst"] = scan_args["exp_burst"]
|
||||
if "image_width" in scan_args and scan_args["image_width"] is not None:
|
||||
d["image_width"] = scan_args["image_width"]
|
||||
if "image_height" in scan_args and scan_args["image_height"] is not None:
|
||||
@@ -261,10 +278,16 @@ class PcoEdge5M(PSIDeviceBase, PcoEdgeBase):
|
||||
d["exposure_time_ms"] = scan_args["exp_time"]
|
||||
if "exp_period" in scan_args and scan_args["exp_period"] is not None:
|
||||
d["exposure_period_ms"] = scan_args["exp_period"]
|
||||
# if 'exp_burst' in scan_args and scan_args['exp_burst'] is not None:
|
||||
# d['exposure_num_burst'] = scan_args['exp_burst']
|
||||
# if 'acq_mode' in scan_args and scan_args['acq_mode'] is not None:
|
||||
# d['acq_mode'] = scan_args['acq_mode']
|
||||
if 'exp_burst' in scan_args and scan_args['exp_burst'] is not None:
|
||||
d['exposure_num_burst'] = scan_args['exp_burst']
|
||||
if "acq_time" in scan_args and scan_args["acq_time"] is not None:
|
||||
d["exposure_time_ms"] = scan_args["acq_time"]
|
||||
if "acq_period" in scan_args and scan_args["acq_period"] is not None:
|
||||
d["exposure_period_ms"] = scan_args["acq_period"]
|
||||
if 'acq_burst' in scan_args and scan_args['acq_burst'] is not None:
|
||||
d['exposure_num_burst'] = scan_args['acq_burst']
|
||||
if 'acq_mode' in scan_args and scan_args['acq_mode'] is not None:
|
||||
d['acq_mode'] = scan_args['acq_mode']
|
||||
# elif self.scaninfo.scan_type == "step":
|
||||
# d['acq_mode'] = "default"
|
||||
if "pco_store_mode" in scan_args and scan_args["pco_store_mode"] is not None:
|
||||
@@ -305,6 +328,7 @@ class PcoEdge5M(PSIDeviceBase, PcoEdgeBase):
|
||||
|
||||
def on_pre_scan(self) -> DeviceStatus | None:
|
||||
"""Called right before the scan starts on all devices automatically."""
|
||||
logger.warning("Called op_prescan on PCO camera")
|
||||
# First start the stdDAQ
|
||||
if self.backend is not None:
|
||||
self.backend.start(
|
||||
@@ -371,8 +395,7 @@ class PcoEdge5M(PSIDeviceBase, PcoEdgeBase):
|
||||
|
||||
def on_complete(self) -> DeviceStatus | None:
|
||||
"""Called to inquire if a device has completed a scans."""
|
||||
# return self.acq_done()
|
||||
return None
|
||||
return self.acq_done()
|
||||
|
||||
def on_kickoff(self) -> DeviceStatus | None:
|
||||
"""Start data transfer
|
||||
|
||||
@@ -48,9 +48,10 @@ class StdDaqStatus(str, enum.Enum):
|
||||
|
||||
class StdDaqClient:
|
||||
|
||||
USER_ACCESS = ["status", "start", "stop", "get_config", "set_config", "reset", "_status"]
|
||||
USER_ACCESS = ["status", "count", "start", "stop", "get_config", "set_config", "reset", "_status"]
|
||||
|
||||
_ws_client: ws.ClientConnection | None = None
|
||||
_count: int = 0
|
||||
_status: StdDaqStatus = StdDaqStatus.UNDEFINED
|
||||
_status_timestamp: float | None = None
|
||||
_ws_recv_mutex = threading.Lock()
|
||||
@@ -81,6 +82,11 @@ class StdDaqClient:
|
||||
"""
|
||||
return self._status
|
||||
|
||||
@property
|
||||
def count(self) -> int:
|
||||
""" Get the recorded frame count"""
|
||||
return self._count
|
||||
|
||||
def add_status_callback(
|
||||
self, status: DeviceStatus, success: list[StdDaqStatus], error: list[StdDaqStatus]
|
||||
):
|
||||
@@ -113,15 +119,17 @@ class StdDaqClient:
|
||||
# Ensure connection
|
||||
self.wait_for_connection()
|
||||
|
||||
logger.info(f"Starting StdDaq backend. Current status: {self.status}")
|
||||
status = StatusBase()
|
||||
self.add_status_callback(status, success=["waiting_for_first_image"], error=["rejected"])
|
||||
# NOTE: CREATING_FILE --> IDLE is a known error, the exact cause is unknown, nut might be botched overwrite protection
|
||||
# Changing file_prefix often solves the problem, but still allows overwrites
|
||||
self.add_status_callback(status, success=["waiting_for_first_image"], error=["rejected", "idle"])
|
||||
message = {
|
||||
"command": "start",
|
||||
"path": file_path,
|
||||
"file_prefix": file_prefix,
|
||||
"n_image": num_images,
|
||||
}
|
||||
logger.info(f"Starting StdDaq backend. Current status: {self.status}. Message: {message}")
|
||||
self._ws_client.send(json.dumps(message))
|
||||
if wait:
|
||||
status.wait(timeout=timeout)
|
||||
@@ -327,7 +335,10 @@ class StdDaqClient:
|
||||
continue
|
||||
msg = json.loads(msg)
|
||||
if self._status != msg["status"]:
|
||||
logger.info(f"stdDAQ state transition by: {msg}")
|
||||
logger.warning(f"stdDAQ state transition: {self._status} --> {msg}")
|
||||
if msg["status"] == "recording":
|
||||
self._count = msg.get("count", 0)
|
||||
# Update status and run callbacks
|
||||
self._status = msg["status"]
|
||||
self._status_timestamp = msg_timestamp
|
||||
self._run_status_callbacks()
|
||||
|
||||
0
tomcat_bec/scans/simple_scans.py
Normal file
0
tomcat_bec/scans/simple_scans.py
Normal file
Reference in New Issue
Block a user