From 8bba6b3fb7c7b8bdbba31357d7b1fe505e50daf9 Mon Sep 17 00:00:00 2001 From: x06da Date: Tue, 4 Aug 2026 09:53:56 +0200 Subject: [PATCH] Changes from beamline as of 260804 --- .../old/pxiii-rest-devices.yaml | 18 + .../old/pxiii-standard-devices.yaml | 1333 ++++++++++++++ .../old/pxiii-state-devices.yaml | 130 ++ .../old/x06da_device_config.yaml | 30 + .../device_configs/pxiii-beamline-states.yaml | 2 + pxiii_bec/device_configs/pxiii-devices.yaml | 1544 +++++++++++++++++ pxiii_bec/macros/beamline_planner.py | 69 +- pxiii_bec/macros/beampos_with_en.py | 13 + pxiii_bec/macros/calibrate.py | 24 + pxiii_bec/macros/enums.bak | 22 + pxiii_bec/macros/katscripts.py | 1538 ++++++++++++++++ pxiii_bec/macros/katscripts.py-save | 1536 ++++++++++++++++ pxiii_bec/macros/luts/22060940_lut.csv | 10 + .../beampos19_20_clean_1306081012p414.csv | 119 ++ .../macros/luts/beampos/beampos_17071807.csv | 5 + .../macros/luts/beampos/beampos_17071810.csv | 3 + .../macros/luts/beampos/beampos_17071813.csv | 103 ++ .../macros/luts/beampos/beampos_18071203.csv | 73 + .../luts/beampos/beampos_18071203_clean.csv | 73 + .../macros/luts/beampos/beampos_19072001.csv | 15 + .../macros/luts/beampos/beampos_19072104.csv | 8 + .../macros/luts/beampos/beampos_19072256.csv | 9 + .../macros/luts/beampos/beampos_19072330.csv | 20 + .../macros/luts/beampos/beampos_20070058.csv | 26 + .../macros/luts/beampos/beampos_20070256.csv | 27 + .../macros/luts/beampos/beampos_20070459.csv | 26 + 26 files changed, 6772 insertions(+), 4 deletions(-) create mode 100644 pxiii_bec/device_configs/old/pxiii-rest-devices.yaml create mode 100644 pxiii_bec/device_configs/old/pxiii-standard-devices.yaml create mode 100644 pxiii_bec/device_configs/old/pxiii-state-devices.yaml create mode 100644 pxiii_bec/device_configs/old/x06da_device_config.yaml create mode 100644 pxiii_bec/device_configs/pxiii-devices.yaml create mode 100644 pxiii_bec/macros/beampos_with_en.py create mode 100644 pxiii_bec/macros/calibrate.py create mode 100644 pxiii_bec/macros/enums.bak create mode 100755 pxiii_bec/macros/katscripts.py create mode 100755 pxiii_bec/macros/katscripts.py-save create mode 100644 pxiii_bec/macros/luts/22060940_lut.csv create mode 100644 pxiii_bec/macros/luts/beampos/beampos19_20_clean_1306081012p414.csv create mode 100644 pxiii_bec/macros/luts/beampos/beampos_17071807.csv create mode 100644 pxiii_bec/macros/luts/beampos/beampos_17071810.csv create mode 100644 pxiii_bec/macros/luts/beampos/beampos_17071813.csv create mode 100644 pxiii_bec/macros/luts/beampos/beampos_18071203.csv create mode 100644 pxiii_bec/macros/luts/beampos/beampos_18071203_clean.csv create mode 100644 pxiii_bec/macros/luts/beampos/beampos_19072001.csv create mode 100644 pxiii_bec/macros/luts/beampos/beampos_19072104.csv create mode 100644 pxiii_bec/macros/luts/beampos/beampos_19072256.csv create mode 100644 pxiii_bec/macros/luts/beampos/beampos_19072330.csv create mode 100644 pxiii_bec/macros/luts/beampos/beampos_20070058.csv create mode 100644 pxiii_bec/macros/luts/beampos/beampos_20070256.csv create mode 100644 pxiii_bec/macros/luts/beampos/beampos_20070459.csv diff --git a/pxiii_bec/device_configs/old/pxiii-rest-devices.yaml b/pxiii_bec/device_configs/old/pxiii-rest-devices.yaml new file mode 100644 index 0000000..e651780 --- /dev/null +++ b/pxiii_bec/device_configs/old/pxiii-rest-devices.yaml @@ -0,0 +1,18 @@ +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/old/pxiii-standard-devices.yaml b/pxiii_bec/device_configs/old/pxiii-standard-devices.yaml new file mode 100644 index 0000000..e8d8767 --- /dev/null +++ b/pxiii_bec/device_configs/old/pxiii-standard-devices.yaml @@ -0,0 +1,1333 @@ +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/old/pxiii-state-devices.yaml b/pxiii_bec/device_configs/old/pxiii-state-devices.yaml new file mode 100644 index 0000000..e96c4aa --- /dev/null +++ b/pxiii_bec/device_configs/old/pxiii-state-devices.yaml @@ -0,0 +1,130 @@ +bl_bright: + description: Backlight Brightness + deviceClass: ophyd.EpicsSignal + deviceConfig: {read_pv: 'X06DA-ES-BL:SET', auto_monitor: true} + onFailure: buffer + enabled: True + readoutPriority: baseline + deviceTags: + - state + readOnly: False + softwareTrigger: false + userParameter: {"type": continuous, "on": 1.3, "off": 0, “tol”: 0.01} + +bl_pos: + description: Backlight Positioner + deviceClass: ophyd.EpicsSignal + deviceConfig: {read_pv: 'X06DA-ES-BL:POS-SET', auto_monitor: true} + onFailure: buffer + enabled: True + readoutPriority: baseline + deviceTags: + - state + readOnly: False + softwareTrigger: false + userParameter: {"type": discrete, "in": 1, "out": 0} + +bs_pos: + description: Beamstop Positioner + deviceClass: ophyd.EpicsSignal + deviceConfig: {read_pv: 'X06DA-ES-BS:POS-SET', auto_monitor: true} + onFailure: buffer + enabled: True + readoutPriority: baseline + deviceTags: + - state + readOnly: False + softwareTrigger: false + userParameter: {"type": discrete, "in": 1, "out": 0} + +bs_z: + description: Beamstop Z + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: {prefix: 'X06DA-ES-BS:TRZ'} + onFailure: buffer + enabled: True + readoutPriority: baseline + deviceTags: + - state + readOnly: False + softwareTrigger: false + userParameter: {"type": continuous, "min": 13, "samp": 15, "work_min": 20, "safe": 25, "max_blin": 26, "max_blout": 35} + +coll_y: + description: Collimator Y + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: {prefix: 'X06DA-ES-COL:TRY'} + onFailure: buffer + enabled: True + readoutPriority: baseline + deviceTags: + - state + readOnly: False + softwareTrigger: false + userParameter: {"type": continuous, "in": 25.42, "intermediate": 15, "out":5.0, "park": 0,"tol":0.05} + +cryo_pos: + description: Cryo Positioner + deviceClass: ophyd.EpicsSignal + deviceConfig: {read_pv: 'X06DA-ES-CS:POS-SET', auto_monitor: true} + onFailure: buffer + enabled: True + readoutPriority: baseline + deviceTags: + - state + readOnly: False + softwareTrigger: false + userParameter: {"type": discrete, "in": 1, "out": 0} + +det_cov: + description: Detector Cover + deviceClass: ophyd.EpicsSignal + deviceConfig: {read_pv: 'X06DA-ES-DETCOV:SET', auto_monitor: true} + onFailure: buffer + enabled: True + readoutPriority: baseline + deviceTags: + - state + readOnly: False + softwareTrigger: false + userParameter: {"type": discrete, "open": 2, "close": 1} + +diag_y: + description: Scintillator/diode Y + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: {prefix: 'X06DA-ES-SCL:TRY'} + onFailure: buffer + enabled: True + readoutPriority: baseline + deviceTags: + - state + readOnly: False + softwareTrigger: false + userParameter: {"type": continuous, "scint": 22, "i1": 29, "out": 5.0,"park": 0,"tol":0.3} + +fl_bright: + description: Frontlight Brightness + deviceClass: ophyd.EpicsSignal + deviceConfig: {read_pv: 'X06DA-ES-FL:SET', auto_monitor: true} + onFailure: buffer + enabled: True + readoutPriority: baseline + deviceTags: + - state + readOnly: False + softwareTrigger: false + userParameter: {"type": continuous, "on": 3.0, "off": 0, “tol”: 0.01} + +xrf_pos: + description: XRF Positioner + deviceClass: ophyd.EpicsSignal + deviceConfig: {read_pv: 'X06DA-ES-XRF:POS-SET', auto_monitor: true} + onFailure: buffer + enabled: True + readoutPriority: baseline + deviceTags: + - state + readOnly: False + softwareTrigger: false + userParameter: {"type": discrete, "in": 1, "out": 0} + diff --git a/pxiii_bec/device_configs/old/x06da_device_config.yaml b/pxiii_bec/device_configs/old/x06da_device_config.yaml new file mode 100644 index 0000000..19cfc62 --- /dev/null +++ b/pxiii_bec/device_configs/old/x06da_device_config.yaml @@ -0,0 +1,30 @@ +base_config: + - !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/device_configs/pxiii-beamline-states.yaml b/pxiii_bec/device_configs/pxiii-beamline-states.yaml index 8628a22..e8579d9 100644 --- a/pxiii_bec/device_configs/pxiii-beamline-states.yaml +++ b/pxiii_bec/device_configs/pxiii-beamline-states.yaml @@ -103,6 +103,7 @@ states: smargon_chi: mount smargon_phi: mount xrf_pos: out + det_z: 'mse' beam_visualisation: bl_pos: out @@ -112,6 +113,7 @@ states: coll_y: in cryo_pos: out det_cov: 'close' + det_z: 'vis' diag_y: scint fl_bright: 'off' aerotech_x: out diff --git a/pxiii_bec/device_configs/pxiii-devices.yaml b/pxiii_bec/device_configs/pxiii-devices.yaml new file mode 100644 index 0000000..2ac3186 --- /dev/null +++ b/pxiii_bec/device_configs/pxiii-devices.yaml @@ -0,0 +1,1544 @@ +# BEC Device Configuration File +# +# The device config consists of a mapping of device names to their configurations. +# +# The following fields are required for each device: +# - deviceClass: The class of the device (e.g., ophyd_devices.SimPositioner). +# - enabled: A boolean indicating if the device is enabled. +# - readoutPriority: Determines how the device is read out during a scan. Possible values are ["monitored", "baseline", "async", "on_request", "continuous"]. +# +# Optional fields (defaults shown): +# - connectionTimeout: Connection timeout in seconds. Default is 5. +# - description: A string description of the device. Default is "" (empty string). +# - deviceConfig: A dictionary of configuration parameters specific to the device class. Default is None. +# - deviceTags: A list/set of tags associated with the device. Default is an empty list/set. +# - needs: A list of other device names that this device depends on. Default is []. +# - onFailure: The action to take on failure. Possible values are ["buffer", "retry", "raise"]. Default is "retry". +# - readOnly: A boolean indicating if the device is read-only. Default is false. +# - softwareTrigger: A boolean indicating if the device uses software triggering. Default is false. +# - userParameter: A dictionary of user-defined parameters. Default is {}. +# +# Default values may be omitted for brevity. +########################################################################################################################## + + +# An example device configuration with all fields: + +# device1: +# deviceClass: ophyd_devices.SimPositioner +# description: Sample positioner device +# deviceConfig: +# delay: 1 +# update_frequency: 10 +# deviceTags: +# - frontend +# - motor +# enabled: true +# connectionTimeout: 20 +# readoutPriority: baseline +# needs: +# - device2 +# - device3 +# onFailure: retry +# readOnly: false +# softwareTrigger: false +# userParameter: +# in: 23.1 +# out: -50 + +########################################################################################################################## + + +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 + deviceTags: + - motors + - aerotech + enabled: true + onFailure: buffer + readoutPriority: baseline + userParameter: + u: + mount: 0 + work: 0 + work: null + x: + in: 0 + out: -10 + safe: -50 + y: + mount: 0 + work: 0.026 + z: + mount: 0 + work: 0.022 +bcu_bpm1: + description: BCU BPM Channel 1 + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-BCBPM:Current1:MeanValue_RBV + deviceTags: + - bpm + enabled: true + onFailure: buffer + readOnly: true + readoutPriority: monitored +bcu_bpm2: + description: BCU BPM Channel 2 + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-BCBPM:Current2:MeanValue_RBV + deviceTags: + - bpm + enabled: true + onFailure: buffer + readOnly: true + readoutPriority: monitored +bcu_bpm3: + description: BCU BPM Channel 3 + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-BCBPM:Current3:MeanValue_RBV + deviceTags: + - bpm + enabled: true + onFailure: buffer + readOnly: true + readoutPriority: monitored +bcu_bpm4: + description: BCU BPM Channel 4 + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-BCBPM:Current4:MeanValue_RBV + deviceTags: + - bpm + enabled: true + onFailure: buffer + readOnly: true + readoutPriority: monitored +bcu_bpm_x: + description: BCU BPM X + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-BCBPM:TRX + deviceTags: + - bcu + enabled: true + onFailure: buffer + readoutPriority: baseline +bcu_bpm_y: + description: BCU BPM Y + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-BCBPM:TRY + deviceTags: + - bcu + enabled: true + onFailure: buffer + readoutPriority: baseline +bcu_bpmsum: + description: BCU BPM Summed + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-BCBPM:SumAll:MeanValue_RBV + deviceTags: + - bpm + enabled: true + onFailure: buffer + readOnly: true + readoutPriority: monitored +bcu_shutter: + description: Fast Shutter + deviceClass: ophyd_devices.EpicsSignal + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-SHUTTER:SET + deviceTags: + - state + enabled: true + onFailure: buffer + readoutPriority: baseline +bcu_sl_xcen: + description: BCU Slit X Centre + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-BCSLH:CENTER + deviceTags: + - bcu + enabled: true + onFailure: buffer + readoutPriority: baseline +bcu_sl_xr: + description: BCU Slit Ring + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-BCSLH:TRXR + deviceTags: + - bcu + enabled: true + onFailure: buffer + readoutPriority: baseline +bcu_sl_xsize: + description: BCU Slit X Size + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-BCSLH:SIZE + deviceTags: + - bcu + enabled: true + onFailure: buffer + readoutPriority: baseline +bcu_sl_xw: + description: BCU Slit Wall + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-BCSLH:TRXW + deviceTags: + - bcu + enabled: true + onFailure: buffer + readoutPriority: baseline +bcu_sl_yb: + description: BCU Slit Bottom + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-BCSLV:TRYB + deviceTags: + - bcu + enabled: true + onFailure: buffer + readoutPriority: baseline +bcu_sl_ycen: + description: BCU Slit Y Centre + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-BCSLV:CENTER + deviceTags: + - bcu + enabled: true + onFailure: buffer + readoutPriority: baseline +bcu_sl_ysize: + description: BCU Slit Y Size + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-BCSLV:SIZE + deviceTags: + - bcu + enabled: true + onFailure: buffer + readoutPriority: baseline +bcu_sl_yt: + description: BCU Slit top + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-BCSLV:TRYT + deviceTags: + - bcu + enabled: true + onFailure: buffer + readoutPriority: baseline +bl_bright: + description: Backlight Brightness + deviceClass: ophyd.EpicsSignal + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-BL:SET + deviceTags: + - state + enabled: true + onFailure: buffer + readoutPriority: baseline + userParameter: + 'off': 0 + 'on': 1.3 + type: continuous + "\u201Ctol\u201D": 0.01 +bl_pos: + description: Backlight Positioner + deviceClass: ophyd.EpicsSignal + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-BL:POS-SET + deviceTags: + - state + enabled: true + onFailure: buffer + readoutPriority: baseline + userParameter: + in: 1 + out: 0 + type: discrete +bs_pos: + description: Beamstop Positioner + deviceClass: ophyd.EpicsSignal + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-BS:POS-SET + deviceTags: + - state + enabled: true + onFailure: buffer + readoutPriority: baseline + userParameter: + in: 1 + out: 0 + type: discrete +bs_x: + description: Beamstop X + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-BS:TRX + deviceTags: + - se + enabled: true + onFailure: buffer + readoutPriority: baseline +bs_y: + description: Beamstop Y + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-BS:TRY + deviceTags: + - se + enabled: true + onFailure: buffer + readoutPriority: baseline +bs_z: + description: Beamstop Z + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-BS:TRZ + deviceTags: + - state + enabled: true + onFailure: buffer + readoutPriority: baseline + userParameter: + max_blin: 26 + max_blout: 35 + min: 13 + safe: 24 + samp: 15 + type: continuous + work_min: 20 +bsf_f1_y: + description: BSF Filter 1 Y + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-OP-BSFFI1:TRY + deviceTags: + - bsf + enabled: true + onFailure: buffer + readoutPriority: baseline +bsf_sl_xcen: + description: BSF X Centre + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-OP-BSFSLH:CENTER + deviceTags: + - bsf + enabled: true + onFailure: buffer + readoutPriority: baseline +bsf_sl_xr: + description: BSF Slit inboard + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-OP-BSFSLH:TRXR + deviceTags: + - bsf + enabled: true + onFailure: buffer + readoutPriority: baseline +bsf_sl_xsize: + description: BSF X Size + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-OP-BSFSLH:SIZE + deviceTags: + - bsf + enabled: true + onFailure: buffer + readoutPriority: baseline +bsf_sl_xw: + description: BSF Slit outboard + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-OP-BSFSLH:TRXW + deviceTags: + - bsf + enabled: true + onFailure: buffer + readoutPriority: baseline +coll_x: + description: Collimator X + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-COL:TRX + deviceTags: + - se + enabled: true + onFailure: buffer + readoutPriority: baseline +coll_y: + description: Collimator Y + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-COL:TRY + deviceTags: + - state + enabled: true + onFailure: buffer + readoutPriority: baseline + userParameter: + in: 25.42 + intermediate: 15 + out: 4.901 + park: 0 + tol: 0.05 + type: continuous +cryo_pos: + description: Cryo Positioner + deviceClass: ophyd.EpicsSignal + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-CS:POS-SET + deviceTags: + - state + enabled: true + onFailure: buffer + readoutPriority: baseline + userParameter: + in: 1 + out: 0 + type: discrete +cryo_temp: + description: Cryo Temperature + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-CS:TEMP_RBV + deviceTags: + - se + enabled: true + onFailure: buffer + readoutPriority: baseline +cryo_x: + description: Cryo X + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-CS:TRX + deviceTags: + - se + enabled: true + onFailure: buffer + readoutPriority: baseline +dccm_bpm1: + description: DCCM BPM Channel 1 + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-OP-DCCMXBPM2:Current1:MeanValue_RBV + deviceTags: + - dccm + enabled: true + onFailure: buffer + readoutPriority: monitored +dccm_bpm2: + description: DCCM BPM Channel 2 + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-OP-DCCMXBPM2:Current2:MeanValue_RBV + deviceTags: + - dccm + enabled: true + onFailure: buffer + readoutPriority: monitored +dccm_bpm3: + description: DCCM BPM Channel 3 + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-OP-DCCMXBPM2:Current3:MeanValue_RBV + deviceTags: + - dccm + enabled: true + onFailure: buffer + readoutPriority: monitored +dccm_bpm4: + description: DCCM BPM Channel 4 + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-OP-DCCMXBPM2:Current4:MeanValue_RBV + deviceTags: + - dccm + enabled: true + onFailure: buffer + readoutPriority: monitored +dccm_bpmsum: + description: DCCM BPM Summed + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-OP-DCCMXBPM2:SumAll:MeanValue_RBV + deviceTags: + - dccm + enabled: true + onFailure: buffer + readoutPriority: monitored +dccm_di_bot: + description: DCCM Diode Bottom + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-OP-DCCMXBPM1B:READOUT + deviceTags: + - dccm + enabled: true + onFailure: buffer + readoutPriority: monitored +dccm_di_top: + description: DCCM Diode Top + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-OP-DCCMXBPM1T:READOUT + deviceTags: + - dccm + enabled: true + onFailure: buffer + readoutPriority: monitored +dccm_energy: + description: DCCM Energy + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-OP-DCCM:ENERGY + deviceTags: + - dccm + enabled: true + onFailure: buffer + readoutPriority: baseline +dccm_rotz: + description: DCCM RotZ Xtal 2 + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-OP-DCCM:ROTZ-CR2 + deviceTags: + - dccm + enabled: true + onFailure: buffer + readoutPriority: baseline +dccm_theta1: + description: DCCM Theta Xtal1 + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-OP-DCCM:ROTX-CR1 + deviceTags: + - dccm + enabled: true + onFailure: buffer + readoutPriority: baseline +dccm_theta2: + description: DCCM Theta Xtal2 + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-OP-DCCM:ROTX-CR2 + deviceTags: + - dccm + enabled: true + onFailure: buffer + readoutPriority: baseline +dccm_xbpm1_y: + description: DCCM BPM1 Y + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-OP-DCCMXBPM1:TRY + deviceTags: + - dccm + enabled: true + onFailure: buffer + readoutPriority: baseline +dccm_xbpm2_y: + description: DCCM BPM2 Y + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-OP-DCCMXBPM2:TRY + deviceTags: + - dccm + enabled: true + onFailure: buffer + readoutPriority: baseline +det_cov: + description: Detector Cover + deviceClass: ophyd.EpicsSignal + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-DETCOV:SET + deviceTags: + - state + enabled: true + onFailure: buffer + readoutPriority: baseline + userParameter: + close: 1 + open: 2 + type: discrete +det_y: + description: Detector Y + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-ES-DET:TRY + deviceTags: + - det + enabled: true + onFailure: buffer + readoutPriority: baseline +det_z: + description: Detector Z + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-ES-DET:TRZ + deviceTags: + - det + enabled: true + onFailure: buffer + readoutPriority: baseline + userParameter: + vis: 150 + mse: 800 +diag_y: + description: Scintillator/diode Y + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-SCL:TRY + deviceTags: + - state + enabled: true + onFailure: buffer + readoutPriority: baseline + userParameter: + i1: 27 + out: 5.0 + park: 0 + scint: 22 + tol: 0.3 + type: continuous +diag_z: + description: Scintillator/diode Z + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-SCL:TRZ + deviceTags: + - se + enabled: true + onFailure: buffer + readoutPriority: baseline +fe_sl_xcen: + description: FE Slit X Centre + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-FE-SLDI:CENTERX + deviceTags: + - fe + enabled: true + onFailure: buffer + readoutPriority: baseline +fe_sl_xr: + description: FE Slit X Ring + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-FE-SLDI:TRXR + deviceTags: + - fe + enabled: true + onFailure: buffer + readoutPriority: baseline +fe_sl_xsize: + description: FE Slit X Size + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-FE-SLDI:SIZEX + deviceTags: + - fe + enabled: true + onFailure: buffer + readoutPriority: baseline +fe_sl_xw: + description: FE Slit X Wall + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-FE-SLDI:TRXW + deviceTags: + - fe + enabled: true + onFailure: buffer + readoutPriority: baseline +fe_sl_yb: + description: FE Slit Y Bottom + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-FE-SLDI:TRYB + deviceTags: + - fe + enabled: true + onFailure: buffer + readoutPriority: baseline +fe_sl_ycen: + description: FE Slit Y Centre + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-FE-SLDI:CENTERY + deviceTags: + - fe + enabled: true + onFailure: buffer + readoutPriority: baseline +fe_sl_ysize: + description: FE Slit Y Size + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-FE-SLDI:SIZEY + deviceTags: + - fe + enabled: true + onFailure: buffer + readoutPriority: baseline +fe_sl_yt: + description: FE Slit Y Top + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-FE-SLDI:TRYT + deviceTags: + - fe + enabled: true + onFailure: buffer + readoutPriority: baseline +fl_bright: + description: Frontlight Brightness + deviceClass: ophyd.EpicsSignal + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-FL:SET + deviceTags: + - state + enabled: true + onFailure: buffer + readoutPriority: baseline + userParameter: + 'off': 0 + 'on': 3.0 + type: continuous + "\u201Ctol\u201D": 0.01 +hfm_bd: + description: HFM Downstream Bender + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-ES-HFM:BNDD + deviceTags: + - hfm + enabled: true + onFailure: buffer + readoutPriority: baseline +hfm_bu: + description: HFM Upstream Bender + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-ES-HFM:BNDU + deviceTags: + - hfm + enabled: true + onFailure: buffer + readoutPriority: baseline +hfm_pitch: + description: HFM Virtual Pitch + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-ES-HFM:PITCH + deviceTags: + - hfm + enabled: true + onFailure: buffer + readoutPriority: baseline +hfm_roll: + description: HFM Virtual Roll + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-ES-HFM:ROLL + deviceTags: + - hfm + enabled: true + onFailure: buffer + readoutPriority: baseline +hfm_x: + description: HFM Virtual X + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-ES-HFM:TRX + deviceTags: + - hfm + enabled: true + onFailure: buffer + readoutPriority: baseline +hfm_xd: + description: HFM Downstream X + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-ES-HFM:TRXD + deviceTags: + - hfm + enabled: true + onFailure: buffer + readoutPriority: baseline +hfm_xu: + description: HFM Upstream X + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-ES-HFM:TRXU + deviceTags: + - hfm + enabled: true + onFailure: buffer + readoutPriority: baseline +hfm_y: + description: HFM Virtual Y + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-ES-HFM:TRY + deviceTags: + - hfm + enabled: true + onFailure: buffer + readoutPriority: baseline +hfm_yaw: + description: HFM Virtual Yaw + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-ES-HFM:YAW + deviceTags: + - hfm + enabled: true + onFailure: buffer + readoutPriority: baseline +hfm_ydw: + description: HFM Downstream Wall Y + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-ES-HFM:TRYDW + deviceTags: + - hfm + enabled: true + onFailure: buffer + readoutPriority: baseline +hfm_yr: + description: HFM Ring Y + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-ES-HFM:TRYR + deviceTags: + - hfm + enabled: true + onFailure: buffer + readoutPriority: baseline +hfm_yuw: + description: HFM Upstream Wall Y + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-ES-HFM:TRYUW + deviceTags: + - hfm + enabled: true + onFailure: buffer + readoutPriority: baseline +i1: + description: I1 diode + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-SCLDI:READOUT + deviceTags: + - bpm + enabled: true + onFailure: buffer + readOnly: true + readoutPriority: monitored +samcam_ecc: + description: Sample Camera Eccentricity + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-MS:Stats5:Eccentricity_RBV + deviceTags: + - scam + enabled: true + onFailure: buffer + readOnly: true + readoutPriority: monitored +samcam_exp: + description: Sample Camera Exposure + deviceClass: ophyd.EpicsSignal + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-MS:cam1:AcquireTime + deviceTags: + - scam + enabled: true + onFailure: buffer + readoutPriority: baseline +samcam_gain: + description: Sample Camera Gain + deviceClass: ophyd.EpicsSignal + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-MS:cam1:Gain + deviceTags: + - scam + enabled: true + onFailure: buffer + readoutPriority: baseline +samcam_max: + description: Sample Camera Max + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-MS:Stats5:MaxValue_RBV + deviceTags: + - scam + enabled: true + onFailure: buffer + readOnly: true + readoutPriority: monitored +samcam_mean: + description: Sample Camera Mean + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-MS:Stats1:MeanValue_RBV + deviceTags: + - scam + enabled: true + onFailure: buffer + readOnly: true + readoutPriority: monitored +samcam_sigma: + description: Sample Camera Sigma + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-MS:Stats1:Sigma_RBV + deviceTags: + - scam + enabled: true + onFailure: buffer + readOnly: true + readoutPriority: monitored +samcam_x: + description: Sample Camera X + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-MS:Stats5:CentroidX_RBV + deviceTags: + - scam + enabled: true + onFailure: buffer + readOnly: true + readoutPriority: monitored +samcam_xsig: + description: Sample Camera X Sigma + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-MS:Stats5:SigmaX_RBV + deviceTags: + - scam + enabled: true + onFailure: buffer + readOnly: true + readoutPriority: monitored +samcam_y: + description: Sample Camera Y + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-MS:Stats5:CentroidY_RBV + deviceTags: + - scam + enabled: true + onFailure: buffer + readOnly: true + readoutPriority: monitored +samcam_ysig: + description: Sample Camera Y Sigma + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-MS:Stats5:SigmaY_RBV + deviceTags: + - scam + enabled: true + onFailure: buffer + readOnly: true + readoutPriority: monitored +scam_zoom: + description: Sample Camera Zoom + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-MS:ZOOM + deviceTags: + - scam + enabled: true + onFailure: buffer + readoutPriority: baseline +sls_current: + description: SLS Current + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: ARS07-DPCT-0100:CURR + deviceTags: + - SLS + enabled: true + onFailure: buffer + readOnly: true + readoutPriority: monitored +smargon: + description: REST-based device which connects to Smargopolo + deviceClass: pxiii_bec.devices.smargopolo_smargon.Smargon + deviceConfig: + prefix: http://x06da-smargopolo.psi.ch:3000 + deviceTags: + - smargon + - motors + enabled: true + onFailure: buffer + readoutPriority: baseline + userParameter: + chi: + mount: 0 + phi: + mount: 0 + x: + mount: 0 + y: + mount: 0 + z: + mount: 18 +ss_bpm1: + description: SS BPM Channel 1 + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-SSBPM:Current1:MeanValue_RBV + deviceTags: + - bpm + enabled: true + onFailure: buffer + readOnly: true + readoutPriority: monitored +ss_bpm2: + description: SS BPM Channel 2 + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-SSBPM:Current2:MeanValue_RBV + deviceTags: + - bpm + enabled: true + onFailure: buffer + readOnly: true + readoutPriority: monitored +ss_bpm3: + description: SS BPM Channel 3 + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-SSBPM:Current3:MeanValue_RBV + deviceTags: + - bpm + enabled: true + onFailure: buffer + readOnly: true + readoutPriority: monitored +ss_bpm4: + description: SS BPM Channel 4 + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-SSBPM:Current4:MeanValue_RBV + deviceTags: + - bpm + enabled: true + onFailure: buffer + readOnly: true + readoutPriority: monitored +ss_bpm_x: + description: SS BPM X + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-SSBPM:TRX + deviceTags: + - ss + enabled: true + onFailure: buffer + readoutPriority: baseline +ss_bpm_y: + description: SS BPM Y + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-SSBPM:TRY + deviceTags: + - ss + enabled: true + onFailure: buffer + readoutPriority: baseline +ss_bpmsum: + description: SS BPM Summed + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-SSBPM:SumAll:MeanValue_RBV + deviceTags: + - bpm + enabled: true + onFailure: buffer + readOnly: true + readoutPriority: monitored +ss_sl_xcen: + description: SS Slit X Centre + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-SSSLH:CENTER + deviceTags: + - ss + enabled: true + onFailure: buffer + readoutPriority: baseline +ss_sl_xr: + description: SS Slit Ring + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-SSSLH:TRXR + deviceTags: + - ss + enabled: true + onFailure: buffer + readoutPriority: baseline +ss_sl_xsize: + description: SS Slit X Size + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-SSSLH:SIZE + deviceTags: + - ss + enabled: true + onFailure: buffer + readoutPriority: baseline +ss_sl_xw: + description: SS Slit Wall + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-SSSLH:TRXW + deviceTags: + - ss + enabled: true + onFailure: buffer + readoutPriority: baseline +ss_sl_yb: + description: SS Slit Bottom + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-SSSLV:TRYB + deviceTags: + - ss + enabled: true + onFailure: buffer + readoutPriority: baseline +ss_sl_ycen: + description: SS Slit Y Centre + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-SSSLV:CENTER + deviceTags: + - ss + enabled: true + onFailure: buffer + readoutPriority: baseline +ss_sl_ysize: + description: SS Slit Y Size + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-SSSLV:SIZE + deviceTags: + - ss + enabled: true + onFailure: buffer + readoutPriority: baseline +ss_sl_yt: + description: SS Slit Top + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-SSSLV:TRYT + deviceTags: + - ss + enabled: true + onFailure: buffer + readoutPriority: baseline +ss_xi_x: + description: SS X-ray Eye X + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-SSXI:TRX + deviceTags: + - ss + enabled: true + onFailure: buffer + readoutPriority: baseline +ss_xi_y: + description: SS X-ray Eye Y + deviceClass: ophyd_devices.EpicsMotor + deviceConfig: + prefix: X06DA-ES-SSXI:TRY + deviceTags: + - ss + enabled: true + onFailure: buffer + readoutPriority: baseline +ss_xicam_exp: + description: SS Camera Exposure + deviceClass: ophyd.EpicsSignal + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-SSCAM:cam1:AcquireTime + deviceTags: + - ss + enabled: true + onFailure: buffer + readoutPriority: baseline +ss_xicam_gain: + description: SS Camera Gain + deviceClass: ophyd.EpicsSignal + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-SSCAM:cam1:Gain + deviceTags: + - ss + enabled: true + onFailure: buffer + readoutPriority: baseline +ss_xicam_max: + description: SS Cam Max + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-SSCAM:Stats5:MaxValue_RBV + deviceTags: + - ss + enabled: true + onFailure: buffer + readOnly: true + readoutPriority: monitored +ss_xicam_x: + description: SS Camera X + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-SSCAM:Stats5:CentroidX_RBV + deviceTags: + - ss + enabled: true + onFailure: buffer + readOnly: true + readoutPriority: baseline +ss_xicam_xsig: + description: SS Camera X Sigma + deviceClass: ophyd.EpicsSignal + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-SSCAM:Stats5:SigmaX_RBV + deviceTags: + - ss + enabled: true + onFailure: buffer + readOnly: true + readoutPriority: baseline +ss_xicam_y: + description: SS Camera Y + deviceClass: ophyd.EpicsSignalRO + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-SSCAM:Stats5:CentroidY_RBV + deviceTags: + - ss + enabled: true + onFailure: buffer + readOnly: true + readoutPriority: baseline +ss_xicam_ysig: + description: SS Camera Y Sigma + deviceClass: ophyd.EpicsSignal + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-SSCAM:Stats5:SigmaY_RBV + deviceTags: + - ss + enabled: true + onFailure: buffer + readOnly: true + readoutPriority: baseline +tm_b1: + description: TorM Bender + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-FE-MI1:BEND1 + deviceTags: + - tm + enabled: true + onFailure: buffer + readoutPriority: baseline +tm_pitch: + description: TorM Virtual Pitch + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-FE-MI1:PITCH + deviceTags: + - tm + enabled: true + onFailure: buffer + readoutPriority: baseline +tm_roll: + description: TorM Virtual Roll + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-FE-MI1:ROLL + deviceTags: + - tm + enabled: true + onFailure: buffer + readoutPriority: baseline +tm_x: + description: TorM Virtual X + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-FE-MI1:TRX + deviceTags: + - tm + enabled: true + onFailure: buffer + readoutPriority: baseline +tm_xd: + description: TorM Downstream X + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-FE-MI1:TRXD + deviceTags: + - tm + enabled: true + onFailure: buffer + readoutPriority: baseline +tm_xu: + description: TorM Upstream X + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-FE-MI1:TRXU + deviceTags: + - tm + enabled: true + onFailure: buffer + readoutPriority: baseline +tm_y: + description: TorM Virtual Y + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-FE-MI1:TRY + deviceTags: + - tm + enabled: true + onFailure: buffer + readoutPriority: baseline +tm_yaw: + description: TorM Virtual Yaw + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-FE-MI1:YAW + deviceTags: + - tm + enabled: true + onFailure: buffer + readoutPriority: baseline +tm_yd: + description: TorM Downstream Y + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-FE-MI1:TRYD + deviceTags: + - tm + enabled: true + onFailure: buffer + readoutPriority: baseline +tm_yur: + description: TorM Upstream Ring Y + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-FE-MI1:TRYUR + deviceTags: + - tm + enabled: true + onFailure: buffer + readoutPriority: baseline +tm_yw: + description: TorM Wall Y + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-FE-MI1:TRYUW + deviceTags: + - tm + enabled: true + onFailure: buffer + readoutPriority: baseline +vfm_bd: + description: VFM Downstream Bender + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-ES-VFM:BNDD + deviceTags: + - vfm + enabled: true + onFailure: buffer + readoutPriority: baseline +vfm_bu: + description: VFM Upstream Bender + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-ES-VFM:BNDU + deviceTags: + - vfm + enabled: true + onFailure: buffer + readoutPriority: baseline +vfm_pitch: + description: VFM Virtual Pitch + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-ES-VFM:PITCH + deviceTags: + - vfm + enabled: true + onFailure: buffer + readoutPriority: baseline +vfm_roll: + description: VFM Virtual Roll + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-ES-VFM:ROLL + deviceTags: + - vfm + enabled: true + onFailure: buffer + readoutPriority: baseline +vfm_x: + description: VFM Virtual X + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-ES-VFM:TRX + deviceTags: + - vfm + enabled: true + onFailure: buffer + readoutPriority: baseline +vfm_xd: + description: VFM Downstream X + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-ES-VFM:TRXD + deviceTags: + - vfm + enabled: true + onFailure: buffer + readoutPriority: baseline +vfm_xu: + description: VFM Upstream X + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-ES-VFM:TRXU + deviceTags: + - vfm + enabled: true + onFailure: buffer + readoutPriority: baseline +vfm_y: + description: VFM Virtual Y + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-ES-VFM:TRY + deviceTags: + - vfm + enabled: true + onFailure: buffer + readoutPriority: baseline +vfm_yaw: + description: VFM Virtual Yaw + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-ES-VFM:YAW + deviceTags: + - vfm + enabled: true + onFailure: buffer + readoutPriority: baseline +vfm_ydr: + description: VFM Downstream Ring Y + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-ES-VFM:TRYDR + deviceTags: + - vfm + enabled: true + onFailure: buffer + readoutPriority: baseline +vfm_yur: + description: VFM Upstream Ring Y + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-ES-VFM:TRYUR + deviceTags: + - vfm + enabled: true + onFailure: buffer + readoutPriority: baseline +vfm_yw: + description: VFM Wall Y + deviceClass: ophyd_devices.EpicsMotorEC + deviceConfig: + prefix: X06DA-ES-VFM:TRYW + deviceTags: + - vfm + enabled: true + onFailure: buffer + readoutPriority: baseline +xrf_pos: + description: XRF Positioner + deviceClass: ophyd.EpicsSignal + deviceConfig: + auto_monitor: true + read_pv: X06DA-ES-XRF:POS-SET + deviceTags: + - state + enabled: true + onFailure: buffer + readoutPriority: baseline + userParameter: + in: 1 + out: 0 + type: discrete diff --git a/pxiii_bec/macros/beamline_planner.py b/pxiii_bec/macros/beamline_planner.py index aa99268..e96f01d 100644 --- a/pxiii_bec/macros/beamline_planner.py +++ b/pxiii_bec/macros/beamline_planner.py @@ -95,20 +95,81 @@ class StateChangePlanner: def available_states(self): """Return a list of available states""" return list(self.states.keys()) + + def state_devices(self): + """Return the set of devices that participate in + beamline state definitions""" + + devices = set() + + for state in self.states.values(): + devices.update(state.keys()) + + return sorted(devices) def get_positions(self): - """Return current positions of all SE devices""" - return {name: dev.pos for name, dev in self.devices.items()} + """Return current positions of devices that are used + in state transitions""" + return {name: self.devices[name].pos + for name in self.state_devices()} def print_positions(self): """Return current state of all devices""" - for name, device in self.devices.items(): - print(f"{name:10s} : {device.pos:10s} value: {device.actual}") + for name in self.state_devices(): + device = self.devices[name] + + print(f"{name:10s} : {device.pos:10s} value: {device.actual:.5g}") def diff_states(self, before): """Return a dict of {device: (before, after)} pairs for devices that changed state""" after = self.get_positions() return {k: (before[k], after[k]) for k in before if before[k] != after[k]} + + def __get_closest_states(self): + """ + Return states ordered by number of mismatches. + """ + + results = [] + + for state in self.states: + + config = self._merged_state(state, None) + + mismatches = [] + + for dev, expected in config.items(): + + if not self.devices[dev].is_at(expected): + mismatches.append( + ( + dev, + self.devices[dev].pos, + expected, + ) + ) + + results.append( + ( + state.name, + len(mismatches), + mismatches, + ) + ) + + return sorted(results, key=lambda x: x[1]) + + def closest_states(self, n=5): + + for state, count, mismatches in self.__get_closest_states()[:n]: + + print(f"\n{state}: {count} mismatch(es)") + + for dev, actual, expected in mismatches: + print( + f" {dev:15s} " + f"{actual:10s} -> {expected}" + ) def current_state(self): """Return all current matching BeamlineState and TemperatureMode combinations, diff --git a/pxiii_bec/macros/beampos_with_en.py b/pxiii_bec/macros/beampos_with_en.py new file mode 100644 index 0000000..547325f --- /dev/null +++ b/pxiii_bec/macros/beampos_with_en.py @@ -0,0 +1,13 @@ +def beampos_with_en(planner): + deltat = 5 + bl_energy(6000) + record_beampos_until("23:30",planner,interval_minutes=deltat) + bl_energy(8000) + record_beampos_until("01:00",planner,interval_minutes=deltat) + bl_energy(10000) + record_beampos_until("03:00",planner,interval_minutes=deltat) + bl_energy(12400) + record_beampos_until("05:00",planner,interval_minutes=deltat) + bl_energy(14000) + record_beampos_until("07:00",planner,interval_minutes=deltat) + diff --git a/pxiii_bec/macros/calibrate.py b/pxiii_bec/macros/calibrate.py new file mode 100644 index 0000000..c194ac6 --- /dev/null +++ b/pxiii_bec/macros/calibrate.py @@ -0,0 +1,24 @@ +from datetime import datetime + +def generate_dccm_lut(start_energy=5000, end_energy=14000, step=1000): + """Generate a lookup table for the dcm from start_energy to end_energy in steps of step""" + now = datetime.now() + fnow = now.strftime("%d%m%H%M") + filename = f"luts/{fnow}_lut.csv" + with open(filename, "w", encoding="utf-8") as f: + # f.write("energy,pitch,roll,perp,ss_xicam_x,ss_xicam_y\n") + f.write("energy, pitch\n") + + for energy in range(start_energy, end_energy, step): + print(f"Moving to {energy: .0f}eV") + bl_energy(energy) + pitch = EnergyDefaults.mono_pitch.position + # auto_exposure(cam="ss_xicam", max_iter=25) + # x = dev.ss_xicam_x.read()["ss_xicam_x"]["value"] + # y = dev.ss_xicam_y.read()["ss_xicam_y"]["value"] + with open(filename, "a", encoding="utf-8") as f: + f.write( + # f"{energy:.0f},{pitch:.5g},,{x:.4g},{y:.4g}\n" + (f"{energy:.0f},{pitch:.7g}\n") + ) + bl_energy(13000) diff --git a/pxiii_bec/macros/enums.bak b/pxiii_bec/macros/enums.bak new file mode 100644 index 0000000..40b8d9f --- /dev/null +++ b/pxiii_bec/macros/enums.bak @@ -0,0 +1,22 @@ +"""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/katscripts.py b/pxiii_bec/macros/katscripts.py new file mode 100755 index 0000000..ce75f8f --- /dev/null +++ b/pxiii_bec/macros/katscripts.py @@ -0,0 +1,1538 @@ +"""Some simple scripts for commissioning""" + +import time, os +from datetime import datetime, timedelta +from dataclasses import dataclass +import numpy as np +import matplotlib.pyplot as plt +from scipy.signal import find_peaks as fp +import pandas as pd +from scipy.optimize import linear_sum_assignment + + + +def bragg_scan(): + """Energy scans from 6 to 18 keV at various gap positions""" + + start_bragg = 110.05 # 18 keV + end_bragg = 335.77 # 6 keV + steps = 1200 + exp = 0.05 + gap = 7.5 + umv(dev.id_gap, gap) + time.sleep(10) + while gap < 9.6: + print(f"Scanning the dcm_bragg from {start_bragg} to {end_bragg} at a gap of {gap: .2f} mm") + umv(dev.id_gap, gap) + scans.line_scan( + dev.dcm_bragg, start_bragg, end_bragg, steps=steps, exp_time=exp, relative=False + ) + gap += 0.5 + + +def move_xeye(direction): + """Move the xeye in or out""" + if direction == "in": + umv(dev.ss_xicam_x, 7.0) + else: + umv(dev.ss_xicam_x, -7) + + +def close_fe_slits(close=True): + """Close FE slits to (0.3,0.3) or open the FE slits to (2.0,1.0)""" + if close: + umv(dev.fe_sl_xsize, 0.3, dev.fe_sl_ysize, 0.3) + else: + umv(dev.fe_sl_xsize, 1.5, dev.fe_sl_ysize, 1.0) + + +def energy_checks(start_energy=8000, end_energy=20000): + """Check gap, pitch and intensities at different energies""" + f = open("luts/test.csv", "a", encoding="utf-8") + + for energy in range(start_energy, end_energy, 1000): + f = open("luts/test.csv", "a", encoding="utf-8") + print(f"Moving to {energy} eV") + bl_energy + if energy < 16000: + close_fe_slits(True) + go_to_peak( + dev.id_gap, dev.lu_bpmsum, -0.3, 0.3, 40, relative=True, confirm=False, gomax=True + ) + scan_fe() + close_fe_slits(True) + go_to_peak( + dev.id_gap, dev.lu_bpmsum, -0.1, 0.1, 15, relative=True, confirm=False, gomax=True + ) + go_to_peak( + dev.id_gap, + dev.lu_bpmsum, + -0.025, + 0.025, + 15, + relative=True, + confirm=False, + gomax=True, + ) + close_fe_slits(False) + + else: + umv(dev.s1_xsize, 0.5) + go_to_peak( + dev.id_gap, dev.bcu_bpmsum, -0.3, 0.3, 40, relative=True, confirm=False, gomax=True + ) + scan_fe() + go_to_peak( + dev.id_gap, dev.bcu_bpmsum, -0.1, 0.1, 15, relative=True, confirm=False, gomax=True + ) + umv(dev.s1_xsize, 2.5) + mono_pitch_scan() + gap = dev.id_gap.read()["id_gap"]["value"] + pitch = dev.dcm_pitch.read()["dcm_pitch"]["value"] + fe_x = dev.fe_sxcen.read()["fe_sxcen"]["value"] + fe_y = dev.fe_sycen.read()["fe_sycen"]["value"] + lu_read = dev.lu_bpmsum.read()["lu_bpmsum"]["value"] + ss_read = dev.ss_bpmsum.read()["ss_bpmsum"]["value"] + bcu_read = dev.bcu_bpmsum.read()["bcu_bpmsum"]["value"] + f.write( + f"{energy}, {gap: .5g}, {pitch: .5g}, {lu_read: .5g}, " + f"{ss_read: .5g}, {bcu_read: .5g}, " + f"{fe_x: .5g}, {fe_y: .5g}\n" + ) + + f.close() + + +def scan_fe(): + """Scan the FE slits in X and Y""" + print("Scanning FE slits in X") + umv(dev.fe_sxsize, 0.05, dev.fe_sysize, 2) + go_to_peak(dev.fe_sxcen, dev.lu_bpmsum, -1.5, 1.5, 20, confirm=False, relative=True) + print("Scanning FE slits in Y") + umv(dev.fe_sxsize, 0.3, dev.fe_sysize, 0.05) + go_to_peak(dev.fe_sycen, dev.lu_bpmsum, -1.2, 1.2, 15, confirm=False, relative=True) + close_fe_slits(False) + + +def scan_gap(): + """Scan the gap and monitor on lu_bpmsum or bcu_bpmsum""" + # close_fe_slits(True) + current_gap = dev.id_gap.read()["id_gap"]["value"] + if current_gap > 4.6: + go_to_peak( + dev.id_gap, dev.lu_bpmsum, -0.1, 0.1, 25, relative=True, confirm=False, gomax=False + ) + else: + go_to_peak( + dev.id_gap, dev.lu_bpmsum, 4.5, 4.75, 25, relative=False, confirm=False, gomax=False + ) + # close_fe_slits(False) + + +def record_pitch(): + """Record the pitch and perp distance to file""" + with open("luts/pitch_record.csv", "a", encoding="utf-8") as f: + current_energy = get_current_energy() + pitch = dev.dcm_pitch.read()["dcm_pitch"]["value"] + gap = dev.id_gap.read()["id_gap"]["value"] + f.write(f"{current_energy: .0f}, {pitch: .5g}, {gap: .4g}\n") + f.close() + + +def record_roll(): + """Record the roll and perp distance to file""" + with open("luts/roll_record.csv", "a", encoding="utf-8") as f: + current_energy = get_current_energy() + roll = dev.dcm_froll.read()["dcm_froll"]["value"] + f.write(f"{current_energy:.0f}, {roll:.5g}\n") + f.close() + + +def record_perp(): + """Check perp calibrations at various energies""" + with open("luts/perp_record.csv", "a", encoding="utf-8") as f: + current_energy = get_current_energy() + perp = dev.dcm_perp.read()["dcm_perp"]["value"] + ss_xicam_x = dev.ss_xicam_x.read()["ss_xicam_x"]["value"] + ss_xicam_y = dev.ss_xicam_y.read()["ss_xicam_y"]["value"] + f.write(f"{current_energy:.0f},{perp:.5g},{ss_xicam_x:.5g},{ss_xicam_y:.5g}\n") + f.close() + + +def beam_centre_from_ss(): + """Compute the beam centre from the ss_cam""" + y = dev.ss_xicam_x.read()["ss_xicam_x"]["value"] + x = dev.ss_xicam_y.read()["ss_xicam_y"]["value"] + beampos = {"xpos": x, "ypos": y} + print(f"X is {x: .4g}, Y is {y: .4g}") + return beampos + + +def generate_dcm_lut(start_energy=6000, end_energy=30000, step=300): + """Generate a lookup table for the dcm from start_energy to end_energy in steps of step""" + now = datetime.now() + fnow = now.strftime("%d%m%H%M") + filename = f"luts/{fnow}_lut.csv" + zoom = dev.scam_zoom.read()['scam_zoom']['value'] + with open(filename, "w", encoding="utf-8") as f: + f.write(f"energy,harmonic,gap,pitch,roll,perp,samcam_x,samcam_y,zoom={zoom}\n") + + for energy in range(start_energy, end_energy, step): + print(f"Moving to {energy: .0f}eV") + bl_energy(energy, mono_scan=False) + try: + scan_gap() + except Exception as exc: + print(f"Gap scan failed at {energy:.0f} eV: {exc}") + set_gap(energy) # set fallback gap here + + mono_pitch_scan() + gap = dev.id_gap.read()["id_gap"]["value"] + harm = Gap() + h = harm.get_harmonic_by_energy(energy) + pitch = dev.dcm_pitch.read()["dcm_pitch"]["value"] + roll = dev.dcm_froll.read()["dcm_froll"]["value"] + perp = dev.dcm_perp.read()["dcm_perp"]["value"] + # auto_exposure(cam="ss_xicam", max_iter=25) + # x = dev.ss_xicam_x.read()["ss_xicam_x"]["value"] + # y = dev.ss_xicam_y.read()["ss_xicam_y"]["value"] + auto_exposure(cam="samcam", max_iter=20) + x = dev.samcam_x.read()['samcam_x']['value'] + y = dev.samcam_y.read()['samcam_y']['value'] + with open(filename, "a", encoding="utf-8") as f: + f.write( + f"{energy:.0f},{h},{gap:.5g},{pitch:.5g},{roll:.4g},{perp:.5g},{x:.4g},{y:.4g}\n" + ) + bl_energy(12400) + umv(dev.id_gap, 20.0) + + +def write_lut(): + """Write DCM parameters to file""" + filename = "luts/manual_big.csv" + energy = get_current_energy() + mono_pitch_scan() + roll_scan_to_target() + gap = dev.id_gap.read()["id_gap"]["value"] + pitch = dev.dcm_pitch.read()["dcm_pitch"]["value"] + roll = dev.dcm_froll.read()["dcm_froll"]["value"] + perp = dev.dcm_perp.read()["dcm_perp"]["value"] + x = dev.ss_xicam_x.read()["ss_xicam_x"]["value"] + y = dev.ss_xicam_y.read()["ss_xicam_y"]["value"] + with open(filename, "a", encoding="utf-8") as f: + f.write(f"{energy:.0f},{gap:.5g},{pitch:.5g},{roll:.4g},{perp:.5g},{x:.4g},{y:.4g}\n") + + +def measure_beamsize(cam="samcam"): + auto_exposure("samcam", max_iter=20) + a = dev.samcam_xsig.read()["samcam_xsig"]["value"] + b = dev.samcam_ysig.read()["samcam_ysig"]["value"] + zoom = dev.scam_zoom.read()["scam_zoom"]["value"] + sx = calc_scam_microns(a, zoom=zoom) * 2.35 + sy = calc_scam_microns(b, zoom=zoom) * 2.35 + print(f"FWHM in um : {sx, sy}") + return sx, sy + + +def write_beamsize(): + """Write beam size and flux to file""" + filename = "luts/beamsizes.csv" + with open(filename, "a", encoding="utf-8") as f: + f.write("lens_config,size_x,size_y,i1\n") + lens_config = input("Which lenses are in?") + if SE.scin.checkpos: + filters("out") + sx, sy = measure_beamsize() + else: + scin("in") + filters("out") + sx, sy = measure_beamsize() + i1_reading = i1() + with open(filename, "a", encoding="utf-8") as f: + f.write(f"{lens_config},{sx:.4g},{sy:.4g},{i1_reading:.4g}\n") + + + +def scan_Ge(): + scanbefore = 30 # eV + scanafter = 30 # eV + stepsize = 0.2 # eV + # Edge sgould be at 11103.1 + actual_edge_Ge = 11103.1 # eV + actual_bragg = convert_from_energy(actual_edge_Ge)["bragg_angle_mrad"] + current_edge = 11095 + current_bragg = convert_from_energy(current_edge)["bragg_angle_mrad"] + print(f"Ge edge should be at a bragg angle of {actual_bragg:.5g} mrad\n") + print(f"Current estimate of edge is {current_bragg:.5g} mrad\n") + xdata = [] + ydata = [] + filedir, fname = fnow() + filename = f"{filedir}{fname}_ge_edge.csv" + print(filename) + with open(filename, 'w') as f: + f.write(f"Energy,Bragg,bcu_bpmsum\n") + + # scanstart = edge_Ge + scanafter + # scanend = edge_Ge - scanbefore + # bragg_start = convert_from_energy(scanstart)["bragg_angle_mrad"] + # bragg_end = convert_from_energy(scanend)["bragg_angle_mrad"] + # stepnumber = abs(int((scanend - scanstart) / stepsize)) + # print(f"Changing energy to {scanstart}") + # bl_energy(scanstart) + # # scan_gap() + # umv(dev.ss_f4_x, 6) # Put Ge filter in place + # print(f"scanning from {bragg_start} to {bragg_end} with {stepnumber} steps") + # s = scans.line_scan(dev.dcm_bragg, bragg_start, bragg_end, steps=stepnumber, relative=False) + # print(s) + # umv(dev.ss_f4_x, 2) + + plot_live_data_bec(dev.dcm_bragg,dev.bcu_bpmsum) + scanpoints = np.linspace(current_bragg - 0.5, current_bragg + 0.5, 300) + start_energy = convert_from_bragg(current_bragg+0.5)["energy_ev"] + bl_energy(start_energy) + umv(dev.ss_f4_x, 6) # Put Ge filter in place + + for bragg in scanpoints: + scans.umv(dev.dcm_bragg, bragg, relative=False) + energy = convert_from_bragg(bragg)["energy_ev"] + inten = average_inten() + xdata.append(energy) + ydata.append(inten) + with open(filename, 'a') as f: + f.write(f"{energy:.2f},{bragg:.2f},{inten:.2f}\n") + data = { + "x_data": np.array(xdata), + "y_data": np.array(ydata), + "motor_name": "dcm_bragg", + "signal_name": "bcu_bpmsum", + "motor_device": dev.dcm_bragg, + "scan_number": "Current", + } + + # Define and fit model to scan data + fit_params = create_fit_parameters(deriv = True, + negative = False, + model = FitDefaults.MODEL, + baseline = FitDefaults.BASELINE) + fit_result = fit(data, fit_params) + + # Plot the fitted data if plot = True + + plot_fitted_data_bec(data, fit_result) + + + + +def cal_samcam_fixed_x(): + # lat = dev.hfm_x.read()["hfm_x"]["value"] + # pitch = dev.hfm_pitch.read()["hfm_pitch"]["value"] + fpitch = dev.dcm_fpitch.read()['dcm_fpitch']['value'] + scanpoints = np.linspace(3.75, 4.75, 7) + zoom_high = 800 + zoom_low = 200 + highs, lows = [], [] + high_fpitch, low_fpitch = [], [] + av_high = [] + av_low = [] + + # high zoom + umv(dev.scam_zoom, zoom_high) + auto_exposure("samcam") + for i in scanpoints: + umv(dev.dcm_fpitch, i) + time.sleep(0.2) + for _ in range(5): + reading = dev.samcam_x.read()["samcam_x"]["value"] + av_high.append(reading) + high_y = np.mean(av_high) + high_x = dev.dcm_fpitch.read()["dcm_fpitch"]["value"] + print(f"Xpos at zoom {zoom_high} is {high_y}") + highs.append(high_y) + high_fpitch.append(high_x) + + umv(dev.scam_zoom, zoom_low) + auto_exposure("samcam") + for i in scanpoints: + umv(dev.dcm_fpitch, i) + time.sleep(0.2) + for i in range(5): + reading = dev.samcam_x.read()["samcam_x"]["value"] + av_low.append(reading) + low_y = np.mean(av_low) + low_x = dev.dcm_fpitch.read()["dcm_fpitch"]["value"] + print(f"Xpos at zoom {zoom_low} is {low_y}") + lows.append(low_y) + low_fpitch.append(low_x) + + umv(dev.dcm_fpitch, 5) + + # Convert to numpy arrays + x_high = np.array(high_fpitch) + x_low = np.array(low_fpitch) + y_high = np.array(highs) + y_low = np.array(lows) + + # Fit linear models: y = m*x + b + m_high, b_high = np.polyfit(x_high, y_high, 1) + m_low, b_low = np.polyfit(x_low, y_low, 1) + + # Intersection point + x_intersect = (b_low - b_high) / (m_high - m_low) + y_intersect = m_high * x_intersect + b_high + + print(f"\nIntersection at:") + print(f" dcm_fpitch = {x_intersect:.5f}") + print(f" SamCam_x = {y_intersect:.2f}") + + # --- Plot --- + plt.figure(figsize=(7, 5)) + plt.scatter(x_high, y_high, color="red", label=f"Zoom = {zoom_high} data") + plt.scatter(x_low, y_low, color="blue", label=f"Zoom = {zoom_low} data") + + x_fit = np.linspace(min(x_high), max(x_high), 100) + plt.plot(x_fit, m_high * x_fit + b_high, "r--", label=f"Fit: Zoom {zoom_high}") + plt.plot(x_fit, m_low * x_fit + b_low, "b--", label=f"Fit: Zoom {zoom_low}") + + plt.scatter(x_intersect, y_intersect, color="green", s=80, zorder=5, label="Intersection") + + plt.xlabel("DCM Fine Pitch Position") + plt.ylabel("SamCam X") + plt.title("Zoom Calibration") + plt.legend() + plt.grid(True) + plt.tight_layout() + plt.show() + + +def cal_samcam_fixed_y(): + vert = dev.vfm_y.read()["vfm_y"]["value"] + pitch = dev.vfm_pitch.read()["vfm_pitch"]["value"] + scanpoints = np.linspace(vert - 0.1, vert + 0.1, 7) + zoom_high = 800 + zoom_low = 200 + highs, lows = [], [] + high_vert, low_vert = [], [] + + # high zoom + umv(dev.scam_zoom, zoom_high) + auto_exposure("samcam") + for i in scanpoints: + umv(dev.vfm_y, i) + umv(dev.vfm_pitch, pitch) + time.sleep(0.2) + high_y = dev.samcam_y.read()["samcam_y"]["value"] + high_x = dev.vfm_y.read()["vfm_y"]["value"] + print(f"Ypos at zoom {zoom_high} is {high_y}") + highs.append(high_y) + high_vert.append(high_x) + + umv(dev.scam_zoom, zoom_low) + auto_exposure("samcam") + for i in scanpoints: + umv(dev.vfm_y, i) + umv(dev.vfm_pitch, pitch) + time.sleep(0.2) + low_y = dev.samcam_y.read()["samcam_y"]["value"] + low_x = dev.vfm_y.read()["vfm_y"]["value"] + print(f"Ypos at zoom {zoom_low} is {low_y}") + lows.append(low_y) + low_vert.append(low_x) + + umv(dev.vfm_y, vert) + umv(dev.vfm_pitch, pitch) + + # Convert to numpy arrays + x_high = np.array(high_vert) + x_low = np.array(low_vert) + y_high = np.array(highs) + y_low = np.array(lows) + + # Fit linear models: y = m*x + b + m_high, b_high = np.polyfit(x_high, y_high, 1) + m_low, b_low = np.polyfit(x_low, y_low, 1) + + # Intersection point + x_intersect = (b_low - b_high) / (m_high - m_low) + y_intersect = m_high * x_intersect + b_high + + print(f"\nIntersection at:") + print(f" vfm_y = {x_intersect:.5f}") + print(f" SamCam_y = {y_intersect:.2f}") + + # --- Plot --- + plt.figure(figsize=(7, 5)) + plt.scatter(x_high, y_high, color="red", label=f"Zoom = {zoom_high} data") + plt.scatter(x_low, y_low, color="blue", label=f"Zoom = {zoom_low} data") + + x_fit = np.linspace(min(x_high), max(x_high), 100) + plt.plot(x_fit, m_high * x_fit + b_high, "r--", label=f"Fit: Zoom {zoom_high}") + plt.plot(x_fit, m_low * x_fit + b_low, "b--", label=f"Fit: Zoom {zoom_low}") + + plt.scatter(x_intersect, y_intersect, color="green", s=80, zorder=5, label="Intersection") + + plt.xlabel("VFM Vert Position") + plt.ylabel("SamCam Y") + plt.title("Zoom Calibration") + plt.legend() + plt.grid(True) + plt.tight_layout() + plt.show() + + +def correlate_froll(): + x_correlation = [] + y_correlation = [] + scanpoints = np.linspace(0, 0.2, 10) + for pos in scanpoints: + umv(dev.dcm_froll, pos) + xpos, ypos = compute_pos() + x_correlation.append(xpos) + y_correlation.append(ypos) + + x = np.array(scanpoints) + y1 = np.array(x_correlation) + y2 = np.array(y_correlation) + + xslope, xint = np.polyfit(x, y1, 1) + yslope, yint = np.polyfit(x, y2, 1) + + print(f"Fit for xpos is: y = {xslope}.x + {xint}") + print(f"Fit for ypos is: y = {yslope}.x + {yint}") + + plt.figure(figsize=(7, 5)) + # plt.scatter(x, y1, label='xpos') + plt.scatter(x, y2, label="beam y position", color="rebeccapurple") + + x_fit = np.linspace(min(x), max(x), 100) + # plt.plot(x_fit, xslope*x_fit + xint, 'r--', label=f'y = {xslope}*x + {xint}') + plt.plot( + x_fit, + yslope * x_fit + yint, + "r--", + label=f"y = {yslope:.3g}*x + ({yint:.3g})", + color="lightcoral", + ) + plt.xlabel("dcm fine roll (V)") + plt.ylabel("beam Y (from BCU BPM)") + plt.legend() + plt.grid(True) + plt.tight_layout() + plt.show() + + +def correlate_fpitch(): + x_correlation = [] + y_correlation = [] + scanpoints = np.linspace(0, 0.2, 10) + for pos in scanpoints: + umv(dev.dcm_fpitch, pos) + xpos, ypos = compute_pos() + x_correlation.append(xpos) + y_correlation.append(ypos) + + x = np.array(scanpoints) + y1 = np.array(x_correlation) + y2 = np.array(y_correlation) + + xslope, xint = np.polyfit(x, y1, 1) + yslope, yint = np.polyfit(x, y2, 1) + + print(f"Fit for xpos is: y = {xslope}.x + {xint}") + print(f"Fit for ypos is: y = {yslope}.x + {yint}") + + plt.figure(figsize=(7, 5)) + # plt.scatter(x, y1, label='xpos') + plt.scatter(x, y1, label="beam x position", color="rebeccapurple") + + x_fit = np.linspace(min(x), max(x), 100) + # plt.plot(x_fit, xslope*x_fit + xint, 'r--', label=f'y = {xslope}*x + {xint}') + plt.plot( + x_fit, xslope * x_fit + xint, label=f"y = {xslope:.3g}*x + ({xint:.3g})", color="lightcoral" + ) + plt.xlabel("dcm fine pitch (V)") + plt.ylabel("beam X (from BCU BPM)") + plt.legend() + plt.grid(True) + plt.tight_layout() + plt.show() + + +def correlate_hfm_x(): + x_correlation = [] + lat = dev.hfm_x.read()["hfm_x"]["value"] + scanpoints = np.linspace(lat - 0.1, lat + 0.1, 10) + for pos in scanpoints: + umv(dev.hfm_x, pos) + xpos, ypos = compute_pos() + x_correlation.append(xpos) + umv(dev.hfm_x, lat) + + x = np.array(scanpoints) + y1 = np.array(x_correlation) + + xslope, xint = np.polyfit(x, y1, 1) + + print(f"Fit for xpos is: y = {xslope}.x + {xint}") + plt.figure(figsize=(7, 5)) + # plt.scatter(x, y1, label='xpos') + plt.scatter(x, y1, label="beam x position", color="rebeccapurple") + + x_fit = np.linspace(min(x), max(x), 100) + # plt.plot(x_fit, xslope*x_fit + xint, 'r--', label=f'y = {xslope}*x + {xint}') + plt.plot( + x_fit, xslope * x_fit + xint, label=f"y = {xslope:.5g}*x + ({xint:.5g})", color="lightcoral" + ) + plt.xlabel("HFM lateral (mm)") + plt.ylabel("beam X (from BCU BPM)") + plt.legend() + plt.grid(True) + plt.tight_layout() + plt.show() + + +# def correlate_vfm_y(): +# y_correlation = [] +# vert = dev.vfm_y.read()["vfm_y"]["value"] +# scanpoints = np.linspace(vert - 0.06, vert + 0.06, 10) +# for pos in scanpoints: +# umv(dev.vfm_y, pos) +# xpos, ypos = compute_pos() +# y_correlation.append(ypos) +# umv(dev.vfm_y, vert) + +# x = np.array(scanpoints) +# y1 = np.array(y_correlation) + +# yslope, yint = np.polyfit(x, y1, 1) + +# print(f"Fit for xpos is: y = {yslope}.x + {yint}") +# plt.figure(figsize=(7, 5)) +# # plt.scatter(x, y1, label='xpos') +# plt.scatter(x, y1, label="beam y position", color="rebeccapurple") + +# x_fit = np.linspace(min(x), max(x), 100) +# # plt.plot(x_fit, xslope*x_fit + xint, 'r--', label=f'y = {xslope}*x + {xint}') +# plt.plot( +# x_fit, yslope * x_fit + yint, label=f"y = {yslope:.5g}*x + ({yint:.5g})", color="lightcoral" +# ) +# plt.xlabel("VFM vertical (mm)") +# plt.ylabel("beam Y(from BCU BPM)") +# plt.legend() +# plt.grid(True) +# plt.tight_layout() +# plt.show() + + +def correlate_hfm_pitch(): + x_correlation = [] + pitch = dev.hfm_pitch.read()["hfm_pitch"]["value"] + scanpoints = np.linspace(pitch - 0.05, pitch + 0.05, 10) + for pos in scanpoints: + umv(dev.hfm_pitch, pos) + xpos, ypos = compute_pos() + x_correlation.append(xpos) + umv(dev.hfm_pitch, pitch) + + x = np.array(scanpoints) + y1 = np.array(x_correlation) + + xslope, xint = np.polyfit(x, y1, 1) + + print(f"Fit for xpos is: y = {xslope}.x + {xint}") + plt.figure(figsize=(7, 5)) + # plt.scatter(x, y1, label='xpos') + plt.scatter(x, y1, label="beam x position", color="rebeccapurple") + + x_fit = np.linspace(min(x), max(x), 100) + # plt.plot(x_fit, xslope*x_fit + xint, 'r--', label=f'y = {xslope}*x + {xint}') + plt.plot( + x_fit, xslope * x_fit + xint, label=f"y = {xslope:.5g}*x + ({xint:.5g})", color="lightcoral" + ) + plt.xlabel("HFM Pitch (mm)") + plt.ylabel("beam X (from BCU BPM)") + plt.legend() + plt.grid(True) + plt.tight_layout() + plt.show() + + +def move_to_x(targetx=0.13): + # Calibration and drift compensation + # target from previous run was 0.1465 + slope = -1.004 + intercept = 1.793 + + xpos, ypos = compute_pos() + + beam_drift = xpos - targetx # beam moved +0.1 mm (100 µm) + mot_current = dev.hfm_x.read()["hfm_x"]["value"] # current motor position (example) + + # Compute correction + delta = -beam_drift / slope + mot_new = mot_current + delta + umv(dev.hfm_x, mot_new) + + +# def move_to_y(targety=-0.033): +# # Calibration and drift compensation +# # target from previous run = -0.283 +# slope = -1.2779 +# intercept = 2.4374 + +# xpos, ypos = compute_pos() + +# beam_drift = ypos - targety # beam moved +0.1 mm (100 µm) +# mot_current = dev.vfm_y.read()["vfm_y"]["value"] # current motor position (example) + +# # Compute correction +# delta = -beam_drift / slope +# mot_new = mot_current + delta +# umv(dev.vfm_y, mot_new) + + +from epics import caget, caput +import time + + +def auto_exposure( + cam="samcam", target=200, tol=5, gain=0.9, min_exp=0.00001, max_exp=0.2, max_iter=10 +): + """ + Adjust camera exposure time to reach a target max pixel value. + + Parameters + ---------- + target : float + Desired MaxValue (counts) + tol : float + Acceptable deviation from target + min_exp, max_exp : float + Exposure time limits (s) + max_iter : int + Maximum number of adjustment iterations + """ + if cam == "samcam": + exposure = dev.samcam_exp.read()["samcam_exp"]["value"] + else: + exposure = dev.ss_xicam_exp.read()["ss_xicam_exp"]["value"] + + print(f"Starting exposure = {exposure:.4f} s") + + for i in range(max_iter): + time.sleep(0.1) # allow a frame or two to update + if cam == "samcam": + maxval = dev.samcam_max.read()["samcam_max"]["value"] + if maxval is None: + print("No reading — check camera.") + break + if cam == "ss_xicam": + maxval = dev.ss_xicam_max.read()["ss_xicam_max"]["value"] + if maxval is None: + print("No reading — check camera.") + break + + error = target - maxval + # print(f"Iter {i+1}: MaxValue = {maxval:.1f}, error = {error:.1f}") + + # stop if within tolerance + if abs(error) <= tol: + # print(f"Target reached (MaxValue={maxval:.1f}) after {i+1} iterations.") + break + + # proportional correction (simple gain control) + gain_setting = gain # moderate response + new_exp = exposure * (1 + gain_setting * error / target) + + # limit exposure bounds + new_exp = max(min_exp, min(max_exp, new_exp)) + + # update camera perp = dev.dcm_perp.read()["dcm_perp"]["value"] + y = dev.ss_xicam_x.read()["ss_xicam_x"]["value"] + x = dev.ss_xicam_y.read()["ss_xicam_y"]["value"] + if cam == "samcam": + dev.samcam_exp.put(new_exp) + print(f" → Adjusting exposure to {new_exp:.4f} s") + else: + dev.ss_xicam_exp.put(new_exp) + print(f" → Adjusting exposure to {new_exp:.4f} s") + + exposure = new_exp + + print(f"New exposure time is {exposure:.3g}") + return exposure + + +# def get_new_beamsizes(mirror): +# filename = f"luts/{mirror}_size.csv" +# if mirror == "hfm": +# bu = dev.hfm_bu +# bd = dev.hfm_bd +# step = 0.2 +# else: +# bu = dev.vfm_bu +# bd = dev.vfm_bd +# step = 0.05 +# beamsize("xs") +# move_targetx_with_hfm_x() +# move_targety_with_vfm_y() +# with open(filename, "w") as f: +# for _ in range(4): +# curr_bu = bu.user_readback.get() +# curr_bd = bd.user_readback.get() +# auto_exposure() +# umv(bu, curr_bu + step) +# umv(bd, curr_bd + step) +# move_targetx_with_hfm_x() +# move_targety_with_vfm_y() +# xpos = dev.samcam_x.read()["samcam_x"]["value"] +# ypos = dev.samcam_y.read()["samcam_y"]["value"] +# xsig = dev.samcam_xsig.read()["samcam_xsig"]["value"] +# ysig = dev.samcam_ysig.read()["samcam_ysig"]["value"] +# f.write(f"{curr_bu}, {curr_bd}, {xpos}, {ypos}, {xsig}, {ysig}\n") +# print(f"{curr_bu}, {curr_bd}, {xpos}, {ypos}, {xsig}, {ysig}") + + +def filters(pos="out"): + if pos == "out": + umv(dev.ss_f1_x, 2.0, dev.ss_f2_x, 2.0, dev.ss_f3_x, 12.0, dev.ss_f4_x, 8.0) + if SE.scin.checkpos(): + auto_exposure(cam="samcam", max_iter=20) + else: + umv(dev.ss_f1_x, 2.0, dev.ss_f2_x, 2.0, dev.ss_f3_x, 8.0, dev.ss_f4_x, 8.0) + if SE.scin.checkpos(): + auto_exposure(cam="samcam", max_iter=20) + +def fnow(): + now = datetime.now() + fnow = now.strftime("%Y%m%d-%H%M") + filedir = "luts/" + return filedir, fnow + +def energy_vs_height(start_energy=11000, end_energy=25000, step=1000): + """Correlate beam height with energy from start_energy to end_energy in steps of step""" + now = datetime.now() + # fnow = now.strftime("%d%m%H%M_") + fnow = now.strftime("%Y-%m-%d-%H%M") + filename = f"luts/{fnow}_energy-height-ss.csv" + with open(filename, "w", encoding="utf-8") as f: + # f.write("energy,bcu_norm_y,bcu_y,samcam_ypix,samcam_y\n") + f.write("energy,y_px,diffy_mic\n") + + for energy in range(start_energy, end_energy, step): + print(f"Moving to {energy: .0f}eV") + bl_energy(energy) + # scan_gap() + # mono_pitch_scan() + # scan_slits("s3",x=False,y=True) + # height = dev.s3_ycen.read()["s3_ycen"]["value"] + # bcu_norm_y = compute_norm()[1] + # bcu_y = compute_pos()[1] + # auto_exposure(cam="samcam", target=200) + # samcam_ypix, samcam_y = calc_from_centre() + # with open(filename, "a", encoding="utf-8") as f: + # f.write(f"{energy:.0f},{bcu_norm_y:.4g},{bcu_y:.4g},{samcam_ypix:.5g},{samcam_y:.4g}\n") + + auto_exposure(cam="ss_xicam", target=200, max_iter=25) + time.sleep(0.5) + ypx, diffm = calc_from_centre("ss_xicam") + # pitch = dev.dcm_pitch.read()['dcm_pitch']['value'] + + with open(filename, "a", encoding="utf-8") as f: + f.write(f"{energy:.0f},{ypx:.4g},{diffm:.4g}\n") + # umv(dev.id_gap, 20.0) + + + +def scan_in_x(xsize, xcen, mon, small, large, width, steps): + umv(xsize, small) + go_to_peak(xcen, mon, -(width * 0.5), (width * 0.5), steps=steps, relative=False) + umv(xsize, large) + + +def scan_in_y(ysize, ycen, mon, small, large, width, steps): + umv(ysize, small) + go_to_peak(ycen, mon, -(width * 0.5), (width * 0.5), steps=steps, relative=True, confirm=False) + umv(ysize, large) + + +def trans_fils(inc): + x1 = dev.ss_f1_x.read()["ss_f1_x"]["value"] + x2 = dev.ss_f2_x.read()["ss_f2_x"]["value"] + x3 = dev.ss_f3_x.read()["ss_f3_x"]["value"] + x4 = dev.ss_f4_x.read()["ss_f4_x"]["value"] + umv( + dev.ss_f1_x, + x1 + inc, + dev.ss_f2_x, + x2 + inc, + dev.ss_f3_x, + x3 + inc, + dev.ss_f4_x, + x4 + inc, + ) + + +def calc_from_centre(cam="samcam"): + if cam == "samcam": + read = dev.samcam_y.read()["samcam_y"]["value"] + diff = 1092 - read + diff_px = calc_scam_microns(diff, zoom=1000) + return read, float(diff_px) + else: + read = dev.ss_xicam_y.read()["ss_xicam_y"]["value"] + diff = 140 - read + diff_px = calc_ss_xicam_microns(diff) + return read, diff_px + + +def get_cam(low_zoom, high_zoom): + umv(dev.scam_zoom, low_zoom) + x = dev.samcam_x.read()["samcam_x"]["value"] + y = dev.samcam_y.read()["samcam_y"]["value"] + print(f"Low zoom: x = {x}, y = {y}") + umv(dev.scam_zoom, high_zoom) + x = dev.samcam_x.read()["samcam_x"]["value"] + y = dev.samcam_y.read()["samcam_y"]["value"] + print(f"High zoom: x = {x}, y = {y}") + + +# def read_currents(): +# """Read the individual bpm channels""" +# bpm1 = dev.bcu_bpm1.read()["bcu_bpm1"]["value"] +# bpm2 = dev.bcu_bpm2.read()["bcu_bpm2"]["value"] +# bpm3 = dev.bcu_bpm3.read()["bcu_bpm3"]["value"] +# bpm4 = dev.bcu_bpm4.read()["bcu_bpm4"]["value"] +# # print(f"bpm1 = {bpm1:.3f}, bpm2 = {bpm2:.3f}, bpm3 = {bpm3:.3f}, bpm4 = {bpm4:.3f}") +# return {"bpm1": bpm1, "bpm2": bpm2, "bpm3": bpm3, "bpm4": bpm4} + + +# def compute_norm(): +# """Compute normalised x and y positions""" +# readings = read_currents() +# total = readings["bpm1"] + readings["bpm2"] + readings["bpm3"] + readings["bpm4"] +# # print(f"Sum is {total:.2f}") +# xn = ((readings["bpm1"] + readings["bpm2"]) - (readings["bpm3"] + readings["bpm4"])) / total +# yn = ((readings["bpm1"] + readings["bpm3"]) - (readings["bpm2"] + readings["bpm4"])) / total +# return xn, yn + +def average_inten(): + vals_inten = [] + for _ in range(5): + vals_inten.append(dev.bcu_bpmsum.read()['bcu_bpmsum']['value']) + time.sleep(0.1) + inten = np.mean(vals_inten) + return inten + +def mirror_pitch(mirror = 'vfm'): + + if mirror == 'vfm': + pitch = dev.vfm_pitch.position + mot = dev.vfm_pitch + start = 2.94 + else: + pitch = dev.hfm_pitch.position + mot = dev.hfm_pitch + start = 3.3 + print(f"Scanning {mirror}_pitch from 10-29 keV") + pitch_range = [start - 0.25, start - 0.2, start -0.15, start - 0.1, start -0.05] + + umv(mot,start) + + results = [] + now = datetime.now() + fnow = now.strftime("%d%m%H%M") + csvfile = f"luts/{fnow}_{mirror}_pitch_energy.csv" + + with open(csvfile, "w") as f: + f.write("energy,pitch,diode\n") + + # for p in pitch_range: + for energy in range(17, 26): + bl_energy(energy) + time.sleep(1) + + for p in pitch_range: + umv(mot, p) + print(f"{mirror}_pitch = {p}") + time.sleep(0.2) + vals_diode = [] + + for _ in range(5): + vals_diode.append(dev.xidiode.read()['xidiode']['value']) + time.sleep(0.1) + + diode = np.mean(vals_diode) + + results.append([ + energy, + p, + diode, + ]) + + with open(csvfile, "a") as f: + f.write( + f"{energy:.2f},{p:.5f},{diode:.5g}\n" + ) + umv(mot,start) + bl_energy(12400) + results = np.array(results) + +def find_best_roll(low = 6000, high = 20000): + low_scanpoints = np.linspace(2.0, 7.0, 11) + high_scanpoints = np.linspace(1.0, 9.0,9) + highs_y, lows_y = [], [] + + # high energy + bl_energy(high) + filename = f"./luts/roll_{high:.0f}.csv" + with open(filename, "w", encoding="utf-8") as f: + f.write("Roll, Y pos\n") + auto_exposure("samcam", max_iter=25) + for i in high_scanpoints: + umv(dev.dcm_froll, i) + time.sleep(0.2) + high_y = dev.samcam_y.read()['samcam_y']['value'] + print(f"Ypos at sample cam is {high_y}") + highs_y.append(high_y) + with open(filename, "a", encoding="utf-8") as f: + f.write(f"{i:.4g},{high_y:.4g} \n") + + # low energy + bl_energy(low) + filename = f"./luts/roll_{low:.0f}.csv" + with open(filename, "w", encoding="utf-8") as f: + f.write("Roll, Y pos\n") + auto_exposure("samcam", max_iter=25) + for i in low_scanpoints: + umv(dev.dcm_froll, i) + time.sleep(0.2) + low_y = dev.samcam_y.read()['samcam_y']['value'] + print(f"Ypos at sample cam is {low_y}") + lows_y.append(low_y) + with open(filename, "a", encoding="utf-8") as f: + f.write(f"{i:.4g},{low_y:.4g} \n") + + + y_high = np.array(highs_y) + y_low = np.array(lows_y) + + + # # Fit linear models: y = m*x + b + m_high, b_high = np.polyfit(high_scanpoints, y_high, 1) + m_low, b_low = np.polyfit(low_scanpoints, y_low, 1) + + # # Intersection point + x_intersect = (b_low - b_high) / (m_high - m_low) + y_intersect = m_high * x_intersect + b_high + + print(f"\nIntersection at:") + print(f" DCM Roll = {x_intersect:.5f}") + print(f" samcam Y = {y_intersect:.2f}") + + # # --- Plot --- + plt.figure(figsize=(7,5)) + plt.scatter(high_scanpoints, y_high, color='red', label=f'High energy') + plt.scatter(low_scanpoints, y_low, color='blue', label=f'Low energy') + + x_fit = np.linspace(min(high_scanpoints), max(high_scanpoints), 100) + plt.plot(x_fit, m_high*x_fit + b_high, 'r--', label=f'High energy') + plt.plot(x_fit, m_low*x_fit + b_low, 'b--', label=f'Low energy') + + plt.scatter(x_intersect, y_intersect, color='green', s=80, zorder=5, label='Intersection') + + plt.xlabel('DCM fine roll') + plt.ylabel('samcam Y pos') + plt.title('Roll Calibration') + plt.legend() + plt.grid(True) + plt.tight_layout() + plt.show() + +def vfm_yaw_check(): + slit_size = 0.02 + slit_point1 = -1.2 + slit_point2 = -0.12 + mirror_start = 0.5 + mirror_end = -5 + yaw_values = [-1.5, -0.5, 0, 0.5, 1] + point1 = [] + point2 = [] + + umv(dev.ss_sl_ysize, slit_size) + + for yaw in yaw_values: + print(f"Moving VFM yaw to {yaw}") + umv(dev.vfm_yaw, yaw) + # Point 1 + print(f"Moving slits to position 1") + umv(dev.ss_sl_ycen, slit_point1) + scans.line_scan(dev.vfm_x, mirror_start, mirror_end, steps = 20, relative=False) + fit_result = fit_history(-1, "xidiode", deriv=True) + centre = fit_result['centre'] + print(f'Yaw = {yaw}, position = {slit_point1}, centre = {centre}') + point1.append(centre) + # Point 2 + print(f"Moving slits to position 2") + umv(dev.ss_sl_ycen, slit_point2) + scans.line_scan(dev.vfm_x, mirror_start, mirror_end, steps = 20, relative=False) + fit_result = fit_history(-1, "xidiode", deriv=True) + centre = fit_result['centre'] + print(f'Yaw = {yaw}, position = {slit_point2}, centre = {centre}') + point2.append(centre) + print(f"Point 1 values are {point1}") + print(f"Point 2 values are {point2}") + go_to_peak(dev.ss_sl_ycen, dev.xidiode, -2, 2, 100) + umv(dev.ss_sl_ysize, 2) + y_point1 = np.array(point1) + y_point2 = np.array(point2) + + + # # Fit linear models: y = m*x + b + m_point1, b_point1 = np.polyfit(yaw_values, y_point1, 1) + m_point2, b_point2 = np.polyfit(yaw_values, y_point2, 1) + + # # Intersection point + x_intersect = (b_point2 - b_point1) / (m_point1 - m_point1) + y_intersect = m_point1 * x_intersect + b_point1 + + print(f"\nIntersection at:") + print(f" Mirror yaw = {x_intersect:.5f}") + print(f" Y = {y_intersect:.2f}") + + # # --- Plot --- + plt.figure(figsize=(7,5)) + plt.scatter(yaw_values, y_point1, color='red', label=f'point1') + plt.scatter(yaw_values, y_point2, color='blue', label=f'point2') + + x_fit = np.linspace(min(yaw_values), max(yaw_values), 100) + plt.plot(x_fit, m_point1*x_fit + b_point1, 'r--', label=f'point1') + plt.plot(x_fit, m_point2*x_fit + b_point2, 'b--', label=f'point2') + + plt.scatter(x_intersect, y_intersect, color='green', s=80, zorder=5, label='Intersection') + + plt.xlabel('VFM yaw') + plt.ylabel('Edge') + plt.title('VFM Yaw Calibration') + plt.legend() + plt.grid(True) + plt.tight_layout() + plt.show() + +from dataclasses import dataclass +import time + + +@dataclass +class SlitAxis: + name: str + centre_motor: object # e.g. dev.slit1_x + size_motor: object # e.g. dev.slit1_xsize + scan_func: callable # your existing peak scan function + scan_range: float = 2.0 + open_size: float = 2.0 + min_size: float = -0.4 + max_size: float = 5.0 + + +@dataclass +class Slit: + name: str + x: SlitAxis + y: SlitAxis + + +def read_intensity(detector, n=5, delay=0.1): + values = [] + for _ in range(n): + values.append(detector.read()[detector.name]["value"]) + time.sleep(delay) + return sum(values) / len(values) + + + +def reduce_to_transmission(axis, detector, baseline, target=0.15, step=0.05): + """ + Close slit size until intensity is around target * baseline. + """ + size = axis.size_motor.position + + while size > axis.min_size: + intensity = read_intensity(detector) + transmission = intensity / baseline + + print( + f"{axis.name}: size={size:.4f}, " + f"I={intensity:.3g}, transmission={transmission:.3f}" + ) + + if transmission <= target: + return size, intensity + + size -= step + umv(axis.size_motor, size) + + raise RuntimeError(f"{axis.name}: reached minimum slit size without reaching target") + + +def open_to_transmission(axis, detector, baseline, target=0.99, step=0.05): + """ + Open slit until intensity is close to the original baseline. + """ + size = axis.size_motor.position + + while size < axis.max_size: + intensity = read_intensity(detector) + transmission = intensity / baseline + + print( + f"{axis.name}: size={size:.4f}, " + f"I={intensity:.3g}, transmission={transmission:.3f}" + ) + + if transmission >= target: + return size, intensity + + size += step + umv(axis.size_motor, size) + # final_size = axis.size.motor.position + # fudge = 0.5 + # umv(axis.size_motor,final_size + fudge) + + raise RuntimeError(f"{axis.name}: reached maximum slit size without restoring intensity") + +# def approx_centre_axis(axis, detector, slitsize=0.5): +# umv(axis.size_motor, slitsize) +# go_to_peak(axis.centre_motor, detector, -4, 4, 50, confirm=False) + + +def centre_axis(axis, detector, close_fraction=0.10, open_fraction=0.95): + print(f"\nAligning {axis.name}") + + # approx_centre_axis(axis, detector, slitsize=0.5) + + umv(axis.size_motor, axis.open_size) + + baseline = read_intensity(detector) + print(f"{axis.name}: baseline intensity = {baseline:.3g}") + + # if baseline <= 0: + # raise RuntimeError(f"{axis.name}: invalid baseline intensity") + + reduce_to_transmission( + axis, + detector, + baseline, + target=close_fraction, + ) + + go_to_peak(axis.centre_motor, detector, axis.centre_motor.position - axis.scan_range, + axis.centre_motor.position + axis.scan_range, + 50, + confirm=False) + print(f"{axis.name}: moving centre to peak position") + + open_to_transmission( + axis, + detector, + baseline, + target=open_fraction, + ) + + final_intensity = read_intensity(detector) + print( + f"{axis.name}: final intensity = {final_intensity:.3g}, " + f"transmission = {final_intensity / baseline:.3f}" + ) + +def open_slits(size=3): + slits = define_slits() + for slit in slits: + umv(slit.x.size_motor, size) + umv(slit.y.size_motor, size) + + +def centre_slit(slit, detector): + print(f"\n=== Aligning {slit.name} ===") + + centre_axis(slit.x, detector) + centre_axis(slit.y, detector) + + print(f"=== Finished {slit.name} ===") + + +def centre_all_slits(slits, detector): + for slit in slits: + try: + centre_slit(slit, detector) + except Exception as exc: + print(f"WARNING: failed to align {slit.name}: {exc}") + print("Continuing with next slit.") + +def centre_one(name, detector): + slits = define_slits() + for slit in slits: + if slit.name == name: + centre_slit(slit, detector) + +def define_slits(): + slits = [ + Slit( + name="bsf", + x=SlitAxis( + name="bsf_sl_x", + centre_motor=dev.bsf_sl_xcen, + size_motor=dev.bsf_sl_xsize, + scan_func=go_to_peak, + ), + y=SlitAxis( + name="bsf_sl_y", + centre_motor=dev.bsf_sl_ycen, + size_motor=dev.bsf_sl_ysize, + scan_func=go_to_peak, + ), + ), + Slit( + name="ss", + x=SlitAxis( + name="ss_sl_x", + centre_motor=dev.ss_sl_xcen, + size_motor=dev.ss_sl_xsize, + scan_func=go_to_peak, + ), + y=SlitAxis( + name="ss_sl_y", + centre_motor=dev.ss_sl_ycen, + size_motor=dev.ss_sl_ysize, + scan_func=go_to_peak, + ), + ), + Slit( + name="bcu", + x=SlitAxis( + name="bcu_sl_x", + centre_motor=dev.bcu_sl_xcen, + size_motor=dev.bcu_sl_xsize, + scan_func=go_to_peak, + ), + y=SlitAxis( + name="ss_sl_y", + centre_motor=dev.bcu_sl_ycen, + size_motor=dev.bcu_sl_ysize, + scan_func=go_to_peak, + ), + ), + ] + return slits + +def get_mirror_data(history_index: int): + """Read data from the BEC history and return the X and Y data as arrays.""" + motor1 = "vfm_bu" + motor2 = "vfm_bd" + + scan = bec.history[history_index] + md = scan.metadata["bec"] + x1_data = scan.devices[motor1][motor1].read()["value"] + x2_data = scan.devices[motor2][motor2].read()["value"] + y1_data = scan.devices['microscope_stats']['microscope_stats_data_sigma_y'].read()['value'] + y2_data = scan.devices['microscope_stats']['microscope_stats_data_eccentricity'].read()['value'] + np.savetxt("luts/x1_data", x1_data) + np.savetxt("luts/x2_data", x2_data) + np.savetxt("luts/y1_data", y1_data) + np.savetxt("luts/y2_data", y2_data) + + + # plt.imshow(y1_data, cmap="hot") + # plt.clf + # return { + # "signal_name": signal_name, + # "x_data": x_data, + # "y_data": y_data, + # "motor_name": motor_name, + # "scan_number": scan_number, + # } + + +def record_beampos_until(stop_time_str, planner, interval_minutes=10): + """ + Runs `record_beam()` every `interval_minutes` minutes + until the next occurrence of the given stop time (HH:MM). + """ + + # Prepare the file + now = datetime.now() + fnow = now.strftime("%d%m%H%M") + fdir = "/sls/x06da/config/bec/production/pxiii_bec/pxiii_bec/macros/" + fname = f"luts/beampos/beampos_{fnow}.csv" + filename = fdir + fname + scam_zoom = dev.scam_zoom.read()['scam_zoom']['value'] + umv(dev.scam_zoom, 1000) + #dev.transm.put(0.1) + beam_size = "25 x 20" + + energy = get_current_energy() + + + # Write the header to the file + with open(filename, "w", encoding="utf-8") as f: + f.write(f"Beam size: {beam_size}, Energy: {energy:.0f} eV, Zoom: {scam_zoom}\n") + # f.write("Time,BPM_x,BPM_y,Scin_x,Scin_y,BPM_x,BPM_y\n") + f.write("Time,Scin_x,Scin_y,BPM_x,BPM_y\n") + + + # Parse the stop time (HH:MM) + stop_hour, stop_minute = map(int, stop_time_str.split(":")) + end_time = now.replace(hour=stop_hour, minute=stop_minute, second=0, microsecond=0) + + # If that time already passed today, set it for tomorrow + if end_time <= now: + end_time += timedelta(days=1) + + # Change to beam visualisation state, ensure shutter is closed first + dev.bcu_shutter.put(0) + planner.move_to(BeamlineState.BEAM_VISUALISATION) + + # Start recording beam position + print(f"Starting now ({now:%Y-%m-%d %H:%M}), running until {end_time:%Y-%m-%d %H:%M}") + print(f"Interval: {interval_minutes} minutes\n") + + while datetime.now() < end_time: + record_beam(filename) + next_run = datetime.now() + timedelta(minutes=interval_minutes) + if next_run > end_time: + break + print(f"Next run at {next_run:%H:%M:%S}") + time.sleep(interval_minutes * 60) + + print(f"Finished — reached {end_time:%H:%M}.") + planner.move_to(BeamlineState.MANUAL_SAMPLE_EXCHANGE) + + + + +def record_beam(filename): + """ + Record the beam position to file. + """ + # Set transmission and bpm position + #dev.transm.put(0.1) + #umv(dev.bcu_bpm_x, 0.43) + #umv(dev.bcu_bpm_y, -1.543 ) + + # Open shutter and record positions + dev.bcu_shutter.put(1) + auto_exposure(cam="samcam") + time.sleep(2) + now = datetime.now() + + # Append data to the file + with open(filename, "a", encoding="utf-8") as f: + fnow = now.strftime("%H:%M:%S") + xpos_cam = dev.samcam_x.read()["samcam_x"]["value"] + ypos_cam = dev.samcam_y.read()["samcam_y"]["value"] + # x_bpm, y_bpm = get_beampos() + print(f"Time is {fnow}, X position is {xpos_cam:.5g}, Y position is {ypos_cam:.5g}") + #x_bpm, y_bpm = compute_norm() + #f.write( + # # f"{fnow}, {xpos: .5g}, {ypos: .4g}, {xpos_cam: .5g}, {ypos_cam: .4g}\n" + # f"{fnow},{xpos_cam: .5g},{ypos_cam: .4g},{x_bpm: .5g},{y_bpm: .5g}\n" + #) + f.write(f"{fnow},{xpos_cam: .5g},{ypos_cam: .4g}\n") + # Close shutter + dev.bcu_shutter.put(0) + + +def analyse_beampos(file): + """Plot the recorded beam position data""" + # Load the CSV file into a Pandas DataFrame + filedir = "/sls/x06da/config/bec/production/pxiii_bec/pxiii_bec/macros/luts/beampos/" + filename = filedir + file + data = pd.read_csv(filename, skiprows=1) + print(data.head()) + + # ref_bpmx = 0.110 + # ref_bmpy = -0.175 + ref_scinx = 1024 + ref_sciny = 980 + scam_zoom = 1000 + + # Extract the first column (time) as the x-axis + meas_time = data["Time"] + + # subtract the reference positions from the measures position + # data["bpm_x"] = data["bpm_x"] - ref_bpmx + # data["bpm_y"] = data["bpm_y"] - ref_bmpy + data["Scin_x"] = (data["Scin_x"] - ref_scinx) * calc_scam_microns(1) + data["Scin_y"] = (data["Scin_y"] - ref_sciny) * calc_scam_microns(1) + + + # Extract Y-position columns (all columns except the first column) + y_positions = data.iloc[:, 1:] # Exclude the first column + + fig, axs = plt.subplots( + 2, 2, figsize=(12, 8), layout="constrained" + ) # Create a 2x2 grid for subplots + # Flatten axs for easy iteration (if axs is a 2D array of axes) + axs = axs.flatten() + # Specify which columns to color differently + #red_columns = ["bpm_x", "scin_x"] + red_columns = ["scin_x"] + + for idx, column in enumerate(y_positions.columns): + ax = axs[idx] # Select the current subplot + + # Determine the color based on the column name + color = "red" if column in red_columns else "blue" + + # Plot the line and scatter with the chosen color + ax.plot(meas_time, y_positions[column], color=color, linewidth=0.5) # Line plot + ax.scatter( + meas_time, y_positions[column], color=color, label=column + ) # Scatter plot + + # Set x-axis tick positions and labels + tick_positions = range(0, len(meas_time), 7) # Adjust the step size as needed + ax.set_xticks(tick_positions) + ax.set_xticklabels([meas_time[i] for i in tick_positions], rotation=45) + + # Add labels, title, legend, and grid to each subplot + ax.set_xlabel("Time") + ax.set_ylabel("beam displacement (microns)") + ax.set_title(f"Beam position at {column}") + ax.legend() + ax.grid(True) + + # Show the resulting figure + plt.show() + +import time +import numpy as np +import matplotlib.pyplot as plt +from epics import caget + + + +def scan_scin_focus(planner, type = 'fine'): + dev.bcu_shutter.put(0) + planner.move_to(BeamlineState.BEAM_VISUALISATION) + dev.bcu_shutter.put(1) + z0 = dev.diag_z.position + + min = 0.1 + max = 9.9 + + + if type == 'fine': + steps = 100 + elif type == 'coarse': + steps = 30 + else: + steps = 60 + + umv(dev.scam_zoom, 1000) + dev.transm.put(0.1) + + auto_exposure("samcam", target=200, max_iter=20) + time.sleep(0.2) + + go_to_peak(dev.diag_z, dev.scam, min, max, steps, relative=True, gomax=True, confirm=False) + dev.bcu_shutter.put(0) diff --git a/pxiii_bec/macros/katscripts.py-save b/pxiii_bec/macros/katscripts.py-save new file mode 100755 index 0000000..451fb84 --- /dev/null +++ b/pxiii_bec/macros/katscripts.py-save @@ -0,0 +1,1536 @@ +"""Some simple scripts for commissioning""" + +import time, os +from datetime import datetime, timedelta +from dataclasses import dataclass +import numpy as np +import matplotlib.pyplot as plt +from scipy.signal import find_peaks as fp +import pandas as pd +from scipy.optimize import linear_sum_assignment + + + +def bragg_scan(): + """Energy scans from 6 to 18 keV at various gap positions""" + + start_bragg = 110.05 # 18 keV + end_bragg = 335.77 # 6 keV + steps = 1200 + exp = 0.05 + gap = 7.5 + umv(dev.id_gap, gap) + time.sleep(10) + while gap < 9.6: + print(f"Scanning the dcm_bragg from {start_bragg} to {end_bragg} at a gap of {gap: .2f} mm") + umv(dev.id_gap, gap) + scans.line_scan( + dev.dcm_bragg, start_bragg, end_bragg, steps=steps, exp_time=exp, relative=False + ) + gap += 0.5 + + +def move_xeye(direction): + """Move the xeye in or out""" + if direction == "in": + umv(dev.ss_xicam_x, 7.0) + else: + umv(dev.ss_xicam_x, -7) + + +def close_fe_slits(close=True): + """Close FE slits to (0.3,0.3) or open the FE slits to (2.0,1.0)""" + if close: + umv(dev.fe_sl_xsize, 0.3, dev.fe_sl_ysize, 0.3) + else: + umv(dev.fe_sl_xsize, 1.5, dev.fe_sl_ysize, 1.0) + + +def energy_checks(start_energy=8000, end_energy=20000): + """Check gap, pitch and intensities at different energies""" + f = open("luts/test.csv", "a", encoding="utf-8") + + for energy in range(start_energy, end_energy, 1000): + f = open("luts/test.csv", "a", encoding="utf-8") + print(f"Moving to {energy} eV") + bl_energy + if energy < 16000: + close_fe_slits(True) + go_to_peak( + dev.id_gap, dev.lu_bpmsum, -0.3, 0.3, 40, relative=True, confirm=False, gomax=True + ) + scan_fe() + close_fe_slits(True) + go_to_peak( + dev.id_gap, dev.lu_bpmsum, -0.1, 0.1, 15, relative=True, confirm=False, gomax=True + ) + go_to_peak( + dev.id_gap, + dev.lu_bpmsum, + -0.025, + 0.025, + 15, + relative=True, + confirm=False, + gomax=True, + ) + close_fe_slits(False) + + else: + umv(dev.s1_xsize, 0.5) + go_to_peak( + dev.id_gap, dev.bcu_bpmsum, -0.3, 0.3, 40, relative=True, confirm=False, gomax=True + ) + scan_fe() + go_to_peak( + dev.id_gap, dev.bcu_bpmsum, -0.1, 0.1, 15, relative=True, confirm=False, gomax=True + ) + umv(dev.s1_xsize, 2.5) + mono_pitch_scan() + gap = dev.id_gap.read()["id_gap"]["value"] + pitch = dev.dcm_pitch.read()["dcm_pitch"]["value"] + fe_x = dev.fe_sxcen.read()["fe_sxcen"]["value"] + fe_y = dev.fe_sycen.read()["fe_sycen"]["value"] + lu_read = dev.lu_bpmsum.read()["lu_bpmsum"]["value"] + ss_read = dev.ss_bpmsum.read()["ss_bpmsum"]["value"] + bcu_read = dev.bcu_bpmsum.read()["bcu_bpmsum"]["value"] + f.write( + f"{energy}, {gap: .5g}, {pitch: .5g}, {lu_read: .5g}, " + f"{ss_read: .5g}, {bcu_read: .5g}, " + f"{fe_x: .5g}, {fe_y: .5g}\n" + ) + + f.close() + + +def scan_fe(): + """Scan the FE slits in X and Y""" + print("Scanning FE slits in X") + umv(dev.fe_sxsize, 0.05, dev.fe_sysize, 2) + go_to_peak(dev.fe_sxcen, dev.lu_bpmsum, -1.5, 1.5, 20, confirm=False, relative=True) + print("Scanning FE slits in Y") + umv(dev.fe_sxsize, 0.3, dev.fe_sysize, 0.05) + go_to_peak(dev.fe_sycen, dev.lu_bpmsum, -1.2, 1.2, 15, confirm=False, relative=True) + close_fe_slits(False) + + +def scan_gap(): + """Scan the gap and monitor on lu_bpmsum or bcu_bpmsum""" + # close_fe_slits(True) + current_gap = dev.id_gap.read()["id_gap"]["value"] + if current_gap > 4.6: + go_to_peak( + dev.id_gap, dev.lu_bpmsum, -0.1, 0.1, 25, relative=True, confirm=False, gomax=False + ) + else: + go_to_peak( + dev.id_gap, dev.lu_bpmsum, 4.5, 4.75, 25, relative=False, confirm=False, gomax=False + ) + # close_fe_slits(False) + + +def record_pitch(): + """Record the pitch and perp distance to file""" + with open("luts/pitch_record.csv", "a", encoding="utf-8") as f: + current_energy = get_current_energy() + pitch = dev.dcm_pitch.read()["dcm_pitch"]["value"] + gap = dev.id_gap.read()["id_gap"]["value"] + f.write(f"{current_energy: .0f}, {pitch: .5g}, {gap: .4g}\n") + f.close() + + +def record_roll(): + """Record the roll and perp distance to file""" + with open("luts/roll_record.csv", "a", encoding="utf-8") as f: + current_energy = get_current_energy() + roll = dev.dcm_froll.read()["dcm_froll"]["value"] + f.write(f"{current_energy:.0f}, {roll:.5g}\n") + f.close() + + +def record_perp(): + """Check perp calibrations at various energies""" + with open("luts/perp_record.csv", "a", encoding="utf-8") as f: + current_energy = get_current_energy() + perp = dev.dcm_perp.read()["dcm_perp"]["value"] + ss_xicam_x = dev.ss_xicam_x.read()["ss_xicam_x"]["value"] + ss_xicam_y = dev.ss_xicam_y.read()["ss_xicam_y"]["value"] + f.write(f"{current_energy:.0f},{perp:.5g},{ss_xicam_x:.5g},{ss_xicam_y:.5g}\n") + f.close() + + +def beam_centre_from_ss(): + """Compute the beam centre from the ss_cam""" + y = dev.ss_xicam_x.read()["ss_xicam_x"]["value"] + x = dev.ss_xicam_y.read()["ss_xicam_y"]["value"] + beampos = {"xpos": x, "ypos": y} + print(f"X is {x: .4g}, Y is {y: .4g}") + return beampos + + +def generate_dcm_lut(start_energy=6000, end_energy=30000, step=300): + """Generate a lookup table for the dcm from start_energy to end_energy in steps of step""" + now = datetime.now() + fnow = now.strftime("%d%m%H%M") + filename = f"luts/{fnow}_lut.csv" + zoom = dev.scam_zoom.read()['scam_zoom']['value'] + with open(filename, "w", encoding="utf-8") as f: + f.write(f"energy,harmonic,gap,pitch,roll,perp,samcam_x,samcam_y,zoom={zoom}\n") + + for energy in range(start_energy, end_energy, step): + print(f"Moving to {energy: .0f}eV") + bl_energy(energy, mono_scan=False) + try: + scan_gap() + except Exception as exc: + print(f"Gap scan failed at {energy:.0f} eV: {exc}") + set_gap(energy) # set fallback gap here + + mono_pitch_scan() + gap = dev.id_gap.read()["id_gap"]["value"] + harm = Gap() + h = harm.get_harmonic_by_energy(energy) + pitch = dev.dcm_pitch.read()["dcm_pitch"]["value"] + roll = dev.dcm_froll.read()["dcm_froll"]["value"] + perp = dev.dcm_perp.read()["dcm_perp"]["value"] + # auto_exposure(cam="ss_xicam", max_iter=25) + # x = dev.ss_xicam_x.read()["ss_xicam_x"]["value"] + # y = dev.ss_xicam_y.read()["ss_xicam_y"]["value"] + auto_exposure(cam="samcam", max_iter=20) + x = dev.samcam_x.read()['samcam_x']['value'] + y = dev.samcam_y.read()['samcam_y']['value'] + with open(filename, "a", encoding="utf-8") as f: + f.write( + f"{energy:.0f},{h},{gap:.5g},{pitch:.5g},{roll:.4g},{perp:.5g},{x:.4g},{y:.4g}\n" + ) + bl_energy(12400) + umv(dev.id_gap, 20.0) + + +def write_lut(): + """Write DCM parameters to file""" + filename = "luts/manual_big.csv" + energy = get_current_energy() + mono_pitch_scan() + roll_scan_to_target() + gap = dev.id_gap.read()["id_gap"]["value"] + pitch = dev.dcm_pitch.read()["dcm_pitch"]["value"] + roll = dev.dcm_froll.read()["dcm_froll"]["value"] + perp = dev.dcm_perp.read()["dcm_perp"]["value"] + x = dev.ss_xicam_x.read()["ss_xicam_x"]["value"] + y = dev.ss_xicam_y.read()["ss_xicam_y"]["value"] + with open(filename, "a", encoding="utf-8") as f: + f.write(f"{energy:.0f},{gap:.5g},{pitch:.5g},{roll:.4g},{perp:.5g},{x:.4g},{y:.4g}\n") + + +def measure_beamsize(cam="samcam"): + auto_exposure("samcam", max_iter=20) + a = dev.samcam_xsig.read()["samcam_xsig"]["value"] + b = dev.samcam_ysig.read()["samcam_ysig"]["value"] + zoom = dev.scam_zoom.read()["scam_zoom"]["value"] + sx = calc_scam_microns(a, zoom=zoom) * 2.35 + sy = calc_scam_microns(b, zoom=zoom) * 2.35 + print(f"FWHM in um : {sx, sy}") + return sx, sy + + +def write_beamsize(): + """Write beam size and flux to file""" + filename = "luts/beamsizes.csv" + with open(filename, "a", encoding="utf-8") as f: + f.write("lens_config,size_x,size_y,i1\n") + lens_config = input("Which lenses are in?") + if SE.scin.checkpos: + filters("out") + sx, sy = measure_beamsize() + else: + scin("in") + filters("out") + sx, sy = measure_beamsize() + i1_reading = i1() + with open(filename, "a", encoding="utf-8") as f: + f.write(f"{lens_config},{sx:.4g},{sy:.4g},{i1_reading:.4g}\n") + + + +def scan_Ge(): + scanbefore = 30 # eV + scanafter = 30 # eV + stepsize = 0.2 # eV + # Edge sgould be at 11103.1 + actual_edge_Ge = 11103.1 # eV + actual_bragg = convert_from_energy(actual_edge_Ge)["bragg_angle_mrad"] + current_edge = 11095 + current_bragg = convert_from_energy(current_edge)["bragg_angle_mrad"] + print(f"Ge edge should be at a bragg angle of {actual_bragg:.5g} mrad\n") + print(f"Current estimate of edge is {current_bragg:.5g} mrad\n") + xdata = [] + ydata = [] + filedir, fname = fnow() + filename = f"{filedir}{fname}_ge_edge.csv" + print(filename) + with open(filename, 'w') as f: + f.write(f"Energy,Bragg,bcu_bpmsum\n") + + # scanstart = edge_Ge + scanafter + # scanend = edge_Ge - scanbefore + # bragg_start = convert_from_energy(scanstart)["bragg_angle_mrad"] + # bragg_end = convert_from_energy(scanend)["bragg_angle_mrad"] + # stepnumber = abs(int((scanend - scanstart) / stepsize)) + # print(f"Changing energy to {scanstart}") + # bl_energy(scanstart) + # # scan_gap() + # umv(dev.ss_f4_x, 6) # Put Ge filter in place + # print(f"scanning from {bragg_start} to {bragg_end} with {stepnumber} steps") + # s = scans.line_scan(dev.dcm_bragg, bragg_start, bragg_end, steps=stepnumber, relative=False) + # print(s) + # umv(dev.ss_f4_x, 2) + + plot_live_data_bec(dev.dcm_bragg,dev.bcu_bpmsum) + scanpoints = np.linspace(current_bragg - 0.5, current_bragg + 0.5, 300) + start_energy = convert_from_bragg(current_bragg+0.5)["energy_ev"] + bl_energy(start_energy) + umv(dev.ss_f4_x, 6) # Put Ge filter in place + + for bragg in scanpoints: + scans.umv(dev.dcm_bragg, bragg, relative=False) + energy = convert_from_bragg(bragg)["energy_ev"] + inten = average_inten() + xdata.append(energy) + ydata.append(inten) + with open(filename, 'a') as f: + f.write(f"{energy:.2f},{bragg:.2f},{inten:.2f}\n") + data = { + "x_data": np.array(xdata), + "y_data": np.array(ydata), + "motor_name": "dcm_bragg", + "signal_name": "bcu_bpmsum", + "motor_device": dev.dcm_bragg, + "scan_number": "Current", + } + + # Define and fit model to scan data + fit_params = create_fit_parameters(deriv = True, + negative = False, + model = FitDefaults.MODEL, + baseline = FitDefaults.BASELINE) + fit_result = fit(data, fit_params) + + # Plot the fitted data if plot = True + + plot_fitted_data_bec(data, fit_result) + + + + +def cal_samcam_fixed_x(): + # lat = dev.hfm_x.read()["hfm_x"]["value"] + # pitch = dev.hfm_pitch.read()["hfm_pitch"]["value"] + fpitch = dev.dcm_fpitch.read()['dcm_fpitch']['value'] + scanpoints = np.linspace(3.75, 4.75, 7) + zoom_high = 800 + zoom_low = 200 + highs, lows = [], [] + high_fpitch, low_fpitch = [], [] + av_high = [] + av_low = [] + + # high zoom + umv(dev.scam_zoom, zoom_high) + auto_exposure("samcam") + for i in scanpoints: + umv(dev.dcm_fpitch, i) + time.sleep(0.2) + for _ in range(5): + reading = dev.samcam_x.read()["samcam_x"]["value"] + av_high.append(reading) + high_y = np.mean(av_high) + high_x = dev.dcm_fpitch.read()["dcm_fpitch"]["value"] + print(f"Xpos at zoom {zoom_high} is {high_y}") + highs.append(high_y) + high_fpitch.append(high_x) + + umv(dev.scam_zoom, zoom_low) + auto_exposure("samcam") + for i in scanpoints: + umv(dev.dcm_fpitch, i) + time.sleep(0.2) + for i in range(5): + reading = dev.samcam_x.read()["samcam_x"]["value"] + av_low.append(reading) + low_y = np.mean(av_low) + low_x = dev.dcm_fpitch.read()["dcm_fpitch"]["value"] + print(f"Xpos at zoom {zoom_low} is {low_y}") + lows.append(low_y) + low_fpitch.append(low_x) + + umv(dev.dcm_fpitch, 5) + + # Convert to numpy arrays + x_high = np.array(high_fpitch) + x_low = np.array(low_fpitch) + y_high = np.array(highs) + y_low = np.array(lows) + + # Fit linear models: y = m*x + b + m_high, b_high = np.polyfit(x_high, y_high, 1) + m_low, b_low = np.polyfit(x_low, y_low, 1) + + # Intersection point + x_intersect = (b_low - b_high) / (m_high - m_low) + y_intersect = m_high * x_intersect + b_high + + print(f"\nIntersection at:") + print(f" dcm_fpitch = {x_intersect:.5f}") + print(f" SamCam_x = {y_intersect:.2f}") + + # --- Plot --- + plt.figure(figsize=(7, 5)) + plt.scatter(x_high, y_high, color="red", label=f"Zoom = {zoom_high} data") + plt.scatter(x_low, y_low, color="blue", label=f"Zoom = {zoom_low} data") + + x_fit = np.linspace(min(x_high), max(x_high), 100) + plt.plot(x_fit, m_high * x_fit + b_high, "r--", label=f"Fit: Zoom {zoom_high}") + plt.plot(x_fit, m_low * x_fit + b_low, "b--", label=f"Fit: Zoom {zoom_low}") + + plt.scatter(x_intersect, y_intersect, color="green", s=80, zorder=5, label="Intersection") + + plt.xlabel("DCM Fine Pitch Position") + plt.ylabel("SamCam X") + plt.title("Zoom Calibration") + plt.legend() + plt.grid(True) + plt.tight_layout() + plt.show() + + +def cal_samcam_fixed_y(): + vert = dev.vfm_y.read()["vfm_y"]["value"] + pitch = dev.vfm_pitch.read()["vfm_pitch"]["value"] + scanpoints = np.linspace(vert - 0.1, vert + 0.1, 7) + zoom_high = 800 + zoom_low = 200 + highs, lows = [], [] + high_vert, low_vert = [], [] + + # high zoom + umv(dev.scam_zoom, zoom_high) + auto_exposure("samcam") + for i in scanpoints: + umv(dev.vfm_y, i) + umv(dev.vfm_pitch, pitch) + time.sleep(0.2) + high_y = dev.samcam_y.read()["samcam_y"]["value"] + high_x = dev.vfm_y.read()["vfm_y"]["value"] + print(f"Ypos at zoom {zoom_high} is {high_y}") + highs.append(high_y) + high_vert.append(high_x) + + umv(dev.scam_zoom, zoom_low) + auto_exposure("samcam") + for i in scanpoints: + umv(dev.vfm_y, i) + umv(dev.vfm_pitch, pitch) + time.sleep(0.2) + low_y = dev.samcam_y.read()["samcam_y"]["value"] + low_x = dev.vfm_y.read()["vfm_y"]["value"] + print(f"Ypos at zoom {zoom_low} is {low_y}") + lows.append(low_y) + low_vert.append(low_x) + + umv(dev.vfm_y, vert) + umv(dev.vfm_pitch, pitch) + + # Convert to numpy arrays + x_high = np.array(high_vert) + x_low = np.array(low_vert) + y_high = np.array(highs) + y_low = np.array(lows) + + # Fit linear models: y = m*x + b + m_high, b_high = np.polyfit(x_high, y_high, 1) + m_low, b_low = np.polyfit(x_low, y_low, 1) + + # Intersection point + x_intersect = (b_low - b_high) / (m_high - m_low) + y_intersect = m_high * x_intersect + b_high + + print(f"\nIntersection at:") + print(f" vfm_y = {x_intersect:.5f}") + print(f" SamCam_y = {y_intersect:.2f}") + + # --- Plot --- + plt.figure(figsize=(7, 5)) + plt.scatter(x_high, y_high, color="red", label=f"Zoom = {zoom_high} data") + plt.scatter(x_low, y_low, color="blue", label=f"Zoom = {zoom_low} data") + + x_fit = np.linspace(min(x_high), max(x_high), 100) + plt.plot(x_fit, m_high * x_fit + b_high, "r--", label=f"Fit: Zoom {zoom_high}") + plt.plot(x_fit, m_low * x_fit + b_low, "b--", label=f"Fit: Zoom {zoom_low}") + + plt.scatter(x_intersect, y_intersect, color="green", s=80, zorder=5, label="Intersection") + + plt.xlabel("VFM Vert Position") + plt.ylabel("SamCam Y") + plt.title("Zoom Calibration") + plt.legend() + plt.grid(True) + plt.tight_layout() + plt.show() + + +def correlate_froll(): + x_correlation = [] + y_correlation = [] + scanpoints = np.linspace(0, 0.2, 10) + for pos in scanpoints: + umv(dev.dcm_froll, pos) + xpos, ypos = compute_pos() + x_correlation.append(xpos) + y_correlation.append(ypos) + + x = np.array(scanpoints) + y1 = np.array(x_correlation) + y2 = np.array(y_correlation) + + xslope, xint = np.polyfit(x, y1, 1) + yslope, yint = np.polyfit(x, y2, 1) + + print(f"Fit for xpos is: y = {xslope}.x + {xint}") + print(f"Fit for ypos is: y = {yslope}.x + {yint}") + + plt.figure(figsize=(7, 5)) + # plt.scatter(x, y1, label='xpos') + plt.scatter(x, y2, label="beam y position", color="rebeccapurple") + + x_fit = np.linspace(min(x), max(x), 100) + # plt.plot(x_fit, xslope*x_fit + xint, 'r--', label=f'y = {xslope}*x + {xint}') + plt.plot( + x_fit, + yslope * x_fit + yint, + "r--", + label=f"y = {yslope:.3g}*x + ({yint:.3g})", + color="lightcoral", + ) + plt.xlabel("dcm fine roll (V)") + plt.ylabel("beam Y (from BCU BPM)") + plt.legend() + plt.grid(True) + plt.tight_layout() + plt.show() + + +def correlate_fpitch(): + x_correlation = [] + y_correlation = [] + scanpoints = np.linspace(0, 0.2, 10) + for pos in scanpoints: + umv(dev.dcm_fpitch, pos) + xpos, ypos = compute_pos() + x_correlation.append(xpos) + y_correlation.append(ypos) + + x = np.array(scanpoints) + y1 = np.array(x_correlation) + y2 = np.array(y_correlation) + + xslope, xint = np.polyfit(x, y1, 1) + yslope, yint = np.polyfit(x, y2, 1) + + print(f"Fit for xpos is: y = {xslope}.x + {xint}") + print(f"Fit for ypos is: y = {yslope}.x + {yint}") + + plt.figure(figsize=(7, 5)) + # plt.scatter(x, y1, label='xpos') + plt.scatter(x, y1, label="beam x position", color="rebeccapurple") + + x_fit = np.linspace(min(x), max(x), 100) + # plt.plot(x_fit, xslope*x_fit + xint, 'r--', label=f'y = {xslope}*x + {xint}') + plt.plot( + x_fit, xslope * x_fit + xint, label=f"y = {xslope:.3g}*x + ({xint:.3g})", color="lightcoral" + ) + plt.xlabel("dcm fine pitch (V)") + plt.ylabel("beam X (from BCU BPM)") + plt.legend() + plt.grid(True) + plt.tight_layout() + plt.show() + + +def correlate_hfm_x(): + x_correlation = [] + lat = dev.hfm_x.read()["hfm_x"]["value"] + scanpoints = np.linspace(lat - 0.1, lat + 0.1, 10) + for pos in scanpoints: + umv(dev.hfm_x, pos) + xpos, ypos = compute_pos() + x_correlation.append(xpos) + umv(dev.hfm_x, lat) + + x = np.array(scanpoints) + y1 = np.array(x_correlation) + + xslope, xint = np.polyfit(x, y1, 1) + + print(f"Fit for xpos is: y = {xslope}.x + {xint}") + plt.figure(figsize=(7, 5)) + # plt.scatter(x, y1, label='xpos') + plt.scatter(x, y1, label="beam x position", color="rebeccapurple") + + x_fit = np.linspace(min(x), max(x), 100) + # plt.plot(x_fit, xslope*x_fit + xint, 'r--', label=f'y = {xslope}*x + {xint}') + plt.plot( + x_fit, xslope * x_fit + xint, label=f"y = {xslope:.5g}*x + ({xint:.5g})", color="lightcoral" + ) + plt.xlabel("HFM lateral (mm)") + plt.ylabel("beam X (from BCU BPM)") + plt.legend() + plt.grid(True) + plt.tight_layout() + plt.show() + + +# def correlate_vfm_y(): +# y_correlation = [] +# vert = dev.vfm_y.read()["vfm_y"]["value"] +# scanpoints = np.linspace(vert - 0.06, vert + 0.06, 10) +# for pos in scanpoints: +# umv(dev.vfm_y, pos) +# xpos, ypos = compute_pos() +# y_correlation.append(ypos) +# umv(dev.vfm_y, vert) + +# x = np.array(scanpoints) +# y1 = np.array(y_correlation) + +# yslope, yint = np.polyfit(x, y1, 1) + +# print(f"Fit for xpos is: y = {yslope}.x + {yint}") +# plt.figure(figsize=(7, 5)) +# # plt.scatter(x, y1, label='xpos') +# plt.scatter(x, y1, label="beam y position", color="rebeccapurple") + +# x_fit = np.linspace(min(x), max(x), 100) +# # plt.plot(x_fit, xslope*x_fit + xint, 'r--', label=f'y = {xslope}*x + {xint}') +# plt.plot( +# x_fit, yslope * x_fit + yint, label=f"y = {yslope:.5g}*x + ({yint:.5g})", color="lightcoral" +# ) +# plt.xlabel("VFM vertical (mm)") +# plt.ylabel("beam Y(from BCU BPM)") +# plt.legend() +# plt.grid(True) +# plt.tight_layout() +# plt.show() + + +def correlate_hfm_pitch(): + x_correlation = [] + pitch = dev.hfm_pitch.read()["hfm_pitch"]["value"] + scanpoints = np.linspace(pitch - 0.05, pitch + 0.05, 10) + for pos in scanpoints: + umv(dev.hfm_pitch, pos) + xpos, ypos = compute_pos() + x_correlation.append(xpos) + umv(dev.hfm_pitch, pitch) + + x = np.array(scanpoints) + y1 = np.array(x_correlation) + + xslope, xint = np.polyfit(x, y1, 1) + + print(f"Fit for xpos is: y = {xslope}.x + {xint}") + plt.figure(figsize=(7, 5)) + # plt.scatter(x, y1, label='xpos') + plt.scatter(x, y1, label="beam x position", color="rebeccapurple") + + x_fit = np.linspace(min(x), max(x), 100) + # plt.plot(x_fit, xslope*x_fit + xint, 'r--', label=f'y = {xslope}*x + {xint}') + plt.plot( + x_fit, xslope * x_fit + xint, label=f"y = {xslope:.5g}*x + ({xint:.5g})", color="lightcoral" + ) + plt.xlabel("HFM Pitch (mm)") + plt.ylabel("beam X (from BCU BPM)") + plt.legend() + plt.grid(True) + plt.tight_layout() + plt.show() + + +def move_to_x(targetx=0.13): + # Calibration and drift compensation + # target from previous run was 0.1465 + slope = -1.004 + intercept = 1.793 + + xpos, ypos = compute_pos() + + beam_drift = xpos - targetx # beam moved +0.1 mm (100 µm) + mot_current = dev.hfm_x.read()["hfm_x"]["value"] # current motor position (example) + + # Compute correction + delta = -beam_drift / slope + mot_new = mot_current + delta + umv(dev.hfm_x, mot_new) + + +# def move_to_y(targety=-0.033): +# # Calibration and drift compensation +# # target from previous run = -0.283 +# slope = -1.2779 +# intercept = 2.4374 + +# xpos, ypos = compute_pos() + +# beam_drift = ypos - targety # beam moved +0.1 mm (100 µm) +# mot_current = dev.vfm_y.read()["vfm_y"]["value"] # current motor position (example) + +# # Compute correction +# delta = -beam_drift / slope +# mot_new = mot_current + delta +# umv(dev.vfm_y, mot_new) + + +from epics import caget, caput +import time + + +def auto_exposure( + cam="samcam", target=200, tol=5, gain=0.9, min_exp=0.00001, max_exp=0.2, max_iter=10 +): + """ + Adjust camera exposure time to reach a target max pixel value. + + Parameters + ---------- + target : float + Desired MaxValue (counts) + tol : float + Acceptable deviation from target + min_exp, max_exp : float + Exposure time limits (s) + max_iter : int + Maximum number of adjustment iterations + """ + if cam == "samcam": + exposure = dev.samcam_exp.read()["samcam_exp"]["value"] + else: + exposure = dev.ss_xicam_exp.read()["ss_xicam_exp"]["value"] + + print(f"Starting exposure = {exposure:.4f} s") + + for i in range(max_iter): + time.sleep(0.1) # allow a frame or two to update + if cam == "samcam": + maxval = dev.samcam_max.read()["samcam_max"]["value"] + if maxval is None: + print("No reading — check camera.") + break + if cam == "ss_xicam": + maxval = dev.ss_xicam_max.read()["ss_xicam_max"]["value"] + if maxval is None: + print("No reading — check camera.") + break + + error = target - maxval + # print(f"Iter {i+1}: MaxValue = {maxval:.1f}, error = {error:.1f}") + + # stop if within tolerance + if abs(error) <= tol: + # print(f"Target reached (MaxValue={maxval:.1f}) after {i+1} iterations.") + break + + # proportional correction (simple gain control) + gain_setting = gain # moderate response + new_exp = exposure * (1 + gain_setting * error / target) + + # limit exposure bounds + new_exp = max(min_exp, min(max_exp, new_exp)) + + # update camera perp = dev.dcm_perp.read()["dcm_perp"]["value"] + y = dev.ss_xicam_x.read()["ss_xicam_x"]["value"] + x = dev.ss_xicam_y.read()["ss_xicam_y"]["value"] + if cam == "samcam": + dev.samcam_exp.put(new_exp) + print(f" → Adjusting exposure to {new_exp:.4f} s") + else: + dev.ss_xicam_exp.put(new_exp) + print(f" → Adjusting exposure to {new_exp:.4f} s") + + exposure = new_exp + + print(f"New exposure time is {exposure:.3g}") + return exposure + + +# def get_new_beamsizes(mirror): +# filename = f"luts/{mirror}_size.csv" +# if mirror == "hfm": +# bu = dev.hfm_bu +# bd = dev.hfm_bd +# step = 0.2 +# else: +# bu = dev.vfm_bu +# bd = dev.vfm_bd +# step = 0.05 +# beamsize("xs") +# move_targetx_with_hfm_x() +# move_targety_with_vfm_y() +# with open(filename, "w") as f: +# for _ in range(4): +# curr_bu = bu.user_readback.get() +# curr_bd = bd.user_readback.get() +# auto_exposure() +# umv(bu, curr_bu + step) +# umv(bd, curr_bd + step) +# move_targetx_with_hfm_x() +# move_targety_with_vfm_y() +# xpos = dev.samcam_x.read()["samcam_x"]["value"] +# ypos = dev.samcam_y.read()["samcam_y"]["value"] +# xsig = dev.samcam_xsig.read()["samcam_xsig"]["value"] +# ysig = dev.samcam_ysig.read()["samcam_ysig"]["value"] +# f.write(f"{curr_bu}, {curr_bd}, {xpos}, {ypos}, {xsig}, {ysig}\n") +# print(f"{curr_bu}, {curr_bd}, {xpos}, {ypos}, {xsig}, {ysig}") + + +def filters(pos="out"): + if pos == "out": + umv(dev.ss_f1_x, 2.0, dev.ss_f2_x, 2.0, dev.ss_f3_x, 12.0, dev.ss_f4_x, 8.0) + if SE.scin.checkpos(): + auto_exposure(cam="samcam", max_iter=20) + else: + umv(dev.ss_f1_x, 2.0, dev.ss_f2_x, 2.0, dev.ss_f3_x, 8.0, dev.ss_f4_x, 8.0) + if SE.scin.checkpos(): + auto_exposure(cam="samcam", max_iter=20) + +def fnow(): + now = datetime.now() + fnow = now.strftime("%Y%m%d-%H%M") + filedir = "luts/" + return filedir, fnow + +def energy_vs_height(start_energy=11000, end_energy=25000, step=1000): + """Correlate beam height with energy from start_energy to end_energy in steps of step""" + now = datetime.now() + # fnow = now.strftime("%d%m%H%M_") + fnow = now.strftime("%Y-%m-%d-%H%M") + filename = f"luts/{fnow}_energy-height-ss.csv" + with open(filename, "w", encoding="utf-8") as f: + # f.write("energy,bcu_norm_y,bcu_y,samcam_ypix,samcam_y\n") + f.write("energy,y_px,diffy_mic\n") + + for energy in range(start_energy, end_energy, step): + print(f"Moving to {energy: .0f}eV") + bl_energy(energy) + # scan_gap() + # mono_pitch_scan() + # scan_slits("s3",x=False,y=True) + # height = dev.s3_ycen.read()["s3_ycen"]["value"] + # bcu_norm_y = compute_norm()[1] + # bcu_y = compute_pos()[1] + # auto_exposure(cam="samcam", target=200) + # samcam_ypix, samcam_y = calc_from_centre() + # with open(filename, "a", encoding="utf-8") as f: + # f.write(f"{energy:.0f},{bcu_norm_y:.4g},{bcu_y:.4g},{samcam_ypix:.5g},{samcam_y:.4g}\n") + + auto_exposure(cam="ss_xicam", target=200, max_iter=25) + time.sleep(0.5) + ypx, diffm = calc_from_centre("ss_xicam") + # pitch = dev.dcm_pitch.read()['dcm_pitch']['value'] + + with open(filename, "a", encoding="utf-8") as f: + f.write(f"{energy:.0f},{ypx:.4g},{diffm:.4g}\n") + # umv(dev.id_gap, 20.0) + + + +def scan_in_x(xsize, xcen, mon, small, large, width, steps): + umv(xsize, small) + go_to_peak(xcen, mon, -(width * 0.5), (width * 0.5), steps=steps, relative=False) + umv(xsize, large) + + +def scan_in_y(ysize, ycen, mon, small, large, width, steps): + umv(ysize, small) + go_to_peak(ycen, mon, -(width * 0.5), (width * 0.5), steps=steps, relative=True, confirm=False) + umv(ysize, large) + + +def trans_fils(inc): + x1 = dev.ss_f1_x.read()["ss_f1_x"]["value"] + x2 = dev.ss_f2_x.read()["ss_f2_x"]["value"] + x3 = dev.ss_f3_x.read()["ss_f3_x"]["value"] + x4 = dev.ss_f4_x.read()["ss_f4_x"]["value"] + umv( + dev.ss_f1_x, + x1 + inc, + dev.ss_f2_x, + x2 + inc, + dev.ss_f3_x, + x3 + inc, + dev.ss_f4_x, + x4 + inc, + ) + + +def calc_from_centre(cam="samcam"): + if cam == "samcam": + read = dev.samcam_y.read()["samcam_y"]["value"] + diff = 1092 - read + diff_px = calc_scam_microns(diff, zoom=1000) + return read, float(diff_px) + else: + read = dev.ss_xicam_y.read()["ss_xicam_y"]["value"] + diff = 140 - read + diff_px = calc_ss_xicam_microns(diff) + return read, diff_px + + +def get_cam(low_zoom, high_zoom): + umv(dev.scam_zoom, low_zoom) + x = dev.samcam_x.read()["samcam_x"]["value"] + y = dev.samcam_y.read()["samcam_y"]["value"] + print(f"Low zoom: x = {x}, y = {y}") + umv(dev.scam_zoom, high_zoom) + x = dev.samcam_x.read()["samcam_x"]["value"] + y = dev.samcam_y.read()["samcam_y"]["value"] + print(f"High zoom: x = {x}, y = {y}") + + +# def read_currents(): +# """Read the individual bpm channels""" +# bpm1 = dev.bcu_bpm1.read()["bcu_bpm1"]["value"] +# bpm2 = dev.bcu_bpm2.read()["bcu_bpm2"]["value"] +# bpm3 = dev.bcu_bpm3.read()["bcu_bpm3"]["value"] +# bpm4 = dev.bcu_bpm4.read()["bcu_bpm4"]["value"] +# # print(f"bpm1 = {bpm1:.3f}, bpm2 = {bpm2:.3f}, bpm3 = {bpm3:.3f}, bpm4 = {bpm4:.3f}") +# return {"bpm1": bpm1, "bpm2": bpm2, "bpm3": bpm3, "bpm4": bpm4} + + +# def compute_norm(): +# """Compute normalised x and y positions""" +# readings = read_currents() +# total = readings["bpm1"] + readings["bpm2"] + readings["bpm3"] + readings["bpm4"] +# # print(f"Sum is {total:.2f}") +# xn = ((readings["bpm1"] + readings["bpm2"]) - (readings["bpm3"] + readings["bpm4"])) / total +# yn = ((readings["bpm1"] + readings["bpm3"]) - (readings["bpm2"] + readings["bpm4"])) / total +# return xn, yn + +def average_inten(): + vals_inten = [] + for _ in range(5): + vals_inten.append(dev.bcu_bpmsum.read()['bcu_bpmsum']['value']) + time.sleep(0.1) + inten = np.mean(vals_inten) + return inten + +def mirror_pitch(mirror = 'vfm'): + + if mirror == 'vfm': + pitch = dev.vfm_pitch.position + mot = dev.vfm_pitch + start = 2.94 + else: + pitch = dev.hfm_pitch.position + mot = dev.hfm_pitch + start = 3.3 + print(f"Scanning {mirror}_pitch from 10-29 keV") + pitch_range = [start - 0.25, start - 0.2, start -0.15, start - 0.1, start -0.05] + + umv(mot,start) + + results = [] + now = datetime.now() + fnow = now.strftime("%d%m%H%M") + csvfile = f"luts/{fnow}_{mirror}_pitch_energy.csv" + + with open(csvfile, "w") as f: + f.write("energy,pitch,diode\n") + + # for p in pitch_range: + for energy in range(17, 26): + bl_energy(energy) + time.sleep(1) + + for p in pitch_range: + umv(mot, p) + print(f"{mirror}_pitch = {p}") + time.sleep(0.2) + vals_diode = [] + + for _ in range(5): + vals_diode.append(dev.xidiode.read()['xidiode']['value']) + time.sleep(0.1) + + diode = np.mean(vals_diode) + + results.append([ + energy, + p, + diode, + ]) + + with open(csvfile, "a") as f: + f.write( + f"{energy:.2f},{p:.5f},{diode:.5g}\n" + ) + umv(mot,start) + bl_energy(12400) + results = np.array(results) + +def find_best_roll(low = 6000, high = 20000): + low_scanpoints = np.linspace(2.0, 7.0, 11) + high_scanpoints = np.linspace(1.0, 9.0,9) + highs_y, lows_y = [], [] + + # high energy + bl_energy(high) + filename = f"./luts/roll_{high:.0f}.csv" + with open(filename, "w", encoding="utf-8") as f: + f.write("Roll, Y pos\n") + auto_exposure("samcam", max_iter=25) + for i in high_scanpoints: + umv(dev.dcm_froll, i) + time.sleep(0.2) + high_y = dev.samcam_y.read()['samcam_y']['value'] + print(f"Ypos at sample cam is {high_y}") + highs_y.append(high_y) + with open(filename, "a", encoding="utf-8") as f: + f.write(f"{i:.4g},{high_y:.4g} \n") + + # low energy + bl_energy(low) + filename = f"./luts/roll_{low:.0f}.csv" + with open(filename, "w", encoding="utf-8") as f: + f.write("Roll, Y pos\n") + auto_exposure("samcam", max_iter=25) + for i in low_scanpoints: + umv(dev.dcm_froll, i) + time.sleep(0.2) + low_y = dev.samcam_y.read()['samcam_y']['value'] + print(f"Ypos at sample cam is {low_y}") + lows_y.append(low_y) + with open(filename, "a", encoding="utf-8") as f: + f.write(f"{i:.4g},{low_y:.4g} \n") + + + y_high = np.array(highs_y) + y_low = np.array(lows_y) + + + # # Fit linear models: y = m*x + b + m_high, b_high = np.polyfit(high_scanpoints, y_high, 1) + m_low, b_low = np.polyfit(low_scanpoints, y_low, 1) + + # # Intersection point + x_intersect = (b_low - b_high) / (m_high - m_low) + y_intersect = m_high * x_intersect + b_high + + print(f"\nIntersection at:") + print(f" DCM Roll = {x_intersect:.5f}") + print(f" samcam Y = {y_intersect:.2f}") + + # # --- Plot --- + plt.figure(figsize=(7,5)) + plt.scatter(high_scanpoints, y_high, color='red', label=f'High energy') + plt.scatter(low_scanpoints, y_low, color='blue', label=f'Low energy') + + x_fit = np.linspace(min(high_scanpoints), max(high_scanpoints), 100) + plt.plot(x_fit, m_high*x_fit + b_high, 'r--', label=f'High energy') + plt.plot(x_fit, m_low*x_fit + b_low, 'b--', label=f'Low energy') + + plt.scatter(x_intersect, y_intersect, color='green', s=80, zorder=5, label='Intersection') + + plt.xlabel('DCM fine roll') + plt.ylabel('samcam Y pos') + plt.title('Roll Calibration') + plt.legend() + plt.grid(True) + plt.tight_layout() + plt.show() + +def vfm_yaw_check(): + slit_size = 0.02 + slit_point1 = -1.2 + slit_point2 = -0.12 + mirror_start = 0.5 + mirror_end = -5 + yaw_values = [-1.5, -0.5, 0, 0.5, 1] + point1 = [] + point2 = [] + + umv(dev.ss_sl_ysize, slit_size) + + for yaw in yaw_values: + print(f"Moving VFM yaw to {yaw}") + umv(dev.vfm_yaw, yaw) + # Point 1 + print(f"Moving slits to position 1") + umv(dev.ss_sl_ycen, slit_point1) + scans.line_scan(dev.vfm_x, mirror_start, mirror_end, steps = 20, relative=False) + fit_result = fit_history(-1, "xidiode", deriv=True) + centre = fit_result['centre'] + print(f'Yaw = {yaw}, position = {slit_point1}, centre = {centre}') + point1.append(centre) + # Point 2 + print(f"Moving slits to position 2") + umv(dev.ss_sl_ycen, slit_point2) + scans.line_scan(dev.vfm_x, mirror_start, mirror_end, steps = 20, relative=False) + fit_result = fit_history(-1, "xidiode", deriv=True) + centre = fit_result['centre'] + print(f'Yaw = {yaw}, position = {slit_point2}, centre = {centre}') + point2.append(centre) + print(f"Point 1 values are {point1}") + print(f"Point 2 values are {point2}") + go_to_peak(dev.ss_sl_ycen, dev.xidiode, -2, 2, 100) + umv(dev.ss_sl_ysize, 2) + y_point1 = np.array(point1) + y_point2 = np.array(point2) + + + # # Fit linear models: y = m*x + b + m_point1, b_point1 = np.polyfit(yaw_values, y_point1, 1) + m_point2, b_point2 = np.polyfit(yaw_values, y_point2, 1) + + # # Intersection point + x_intersect = (b_point2 - b_point1) / (m_point1 - m_point1) + y_intersect = m_point1 * x_intersect + b_point1 + + print(f"\nIntersection at:") + print(f" Mirror yaw = {x_intersect:.5f}") + print(f" Y = {y_intersect:.2f}") + + # # --- Plot --- + plt.figure(figsize=(7,5)) + plt.scatter(yaw_values, y_point1, color='red', label=f'point1') + plt.scatter(yaw_values, y_point2, color='blue', label=f'point2') + + x_fit = np.linspace(min(yaw_values), max(yaw_values), 100) + plt.plot(x_fit, m_point1*x_fit + b_point1, 'r--', label=f'point1') + plt.plot(x_fit, m_point2*x_fit + b_point2, 'b--', label=f'point2') + + plt.scatter(x_intersect, y_intersect, color='green', s=80, zorder=5, label='Intersection') + + plt.xlabel('VFM yaw') + plt.ylabel('Edge') + plt.title('VFM Yaw Calibration') + plt.legend() + plt.grid(True) + plt.tight_layout() + plt.show() + +from dataclasses import dataclass +import time + + +@dataclass +class SlitAxis: + name: str + centre_motor: object # e.g. dev.slit1_x + size_motor: object # e.g. dev.slit1_xsize + scan_func: callable # your existing peak scan function + scan_range: float = 2.0 + open_size: float = 2.0 + min_size: float = -0.4 + max_size: float = 5.0 + + +@dataclass +class Slit: + name: str + x: SlitAxis + y: SlitAxis + + +def read_intensity(detector, n=5, delay=0.1): + values = [] + for _ in range(n): + values.append(detector.read()[detector.name]["value"]) + time.sleep(delay) + return sum(values) / len(values) + + + +def reduce_to_transmission(axis, detector, baseline, target=0.15, step=0.05): + """ + Close slit size until intensity is around target * baseline. + """ + size = axis.size_motor.position + + while size > axis.min_size: + intensity = read_intensity(detector) + transmission = intensity / baseline + + print( + f"{axis.name}: size={size:.4f}, " + f"I={intensity:.3g}, transmission={transmission:.3f}" + ) + + if transmission <= target: + return size, intensity + + size -= step + umv(axis.size_motor, size) + + raise RuntimeError(f"{axis.name}: reached minimum slit size without reaching target") + + +def open_to_transmission(axis, detector, baseline, target=0.99, step=0.05): + """ + Open slit until intensity is close to the original baseline. + """ + size = axis.size_motor.position + + while size < axis.max_size: + intensity = read_intensity(detector) + transmission = intensity / baseline + + print( + f"{axis.name}: size={size:.4f}, " + f"I={intensity:.3g}, transmission={transmission:.3f}" + ) + + if transmission >= target: + return size, intensity + + size += step + umv(axis.size_motor, size) + # final_size = axis.size.motor.position + # fudge = 0.5 + # umv(axis.size_motor,final_size + fudge) + + raise RuntimeError(f"{axis.name}: reached maximum slit size without restoring intensity") + +# def approx_centre_axis(axis, detector, slitsize=0.5): +# umv(axis.size_motor, slitsize) +# go_to_peak(axis.centre_motor, detector, -4, 4, 50, confirm=False) + + +def centre_axis(axis, detector, close_fraction=0.10, open_fraction=0.95): + print(f"\nAligning {axis.name}") + + # approx_centre_axis(axis, detector, slitsize=0.5) + + umv(axis.size_motor, axis.open_size) + + baseline = read_intensity(detector) + print(f"{axis.name}: baseline intensity = {baseline:.3g}") + + # if baseline <= 0: + # raise RuntimeError(f"{axis.name}: invalid baseline intensity") + + reduce_to_transmission( + axis, + detector, + baseline, + target=close_fraction, + ) + + go_to_peak(axis.centre_motor, detector, axis.centre_motor.position - axis.scan_range, + axis.centre_motor.position + axis.scan_range, + 50, + confirm=False) + print(f"{axis.name}: moving centre to peak position") + + open_to_transmission( + axis, + detector, + baseline, + target=open_fraction, + ) + + final_intensity = read_intensity(detector) + print( + f"{axis.name}: final intensity = {final_intensity:.3g}, " + f"transmission = {final_intensity / baseline:.3f}" + ) + +def open_slits(size=3): + slits = define_slits() + for slit in slits: + umv(slit.x.size_motor, size) + umv(slit.y.size_motor, size) + + +def centre_slit(slit, detector): + print(f"\n=== Aligning {slit.name} ===") + + centre_axis(slit.x, detector) + centre_axis(slit.y, detector) + + print(f"=== Finished {slit.name} ===") + + +def centre_all_slits(slits, detector): + for slit in slits: + try: + centre_slit(slit, detector) + except Exception as exc: + print(f"WARNING: failed to align {slit.name}: {exc}") + print("Continuing with next slit.") + +def centre_one(name, detector): + slits = define_slits() + for slit in slits: + if slit.name == name: + centre_slit(slit, detector) + +def define_slits(): + slits = [ + Slit( + name="bsf", + x=SlitAxis( + name="bsf_sl_x", + centre_motor=dev.bsf_sl_xcen, + size_motor=dev.bsf_sl_xsize, + scan_func=go_to_peak, + ), + y=SlitAxis( + name="bsf_sl_y", + centre_motor=dev.bsf_sl_ycen, + size_motor=dev.bsf_sl_ysize, + scan_func=go_to_peak, + ), + ), + Slit( + name="ss", + x=SlitAxis( + name="ss_sl_x", + centre_motor=dev.ss_sl_xcen, + size_motor=dev.ss_sl_xsize, + scan_func=go_to_peak, + ), + y=SlitAxis( + name="ss_sl_y", + centre_motor=dev.ss_sl_ycen, + size_motor=dev.ss_sl_ysize, + scan_func=go_to_peak, + ), + ), + Slit( + name="bcu", + x=SlitAxis( + name="bcu_sl_x", + centre_motor=dev.bcu_sl_xcen, + size_motor=dev.bcu_sl_xsize, + scan_func=go_to_peak, + ), + y=SlitAxis( + name="ss_sl_y", + centre_motor=dev.bcu_sl_ycen, + size_motor=dev.bcu_sl_ysize, + scan_func=go_to_peak, + ), + ), + ] + return slits + +def get_mirror_data(history_index: int): + """Read data from the BEC history and return the X and Y data as arrays.""" + motor1 = "vfm_bu" + motor2 = "vfm_bd" + + scan = bec.history[history_index] + md = scan.metadata["bec"] + x1_data = scan.devices[motor1][motor1].read()["value"] + x2_data = scan.devices[motor2][motor2].read()["value"] + y1_data = scan.devices['microscope_stats']['microscope_stats_data_sigma_y'].read()['value'] + y2_data = scan.devices['microscope_stats']['microscope_stats_data_eccentricity'].read()['value'] + np.savetxt("luts/x1_data", x1_data) + np.savetxt("luts/x2_data", x2_data) + np.savetxt("luts/y1_data", y1_data) + np.savetxt("luts/y2_data", y2_data) + + + # plt.imshow(y1_data, cmap="hot") + # plt.clf + # return { + # "signal_name": signal_name, + # "x_data": x_data, + # "y_data": y_data, + # "motor_name": motor_name, + # "scan_number": scan_number, + # } + + +def record_beampos_until(stop_time_str, planner, interval_minutes=10): + """ + Runs `record_beam()` every `interval_minutes` minutes + until the next occurrence of the given stop time (HH:MM). + """ + + # Prepare the file + now = datetime.now() + fnow = now.strftime("%d%m%H%M") + fdir = "/sls/x10sa/config/bec/production/pxii_bec/pxii_bec/macros/" + fname = f"luts/beampos/beampos_{fnow}.csv" + filename = fdir + fname + scam_zoom = dev.scam_zoom.read()['scam_zoom']['value'] + umv(dev.scam_zoom, 1000) + dev.transm.put(0.1) + beam_size = "25 x 25" + + energy = get_current_energy() + + + # Write the header to the file + with open(filename, "w", encoding="utf-8") as f: + f.write(f"Beam size: {beam_size}, Energy: {energy:.0f} eV, Zoom: {scam_zoom}\n") + # f.write("Time,BPM_x,BPM_y,Scin_x,Scin_y,BPM_x,BPM_y\n") + f.write("Time,Scin_x,Scin_y,BPM_x,BPM_y\n") + + + # Parse the stop time (HH:MM) + stop_hour, stop_minute = map(int, stop_time_str.split(":")) + end_time = now.replace(hour=stop_hour, minute=stop_minute, second=0, microsecond=0) + + # If that time already passed today, set it for tomorrow + if end_time <= now: + end_time += timedelta(days=1) + + # Change to beam visualisation state, ensure shutter is closed first + dev.bcu_shutter.put(0) + planner.move_to(BeamlineState.BEAM_VISUALISATION) + + # Start recording beam position + print(f"Starting now ({now:%Y-%m-%d %H:%M}), running until {end_time:%Y-%m-%d %H:%M}") + print(f"Interval: {interval_minutes} minutes\n") + + while datetime.now() < end_time: + record_beam(filename) + next_run = datetime.now() + timedelta(minutes=interval_minutes) + if next_run > end_time: + break + print(f"Next run at {next_run:%H:%M:%S}") + time.sleep(interval_minutes * 60) + + print(f"Finished — reached {end_time:%H:%M}.") + planner.move_to(BeamlineState.MANUAL_SAMPLE_EXCHANGE) + + + + +def record_beam(filename): + """ + Record the beam position to file. + """ + # Set transmission and bpm position + dev.transm.put(0.1) + umv(dev.bcu_bpm_x, 0.43) + umv(dev.bcu_bpm_y, -1.543 ) + + # Open shutter and record positions + dev.bcu_shutter.put(1) + auto_exposure(cam="samcam") + time.sleep(2) + now = datetime.now() + + # Append data to the file + with open(filename, "a", encoding="utf-8") as f: + fnow = now.strftime("%H:%M:%S") + xpos_cam = dev.samcam_x.read()["samcam_x"]["value"] + ypos_cam = dev.samcam_y.read()["samcam_y"]["value"] + # x_bpm, y_bpm = get_beampos() + print(f"Time is {fnow}, X position is {xpos_cam:.5g}, Y position is {ypos_cam:.5g}") + x_bpm, y_bpm = compute_norm() + f.write( + # f"{fnow}, {xpos: .5g}, {ypos: .4g}, {xpos_cam: .5g}, {ypos_cam: .4g}\n" + f"{fnow},{xpos_cam: .5g},{ypos_cam: .4g},{x_bpm: .5g},{y_bpm: .5g}\n" + ) + # Close shutter + dev.bcu_shutter.put(0) + + +def analyse_beampos(file): + """Plot the recorded beam position data""" + # Load the CSV file into a Pandas DataFrame + filedir = "/sls/x10sa/config/bec/production/pxii_bec/pxii_bec/macros/luts/beampos/" + filename = filedir + file + data = pd.read_csv(filename, skiprows=1) + print(data.head()) + + # ref_bpmx = 0.110 + # ref_bmpy = -0.175 + ref_scinx = 1024 + ref_sciny = 980 + scam_zoom = 1000 + + # Extract the first column (time) as the x-axis + meas_time = data["Time"] + + # subtract the reference positions from the measures position + # data["bpm_x"] = data["bpm_x"] - ref_bpmx + # data["bpm_y"] = data["bpm_y"] - ref_bmpy + data["Scin_x"] = (data["Scin_x"] - ref_scinx) * calc_scam_microns(1) + data["Scin_y"] = (data["Scin_y"] - ref_sciny) * calc_scam_microns(1) + + + # Extract Y-position columns (all columns except the first column) + y_positions = data.iloc[:, 1:] # Exclude the first column + + fig, axs = plt.subplots( + 2, 2, figsize=(12, 8), layout="constrained" + ) # Create a 2x2 grid for subplots + # Flatten axs for easy iteration (if axs is a 2D array of axes) + axs = axs.flatten() + # Specify which columns to color differently + red_columns = ["bpm_x", "scin_x"] + + for idx, column in enumerate(y_positions.columns): + ax = axs[idx] # Select the current subplot + + # Determine the color based on the column name + color = "red" if column in red_columns else "blue" + + # Plot the line and scatter with the chosen color + ax.plot(meas_time, y_positions[column], color=color, linewidth=0.5) # Line plot + ax.scatter( + meas_time, y_positions[column], color=color, label=column + ) # Scatter plot + + # Set x-axis tick positions and labels + tick_positions = range(0, len(meas_time), 7) # Adjust the step size as needed + ax.set_xticks(tick_positions) + ax.set_xticklabels([meas_time[i] for i in tick_positions], rotation=45) + + # Add labels, title, legend, and grid to each subplot + ax.set_xlabel("Time") + ax.set_ylabel("beam displacement (microns)") + ax.set_title(f"Beam position at {column}") + ax.legend() + ax.grid(True) + + # Show the resulting figure + plt.show() + +import time +import numpy as np +import matplotlib.pyplot as plt +from epics import caget + + + +def scan_scin_focus(planner, type = 'fine'): + dev.bcu_shutter.put(0) + planner.move_to(BeamlineState.BEAM_VISUALISATION) + dev.bcu_shutter.put(1) + z0 = dev.diag_z.position + + min = 0.1 + max = 9.9 + + + if type == 'fine': + steps = 100 + elif type == 'coarse': + steps = 30 + else: + steps = 60 + + umv(dev.scam_zoom, 1000) + dev.transm.put(0.1) + + auto_exposure("samcam", target=200, max_iter=20) + time.sleep(0.2) + + go_to_peak(dev.diag_z, dev.scam, min, max, steps, relative=True, gomax=True, confirm=False) + dev.bcu_shutter.put(0) diff --git a/pxiii_bec/macros/luts/22060940_lut.csv b/pxiii_bec/macros/luts/22060940_lut.csv new file mode 100644 index 0000000..d90fd7a --- /dev/null +++ b/pxiii_bec/macros/luts/22060940_lut.csv @@ -0,0 +1,10 @@ +energy, pitch +5000,23.29268,23.2913 +6000,19.24199,19.2387 +7000,16.40998,16.4054 +8000,14.31298,14.3076 +9000,12.69568,12.6896 +10000,11.40928,11.4026 +11000,10.36128,10.3540 +12000,9.49058,9.48285 +13000,8.75558,8.7474 diff --git a/pxiii_bec/macros/luts/beampos/beampos19_20_clean_1306081012p414.csv b/pxiii_bec/macros/luts/beampos/beampos19_20_clean_1306081012p414.csv new file mode 100644 index 0000000..dc6faf4 --- /dev/null +++ b/pxiii_bec/macros/luts/beampos/beampos19_20_clean_1306081012p414.csv @@ -0,0 +1,119 @@ +Beam size: 25 x 20, Energy: 13001 eV, Zoom: 1000.0 +Time,Scin_x,Scin_y +20:01:35, 1060.6, 1049 +20:06:37, 1046.3, 1046 +20:11:40, 1058.1, 1047 +20:16:42, 1067.3, 1050 +20:21:45, 1053.8, 1040 +20:26:48, 1061, 1040 +20:31:50, 1065.3, 1040 +20:36:53, 1056, 1044 +20:41:56, 1074.8, 1044 +20:46:59, 1054.1, 1040 +20:52:01, 1046.7, 1055 +20:57:04, 1066.2, 1045 +21:02:07, 1049.9, 1050 +21:04:24, 1038.8, 1034 +21:09:26, 1053.5, 1043 +21:14:29, 1055.6, 1051 +21:19:31, 1064.2, 1041 +21:24:34, 1061.8, 1050 +21:29:37, 1056.8, 1043 +22:57:13, 1101.8, 1095 +23:02:16, 1103.3, 1096 +23:07:18, 1105.2, 1098 +23:12:21, 1102.5, 1098 +23:17:24, 1103.8, 1100 +23:22:28, 1100.6, 1100 +23:27:31, 1105.2, 1100 +23:30:46, 1079.4, 1068 +23:35:49, 1096.5, 1074 +23:40:51, 1070.1, 1075 +23:45:54, 1090.1, 1074 +23:50:57, 1088.5, 1080 +23:55:59, 1077.1, 1076 +00:01:05, 998.88, 1037 +00:06:12, 1073.2, 1076 +00:11:17, 1092.3, 1078 +00:16:20, 1075, 1073 +00:21:23, 1095.1, 1071 +00:26:25, 1083.9, 1069 +00:31:28, 1082.9, 1071 +00:36:30, 1083.6, 1073 +00:41:33, 1081.8, 1067 +00:46:36, 1084.7, 1066 +00:51:39, 1087.1, 1068 +00:56:41, 1083.2, 1066 +00:59:13, 1057.8, 1053 +01:04:15, 1076.4, 1062 +01:09:18, 1082.5, 1064 +01:14:21, 1080.3, 1063 +01:19:23, 1069.3, 1044 +01:24:26, 1080.9, 1067 +01:29:29, 1075.5, 1068 +01:34:31, 1061.9, 1058 +01:39:34, 1079.6, 1048 +01:44:36, 1079.6, 1069 +01:49:39, 1077.9, 1056 +01:54:42, 1083.5, 1060 +01:59:44, 1056.3, 1045 +02:04:47, 1083.9, 1057 +02:09:50, 1076.5, 1059 +02:14:52, 1075.1, 1061 +02:19:55, 1073.8, 1061 +02:24:58, 1095.2, 1056 +02:30:00, 1088, 1060 +02:35:03, 1072.4, 1054 +02:40:06, 1067.7, 1065 +02:45:09, 1056, 1053 +02:50:11, 1076.4, 1049 +02:55:14, 1073.1, 1052 +02:57:27, 1062, 1044 +03:02:30, 1061.9, 1050 +03:07:33, 1046, 1054 +03:12:35, 1068.2, 1052 +03:17:38, 1055, 1050 +03:22:40, 1063.1, 1053 +03:27:43, 1076.1, 1060 +03:32:46, 1052.1, 1046 +03:37:49, 1069.5, 1050 +03:42:51, 1070.1, 1060 +03:47:54, 1052, 1047 +03:52:56, 1056.3, 1056 +03:57:59, 1068.4, 1055 +04:03:02, 1059.7, 1052 +04:08:05, 1052.3, 1046 +04:13:07, 1058.8, 1054 +04:18:10, 1072.1, 1053 +04:23:13, 1057.3, 1058 +04:28:15, 1062.5, 1046 +04:33:18, 1058.3, 1050 +04:38:20, 1055, 1052 +04:43:24, 1060.3, 1050 +04:48:26, 1061.3, 1048 +04:53:29, 1058, 1048 +04:58:32, 1054.8, 1050 +05:00:19, 1063.9, 1051 +05:05:22, 1046.3, 1047 +05:10:25, 1050.2, 1051 +05:15:28, 1067.6, 1056 +05:20:30, 1059.2, 1053 +05:25:33, 1056.5, 1048 +05:30:36, 1061.9, 1048 +05:35:38, 1064.2, 1050 +05:40:41, 1044.2, 1054 +05:45:43, 1053.7, 1049 +05:50:46, 1053.1, 1050 +05:55:49, 1052, 1050 +06:00:51, 1057.1, 1043 +06:05:54, 1046.9, 1049 +06:10:57, 1059.8, 1049 +06:15:59, 1041.2, 1037 +06:21:02, 1063.3, 1047 +06:26:05, 1043.5, 1052 +06:31:07, 1050.7, 1049 +06:36:10, 1042.9, 1045 +06:41:13, 1053.2, 1052 +06:46:15, 1044.1, 1053 +06:51:18, 1065.9, 1050 +06:56:21, 1052.1, 1048 diff --git a/pxiii_bec/macros/luts/beampos/beampos_17071807.csv b/pxiii_bec/macros/luts/beampos/beampos_17071807.csv new file mode 100644 index 0000000..7bf92cf --- /dev/null +++ b/pxiii_bec/macros/luts/beampos/beampos_17071807.csv @@ -0,0 +1,5 @@ +Beam size: 25 x 20, Energy: 13001 eV, Zoom: 1000.0 +Time,Scin_x,Scin_y,BPM_x,BPM_y +18:07:53, 1025, 952.3 +18:08:55, 1011.2, 954.6 +18:09:58, 1016, 955.2 diff --git a/pxiii_bec/macros/luts/beampos/beampos_17071810.csv b/pxiii_bec/macros/luts/beampos/beampos_17071810.csv new file mode 100644 index 0000000..062309e --- /dev/null +++ b/pxiii_bec/macros/luts/beampos/beampos_17071810.csv @@ -0,0 +1,3 @@ +Beam size: 25 x 20, Energy: 13001 eV, Zoom: 1000.0 +Time,Scin_x,Scin_y,BPM_x,BPM_y +18:11:14, 1012.7, 953.6 diff --git a/pxiii_bec/macros/luts/beampos/beampos_17071813.csv b/pxiii_bec/macros/luts/beampos/beampos_17071813.csv new file mode 100644 index 0000000..f06bc70 --- /dev/null +++ b/pxiii_bec/macros/luts/beampos/beampos_17071813.csv @@ -0,0 +1,103 @@ +Beam size: 25 x 20, Energy: 13001 eV, Zoom: 1000.0 +Time,Scin_x,Scin_y +18:13:58, 1018.8, 960.2 +18:24:01, 1006.3, 963.2 +18:34:04, 1013.1, 964.3 +18:44:07, 1022.6, 965.6 +18:54:09, 1001.1, 969.9 +19:04:13, 997.26, 972.5 +19:14:16, 1006, 970.8 +19:24:18, 1018, 974.5 +19:34:21, 1019.5, 973.1 +19:44:24, 1017, 973.4 +19:54:27, 1005.8, 974.2 +20:04:30, 999.66, 976.6 +20:14:33, 1011.8, 978.8 +20:24:36, 1005.6, 977.5 +20:34:39, 1021.6, 982.2 +20:44:41, 1013.7, 982.3 +20:54:44, 1017.9, 986.4 +21:04:47, 1010.5, 985.2 +21:14:50, 996.42, 988.3 +21:24:53, 1000.6, 991.7 +21:34:56, 1011.8, 997.8 +21:44:59, 1002.1, 997.9 +21:55:02, 1007, 997.2 +22:05:05, 1000.8, 1004 +22:15:08, 1010.9, 1007 +22:25:11, 1004.7, 1006 +22:35:13, 1017.4, 1012 +22:45:16, 997.11, 1009 +22:55:18, 1011.8, 1010 +23:05:21, 1001, 1009 +23:15:24, 1012.8, 1016 +23:25:26, 1001.8, 1014 +23:35:29, 1003.9, 1010 +23:45:32, 1004.4, 1013 +23:55:34, 999.85, 1013 +00:05:37, 1001.2, 1012 +00:15:39, 1009.8, 1006 +00:25:42, 1006.8, 1018 +00:35:45, 1021.8, 1021 +00:45:47, 1020.9, 1015 +00:55:50, 1008.5, 1017 +01:05:53, 1009.1, 1014 +01:15:55, 1023.7, 1011 +01:25:58, 1007.5, 1015 +01:36:00, 1017.1, 1014 +01:46:03, 1022.2, 1014 +01:56:06, 1019.4, 1018 +02:06:08, 1026.6, 1020 +02:16:11, 1019.1, 1022 +02:26:14, 1008.3, 1016 +02:36:16, 1026.3, 1024 +02:46:19, 1022.2, 1022 +02:56:21, 1022.2, 1025 +03:06:24, 1024.2, 1024 +03:16:27, 1015.3, 1016 +03:26:29, 1009.8, 1019 +03:36:32, 1018.3, 1022 +03:46:35, 1008.4, 1012 +03:56:37, 1031.7, 1022 +04:06:40, 1007.9, 1022 +04:16:43, 1025.7, 1018 +04:26:45, 1033.8, 1023 +04:36:48, 1023.9, 1022 +04:46:50, 1016.3, 1020 +04:56:53, 1013.9, 1027 +05:06:59, 950.12, 1064 +05:17:06, 1027.9, 1020 +05:27:09, 1016.3, 1014 +05:37:12, 1030.9, 1026 +05:47:15, 1015.2, 1025 +05:57:18, 1036.6, 1027 +06:07:20, 1029.6, 1030 +06:17:23, 1022.2, 1030 +06:27:25, 1025.7, 1028 +06:37:28, 1017.4, 1023 +06:47:31, 1031.5, 1022 +06:57:34, 1023.2, 1022 +07:07:36, 1020.3, 1019 +07:17:39, 1034.7, 1024 +07:27:42, 1022.5, 1023 +07:37:44, 1023.7, 1029 +07:47:47, 1032.3, 1026 +07:57:49, 1031.6, 1024 +08:07:52, 1039.3, 1027 +08:17:55, 1027.3, 1023 +08:27:57, 1030.3, 1024 +08:38:00, 1041.4, 1024 +08:48:03, 1032.9, 1029 +08:58:05, 1040.5, 1027 +09:08:08, 1036.3, 1023 +09:18:10, 1035.9, 1032 +09:28:13, 1041.2, 1023 +09:38:16, 1025.8, 1023 +09:48:18, 1032.3, 1029 +09:58:21, 1026.9, 1029 +10:08:24, 1027.9, 1035 +10:18:26, 1042.4, 1033 +10:28:29, 1042.8, 1031 +10:38:31, 1023.6, 1018 +10:48:34, 1022.5, 1027 +10:58:37, 1041.1, 1033 diff --git a/pxiii_bec/macros/luts/beampos/beampos_18071203.csv b/pxiii_bec/macros/luts/beampos/beampos_18071203.csv new file mode 100644 index 0000000..1a96b02 --- /dev/null +++ b/pxiii_bec/macros/luts/beampos/beampos_18071203.csv @@ -0,0 +1,73 @@ +Beam size: 25 x 20, Energy: 13001 eV, Zoom: 1000.0 +Time,Scin_x,Scin_y,BPM_x,BPM_y +12:04:04, 1034.5, 1032 +12:09:07, 1047.8, 1036 +12:14:09, 1048.8, 1030 +12:19:12, 1050.5, 1033 +12:24:15, 1031.5, 1032 +12:29:17, 1046.3, 1035 +12:34:20, 1029.1, 1019 +12:39:23, 1044, 1034 +12:44:25, 1042.3, 1021 +12:49:28, 1037.1, 1032 +12:54:30, 1055.4, 1030 +12:59:33, 1034.8, 1038 +13:04:36, 1042.7, 1031 +13:09:38, 1044.4, 1039 +13:14:41, 1039.9, 1037 +13:19:44, 1038.6, 1039 +13:24:46, 1035.5, 1033 +13:29:49, 1034, 1034 +13:34:52, 1039.5, 1034 +13:39:54, 1031.9, 1033 +13:44:57, 1048, 1023 +13:50:00, 1043.6, 1038 +13:55:02, 1048.4, 1033 +14:00:05, 1046.2, 1030 +14:05:07, 1045.2, 1027 +14:10:10, 1040.2, 1037 +14:15:13, 1056.5, 1043 +14:20:15, 1049.4, 1041 +14:25:18, 1045.3, 1033 +14:30:21, 1050.9, 1037 +14:35:23, 1039.2, 1032 +14:40:26, 1033.3, 1034 +14:45:28, 1036, 1039 +14:50:31, 1036.6, 1039 +14:55:34, 1038.7, 1040 +15:00:36, 1033.7, 1027 +15:05:39, 1055, 1044 +15:10:42, 1042.3, 1033 +15:15:44, 1042, 1038 +15:20:47, 1040.4, 1040 +15:25:49, 1044, 1042 +15:30:52, 1033.4, 1035 +15:35:55, 1047.6, 1038 +15:40:57, 1040.2, 1036 +15:46:00, 1051.6, 1039 +15:51:02, 1036, 1042 +15:56:05, 1051.8, 1030 +16:01:08, 1039.8, 1039 +16:06:10, 1050.7, 1034 +16:11:13, 1039.6, 1036 +16:16:16, 1030.3, 1039 +16:21:18, 1039.4, 1039 +16:26:21, 1055, 1044 +16:31:23, 1036.5, 1039 +16:36:26, 1035.4, 1031 +16:41:29, 1041.5, 1046 +16:46:31, 1030.2, 1039 +16:51:34, 1050.5, 1041 +16:56:37, 1044.9, 1046 +17:01:39, 1037, 1038 +17:06:42, 1036.7, 1046 +17:11:44, 1030.5, 1037 +17:16:47, 1040.3, 1043 +17:21:50, 1033.9, 1046 +17:26:52, 1050.4, 1040 +17:31:55, 1043.8, 1040 +17:36:58, 1033.8, 1032 +17:42:00, 1053.3, 1043 +17:47:03, 1051.5, 1049 +17:52:05, 1049.1, 1045 +17:57:08, 1029.3, 1037 diff --git a/pxiii_bec/macros/luts/beampos/beampos_18071203_clean.csv b/pxiii_bec/macros/luts/beampos/beampos_18071203_clean.csv new file mode 100644 index 0000000..fb00c57 --- /dev/null +++ b/pxiii_bec/macros/luts/beampos/beampos_18071203_clean.csv @@ -0,0 +1,73 @@ +Beam size: 25 x 20, Energy: 13001 eV, Zoom: 1000.0 +Time,Scin_x,Scin_y +12:04:04, 1034.5, 1032 +12:09:07, 1047.8, 1036 +12:14:09, 1048.8, 1030 +12:19:12, 1050.5, 1033 +12:24:15, 1031.5, 1032 +12:29:17, 1046.3, 1035 +12:34:20, 1029.1, 1019 +12:39:23, 1044, 1034 +12:44:25, 1042.3, 1021 +12:49:28, 1037.1, 1032 +12:54:30, 1055.4, 1030 +12:59:33, 1034.8, 1038 +13:04:36, 1042.7, 1031 +13:09:38, 1044.4, 1039 +13:14:41, 1039.9, 1037 +13:19:44, 1038.6, 1039 +13:24:46, 1035.5, 1033 +13:29:49, 1034, 1034 +13:34:52, 1039.5, 1034 +13:39:54, 1031.9, 1033 +13:44:57, 1048, 1023 +13:50:00, 1043.6, 1038 +13:55:02, 1048.4, 1033 +14:00:05, 1046.2, 1030 +14:05:07, 1045.2, 1027 +14:10:10, 1040.2, 1037 +14:15:13, 1056.5, 1043 +14:20:15, 1049.4, 1041 +14:25:18, 1045.3, 1033 +14:30:21, 1050.9, 1037 +14:35:23, 1039.2, 1032 +14:40:26, 1033.3, 1034 +14:45:28, 1036, 1039 +14:50:31, 1036.6, 1039 +14:55:34, 1038.7, 1040 +15:00:36, 1033.7, 1027 +15:05:39, 1055, 1044 +15:10:42, 1042.3, 1033 +15:15:44, 1042, 1038 +15:20:47, 1040.4, 1040 +15:25:49, 1044, 1042 +15:30:52, 1033.4, 1035 +15:35:55, 1047.6, 1038 +15:40:57, 1040.2, 1036 +15:46:00, 1051.6, 1039 +15:51:02, 1036, 1042 +15:56:05, 1051.8, 1030 +16:01:08, 1039.8, 1039 +16:06:10, 1050.7, 1034 +16:11:13, 1039.6, 1036 +16:16:16, 1030.3, 1039 +16:21:18, 1039.4, 1039 +16:26:21, 1055, 1044 +16:31:23, 1036.5, 1039 +16:36:26, 1035.4, 1031 +16:41:29, 1041.5, 1046 +16:46:31, 1030.2, 1039 +16:51:34, 1050.5, 1041 +16:56:37, 1044.9, 1046 +17:01:39, 1037, 1038 +17:06:42, 1036.7, 1046 +17:11:44, 1030.5, 1037 +17:16:47, 1040.3, 1043 +17:21:50, 1033.9, 1046 +17:26:52, 1050.4, 1040 +17:31:55, 1043.8, 1040 +17:36:58, 1033.8, 1032 +17:42:00, 1053.3, 1043 +17:47:03, 1051.5, 1049 +17:52:05, 1049.1, 1045 +17:57:08, 1029.3, 1037 diff --git a/pxiii_bec/macros/luts/beampos/beampos_19072001.csv b/pxiii_bec/macros/luts/beampos/beampos_19072001.csv new file mode 100644 index 0000000..cc318ed --- /dev/null +++ b/pxiii_bec/macros/luts/beampos/beampos_19072001.csv @@ -0,0 +1,15 @@ +Beam size: 25 x 20, Energy: 13001 eV, Zoom: 1000.0 +Time,Scin_x,Scin_y +20:01:35, 1060.6, 1049 +20:06:37, 1046.3, 1046 +20:11:40, 1058.1, 1047 +20:16:42, 1067.3, 1050 +20:21:45, 1053.8, 1040 +20:26:48, 1061, 1040 +20:31:50, 1065.3, 1040 +20:36:53, 1056, 1044 +20:41:56, 1074.8, 1044 +20:46:59, 1054.1, 1040 +20:52:01, 1046.7, 1055 +20:57:04, 1066.2, 1045 +21:02:07, 1049.9, 1050 diff --git a/pxiii_bec/macros/luts/beampos/beampos_19072104.csv b/pxiii_bec/macros/luts/beampos/beampos_19072104.csv new file mode 100644 index 0000000..c7c4f15 --- /dev/null +++ b/pxiii_bec/macros/luts/beampos/beampos_19072104.csv @@ -0,0 +1,8 @@ +Beam size: 25 x 20, Energy: 13001 eV, Zoom: 1000.0 +Time,Scin_x,Scin_y +21:04:24, 1038.8, 1034 +21:09:26, 1053.5, 1043 +21:14:29, 1055.6, 1051 +21:19:31, 1064.2, 1041 +21:24:34, 1061.8, 1050 +21:29:37, 1056.8, 1043 diff --git a/pxiii_bec/macros/luts/beampos/beampos_19072256.csv b/pxiii_bec/macros/luts/beampos/beampos_19072256.csv new file mode 100644 index 0000000..5ef9e31 --- /dev/null +++ b/pxiii_bec/macros/luts/beampos/beampos_19072256.csv @@ -0,0 +1,9 @@ +Beam size: 25 x 20, Energy: 6000 eV, Zoom: 1000.0 +Time,Scin_x,Scin_y,BPM_x,BPM_y +22:57:13, 1101.8, 1095 +23:02:16, 1103.3, 1096 +23:07:18, 1105.2, 1098 +23:12:21, 1102.5, 1098 +23:17:24, 1103.8, 1100 +23:22:28, 1100.6, 1100 +23:27:31, 1105.2, 1100 diff --git a/pxiii_bec/macros/luts/beampos/beampos_19072330.csv b/pxiii_bec/macros/luts/beampos/beampos_19072330.csv new file mode 100644 index 0000000..3c69dbc --- /dev/null +++ b/pxiii_bec/macros/luts/beampos/beampos_19072330.csv @@ -0,0 +1,20 @@ +Beam size: 25 x 20, Energy: 8000 eV, Zoom: 1000.0 +Time,Scin_x,Scin_y,BPM_x,BPM_y +23:30:46, 1079.4, 1068 +23:35:49, 1096.5, 1074 +23:40:51, 1070.1, 1075 +23:45:54, 1090.1, 1074 +23:50:57, 1088.5, 1080 +23:55:59, 1077.1, 1076 +00:01:05, 998.88, 1037 +00:06:12, 1073.2, 1076 +00:11:17, 1092.3, 1078 +00:16:20, 1075, 1073 +00:21:23, 1095.1, 1071 +00:26:25, 1083.9, 1069 +00:31:28, 1082.9, 1071 +00:36:30, 1083.6, 1073 +00:41:33, 1081.8, 1067 +00:46:36, 1084.7, 1066 +00:51:39, 1087.1, 1068 +00:56:41, 1083.2, 1066 diff --git a/pxiii_bec/macros/luts/beampos/beampos_20070058.csv b/pxiii_bec/macros/luts/beampos/beampos_20070058.csv new file mode 100644 index 0000000..bd8e12b --- /dev/null +++ b/pxiii_bec/macros/luts/beampos/beampos_20070058.csv @@ -0,0 +1,26 @@ +Beam size: 25 x 20, Energy: 10000 eV, Zoom: 1000.0 +Time,Scin_x,Scin_y,BPM_x,BPM_y +00:59:13, 1057.8, 1053 +01:04:15, 1076.4, 1062 +01:09:18, 1082.5, 1064 +01:14:21, 1080.3, 1063 +01:19:23, 1069.3, 1044 +01:24:26, 1080.9, 1067 +01:29:29, 1075.5, 1068 +01:34:31, 1061.9, 1058 +01:39:34, 1079.6, 1048 +01:44:36, 1079.6, 1069 +01:49:39, 1077.9, 1056 +01:54:42, 1083.5, 1060 +01:59:44, 1056.3, 1045 +02:04:47, 1083.9, 1057 +02:09:50, 1076.5, 1059 +02:14:52, 1075.1, 1061 +02:19:55, 1073.8, 1061 +02:24:58, 1095.2, 1056 +02:30:00, 1088, 1060 +02:35:03, 1072.4, 1054 +02:40:06, 1067.7, 1065 +02:45:09, 1056, 1053 +02:50:11, 1076.4, 1049 +02:55:14, 1073.1, 1052 diff --git a/pxiii_bec/macros/luts/beampos/beampos_20070256.csv b/pxiii_bec/macros/luts/beampos/beampos_20070256.csv new file mode 100644 index 0000000..c42a89d --- /dev/null +++ b/pxiii_bec/macros/luts/beampos/beampos_20070256.csv @@ -0,0 +1,27 @@ +Beam size: 25 x 20, Energy: 12400 eV, Zoom: 1000.0 +Time,Scin_x,Scin_y,BPM_x,BPM_y +02:57:27, 1062, 1044 +03:02:30, 1061.9, 1050 +03:07:33, 1046, 1054 +03:12:35, 1068.2, 1052 +03:17:38, 1055, 1050 +03:22:40, 1063.1, 1053 +03:27:43, 1076.1, 1060 +03:32:46, 1052.1, 1046 +03:37:49, 1069.5, 1050 +03:42:51, 1070.1, 1060 +03:47:54, 1052, 1047 +03:52:56, 1056.3, 1056 +03:57:59, 1068.4, 1055 +04:03:02, 1059.7, 1052 +04:08:05, 1052.3, 1046 +04:13:07, 1058.8, 1054 +04:18:10, 1072.1, 1053 +04:23:13, 1057.3, 1058 +04:28:15, 1062.5, 1046 +04:33:18, 1058.3, 1050 +04:38:20, 1055, 1052 +04:43:24, 1060.3, 1050 +04:48:26, 1061.3, 1048 +04:53:29, 1058, 1048 +04:58:32, 1054.8, 1050 diff --git a/pxiii_bec/macros/luts/beampos/beampos_20070459.csv b/pxiii_bec/macros/luts/beampos/beampos_20070459.csv new file mode 100644 index 0000000..0666002 --- /dev/null +++ b/pxiii_bec/macros/luts/beampos/beampos_20070459.csv @@ -0,0 +1,26 @@ +Beam size: 25 x 20, Energy: 14000 eV, Zoom: 1000.0 +Time,Scin_x,Scin_y +05:00:19, 1063.9, 1051 +05:05:22, 1046.3, 1047 +05:10:25, 1050.2, 1051 +05:15:28, 1067.6, 1056 +05:20:30, 1059.2, 1053 +05:25:33, 1056.5, 1048 +05:30:36, 1061.9, 1048 +05:35:38, 1064.2, 1050 +05:40:41, 1044.2, 1054 +05:45:43, 1053.7, 1049 +05:50:46, 1053.1, 1050 +05:55:49, 1052, 1050 +06:00:51, 1057.1, 1043 +06:05:54, 1046.9, 1049 +06:10:57, 1059.8, 1049 +06:15:59, 1041.2, 1037 +06:21:02, 1063.3, 1047 +06:26:05, 1043.5, 1052 +06:31:07, 1050.7, 1049 +06:36:10, 1042.9, 1045 +06:41:13, 1053.2, 1052 +06:46:15, 1044.1, 1053 +06:51:18, 1065.9, 1050 +06:56:21, 1052.1, 1048