DAQ: Add spreadsheetupdater.py

This commit is contained in:
2025-06-25 11:26:10 +02:00
parent 1c2a08ac16
commit 2efaa4dd88
2 changed files with 90 additions and 71 deletions
+72 -71
View File
@@ -125,10 +125,6 @@ class BeamlineConfig:
self.__client.set(f"{self.__bl}:active_session", session)
self.__client.expire(f"{self.__bl}:active_session", expiry_sec)
@property
def tell_mount_count(self) -> int:
return int(self.__client.incr(f"{self.__bl}:tell_mount_count"))
@property
def pgroup(self) -> str | None:
tmp = self.__client.get(f"{self.__bl}:pgroup")
@@ -141,6 +137,70 @@ class BeamlineConfig:
else:
self.__client.set(f"{self.__bl}:pgroup", pgroup)
# Beamline state management
# Atomic check if beamline is busy and if not set state to busy
def try_set_busy(self, timeout: int | None = None):
with redis_lock.Lock(self.__client, f"{self.__bl}:move_state_lock", expire=10):
if self.state_busy:
raise BeamlineBusyException("Beamline is busy")
self.state_busy = True
if timeout is not None:
self.__client.expire(f"{self.__bl}:busy", timeout)
def set_busy(self, target: BeamlineStateEnum, timeout: int | None = None):
self.try_set_busy(timeout=timeout)
curr_state = self.state
if curr_state != target:
self.state_busy = False
raise Exception("Beamline is not in a proper state")
def start_moving(
self, target: BeamlineStateEnum, timeout: int | None = None
) -> BeamlineStateEnum:
self.try_set_busy(timeout=timeout)
curr_state = self.state
if target == curr_state:
self.state_busy = False
else:
self.state = BeamlineStateEnum.Moving
return curr_state
@property
def state(self) -> BeamlineStateEnum:
raw_value = self.__client.get(f"{self.__bl}:state")
if raw_value is None:
return BeamlineStateEnum.Maintenance
try:
int_value = int(raw_value) # Ensure it's an integer
return BeamlineStateEnum(int_value) # Convert to BeamlineStateEnum
except (ValueError, KeyError):
raise ValueError(
f"Invalid 'mx_state' value: {raw_value}. Expected integer corresponding to a BeamlineStateEnum."
)
@state.setter
def state(self, state: BeamlineStateEnum):
self.__client.set(f"{self.__bl}:state", state.value)
@property
def state_busy(self) -> bool:
return self.__client.get(f"{self.__bl}:busy") is not None
@state_busy.setter
def state_busy(self, i: bool):
if i:
self.__client.set(f"{self.__bl}:busy", "1")
else:
self.__client.delete(f"{self.__bl}:busy")
# Other beamline settings
@property
def tell_mount_count(self) -> int:
return int(self.__client.incr(f"{self.__bl}:tell_mount_count"))
def pixel_to_mm(self, zoom: float) -> float:
cfg = self.settings
return 1.0 / (
@@ -162,7 +222,6 @@ class BeamlineConfig:
val_y = 0
return val_x, val_y
@beam_center.setter
def beam_center(self, data: Tuple[float, float]):
self.__client.set(f"{self.__bl}:beam_center_x", data[0])
@@ -214,38 +273,9 @@ class BeamlineConfig:
def put_alc_bkg(self, zoom: float, data: np.ndarray):
self.__client.set(f"{self.__bl}:bkg{zoom:.1f}", numpy_to_base64(data))
@property
def state(self) -> BeamlineStateEnum:
raw_value = self.__client.get(f"{self.__bl}:state")
if raw_value is None:
return BeamlineStateEnum.Maintenance
try:
int_value = int(raw_value) # Ensure it's an integer
return BeamlineStateEnum(int_value) # Convert to BeamlineStateEnum
except (ValueError, KeyError):
raise ValueError(
f"Invalid 'mx_state' value: {raw_value}. Expected integer corresponding to a BeamlineStateEnum."
)
@state.setter
def state(self, state: BeamlineStateEnum):
self.__client.set(f"{self.__bl}:state", state.value)
@property
def state_busy(self) -> bool:
return self.__client.get(f"{self.__bl}:busy") is not None
@state_busy.setter
def state_busy(self, i: bool):
if i:
self.__client.set(f"{self.__bl}:busy", "1")
else:
self.__client.delete(f"{self.__bl}:busy")
@property
def spreadsheet(self) -> SampleShortInfoList:
tmp = self.__client.get(f"{self.__bl}:spreadsheet")
tmp = self.__client.get(f"{self.__bl}:sample_spreadsheet")
if tmp is None:
return SampleShortInfoList(s=[])
@@ -259,7 +289,13 @@ class BeamlineConfig:
@spreadsheet.setter
def spreadsheet(self, data: SampleShortInfoList):
self.__client.set(f"{self.__bl}:spreadsheet", data.model_dump_json())
self.__client.set(f"{self.__bl}:sample_spreadsheet", data.model_dump_json())
def listen_changes_spreadsheet(self) -> redis.client.PubSub:
self.__client.config_set("notify-keyspace-events", "KEA")
pubsub = self.__client.pubsub()
pubsub.psubscribe(f"__keyspace@0__:{self.__bl}:sample_spreadsheet")
return pubsub
@property
def current_sample(self) -> SampleShortInfo | None:
@@ -316,7 +352,6 @@ class BeamlineConfig:
def abr_meas_pos(self, data: Coordinate):
self.__client.set(f"{self.__bl}:abr_meas_pos", data.model_dump_json())
@property
def dtz(self) -> float | None:
tmp = self.__client.get(f"{self.__bl}:dtz")
@@ -328,39 +363,6 @@ class BeamlineConfig:
def dtz(self, dtz: float):
self.__client.set(f"{self.__bl}:dtz", dtz)
def listen_changes(self) -> redis.client.PubSub:
self.__client.config_set("notify-keyspace-events", "KEA")
pubsub = self.__client.pubsub()
pubsub.psubscribe(f"__keyspace@0__:{self.__bl}:*")
return pubsub
# Atomic check if beamline is busy and if not set state to busy
def try_set_busy(self, timeout: int | None = None):
with redis_lock.Lock(self.__client, f"{self.__bl}:move_state_lock", expire=10):
if self.state_busy:
raise BeamlineBusyException("Beamline is busy")
self.state_busy = True
if timeout is not None:
self.__client.expire(f"{self.__bl}:busy", timeout)
def set_busy(self, target: BeamlineStateEnum, timeout: int | None = None):
self.try_set_busy(timeout=timeout)
curr_state = self.state
if curr_state != target:
self.state_busy = False
raise Exception("Beamline is not in a proper state")
def start_moving(
self, target: BeamlineStateEnum, timeout: int | None = None
) -> BeamlineStateEnum:
self.try_set_busy(timeout=timeout)
curr_state = self.state
if target == curr_state:
self.state_busy = False
else:
self.state = BeamlineStateEnum.Moving
return curr_state
def clear_mark_beam(self):
self.__client.delete(f"{self.__bl}:beam_mark")
@@ -391,4 +393,3 @@ class BeamlineConfig:
x_pxl = np.polyval(model.coeff_x, zoom)
y_pxl = np.polyval(model.coeff_y, zoom)
return float(x_pxl), float(y_pxl)
+18
View File
@@ -0,0 +1,18 @@
import time
from aaredaqlib.beamline import MXBeamline
from config import BeamlineConfig
from aaredaq.aaredb import AareWrapper
config = BeamlineConfig(MXBeamline.X06DA)
aaredb = AareWrapper(MXBeamline.X06DA)
while True:
try:
samples = aaredb.get_sample_info()
config.spreadsheet = samples
except Exception as e:
print(f"Error in spreadsheet updater: {e}")
time.sleep(10)