csaxs master class added and init smar positions

This commit is contained in:
x01dc
2026-01-15 10:17:56 +01:00
committed by x12sa
parent bfe84c4eff
commit f38c94490a
4 changed files with 340 additions and 114 deletions
@@ -0,0 +1,40 @@
# import builtins
# import datetime
# import os
# import subprocess
# import time
# from pathlib import Path
# import numpy as np
from bec_lib import bec_logger
# from bec_lib.alarm_handler import AlarmBase
# from bec_lib.pdf_writer import PDFWriter
from typeguard import typechecked
from csaxs_bec.bec_ipython_client.plugins.cSAXS.smaract import cSAXSInitSmaractStages
from csaxs_bec.bec_ipython_client.plugins.cSAXS.smaract import cSAXSSmaract
from csaxs_bec.bec_ipython_client.plugins.omny.omny_general_tools import OMNYTools
class cSAXSError(Exception):
pass
class cSAXS(
cSAXSInitSmaractStages,
cSAXSSmaract,
):
def __init__(self, client):
super().__init__(client)
self.client = client
self.device_manager = client.device_manager
self.OMNYTools = OMNYTools(self.client)
# this is the csaxs master file that imports all routines from csaxs
# can be imported in the bec client by
#
# from csaxs_bec.bec_ipython_client.plugins.cSAXS.cSAXS import cSAXS
# csaxs = cSAXS(bec)
#
# then all commands can be accessed by for example
# csaxs._cSAXS_smaract_stages_.....
@@ -1,114 +0,0 @@
import builtins
import time
from pathlib import Path
from bec_lib import bec_logger
# Logger initialization
logger = bec_logger.logger
if builtins.__dict__.get("bec") is not None:
bec = builtins.__dict__.get("bec")
dev = builtins.__dict__.get("dev")
umv = builtins.__dict__.get("umv")
umvr = builtins.__dict__.get("umvr")
class cSAXSInitError(Exception):
pass
class cSAXSError(Exception):
pass
class cSAXSInitStagesMixin:
# Class-level mappings for axes and devices
AXIS_MAP = {c: i for i, c in enumerate("ABCDEFGHIJKLMNOPQRSTUVWXYZ")}
devices = {
"xbpm3x": "A",
"xbpm3y": "B",
"sl3trxi": "C",
"sl3trxo": "D",
"sl3trxb": "E",
"sl3trxt": "F",
"fast_shutter_n1_x": "H",
"fast_shutter_o1_x": "G",
"fast_shutter_o2_x": "F",
"filter_array_1_x": "B",
"filter_array_2_x": "C",
"filter_array_3_x": "D",
"filter_array_4_x": "E",
"sl4trxi": "G",
"sl4trxo": "H",
"sl4trxb": "I",
"sl4trxt": "A",
"sl5trxi": "C",
"sl5trxo": "D",
"sl5trxb": "E",
"sl5trxt": "F",
"xbimtrx": "A",
"xbimtry": "B",
}
def __init__(self):
"""
Initializes the class. No need to pass 'dev' since it's globally available.
"""
pass # No need for 'dev' parameter anymore
def _cSAXS_smaract_stages_init(self):
"""
Initialize all Smaract stages by setting speed, finding the reference mark, and sleeping.
"""
for dev_name, axis_letter in self.devices.items():
ch = self.AXIS_MAP[axis_letter] # Get the channel number for the axis
d = getattr(dev, dev_name) # Access the device instance using `getattr`
try:
# Set the speed (this is an example, adjust as needed)
print(f"Setting speed for {dev_name} (axis {ch})...")
d.controller.set_closed_loop_move_speed(ch, 1) # Example speed value (1)
# Find the reference mark for the axis
print(f"Finding reference mark for {dev_name} (axis {ch})...")
d.controller.find_reference_mark(ch, 0, 1000, 1) # Example reference find parameters
# Sleep after the operation
print(f"Sleeping for 0.1s after initializing {dev_name} (axis {ch})...")
time.sleep(0.1)
except AttributeError:
print(f"Device {dev_name} does not have a controller or method to initialize.")
except Exception as e:
print(f"Error initializing device {dev_name} (axis {ch}): {e}")
def _cSAXS_smaract_stages_check_all_referenced(self):
"""
Check if all axes of the devices are referenced.
"""
for dev_name, axis_letter in self.devices.items():
ch = self.AXIS_MAP[axis_letter] # Get the channel number for the axis
d = getattr(dev, dev_name) # Access the device instance using `getattr`
try:
# Check if the axis is referenced on the device controller
if not d.controller.axis_is_referenced(ch):
print(f"Device {dev_name} (axis {ch}) is NOT referenced.")
else:
print(f"Device {dev_name} (axis {ch}) is referenced.")
except AttributeError:
print(f"Device {dev_name} does not have a controller or axis_is_referenced method.")
except Exception as e:
print(f"Error checking device {dev_name} (axis {ch}): {e}")
# Usage example:
# Assuming `dev` is a globally available device manager containing all the device instances
# Create an instance of the mixin class
#cSAXS_init = cSAXSInitStagesMixin()
# To initialize all stages:
#cSAXS_init._cSAXS_smaract_stages_init()
# To check if all axes are referenced:
#cSAXS_init._cSAXS_smaract_stages_check_all_referenced()
@@ -0,0 +1,253 @@
import builtins
import time
#from pathlib import Path
from bec_lib import bec_logger
# Logger initialization
logger = bec_logger.logger
if builtins.__dict__.get("bec") is not None:
bec = builtins.__dict__.get("bec")
dev = builtins.__dict__.get("dev")
umv = builtins.__dict__.get("umv")
umvr = builtins.__dict__.get("umvr")
class cSAXSInitSmaractStagesError(Exception):
pass
class cSAXSInitSmaractStages:
# Class-level mappings for axes and devices
AXIS_MAP = {c: i for i, c in enumerate("ABCDEFGHIJKLMNOPQRSTUVWXYZ")}
devices = {
"xbpm3x": "A",
"xbpm3y": "B",
"sl3trxi": "C",
"sl3trxo": "D",
"sl3trxb": "E",
"sl3trxt": "F",
"fast_shutter_n1_x": "H",
"fast_shutter_o1_x": "G",
"fast_shutter_o2_x": "F",
"filter_array_1_x": "B",
"filter_array_2_x": "C",
"filter_array_3_x": "D",
"filter_array_4_x": "E",
"sl4trxi": "G",
"sl4trxo": "H",
"sl4trxb": "I",
"sl4trxt": "A",
"sl5trxi": "C",
"sl5trxo": "D",
"sl5trxb": "E",
"sl5trxt": "F",
"xbimtrx": "A",
"xbimtry": "B",
}
def __init__(self, client) -> None:
self.client = client
def smaract_initialize_all_stages(self):
"""
Initialize all Smaract stages by setting speed, finding the reference mark, and sleeping.
"""
for dev_name, axis_letter in self.devices.items():
ch = self.AXIS_MAP[axis_letter] # Get the channel number for the axis
d = getattr(dev, dev_name) # Access the device instance using `getattr`
try:
# Set the speed (this is an example, adjust as needed)
print(f"Setting speed for {dev_name} (axis {ch})...")
d.controller.set_closed_loop_move_speed(ch, 1) # Example speed value (1)
# Find the reference mark for the axis
print(f"Finding reference mark for {dev_name} (axis {ch})...")
d.controller.find_reference_mark(ch, 0, 1000, 1) # Example reference find parameters
# Sleep after the operation
print(f"Sleeping for 0.1s after initializing {dev_name} (axis {ch})...")
time.sleep(0.1)
except AttributeError:
print(f"Device {dev_name} does not have a controller or method to initialize.")
except Exception as e:
print(f"Error initializing device {dev_name} (axis {ch}): {e}")
self.smaract_all_components_to_initial_position()
def smaract_check_all_referenced(self):
"""
Check if all axes of the devices are referenced.
"""
for dev_name, axis_letter in self.devices.items():
ch = self.AXIS_MAP[axis_letter] # Get the channel number for the axis
d = getattr(dev, dev_name) # Access the device instance using `getattr`
try:
# Check if the axis is referenced on the device controller
if not d.controller.axis_is_referenced(ch):
print(f"Device {dev_name} (axis {ch}) is NOT referenced.")
else:
print(f"Device {dev_name} (axis {ch}) is referenced.")
except AttributeError:
print(f"Device {dev_name} does not have a controller or axis_is_referenced method.")
except Exception as e:
print(f"Error checking device {dev_name} (axis {ch}): {e}")
def smaract_all_components_to_initial_position(
self,
skip_devices=None,
):
"""
Move all SmarAct-based components to their configured init_position.
Parameters
----------
skip_devices : iterable of str, optional
Device names to skip (e.g. ["fast_shutter_n1_x"]).
"""
skip_devices = set(skip_devices or [])
# First confirmation: intent
if not self.OMNYTools.yesno(
"Do you want to move all SmarAct-based components to their "
"configured initial position?",
"y",
):
return
planned_moves = []
not_referenced = []
missing_params = []
# --- Pre-check phase ---
for dev_name, axis_letter in self.devices.items():
if dev_name in skip_devices:
bec_logger.logger.info(
f"[cSAXS] Skipping device {dev_name} (user request)."
)
continue
try:
d = getattr(dev, dev_name)
ch = self.AXIS_MAP[axis_letter]
# Reference check
if not d.controller.axis_is_referenced(ch):
not_referenced.append(dev_name)
continue
# Fetch init_position
init_pos = self.OMNYTools._get_user_param_safe(
dev_name,
"init_position",
)
if init_pos is None:
missing_params.append(dev_name)
continue
planned_moves.append((dev_name, init_pos))
except AttributeError:
bec_logger.logger.warning(
f"[cSAXS] Device {dev_name} not accessible, skipping."
)
except Exception as exc:
bec_logger.logger.error(
f"[cSAXS] Error during pre-check for {dev_name}: {exc}"
)
# --- Hard stop conditions ---
if not_referenced:
bec_logger.logger.error(
"[cSAXS] The following devices are NOT referenced:\n"
+ ", ".join(not_referenced)
)
bec_logger.logger.error(
"[cSAXS] Aborting motion. Please reference axes first."
)
return
if not planned_moves:
bec_logger.logger.warning(
"[cSAXS] No valid initial positions found. Nothing to do."
)
return
# --- Summary table ---
print("\nPlanned SmarAct motions to initial position:")
print("-" * 60)
print(f"{'Device':<35} {'Init position':>20}")
print("-" * 60)
for dev_name, init_pos in planned_moves:
print(f"{dev_name:<35} {init_pos:>20}")
print("-" * 60)
if missing_params:
print(
"\nNote: The following devices have no init_position defined "
"and will be skipped:"
)
print(", ".join(missing_params))
if skip_devices:
print(
"\nNote: The following devices were explicitly skipped:"
)
print(", ".join(sorted(skip_devices)))
# Second confirmation: execution
if not self.OMNYTools.yesno(
"Proceed with the motions listed above?",
"y",
):
bec_logger.logger.info(
"[cSAXS] Motion to initial position aborted by user."
)
return
# --- Execution phase ---
for dev_name, init_pos in planned_moves:
try:
d = getattr(dev, dev_name)
bec_logger.logger.info(
f"[cSAXS] Moving {dev_name} to init_position = {init_pos}"
)
umv(d, init_pos)
except Exception as exc:
bec_logger.logger.error(
f"[cSAXS] Failed to move {dev_name}: {exc}"
)
bec_logger.logger.info(
"[cSAXS] SmarAct motion to initial positions completed."
)
# example usage
# csaxs.smaract_all_components_to_initial_position(
# skip_devices=[
# "fast_shutter_n1_x",
# "fast_shutter_o1_x",
# ]
# )
class cSAXSSmaract:
def __init__(self, client) -> None:
self.client = client
def fshn1in(self):
# Fetch in position
in_pos = self.OMNYTools._get_user_param_safe("fast_shutter_n1_x","in")
umv(dev.fast_shutter_n1_x,in_pos)
@@ -16,6 +16,8 @@ xbpm3x:
onFailure: buffer
readOnly: false
readoutPriority: baseline
userParameter:
init_position: -22.5
xbpm3y:
description: X-ray beam position y monitor 1 in ESbox1
@@ -34,6 +36,8 @@ xbpm3y:
onFailure: buffer
readOnly: false
readoutPriority: baseline
userParameter:
init_position: -2
sl3trxi:
description: ESbox1 slit 3 inner blade movement
@@ -52,6 +56,8 @@ sl3trxi:
onFailure: buffer
readOnly: false
readoutPriority: baseline
userParameter:
init_position: -5.5
sl3trxo:
description: ESbox1 slit 3 outer blade movement
@@ -70,6 +76,8 @@ sl3trxo:
onFailure: buffer
readOnly: false
readoutPriority: baseline
userParameter:
init_position: 6
sl3trxb:
description: ESbox1 slit 3 bottom blade movement
@@ -88,6 +96,8 @@ sl3trxb:
onFailure: buffer
readOnly: false
readoutPriority: baseline
userParameter:
init_position: -5.8
sl3trxt:
description: ESbox1 slit 3 top blade movement
@@ -106,6 +116,8 @@ sl3trxt:
onFailure: buffer
readOnly: false
readoutPriority: baseline
userParameter:
init_position: 5.5
fast_shutter_n1_x:
description: ESbox1 New fast shutter 1 x movment
@@ -124,6 +136,9 @@ fast_shutter_n1_x:
onFailure: buffer
readOnly: false
readoutPriority: baseline
userParameter:
init_position: -7
in: 0
fast_shutter_o1_x:
description: ESbox1 Old fast shutter 1 x movment
@@ -142,6 +157,8 @@ fast_shutter_o1_x:
onFailure: buffer
readOnly: false
readoutPriority: baseline
userParameter:
init_position: -15.8
fast_shutter_o2_x:
description: ESbox1 Old fast shutter 2 x movment
@@ -160,6 +177,8 @@ fast_shutter_o2_x:
onFailure: buffer
readOnly: false
readoutPriority: baseline
userParameter:
init_position: -15.5
filter_array_1_x:
description: ESbox1 Filter Array 1 x movment
@@ -178,6 +197,8 @@ filter_array_1_x:
onFailure: buffer
readOnly: false
readoutPriority: baseline
userParameter:
init_position: 25
filter_array_2_x:
description: ESbox1 Filter Array 2 x movment
@@ -196,6 +217,8 @@ filter_array_2_x:
onFailure: buffer
readOnly: false
readoutPriority: baseline
userParameter:
init_position: 25.5
filter_array_3_x:
description: ESbox1 Filter Array 3 x movment
@@ -214,6 +237,8 @@ filter_array_3_x:
onFailure: buffer
readOnly: false
readoutPriority: baseline
userParameter:
init_position: 25.8
filter_array_4_x:
description: ESbox1 Filter Array 4 x movment
@@ -232,6 +257,8 @@ filter_array_4_x:
onFailure: buffer
readOnly: false
readoutPriority: baseline
userParameter:
init_position: 25
sl4trxi:
description: ESbox1 slit 4 inner blade movement
@@ -250,6 +277,8 @@ sl4trxi:
onFailure: buffer
readOnly: false
readoutPriority: baseline
userParameter:
init_position: -5.5
sl4trxo:
description: ESbox1 slit 4 outer blade movement
@@ -268,6 +297,8 @@ sl4trxo:
onFailure: buffer
readOnly: false
readoutPriority: baseline
userParameter:
init_position: 6
sl4trxb:
description: ESbox1 slit 4 bottom blade movement
@@ -286,6 +317,8 @@ sl4trxb:
onFailure: buffer
readOnly: false
readoutPriority: baseline
userParameter:
init_position: -5.8
sl4trxt:
description: ESbox1 slit 4 top blade movement
@@ -304,6 +337,8 @@ sl4trxt:
onFailure: buffer
readOnly: false
readoutPriority: baseline
userParameter:
init_position: 5.5
################## XBOX 2 ES #####################
@@ -324,6 +359,8 @@ sl5trxi:
onFailure: buffer
readOnly: false
readoutPriority: baseline
userParameter:
init_position: -6
sl5trxo:
description: ESbox2 slit 5 outer blade movement
@@ -342,6 +379,8 @@ sl5trxo:
onFailure: buffer
readOnly: false
readoutPriority: baseline
userParameter:
init_position: 5.5
sl5trxb:
description: ESbox2 slit 5 bottom blade movement
@@ -360,6 +399,8 @@ sl5trxb:
onFailure: buffer
readOnly: false
readoutPriority: baseline
userParameter:
init_position: -5.5
sl5trxt:
description: ESbox1 slit 5 top blade movement
@@ -378,6 +419,8 @@ sl5trxt:
onFailure: buffer
readOnly: false
readoutPriority: baseline
userParameter:
init_position: 6
xbimtrx:
description: ESbox2 beam intensity monitor x movement
@@ -396,6 +439,8 @@ xbimtrx:
onFailure: buffer
readOnly: false
readoutPriority: baseline
userParameter:
init_position: -14.7
xbimtry:
description: ESbox2 beam intensity monitor y movement
@@ -414,3 +459,5 @@ xbimtry:
onFailure: buffer
readOnly: false
readoutPriority: baseline
userParameter:
init_position: 0