mod filter trans to check CCM in use
All checks were successful
CI for csaxs_bec / test (push) Successful in 1m14s
All checks were successful
CI for csaxs_bec / test (push) Successful in 1m14s
This commit is contained in:
@@ -31,6 +31,8 @@ from importlib import resources
|
||||
# Resolve the filter_data/ folder via importlib.resources
|
||||
import csaxs_bec.bec_ipython_client.plugins.cSAXS.filter_transmission as ft_pkg
|
||||
|
||||
from csaxs_bec.bec_ipython_client.plugins.cSAXS import epics_get
|
||||
|
||||
from bec_lib import bec_logger
|
||||
|
||||
import builtins
|
||||
@@ -155,8 +157,6 @@ class cSAXSFilterTransmission:
|
||||
# -----------------------------
|
||||
# Public API
|
||||
# -----------------------------
|
||||
|
||||
|
||||
def fil_trans(
|
||||
self,
|
||||
transmission: Optional[float] = None,
|
||||
@@ -167,17 +167,27 @@ class cSAXSFilterTransmission:
|
||||
Set exposure-box filters to achieve a target transmission.
|
||||
|
||||
If called without 'transmission', prints usage and current status.
|
||||
|
||||
Safety:
|
||||
- fil_trans(1) is always allowed.
|
||||
- fil_trans(<1) is only allowed if:
|
||||
- epics_get("X12SA-OP-DMM-EMLS-3010:THRU") == 1 (DMM translation THROUGH)
|
||||
- epics_get("X12SA-OP-DMM-EMLS-3030:THRU") == 1 (DMM rotation THROUGH)
|
||||
- epics_get("X12SA-OP-CCM1:ENERGY-GET") > 1 (CCM active, energy in keV)
|
||||
Otherwise, prompt with default NO.
|
||||
"""
|
||||
|
||||
# --- No-arg usage helper ---
|
||||
if transmission is None:
|
||||
print("\nUsage example:")
|
||||
print(" csaxs.fil_trans(0.10, energy_kev=6.2)")
|
||||
print(" First parameter is the transmission factor requested.\nIf energy is not specified it will be read from the monochromator (in the future)")
|
||||
print(" First parameter is the transmission factor requested.")
|
||||
print(" If energy is not specified it will be read from the CCM energy PV.")
|
||||
print("\nCurrent filter transmission:")
|
||||
self._fil_trans_report(energy_kev=energy_kev)
|
||||
return None
|
||||
|
||||
# --- Validation ---
|
||||
# --- Validation of transmission ---
|
||||
try:
|
||||
transmission = float(transmission)
|
||||
except Exception:
|
||||
@@ -186,17 +196,64 @@ class cSAXSFilterTransmission:
|
||||
if not (0.0 < transmission <= 1.0):
|
||||
raise ValueError("Transmission must be between 0 and 1.")
|
||||
|
||||
# --- Energy handling ---
|
||||
# -------------------------------------------------------
|
||||
# SAFETY CHECK (before any calculation/motion):
|
||||
# Only allow fil_trans < 1 when DMM is in THROUGH (both)
|
||||
# and CCM energy > 1 keV. fil_trans(1) is always allowed.
|
||||
# -------------------------------------------------------
|
||||
if transmission < 1.0:
|
||||
try:
|
||||
dmm_trans = float(epics_get("X12SA-OP-DMM-EMLS-3010:THRU"))
|
||||
except Exception:
|
||||
dmm_trans = -1
|
||||
try:
|
||||
dmm_rot = float(epics_get("X12SA-OP-DMM-EMLS-3030:THRU"))
|
||||
except Exception:
|
||||
dmm_rot = -1
|
||||
try:
|
||||
ccm_energy = float(epics_get("X12SA-OP-CCM1:ENERGY-GET"))
|
||||
except Exception:
|
||||
ccm_energy = -1
|
||||
|
||||
allowed = (dmm_trans == 1) and (dmm_rot == 1) and (ccm_energy > 1)
|
||||
|
||||
if not allowed:
|
||||
print("\n⚠️ SAFETY WARNING: Reducing transmission (< 1) typically requires:")
|
||||
print(" - DMM translation in THROUGH (THRU == 1)")
|
||||
print(" - DMM rotation in THROUGH (THRU == 1)")
|
||||
print(" - CCM energy > 1 keV")
|
||||
print("\nCurrent state:")
|
||||
print(f" DMM translation THRU : {dmm_trans}")
|
||||
print(f" DMM rotation THRU : {dmm_rot}")
|
||||
print(f" CCM energy (keV) : {ccm_energy}")
|
||||
|
||||
# Ask user (default = NO)
|
||||
if hasattr(self, "OMNYTools") and hasattr(self.OMNYTools, "yesno"):
|
||||
proceed = self.OMNYTools.yesno(
|
||||
"Conditions not satisfied. Proceed anyway?",
|
||||
default="n",
|
||||
)
|
||||
else:
|
||||
# Safe fallback
|
||||
proceed = False
|
||||
|
||||
if not proceed:
|
||||
print("Aborted. Transmission unchanged.")
|
||||
return None
|
||||
|
||||
# --- Energy handling (EPICS only) ---
|
||||
if energy_kev is None:
|
||||
try:
|
||||
energy_kev = float(dev.mokev.read()) # using global dev
|
||||
energy_kev = float(epics_get("X12SA-OP-CCM1:ENERGY-GET"))
|
||||
except Exception as exc:
|
||||
raise RuntimeError(
|
||||
"Energy not specified and could not read current beam energy."
|
||||
"Energy not specified and could not read EPICS PV "
|
||||
"'X12SA-OP-CCM1:ENERGY-GET'."
|
||||
) from exc
|
||||
else:
|
||||
energy_kev = float(energy_kev)
|
||||
|
||||
|
||||
# --- Summary header ---
|
||||
print("\nExposure-box filter transmission request")
|
||||
print("-" * 60)
|
||||
@@ -221,20 +278,23 @@ class cSAXSFilterTransmission:
|
||||
# --- Dry run prompt ---
|
||||
if print_only:
|
||||
print("\n[DRY RUN] No motion executed yet.")
|
||||
if self.OMNYTools.yesno(
|
||||
"Execute motion to the selected filter combination now?",
|
||||
"y", # default YES
|
||||
):
|
||||
self._execute_combination(best, energy_kev)
|
||||
if hasattr(self, "OMNYTools") and hasattr(self.OMNYTools, "yesno"):
|
||||
if self.OMNYTools.yesno(
|
||||
"Execute motion to the selected filter combination now?",
|
||||
"y", # default YES
|
||||
):
|
||||
self._execute_combination(best, energy_kev)
|
||||
else:
|
||||
print("Execution skipped.")
|
||||
else:
|
||||
print("Execution skipped.")
|
||||
# If yesno not available, default to 'skip' on print_only
|
||||
print("No interactive prompt available. Execution skipped (print_only=True).")
|
||||
return None
|
||||
|
||||
# --- Execute motion directly ---
|
||||
self._execute_combination(best, energy_kev)
|
||||
return None
|
||||
|
||||
|
||||
# -----------------------------
|
||||
# Physics helpers
|
||||
# -----------------------------
|
||||
@@ -522,13 +582,18 @@ class cSAXSFilterTransmission:
|
||||
print("ERROR: Global 'dev' object not found.")
|
||||
return
|
||||
|
||||
# Determine energy
|
||||
# --- Energy handling (EPICS only) ---
|
||||
if energy_kev is None:
|
||||
try:
|
||||
energy_kev = float(dev.mokev.read())
|
||||
except Exception:
|
||||
print("WARNING: Could not read current beam energy. Assuming 6.2 keV.")
|
||||
energy_kev = 6.2
|
||||
energy_kev = float(epics_get("X12SA-OP-CCM1:ENERGY-GET"))
|
||||
except Exception as exc:
|
||||
raise RuntimeError(
|
||||
"Energy not specified and could not read EPICS PV "
|
||||
"'X12SA-OP-CCM1:ENERGY-GET'."
|
||||
) from exc
|
||||
else:
|
||||
energy_kev = float(energy_kev)
|
||||
|
||||
|
||||
print("\nCurrent filter transmission report")
|
||||
print("-" * 60)
|
||||
|
||||
85
csaxs_bec/device_configs/user_template.yaml
Normal file
85
csaxs_bec/device_configs/user_template.yaml
Normal file
@@ -0,0 +1,85 @@
|
||||
############################################################
|
||||
#################### OWIS LTM80 ############################
|
||||
############################################################
|
||||
samx:
|
||||
description: Owis motor stage samx
|
||||
deviceClass: ophyd_devices.devices.psi_motor.EpicsUserMotorVME
|
||||
deviceConfig:
|
||||
prefix: X12SA-ES2-ES02
|
||||
motor_resolution: 0.00125
|
||||
base_velocity: 0.0625
|
||||
velocity: 10
|
||||
backlash_distance: 0.125
|
||||
acceleration: 0.2
|
||||
user_offset_dir: 0
|
||||
deviceTags:
|
||||
- cSAXS
|
||||
- owis_samx
|
||||
onFailure: buffer
|
||||
enabled: true
|
||||
readoutPriority: baseline
|
||||
softwareTrigger: false
|
||||
############################################################
|
||||
#################### OWIS Rotation DMT65 ###################
|
||||
############################################################
|
||||
rotx:
|
||||
description: Rotation stage rotx
|
||||
deviceClass: ophyd_devices.devices.psi_motor.EpicsUserMotorVME
|
||||
deviceConfig:
|
||||
prefix: X12SA-ES2-ES03
|
||||
motor_resolution: 0.0025
|
||||
base_velocity: 0.5
|
||||
velocity: 7.5
|
||||
backlash_distance: 0.25
|
||||
acceleration: 0.2
|
||||
user_offset_dir: 1
|
||||
limits:
|
||||
- -0.1
|
||||
- 0.1
|
||||
deviceTags:
|
||||
- cSAXS
|
||||
- rotx
|
||||
onFailure: buffer
|
||||
enabled: true
|
||||
readoutPriority: baseline
|
||||
softwareTrigger: false
|
||||
|
||||
|
||||
############################################################
|
||||
#################### npoint motors #########################
|
||||
############################################################
|
||||
|
||||
npx:
|
||||
description: nPoint x axis on the big npoint controller
|
||||
deviceClass: csaxs_bec.devices.npoint.npoint.NPointAxis
|
||||
deviceConfig:
|
||||
axis_Id: A
|
||||
host: "nPoint000003.psi.ch"
|
||||
limits:
|
||||
- -50
|
||||
- 50
|
||||
port: 23
|
||||
sign: 1
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: baseline
|
||||
deviceTags:
|
||||
- npoint
|
||||
npy:
|
||||
description: nPoint y axis on the big npoint controller
|
||||
deviceClass: csaxs_bec.devices.npoint.npoint.NPointAxis
|
||||
deviceConfig:
|
||||
axis_Id: B
|
||||
host: "nPoint000003.psi.ch"
|
||||
limits:
|
||||
- -50
|
||||
- 50
|
||||
port: 23
|
||||
sign: 1
|
||||
enabled: true
|
||||
onFailure: buffer
|
||||
readOnly: false
|
||||
readoutPriority: baseline
|
||||
deviceTags:
|
||||
- npoint
|
||||
Reference in New Issue
Block a user