From 946a278d167018243de9970df7bfcc2ff24bfec3 Mon Sep 17 00:00:00 2001 From: x06da Date: Wed, 24 Jun 2026 13:08:18 +0200 Subject: [PATCH] updates from pxii --- .../device_configs/pxiii-beamline-states.yaml | 2 +- .../device_configs/pxiii-rest-devices.yaml | 18 - .../pxiii-standard-devices.yaml | 1333 ----------------- .../device_configs/pxiii-state-devices.yaml | 2 +- .../device_configs/x06da_device_config.yaml | 31 +- pxiii_bec/macros/beamline_planner.py | 38 +- pxiii_bec/macros/build_devices.py | 342 ++++- pxiii_bec/macros/dependencies.py | 30 +- pxiii_bec/macros/devices_manager.py | 15 +- pxiii_bec/macros/enums.py | 22 - pxiii_bec/macros/guards.py | 4 +- pxiii_bec/macros/init_beamline.py | 58 +- pxiii_bec/macros/mx_methods.py | 11 + pxiii_bec/macros/policies.py | 5 +- pxiii_bec/macros/pxiii_energy.py | 8 +- pxiii_bec/macros/pxiii_parameters.py | 12 +- 16 files changed, 406 insertions(+), 1525 deletions(-) delete mode 100644 pxiii_bec/device_configs/pxiii-rest-devices.yaml delete mode 100644 pxiii_bec/device_configs/pxiii-standard-devices.yaml delete mode 100644 pxiii_bec/macros/enums.py diff --git a/pxiii_bec/device_configs/pxiii-beamline-states.yaml b/pxiii_bec/device_configs/pxiii-beamline-states.yaml index a9cd830..8628a22 100644 --- a/pxiii_bec/device_configs/pxiii-beamline-states.yaml +++ b/pxiii_bec/device_configs/pxiii-beamline-states.yaml @@ -109,7 +109,7 @@ states: bl_bright: 'off' bs_pos: in bs_z: safe - coll_y: out + coll_y: in cryo_pos: out det_cov: 'close' diag_y: scint diff --git a/pxiii_bec/device_configs/pxiii-rest-devices.yaml b/pxiii_bec/device_configs/pxiii-rest-devices.yaml deleted file mode 100644 index e651780..0000000 --- a/pxiii_bec/device_configs/pxiii-rest-devices.yaml +++ /dev/null @@ -1,18 +0,0 @@ -aerotech_x: - userParameter: {"type": continuous, "in": 0.0, "out": -10.0, "safe": -100, "tol": 0.5} -aerotech_y: - userParameter: {"type": continuous, "mount": 0.0, "work": 0.01, "tol": 0.002} -aerotech_z: - userParameter: {"type": continuous, "mount": 0.0, "work": 0.02, "tol": 0.01} -aerotech_u: - userParameter: {"type": continuous, "mount": 0.0} -smargon_x: - userParameter: {"type": continuous, "mount": 0.0} -smargon_y: - userParameter: {"type": continuous, "mount": 0.0} -smargon_z: - userParameter: {"type": continuous, "mount": 0.0} -smargon_chi: - userParameter: {"type": continuous, "mount": 0.0} -smargon_phi: - userParameter: {"type": continuous, "mount": 0.0} diff --git a/pxiii_bec/device_configs/pxiii-standard-devices.yaml b/pxiii_bec/device_configs/pxiii-standard-devices.yaml deleted file mode 100644 index e8d8767..0000000 --- a/pxiii_bec/device_configs/pxiii-standard-devices.yaml +++ /dev/null @@ -1,1333 +0,0 @@ -sls_current: - description: SLS Current - deviceClass: ophyd.EpicsSignalRO - deviceConfig: {read_pv: 'ARS07-DPCT-0100:CURR', auto_monitor: true} - onFailure: buffer - enabled: True - readoutPriority: monitored - deviceTags: - - SLS - readOnly: True - softwareTrigger: false - -fe_sl_xr: - description: FE Slit X Ring - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-FE-SLDI:TRXR'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - fe - readOnly: False - softwareTrigger: false - -fe_sl_yt: - description: FE Slit Y Top - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-FE-SLDI:TRYT'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - fe - readOnly: False - softwareTrigger: false - -fe_sl_xw: - description: FE Slit X Wall - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-FE-SLDI:TRXW'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - fe - readOnly: False - softwareTrigger: false - -fe_sl_yb: - description: FE Slit Y Bottom - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-FE-SLDI:TRYB'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - fe - readOnly: False - softwareTrigger: false - -fe_sl_xcen: - description: FE Slit X Centre - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-FE-SLDI:CENTERX'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - fe - readOnly: False - softwareTrigger: false - -fe_sl_xsize: - description: FE Slit X Size - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-FE-SLDI:SIZEX'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - fe - readOnly: False - softwareTrigger: false - -fe_sl_ycen: - description: FE Slit Y Centre - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-FE-SLDI:CENTERY'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - fe - readOnly: False - softwareTrigger: false - -fe_sl_ysize: - description: FE Slit Y Size - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-FE-SLDI:SIZEY'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - fe - readOnly: False - softwareTrigger: false - -tm_xu: - description: TorM Upstream X - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-FE-MI1:TRXU'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - tm - readOnly: False - softwareTrigger: false - -tm_xd: - description: TorM Downstream X - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-FE-MI1:TRXD'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - tm - readOnly: False - softwareTrigger: false - -tm_yur: - description: TorM Upstream Ring Y - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-FE-MI1:TRYUR'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - tm - readOnly: False - softwareTrigger: false - -tm_yw: - description: TorM Wall Y - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-FE-MI1:TRYUW'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - tm - readOnly: False - softwareTrigger: false - -tm_yd: - description: TorM Downstream Y - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-FE-MI1:TRYD'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - tm - readOnly: False - softwareTrigger: false - -tm_b1: - description: TorM Bender - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-FE-MI1:BEND1'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - tm - readOnly: False - softwareTrigger: false - -tm_yaw: - description: TorM Virtual Yaw - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-FE-MI1:YAW'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - tm - readOnly: False - softwareTrigger: false - -tm_roll: - description: TorM Virtual Roll - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-FE-MI1:ROLL'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - tm - readOnly: False - softwareTrigger: false - -tm_pitch: - description: TorM Virtual Pitch - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-FE-MI1:PITCH'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - tm - readOnly: False - softwareTrigger: false - -tm_x: - description: TorM Virtual X - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-FE-MI1:TRX'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - tm - readOnly: False - softwareTrigger: false - -tm_y: - description: TorM Virtual Y - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-FE-MI1:TRY'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - tm - readOnly: False - softwareTrigger: false - -bsf_sl_xw: - description: BSF Slit outboard - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-OP-BSFSLH:TRXW'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - bsf - readOnly: False - softwareTrigger: false - -bsf_sl_xr: - description: BSF Slit inboard - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-OP-BSFSLH:TRXR'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - bsf - readOnly: False - softwareTrigger: false - -bsf_sl_xcen: - description: BSF X Centre - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-OP-BSFSLH:CENTER'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - bsf - readOnly: False - softwareTrigger: false - -bsf_sl_xsize: - description: BSF X Size - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-OP-BSFSLH:SIZE'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - bsf - readOnly: False - softwareTrigger: false - -bsf_f1_y: - description: BSF Filter 1 Y - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-OP-BSFFI1:TRY'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - bsf - readOnly: False - softwareTrigger: false - -dccm_theta1: - description: DCCM Theta Xtal1 - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-OP-DCCM:ROTX-CR1'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - dccm - readOnly: False - softwareTrigger: false - -dccm_theta2: - description: DCCM Theta Xtal2 - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-OP-DCCM:ROTX-CR2'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - dccm - readOnly: False - softwareTrigger: false - -dccm_rotz: - description: DCCM RotZ Xtal 2 - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-OP-DCCM:ROTZ-CR2'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - dccm - readOnly: False - softwareTrigger: false - -dccm_xbpm1_y: - description: DCCM BPM1 Y - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-OP-DCCMXBPM1:TRY'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - dccm - readOnly: False - softwareTrigger: false - -dccm_xbpm2_y: - description: DCCM BPM2 Y - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-OP-DCCMXBPM2:TRY'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - dccm - readOnly: False - softwareTrigger: false - -dccm_energy: - description: DCCM Energy - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-OP-DCCM:ENERGY'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - dccm - readOnly: False - softwareTrigger: false - -dccm_di_top: - description: DCCM Diode Top - deviceClass: ophyd.EpicsSignalRO - deviceConfig: {read_pv: 'X06DA-OP-DCCMXBPM1T:READOUT', auto_monitor: true} - onFailure: buffer - enabled: True - readoutPriority: monitored - deviceTags: - - dccm - readOnly: False - softwareTrigger: false - -dccm_di_bot: - description: DCCM Diode Bottom - deviceClass: ophyd.EpicsSignalRO - deviceConfig: {read_pv: 'X06DA-OP-DCCMXBPM1B:READOUT', auto_monitor: true} - onFailure: buffer - enabled: True - readoutPriority: monitored - deviceTags: - - dccm - readOnly: False - softwareTrigger: false - -dccm_bpm1: - description: DCCM BPM Channel 1 - deviceClass: ophyd.EpicsSignalRO - deviceConfig: {read_pv: 'X06DA-OP-DCCMXBPM2:Current1:MeanValue_RBV', auto_monitor: true} - onFailure: buffer - enabled: True - readoutPriority: monitored - deviceTags: - - dccm - readOnly: False - softwareTrigger: false - -dccm_bpm2: - description: DCCM BPM Channel 2 - deviceClass: ophyd.EpicsSignalRO - deviceConfig: {read_pv: 'X06DA-OP-DCCMXBPM2:Current2:MeanValue_RBV', auto_monitor: true} - onFailure: buffer - enabled: True - readoutPriority: monitored - deviceTags: - - dccm - readOnly: False - softwareTrigger: false - -dccm_bpm3: - description: DCCM BPM Channel 3 - deviceClass: ophyd.EpicsSignalRO - deviceConfig: {read_pv: 'X06DA-OP-DCCMXBPM2:Current3:MeanValue_RBV', auto_monitor: true} - onFailure: buffer - enabled: True - readoutPriority: monitored - deviceTags: - - dccm - readOnly: False - softwareTrigger: false - -dccm_bpm4: - description: DCCM BPM Channel 4 - deviceClass: ophyd.EpicsSignalRO - deviceConfig: {read_pv: 'X06DA-OP-DCCMXBPM2:Current4:MeanValue_RBV', auto_monitor: true} - onFailure: buffer - enabled: True - readoutPriority: monitored - deviceTags: - - dccm - readOnly: False - softwareTrigger: false - -dccm_bpmsum: - description: DCCM BPM Summed - deviceClass: ophyd.EpicsSignalRO - deviceConfig: {read_pv: 'X06DA-OP-DCCMXBPM2:SumAll:MeanValue_RBV', auto_monitor: true} - onFailure: buffer - enabled: True - readoutPriority: monitored - deviceTags: - - dccm - readOnly: False - softwareTrigger: false - -ss_bpm1: - description: SS BPM Channel 1 - deviceClass: ophyd.EpicsSignalRO - deviceConfig: {read_pv: 'X06DA-ES-SSBPM:Current1:MeanValue_RBV', auto_monitor: true} - onFailure: buffer - enabled: True - readoutPriority: monitored - deviceTags: - - bpm - readOnly: True - softwareTrigger: false - -ss_bpm2: - description: SS BPM Channel 2 - deviceClass: ophyd.EpicsSignalRO - deviceConfig: {read_pv: 'X06DA-ES-SSBPM:Current2:MeanValue_RBV', auto_monitor: true} - onFailure: buffer - enabled: True - readoutPriority: monitored - deviceTags: - - bpm - readOnly: True - softwareTrigger: false - -ss_bpm3: - description: SS BPM Channel 3 - deviceClass: ophyd.EpicsSignalRO - deviceConfig: {read_pv: 'X06DA-ES-SSBPM:Current3:MeanValue_RBV', auto_monitor: true} - onFailure: buffer - enabled: True - readoutPriority: monitored - deviceTags: - - bpm - readOnly: True - softwareTrigger: false - -ss_bpm4: - description: SS BPM Channel 4 - deviceClass: ophyd.EpicsSignalRO - deviceConfig: {read_pv: 'X06DA-ES-SSBPM:Current4:MeanValue_RBV', auto_monitor: true} - onFailure: buffer - enabled: True - readoutPriority: monitored - deviceTags: - - bpm - readOnly: True - softwareTrigger: false - -ss_bpmsum: - description: SS BPM Summed - deviceClass: ophyd.EpicsSignalRO - deviceConfig: {read_pv: 'X06DA-ES-SSBPM:SumAll:MeanValue_RBV', auto_monitor: true} - onFailure: buffer - enabled: True - readoutPriority: monitored - deviceTags: - - bpm - readOnly: True - softwareTrigger: false - -ss_bpm_x: - description: SS BPM X - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-SSBPM:TRX'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - ss - readOnly: False - softwareTrigger: false - -ss_bpm_y: - description: SS BPM Y - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-SSBPM:TRY'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - ss - readOnly: False - softwareTrigger: false - -ss_sl_xw: - description: SS Slit Wall - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-SSSLH:TRXW'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - ss - readOnly: False - softwareTrigger: false - -ss_sl_xr: - description: SS Slit Ring - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-SSSLH:TRXR'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - ss - readOnly: False - softwareTrigger: false - -ss_sl_xcen: - description: SS Slit X Centre - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-SSSLH:CENTER'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - ss - readOnly: False - softwareTrigger: false - -ss_sl_xsize: - description: SS Slit X Size - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-SSSLH:SIZE'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - ss - readOnly: False - softwareTrigger: false - -ss_sl_yt: - description: SS Slit Top - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-SSSLV:TRYT'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - ss - readOnly: False - softwareTrigger: false - -ss_sl_yb: - description: SS Slit Bottom - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-SSSLV:TRYB'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - ss - readOnly: False - softwareTrigger: false - -ss_sl_ycen: - description: SS Slit Y Centre - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-SSSLV:CENTER'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - ss - readOnly: False - softwareTrigger: false - -ss_sl_ysize: - description: SS Slit Y Size - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-SSSLV:SIZE'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - ss - readOnly: False - softwareTrigger: false - -ss_xi_x: - description: SS X-ray Eye X - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-SSXI:TRX'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - ss - readOnly: False - softwareTrigger: false - userParameter: {"type": multi-position,"in": 7.5, "out": -2.1} - -ss_xi_y: - description: SS X-ray Eye Y - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-SSXI:TRY'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - ss - readOnly: False - softwareTrigger: false - -ss_xicam_x: - description: SS Camera X - deviceClass: ophyd.EpicsSignalRO - deviceConfig: {read_pv: 'X06DA-ES-SSCAM:Stats5:CentroidX_RBV', auto_monitor: true} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - ss - readOnly: True - softwareTrigger: false - -ss_xicam_y: - description: SS Camera Y - deviceClass: ophyd.EpicsSignalRO - deviceConfig: {read_pv: 'X06DA-ES-SSCAM:Stats5:CentroidY_RBV', auto_monitor: true} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - ss - readOnly: True - softwareTrigger: false - -ss_xicam_max: - description: SS Cam Max - deviceClass: ophyd.EpicsSignalRO - deviceConfig: {read_pv: 'X06DA-ES-SSCAM:Stats5:MaxValue_RBV', auto_monitor: true} - onFailure: buffer - enabled: True - readoutPriority: monitored - deviceTags: - - ss - readOnly: True - softwareTrigger: false - -ss_xicam_exp: - description: SS Camera Exposure - deviceClass: ophyd.EpicsSignal - deviceConfig: {read_pv: 'X06DA-ES-SSCAM:cam1:AcquireTime', auto_monitor: true} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - ss - readOnly: False - softwareTrigger: false - -ss_xicam_gain: - description: SS Camera Gain - deviceClass: ophyd.EpicsSignal - deviceConfig: {read_pv: 'X06DA-ES-SSCAM:cam1:Gain', auto_monitor: true} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - ss - readOnly: False - softwareTrigger: false - -ss_xicam_xsig: - description: SS Camera X Sigma - deviceClass: ophyd.EpicsSignal - deviceConfig: {read_pv: 'X06DA-ES-SSCAM:Stats5:SigmaX_RBV', auto_monitor: true} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - ss - readOnly: True - softwareTrigger: false - -ss_xicam_ysig: - description: SS Camera Y Sigma - deviceClass: ophyd.EpicsSignal - deviceConfig: {read_pv: 'X06DA-ES-SSCAM:Stats5:SigmaY_RBV', auto_monitor: true} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - ss - readOnly: True - softwareTrigger: false - -vfm_xu: - description: VFM Upstream X - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-ES-VFM:TRXU'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - vfm - readOnly: False - softwareTrigger: false - -vfm_xd: - description: VFM Downstream X - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-ES-VFM:TRXD'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - vfm - readOnly: False - softwareTrigger: false - -vfm_yur: - description: VFM Upstream Ring Y - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-ES-VFM:TRYUR'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - vfm - readOnly: False - softwareTrigger: false - -vfm_yw: - description: VFM Wall Y - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-ES-VFM:TRYW'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - vfm - readOnly: False - softwareTrigger: false - -vfm_ydr: - description: VFM Downstream Ring Y - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-ES-VFM:TRYDR'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - vfm - readOnly: False - softwareTrigger: false - -vfm_bu: - description: VFM Upstream Bender - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-ES-VFM:BNDU'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - vfm - readOnly: False - softwareTrigger: false - -vfm_bd: - description: VFM Downstream Bender - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-ES-VFM:BNDD'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - vfm - readOnly: False - softwareTrigger: false - -vfm_yaw: - description: VFM Virtual Yaw - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-ES-VFM:YAW'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - vfm - readOnly: False - softwareTrigger: false - -vfm_roll: - description: VFM Virtual Roll - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-ES-VFM:ROLL'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - vfm - readOnly: False - softwareTrigger: false - -vfm_pitch: - description: VFM Virtual Pitch - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-ES-VFM:PITCH'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - vfm - readOnly: False - softwareTrigger: false - -vfm_x: - description: VFM Virtual X - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-ES-VFM:TRX'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - vfm - readOnly: False - softwareTrigger: false - -vfm_y: - description: VFM Virtual Y - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-ES-VFM:TRY'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - vfm - readOnly: False - softwareTrigger: false - -hfm_xu: - description: HFM Upstream X - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-ES-HFM:TRXU'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - hfm - readOnly: False - softwareTrigger: false - -hfm_xd: - description: HFM Downstream X - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-ES-HFM:TRXD'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - hfm - readOnly: False - softwareTrigger: false - -hfm_yuw: - description: HFM Upstream Wall Y - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-ES-HFM:TRYUW'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - hfm - readOnly: False - softwareTrigger: false - -hfm_yr: - description: HFM Ring Y - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-ES-HFM:TRYR'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - hfm - readOnly: False - softwareTrigger: false - -hfm_ydw: - description: HFM Downstream Wall Y - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-ES-HFM:TRYDW'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - hfm - readOnly: False - softwareTrigger: false - -hfm_bu: - description: HFM Upstream Bender - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-ES-HFM:BNDU'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - hfm - readOnly: False - softwareTrigger: false - -hfm_bd: - description: HFM Downstream Bender - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-ES-HFM:BNDD'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - hfm - readOnly: False - softwareTrigger: false - -hfm_yaw: - description: HFM Virtual Yaw - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-ES-HFM:YAW'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - hfm - readOnly: False - softwareTrigger: false - -hfm_roll: - description: HFM Virtual Roll - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-ES-HFM:ROLL'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - hfm - readOnly: False - softwareTrigger: false - -hfm_pitch: - description: HFM Virtual Pitch - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-ES-HFM:PITCH'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - hfm - readOnly: False - softwareTrigger: false - -hfm_x: - description: HFM Virtual X - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-ES-HFM:TRX'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - hfm - readOnly: False - softwareTrigger: false - -hfm_y: - description: HFM Virtual Y - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-ES-HFM:TRY'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - hfm - readOnly: False - softwareTrigger: false - -bcu_bpm1: - description: BCU BPM Channel 1 - deviceClass: ophyd.EpicsSignalRO - deviceConfig: {read_pv: 'X06DA-ES-BCBPM:Current1:MeanValue_RBV', auto_monitor: true} - onFailure: buffer - enabled: True - readoutPriority: monitored - deviceTags: - - bpm - readOnly: True - softwareTrigger: false - -bcu_bpm2: - description: BCU BPM Channel 2 - deviceClass: ophyd.EpicsSignalRO - deviceConfig: {read_pv: 'X06DA-ES-BCBPM:Current2:MeanValue_RBV', auto_monitor: true} - onFailure: buffer - enabled: True - readoutPriority: monitored - deviceTags: - - bpm - readOnly: True - softwareTrigger: false - -bcu_bpm3: - description: BCU BPM Channel 3 - deviceClass: ophyd.EpicsSignalRO - deviceConfig: {read_pv: 'X06DA-ES-BCBPM:Current3:MeanValue_RBV', auto_monitor: true} - onFailure: buffer - enabled: True - readoutPriority: monitored - deviceTags: - - bpm - readOnly: True - softwareTrigger: false - -bcu_bpm4: - description: BCU BPM Channel 4 - deviceClass: ophyd.EpicsSignalRO - deviceConfig: {read_pv: 'X06DA-ES-BCBPM:Current4:MeanValue_RBV', auto_monitor: true} - onFailure: buffer - enabled: True - readoutPriority: monitored - deviceTags: - - bpm - readOnly: True - softwareTrigger: false - -bcu_bpmsum: - description: BCU BPM Summed - deviceClass: ophyd.EpicsSignalRO - deviceConfig: {read_pv: 'X06DA-ES-BCBPM:SumAll:MeanValue_RBV', auto_monitor: true} - onFailure: buffer - enabled: True - readoutPriority: monitored - deviceTags: - - bpm - readOnly: True - softwareTrigger: false - -bcu_bpm_x: - description: BCU BPM X - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-BCBPM:TRX'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - bcu - readOnly: False - softwareTrigger: false - -bcu_bpm_y: - description: BCU BPM Y - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-BCBPM:TRY'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - bcu - readOnly: False - softwareTrigger: false - -bcu_sl_xw: - description: BCU Slit Wall - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-BCSLH:TRXW'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - bcu - readOnly: False - softwareTrigger: false - -bcu_sl_xr: - description: BCU Slit Ring - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-BCSLH:TRXR'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - bcu - readOnly: False - softwareTrigger: false - -bcu_sl_xcen: - description: BCU Slit X Centre - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-BCSLH:CENTER'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - bcu - readOnly: False - softwareTrigger: false - -bcu_sl_xsize: - description: BCU Slit X Size - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-BCSLH:SIZE'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - bcu - readOnly: False - softwareTrigger: false - -bcu_sl_yt: - description: BCU Slit top - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-BCSLV:TRYT'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - bcu - readOnly: False - softwareTrigger: false - -bcu_sl_yb: - description: BCU Slit Bottom - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-BCSLV:TRYB'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - bcu - readOnly: False - softwareTrigger: false - -bcu_sl_ycen: - description: BCU Slit Y Centre - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-BCSLV:CENTER'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - bcu - readOnly: False - softwareTrigger: false - -bcu_sl_ysize: - description: BCU Slit Y Size - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-BCSLV:SIZE'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - bcu - readOnly: False - softwareTrigger: false - -scam_zoom: - description: Sample Camera Zoom - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-MS:ZOOM'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - scam - readOnly: False - softwareTrigger: false - -coll_x: - description: Collimator X - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-COL:TRX'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - se - readOnly: False - softwareTrigger: false - -diag_z: - description: Scintillator/diode Z - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-SCL:TRZ'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - se - readOnly: False - softwareTrigger: false - -i1: - description: I1 diode - deviceClass: ophyd.EpicsSignalRO - deviceConfig: {read_pv: 'X06DA-ES-SCLDI:READOUT', auto_monitor: true} - onFailure: buffer - enabled: True - readoutPriority: monitored - deviceTags: - - bpm - readOnly: True - softwareTrigger: false - -bs_x: - description: Beamstop X - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-BS:TRX'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - se - readOnly: False - softwareTrigger: false - -bs_y: - description: Beamstop Y - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-BS:TRY'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - se - readOnly: False - softwareTrigger: false - -cryo_x: - description: Cryo X - deviceClass: ophyd_devices.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-CS:TRX'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - se - readOnly: False - softwareTrigger: false - -cryo_temp: - description: Cryo Temperature - deviceClass: ophyd.EpicsSignalRO - deviceConfig: {read_pv: 'X06DA-ES-CS:TEMP_RBV', auto_monitor: true} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - se - readOnly: False - softwareTrigger: false - -det_y: - description: Detector Y - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-ES-DET:TRY'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - det - readOnly: False - softwareTrigger: false - -det_z: - description: Detector Z - deviceClass: ophyd_devices.EpicsMotorEC - deviceConfig: {prefix: 'X06DA-ES-DET:TRZ'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - det - readOnly: False - softwareTrigger: false - diff --git a/pxiii_bec/device_configs/pxiii-state-devices.yaml b/pxiii_bec/device_configs/pxiii-state-devices.yaml index e96c4aa..113d6ec 100644 --- a/pxiii_bec/device_configs/pxiii-state-devices.yaml +++ b/pxiii_bec/device_configs/pxiii-state-devices.yaml @@ -9,7 +9,7 @@ bl_bright: - state readOnly: False softwareTrigger: false - userParameter: {"type": continuous, "on": 1.3, "off": 0, “tol”: 0.01} + userParameter: {"type": continuous, "on": 1.56, "off": 0, “tol”: 0.01} bl_pos: description: Backlight Positioner diff --git a/pxiii_bec/device_configs/x06da_device_config.yaml b/pxiii_bec/device_configs/x06da_device_config.yaml index dc74a07..196681f 100644 --- a/pxiii_bec/device_configs/x06da_device_config.yaml +++ b/pxiii_bec/device_configs/x06da_device_config.yaml @@ -1,30 +1,5 @@ base_config: - - !include ./pxiii-standard-devices.yaml -states_config: - - !include ./pxiii-state-devices.yaml + - !include ./pxiii-devices.yaml +#states_config: +# - !include ./pxiii-state-devices.yaml -smargon: - description: REST-based device which connects to Smargopolo - deviceClass: pxiii_bec.devices.smargopolo_smargon.Smargon - deviceConfig: {prefix: 'http://x06da-smargopolo.psi.ch:3000'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - smargon - - motors - readOnly: false - softwareTrigger: false - -aerotech: - description: REST-based device which connects to AareScan and Aerotech - deviceClass: pxiii_bec.devices.aerotech.Aerotech - deviceConfig: {prefix: 'http://mx-x06da-queue-01:5234'} - onFailure: buffer - enabled: True - readoutPriority: baseline - deviceTags: - - aerotech - - motors - readOnly: false - softwareTrigger: false diff --git a/pxiii_bec/macros/beamline_planner.py b/pxiii_bec/macros/beamline_planner.py index 0aedc12..aa99268 100644 --- a/pxiii_bec/macros/beamline_planner.py +++ b/pxiii_bec/macros/beamline_planner.py @@ -1,7 +1,32 @@ -"""Planner to move between beamline statesΩ""" +"""Planner to move between beamline states""" -import time from collections import defaultdict, deque +from enum import Enum + +# from enums import BeamlineState, TemperatureMode +# from matcher import DeviceMatcher, nonzero_is_on + + +class BeamlineState(str, Enum): + """List of beamline states""" + + ROBOT_SAMPLE_EXCHANGE = "robot_sample_exchange" + SAMPLE_ALIGNMENT = "sample_alignment" + DATA_COLLECTION = "data_collection" + DC_XRF = "DC_XRF" + MANUAL_SAMPLE_EXCHANGE = "manual_sample_exchange" + BEAM_VISUALISATION = "beam_visualisation" + FLUX_MEASUREMENT = "flux_measurement" + BEAMSTOP_ALIGNMENT = "beamstop_alignment" + MAINTENANCE = "maintenance" + XTAL_SNAPSHOT = "xtal_snapshot" + + +class TemperatureMode(str, Enum): + """List of temperature modes""" + + CRYO = "cryo" + ROOM_TEMP = "room_temp" class StateChangePlanner: @@ -37,7 +62,6 @@ class StateChangePlanner: target.update(self.modifiers[modifier]) return target - def move_to(self, state_name, modifier=None): """Move devices to the correct positions to achieve a given state""" if isinstance(state_name, str): @@ -102,12 +126,8 @@ class StateChangePlanner: config = self._merged_state(state, modifier) # Check if all devices match their expected positions - if all(self.devices[d].is_at(p) - for d, p in config.items() - if d not in ignore_keys - ): - # print(f"Current state: {state.name}, Modifier: {modifier.name if modifier else 'None'}") - matches.append((state.name, modifier.name if modifier else 'None')) + if all(self.devices[d].is_at(p) for d, p in config.items() if d not in ignore_keys): + matches.append((state.name, modifier.name if modifier else "None")) return matches if matches else None diff --git a/pxiii_bec/macros/build_devices.py b/pxiii_bec/macros/build_devices.py index 3c8dd2e..f731107 100644 --- a/pxiii_bec/macros/build_devices.py +++ b/pxiii_bec/macros/build_devices.py @@ -1,14 +1,15 @@ -""" Build the sample environment devices""" +"""Build the sample environment devices""" + +import os import yaml # from position_device import PositionDevice -def motor_resolver(bec_name): - candidates = [ - bec_name, - bec_name.replace("_", "."), - ] +def motor_resolver(bec_name): + """Used to handle aerotech and smargon motors""" + + candidates = [bec_name, bec_name.replace("_", ".")] for path in candidates: try: @@ -24,9 +25,9 @@ def motor_resolver(bec_name): raise ValueError(f"Cannot resolve motor for '{bec_name}'") -def build_devices(yaml_file, mock_devices): - """ Build devices from the beamline states yaml""" +def build_devices(yaml_file, mock_devices): + """Build devices from the beamline states yaml""" state_devices = {} @@ -41,30 +42,321 @@ def build_devices(yaml_file, mock_devices): if not user: continue + if bec_name in ("aerotech", "smargon"): - tol = user.get("tol", 0.1) + tol = user.get("tol", 0.01) - positions = { - k: v for k, v in user.items() - if k not in ("type", "tol") - } + for axis in ["x", "y", "z", "u", "chi", "phi"]: - allow_arbitrary = (user["type"] == "continuous") - - + positions = user.get(axis) - pos_dev = PositionDevice( - bec_name=bec_name, - mot_device = motor_resolver(bec_name), - positions=positions, - tol=tol, - allow_arbitrary=allow_arbitrary, - use_mock=bec_name in mock_devices, - ) + if positions is None: + continue + + component_name = f"{bec_name}_{axis}" + + pos_dev = PositionDevice( + bec_name=component_name, + mot_device=motor_resolver(component_name), + positions=positions, + tol=tol, + allow_arbitrary=True, + use_mock=component_name in mock_devices, + ) + + state_devices[component_name] = pos_dev + + else: + + tol = user.get("tol", 0.1) + allow_arbitrary = user.get("type") == "continuous" + + positions = {k: v for k, v in user.items() if k not in ("type", "tol")} + + pos_dev = PositionDevice( + bec_name=bec_name, + mot_device=motor_resolver(bec_name), + positions=positions, + tol=tol, + allow_arbitrary=allow_arbitrary, + use_mock=bec_name in mock_devices, + ) + + state_devices[bec_name] = pos_dev - state_devices[bec_name] = pos_dev return state_devices +def update_position( + device, + position, + value, + axis=None, + force=False, + max_delta=0.5, +): + """ + Update a single saved position in memory. + Does NOT save or reload. Use save_and_reload() or + update_positions() afterwards. + """ + + params = device.user_parameter + + # ------------------------------------------------------------------ + # Nested device (e.g. aerotech.x.in) + # ------------------------------------------------------------------ + if axis is not None: + + if axis not in params: + raise KeyError( + f"Unknown axis '{axis}'. " + f"Valid axes: {list(params.keys())}" + ) + + axis_params = params[axis].copy() + + if position not in axis_params: + raise KeyError( + f"Unknown position '{position}'. " + f"Valid positions: {list(axis_params.keys())}" + ) + + old_value = axis_params[position] + + delta = abs(value - old_value) + + if delta > max_delta and not force: + raise ValueError( + f"Refusing to change " + f"{device.name}.{axis}.{position} " + f"from {old_value} to {value} " + f"(Δ={delta:.3f} > {max_delta}). " + f"Use force=True if intentional." + ) + + axis_params[position] = value + + device.update_user_parameter( + {axis: axis_params} + ) + + print( + f"Updated {device.name}.{axis}.{position}: " + f"{old_value} -> {value}" + ) + + return + + # ------------------------------------------------------------------ + # Flat device (e.g. bs_z) + # ------------------------------------------------------------------ + nested_keys = [ + k for k, v in params.items() + if isinstance(v, dict) + ] + + if nested_keys: + raise ValueError( + f"{device.name} has nested parameters " + f"({nested_keys}); specify axis=..." + ) + + if position not in params: + raise KeyError( + f"Unknown position '{position}'. " + f"Valid positions: {list(params.keys())}" + ) + + old_value = params[position] + + delta = abs(value - old_value) + + if delta > max_delta and not force: + raise ValueError( + f"Refusing to change " + f"{device.name}.{position} " + f"from {old_value} to {value} " + f"(Δ={delta:.3f} > {max_delta}). " + f"Use force=True if intentional." + ) + + device.update_user_parameter( + {position: value} + ) + + print( + f"Updated {device.name}.{position}: " + f"{old_value} -> {value}" + ) + + +def save_and_reload(): + """ + Save current configuration to YAML and rebuild + the beamline environment. + """ + + beamline = os.environ["BEAMLINE"] + + env = Environment(beamline=beamline) + + print(f"(saving changes to {env.devices_file})") + + bec.config.save_current_session(env.devices_file) + + return init_beamline_environment() + + +def update_positions(updates): + """ + Apply many updates, then save and reload once. + + updates = [ + { + "device": dev.aerotech, + "axis": "x", + "position": "in", + "value": 0, + }, + { + "device": dev.bs_z, + "position": "max_blout", + "value": 68, + }, + ] + """ + + for update in updates: + + update_position( + device=update["device"], + position=update["position"], + value=update["value"], + axis=update.get("axis"), + force=update.get("force", False), + max_delta=update.get("max_delta", 0.5), + ) + + return save_and_reload() + + +def save_current_position( + device, + position, + axis=None, + force=False, + max_delta=0.5, +): + """ + Save the current motor position as a named position. + """ + print(f"Saving current postion for {device}") + + params = device.user_parameter + + if axis is not None: + + if axis not in params: + raise KeyError( + f"Unknown axis '{axis}'. " + f"Valid axes: {list(params.keys())}" + ) + + axis_params = params[axis].copy() + + if position not in axis_params: + raise KeyError( + f"Unknown position '{position}'. " + f"Valid positions: {list(axis_params.keys())}" + ) + + old_value = axis_params[position] + print(f"Old value is {old_value}") + + current_value = get_current_value(device, axis=None) + + delta = abs(current_value - old_value) + + if delta > max_delta and not force: + raise ValueError( + f"Current position differs from saved value:\n" + f" saved = {old_value}\n" + f" current = {current_value}\n" + f" delta = {delta:.3f}\n" + f"Use force=True if intentional." + ) + + axis_params[position] = current_value + + device.update_user_parameter( + {axis: axis_params} + ) + + print( + f"Updated {device.name}.{axis}.{position}: " + f"{old_value} -> {current_value}" + ) + + return + # ------------------------------------------------------------------ + # Flat device (e.g. bs_z) + # ------------------------------------------------------------------ + nested_keys = [ + k for k, v in params.items() + if isinstance(v, dict) + ] + + if nested_keys: + raise ValueError( + f"{device.name} has nested parameters " + f"({nested_keys}); specify axis=..." + ) + + if position not in params: + raise KeyError( + f"Unknown position '{position}'. " + f"Valid positions: {list(params.keys())}" + ) + + old_value = params[position] + current_value = get_current_value(device, axis=None) + + delta = abs(current_value - old_value) + + if delta > max_delta and not force: + raise ValueError( + f"Refusing to change " + f"{device.name}.{position} " + f"from {old_value} to {current_value} " + f"(Δ={delta:.3f} > {max_delta}). " + f"Use force=True if intentional." + ) + + device.update_user_parameter( + {position: current_value} + ) + + print( + f"Updated {device.name}.{position}: " + f"{old_value} -> {current_value}" + ) + + +def get_current_value(device, axis=None): + """ + Return current motor position. + """ + + if axis is not None: + motor = getattr(device, axis) + else: + motor = device + + data = motor.read() + + signal_name = next(iter(data)) + + return round(data[signal_name]["value"],3) \ No newline at end of file diff --git a/pxiii_bec/macros/dependencies.py b/pxiii_bec/macros/dependencies.py index f83296c..6e9e522 100644 --- a/pxiii_bec/macros/dependencies.py +++ b/pxiii_bec/macros/dependencies.py @@ -1,30 +1,14 @@ """Planner dependencies""" + + def planner_deps(): """Define the dependencies between beamline positions""" return { - ("bs_z", "samp"): [ - ("aerotech_x", "out"), - ("diag_y", "out"), - ("coll_y", "out"), - ], - ("aerotech_x", "in"): [ - ("diag_y", "out"), - ("bs_z", "safe"), - ], - ("aerotech_x", "out"): [ - ("diag_y", "out"), - ("bs_z", "safe"), - ], - ("diag_y", "scint"): [ - ("aerotech_x", "out"), - ("bs_z", "safe"), - ("cryo_pos", "out"), - ], - ("diag_y", "i1"): [ - ("aerotech_x", "out"), - ("bs_z", "safe"), - ("cryo_pos", "out"), - ], + ("bs_z", "samp"): [("aerotech_x", "out"), ("diag_y", "out"), ("coll_y", "out")], + ("aerotech_x", "in"): [("diag_y", "out"), ("bs_z", "safe")], + ("aerotech_x", "out"): [("diag_y", "out"), ("bs_z", "safe")], + ("diag_y", "scint"): [("aerotech_x", "out"), ("bs_z", "safe"), ("cryo_pos", "out")], + ("diag_y", "i1"): [("aerotech_x", "out"), ("bs_z", "safe"), ("cryo_pos", "out")], ("bs_pos", "out"): [("bs_z", "safe")], ("bs_pos", "in"): [("bs_z", "safe")], ("diag_y", "out"): [("bs_z", "safe")], diff --git a/pxiii_bec/macros/devices_manager.py b/pxiii_bec/macros/devices_manager.py index 64b5ab3..cc201db 100644 --- a/pxiii_bec/macros/devices_manager.py +++ b/pxiii_bec/macros/devices_manager.py @@ -1,22 +1,23 @@ """ This module manages the initialization of devices.""" -# from guards import attach_guards -# from policies import attach_policies -# from build_devices import build_devices +#from guards import attach_guards +#from policies import attach_policies +#from build_devices import build_devices class DeviceManager: """Class for building devices and attaching safety guards and policies.""" @staticmethod - def initialize_devices(state_devices_file, rest_devices_file, mock_devices): + # def initialize_devices(state_devices_file, rest_devices_file, mock_devices): + def initialize_devices(devices_file, mock_devices): """ Initializes sample environment devices from the specified file. """ - devices = build_devices(state_devices_file, mock_devices) - rest_devices = build_devices(rest_devices_file, mock_devices) - devices.update(rest_devices) + devices = build_devices(devices_file, mock_devices) + # rest_devices = build_devices(rest_devices_file, mock_devices) + # devices.update(rest_devices) attach_guards(devices) attach_policies(devices) return devices diff --git a/pxiii_bec/macros/enums.py b/pxiii_bec/macros/enums.py deleted file mode 100644 index 40b8d9f..0000000 --- a/pxiii_bec/macros/enums.py +++ /dev/null @@ -1,22 +0,0 @@ -"""Enums for beamline states""" -from enum import Enum - - -class BeamlineState(str, Enum): - """List of beamline states""" - ROBOT_SAMPLE_EXCHANGE = "robot_sample_exchange" - SAMPLE_ALIGNMENT = "sample_alignment" - DATA_COLLECTION = "data_collection" - DC_XRF = "DC_XRF" - MANUAL_SAMPLE_EXCHANGE = "manual_sample_exchange" - BEAM_VISUALISATION = "beam_visualisation" - FLUX_MEASUREMENT = "flux_measurement" - BEAMSTOP_ALIGNMENT = "beamstop_alignment" - MAINTENANCE = "maintenance" - XTAL_SNAPSHOT = "xtal_snapshot" - - -class TemperatureMode(str, Enum): - """List of temperature modes""" - CRYO = "cryo" - ROOM_TEMP = "room_temp" diff --git a/pxiii_bec/macros/guards.py b/pxiii_bec/macros/guards.py index 0446e61..1306af9 100644 --- a/pxiii_bec/macros/guards.py +++ b/pxiii_bec/macros/guards.py @@ -15,9 +15,7 @@ class AtPositionGuard: def check(self): """Check if the device is in the specified position.""" if self.device.pos != self.pos: - raise GuardViolation( - f"{self.device.bec_name} must be in the '{self.pos}' position" - ) + raise GuardViolation(f"{self.device.bec_name} must be in the '{self.pos}' position") # print("move allowed") return True diff --git a/pxiii_bec/macros/init_beamline.py b/pxiii_bec/macros/init_beamline.py index 2147275..78330d6 100644 --- a/pxiii_bec/macros/init_beamline.py +++ b/pxiii_bec/macros/init_beamline.py @@ -8,6 +8,7 @@ from dataclasses import dataclass # from dependencies import planner_deps # from beamline_planner import StateChangePlanner + @dataclass class Environment: @@ -21,18 +22,16 @@ class Environment: # "rest": "pxi-rest-devices.yaml", # "states": "pxi-beamline-states.yaml", # }, - "x10sa" : { + "x10sa": { "devdir": "/sls/x10sa/config/bec/production/pxii_bec/pxii_bec/device_configs/", - "state": "pxii-state-devices.yaml", - "rest": "pxii-rest-devices.yaml", + "devices": "pxii-devices.yaml", "states": "pxii-beamline-states.yaml", }, - "x06da" : { + "x06da": { "devdir": "/sls/x06da/config/bec/production/pxiii_bec/pxiii_bec/device_configs/", - "state": "pxiii-state-devices.yaml", - "rest": "pxiii-rest-devices.yaml", + "devices": "pxiii-devices.yaml", "states": "pxiii-beamline-states.yaml", - } + }, } def __post_init__(self): @@ -60,34 +59,23 @@ class Environment: "xrf_pos": "mock", } - mocks = sorted( - name - for name, backend in self.device_mocks.items() - if backend == "mock" - ) + mocks = sorted(name for name, backend in self.device_mocks.items() if backend == "mock") - reals = sorted( - name - for name, backend in self.device_mocks.items() - if backend == "real" - ) + reals = sorted(name for name, backend in self.device_mocks.items() if backend == "real") - print(f"Mock devices ({len(mocks)}): {mocks}") - print(f"Real devices ({len(reals)}): {reals}") + # print(f"Mock devices ({len(mocks)}): {mocks}") + # print(f"Real devices ({len(reals)}): {reals}") try: cfg = self.beamline_configs[self.beamline] except KeyError: - raise ValueError( - f"Unknown beamline '{self.beamline}'" - ) + raise ValueError(f"Unknown beamline '{self.beamline}'") devdir = cfg["devdir"] - self.state_devices_file = devdir + cfg["state"] - self.rest_devices_file = devdir + cfg["rest"] + self.devices_file = devdir + cfg["devices"] self.states_file = devdir + cfg["states"] - + mock_start_positions = { "aerotech_x": "in", "aerotech_y": "mount", @@ -107,7 +95,7 @@ class Environment: "smargon_z": "mount", "smargon_chi": "mount", "smargon_phi": "mount", - "xrf_pos": "out", + "xrf_pos": "out", } @property @@ -116,7 +104,8 @@ class Environment: for name, device in self.device_mocks.items(): if device == "mock": mock_names.add(name) - return mock_names + return mock_names + def init_beamline_environment(): """ @@ -125,15 +114,11 @@ def init_beamline_environment(): beamline = os.environ["BEAMLINE"] - env = Environment(beamline = beamline) + env = Environment(beamline=beamline) # Initialize devices device_manager = DeviceManager() - devices = device_manager.initialize_devices( - env.state_devices_file, - env.rest_devices_file, - env.mock_devices - ) + devices = device_manager.initialize_devices(env.devices_file, env.mock_devices) # Initialize states state_manager = DefineStatesManager() @@ -144,7 +129,7 @@ def init_beamline_environment(): # Setup planner planner = StateChangePlanner(devices, states, allow_modifiers, deps) - print("Initializing beamline state planner") + print("Initializing beamline state planner and devices") # Set mock motor starting positions @@ -155,9 +140,4 @@ def init_beamline_environment(): except Exception as e: print(f"{e} error when setting {mock_dev}") - return devices, planner - - - - diff --git a/pxiii_bec/macros/mx_methods.py b/pxiii_bec/macros/mx_methods.py index d697d18..4714e4f 100644 --- a/pxiii_bec/macros/mx_methods.py +++ b/pxiii_bec/macros/mx_methods.py @@ -17,6 +17,17 @@ import numpy as np # ) +@dataclass(frozen=True) +class FitDefaults: + """Default values for fitting routines""" + + # Constants for default models, baselines, and parameters + MODEL = "Voigt" + BASELINE = "Linear" + SETTLE_TIME = 0.1 + RELATIVE_MODE = True + + # Method functions def calculate_step_size(start: float, stop: float, steps: int) -> float: """ diff --git a/pxiii_bec/macros/policies.py b/pxiii_bec/macros/policies.py index 576edae..cea388c 100644 --- a/pxiii_bec/macros/policies.py +++ b/pxiii_bec/macros/policies.py @@ -58,15 +58,16 @@ def make_diag_y_policy(d): def diag_y_policy(target): cfg = d["diag_y"].positions # Don't move in if the goniometer is in - if d["aerotech_x"].actual >= d['aerotech_x'].positions['in'] and target > cfg["out"]: + if d["aerotech_x"].actual >= d["aerotech_x"].positions["in"] and target > cfg["out"]: raise GuardViolation( f"Diagnostic device cannot move beyond {cfg['out']} mm when goniometer is not OUT" ) # Don't move if cryocooler is in - if d['cryo_pos'].pos == 'in' and target > cfg['out']: + if d["cryo_pos"].pos == "in" and target > cfg["out"]: raise GuardViolation( f"Diagnostic device cannot move beyond {cfg['out']} mm when cryocooler is IN" ) + return diag_y_policy diff --git a/pxiii_bec/macros/pxiii_energy.py b/pxiii_bec/macros/pxiii_energy.py index e594f06..622e39b 100644 --- a/pxiii_bec/macros/pxiii_energy.py +++ b/pxiii_bec/macros/pxiii_energy.py @@ -147,7 +147,7 @@ def mono_pitch_scan(plot=True): print("Scanning monochromator pitch and moving to peak, with plotting.") go_to_peak( EnergyDefaults.mono_pitch, - EnergyDefaults.signals["sig1"], + EnergyDefaults.signals["sig2"], -EnergyDefaults.pitch_scan["halfwidth"], EnergyDefaults.pitch_scan["halfwidth"], steps=EnergyDefaults.pitch_scan["steps"], @@ -160,7 +160,7 @@ def mono_pitch_scan(plot=True): print("Scanning monochromator pitch and moving to peak, without plotting.") go_to_peak( EnergyDefaults.mono_pitch, - EnergyDefaults.signals["sig1"], + EnergyDefaults.signals["sig2"], -EnergyDefaults.pitch_scan["halfwidth"], EnergyDefaults.pitch_scan["halfwidth"], steps=EnergyDefaults.pitch_scan["steps"], @@ -189,8 +189,10 @@ def get_dccm_motors_positions(energy_ev): # dccm_motor_values = get_value_from_lut(energy_ev) th1_angle = -convert_from_energy(energy_ev, print_result=False)["bragg_angle_deg"] th2_angle = convert_from_energy(energy_ev, temp=298, print_result=False)["bragg_angle_deg"] + # add fudge factor + th2_angle_fudge = th2_angle + 0.006 # dccm_motor_values.update({"theta1_angle": th1_angle, "theta2_angle": th2_angle}) - dccm_motor_values = {"theta1_angle": th1_angle, "theta2_angle": th2_angle} + dccm_motor_values = {"theta1_angle": th1_angle, "theta2_angle": th2_angle_fudge} return dccm_motor_values diff --git a/pxiii_bec/macros/pxiii_parameters.py b/pxiii_bec/macros/pxiii_parameters.py index 62733f0..cba3d5b 100644 --- a/pxiii_bec/macros/pxiii_parameters.py +++ b/pxiii_bec/macros/pxiii_parameters.py @@ -4,16 +4,6 @@ from dataclasses import dataclass import numpy as np -@dataclass(frozen=True) -class FitDefaults: - """Default values for fitting routines""" - - # Constants for default models, baselines, and parameters - MODEL = "Voigt" - BASELINE = "Linear" - SETTLE_TIME = 0.1 - RELATIVE_MODE = True - @dataclass(frozen=True) class EnergyDefaults: @@ -32,7 +22,7 @@ class EnergyDefaults: mono_pitch = dev.dccm_theta2 # LUT_table = "luts/energy_lut.csv" stripe_thresholds = {"silicon": 9000, "rhodium": 40000} - pitch_scan = {"halfwidth": 0.15, "steps": 30} + pitch_scan = {"halfwidth": 0.01, "steps": 25} @dataclass(frozen=True)