From 3bf21ff647fafc4979738697c2802a8582bb2a9c Mon Sep 17 00:00:00 2001 From: Unknown MX Person Date: Mon, 9 Sep 2024 13:23:03 +0200 Subject: [PATCH] Both ABR stage and scan instantiates, need Zac to test it safely --- pxiii_bec/device_configs/x06da_compact.lmay | 19 ++- .../device_configs/x06da_device_config.yaml | 43 ++++-- pxiii_bec/devices/A3200.py | 126 +++++++++++------- pxiii_bec/devices/__init__.py | 2 + pxiii_bec/devices/aeroA3200.py | 58 ++++---- pxiii_bec/scans/__init__.py | 1 + 6 files changed, 151 insertions(+), 98 deletions(-) diff --git a/pxiii_bec/device_configs/x06da_compact.lmay b/pxiii_bec/device_configs/x06da_compact.lmay index 4684593..7ad90d4 100644 --- a/pxiii_bec/device_configs/x06da_compact.lmay +++ b/pxiii_bec/device_configs/x06da_compact.lmay @@ -66,19 +66,19 @@ ssxbpm_try: ssslit_trxr: deviceClass: ophyd.EpicsMotor deviceConfig: - prefix: 'X06DA-ES-SSSH1:TRXR' + prefix: 'X06DA-ES-SSSLH1:TRXR' ssslit_trxw: deviceClass: ophyd.EpicsMotor deviceConfig: - prefix: 'X06DA-ES-SSSH1:TRXW' + prefix: 'X06DA-ES-SSSLH1:TRXW' ssslit_tryt: deviceClass: ophyd.EpicsMotor deviceConfig: - prefix: 'X06DA-ES-SSSV1:TRYT' + prefix: 'X06DA-ES-SSSLV1:TRYT' ssslit_tryb: deviceClass: ophyd.EpicsMotor deviceConfig: - prefix: 'X06DA-ES-SSSV1:TRYB' + prefix: 'X06DA-ES-SSSLV1:TRYB' ssxi1_trx: deviceClass: ophyd.EpicsMotor deviceConfig: @@ -195,5 +195,12 @@ bstop_diode: prefix: 'X06DA-ES-BS:READOUT' - - +# End station +omega: + deviceClass: pxiii_bec.devices.A3200Axis + deviceConfig: + prefix: 'X06DA-ES-DF1:OMEGA' +abr: + deviceClass: pxiii_bec.devices.AerotechAbrStage + deviceConfig: + prefix: 'X06DA-ES' diff --git a/pxiii_bec/device_configs/x06da_device_config.yaml b/pxiii_bec/device_configs/x06da_device_config.yaml index 1893b72..c49d4af 100644 --- a/pxiii_bec/device_configs/x06da_device_config.yaml +++ b/pxiii_bec/device_configs/x06da_device_config.yaml @@ -1,4 +1,3 @@ - slh_trxr: deviceClass: ophyd.EpicsMotor deviceConfig: {prefix: 'X06DA-OP-SLH:TRXR'} @@ -63,6 +62,14 @@ dccm_energy2: readoutPriority: monitored readOnly: false softwareTrigger: false +dccm_xbpm: + deviceClass: ophyd.EpicsSignalRO + deviceConfig: {read_pv: 'X06DA-OP-XBPM1:SumAll:MeanValue_RBV'} + onFailure: buffer + enabled: true + readoutPriority: monitored + readOnly: true + softwareTrigger: false dccm_energy: description: Monochromator energy using ECMC virtual motors deviceClass: ophyd.EpicsMotor @@ -73,7 +80,7 @@ dccm_energy: readOnly: false softwareTrigger: false dccm_eoffset: - description: Monochromator energy offset between crystals using ECMC virtual motors + description: Monochromator energy offset for ECMC virtual motors deviceClass: ophyd.EpicsMotor deviceConfig: {prefix: 'X06DA-OP-DCCM:_EOFFSET'} onFailure: buffer @@ -81,14 +88,6 @@ dccm_eoffset: readoutPriority: monitored readOnly: false softwareTrigger: false -dccm_xbpm: - deviceClass: ophyd.EpicsSignalRO - deviceConfig: {read_pv: 'X06DA-OP-XBPM1:SumAll:MeanValue_RBV'} - onFailure: buffer - enabled: true - readoutPriority: monitored - readOnly: true - softwareTrigger: false ssxbpm_trx: deviceClass: ophyd.EpicsMotor deviceConfig: {prefix: 'X06DA-ES-SSBPM1:TRX'} @@ -107,7 +106,7 @@ ssxbpm_try: softwareTrigger: false ssslit_trxr: deviceClass: ophyd.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-SSSH1:TRXR'} + deviceConfig: {prefix: 'X06DA-ES-SSSLH1:TRXR'} onFailure: buffer enabled: true readoutPriority: monitored @@ -115,7 +114,7 @@ ssslit_trxr: softwareTrigger: false ssslit_trxw: deviceClass: ophyd.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-SSSH1:TRXW'} + deviceConfig: {prefix: 'X06DA-ES-SSSLH1:TRXW'} onFailure: buffer enabled: true readoutPriority: monitored @@ -123,7 +122,7 @@ ssslit_trxw: softwareTrigger: false ssslit_tryt: deviceClass: ophyd.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-SSSV1:TRYT'} + deviceConfig: {prefix: 'X06DA-ES-SSSLV1:TRYT'} onFailure: buffer enabled: true readoutPriority: monitored @@ -131,7 +130,7 @@ ssslit_tryt: softwareTrigger: false ssslit_tryb: deviceClass: ophyd.EpicsMotor - deviceConfig: {prefix: 'X06DA-ES-SSSV1:TRYB'} + deviceConfig: {prefix: 'X06DA-ES-SSSLV1:TRYB'} onFailure: buffer enabled: true readoutPriority: monitored @@ -329,3 +328,19 @@ bstop_diode: readoutPriority: monitored readOnly: true softwareTrigger: false +omega: + deviceClass: pxiii_bec.devices.A3200Axis + deviceConfig: {prefix: 'X06DA-ES-DF1:OMEGA'} + onFailure: buffer + enabled: true + readoutPriority: monitored + readOnly: false + softwareTrigger: false +abr: + deviceClass: pxiii_bec.devices.AerotechAbrStage + deviceConfig: {prefix: X06DA-ES} + onFailure: buffer + enabled: true + readoutPriority: monitored + readOnly: false + softwareTrigger: false diff --git a/pxiii_bec/devices/A3200.py b/pxiii_bec/devices/A3200.py index d91d4c9..b606501 100644 --- a/pxiii_bec/devices/A3200.py +++ b/pxiii_bec/devices/A3200.py @@ -85,7 +85,7 @@ from ophyd import Component, Device, EpicsSignal, EpicsSignalRO, Kind from ophyd.status import MoveStatus, SubscriptionStatus, DeviceStatus -from aeroA3200 import A3200Axis, A3200RasterScanner, A3200Oscillator +from .aeroA3200 import A3200Axis, A3200RasterScanner, A3200Oscillator ABR_DONE = 0 @@ -136,46 +136,56 @@ AXIS_STZ = 6 class AerotechAbrStage(Device): - - taskStop = Component(EpicsSignal, "-ES-AERO:TSK-STOP", put_complete=True, kind=Kind.omitted) - status = Component(EpicsSignal, "-ES-AERO:STAT", put_complete=True, kind=Kind.omitted) + """ Standard PX stage on A3200 controller + + This is the wrapper class for the standard rotation stage layout for the PX + beamlines at SLS. It wraps the main rotation axis OMEGA and the associated + motion axes GMX, GMY and GMZ. The ophyd class associates to the general PX + measurement procedure, which is that the actual scan script is running as + an AeroBasic program on the controller and we communicate to it via 10+1 + global variables. + """ + taskStop = Component(EpicsSignal, "-AERO:TSK-STOP", put_complete=True, kind=Kind.omitted) + status = Component(EpicsSignal, "-AERO:STAT", put_complete=True, kind=Kind.omitted) # Enable/disable motor movement via the IOC (i.e. make it task-only) - axisModeLocked = Component(EpicsSignal, "-ES-DF1:LOCK", put_complete=True, kind=Kind.omitted) - axisModeDirect = Component(EpicsSignal, "-ES-DF1:MODE-DIRECT", put_complete=True, kind=Kind.omitted) - axisAxesMode = Component(EpicsSignal, "-ES-DF1:AXES-MODE", put_complete=True, kind=Kind.omitted) + axisModeLocked = Component(EpicsSignal, "-DF1:LOCK", put_complete=True, kind=Kind.omitted) + axisModeDirect = Component(EpicsSignal, "-DF1:MODE-DIRECT", put_complete=True, kind=Kind.omitted) + axisAxesMode = Component(EpicsSignal, "-DF1:AXES-MODE", put_complete=True, kind=Kind.omitted) - _shutter = Component( - EpicsSignal, "-ES-PH1:GET", write_pv="-ES-PH1:SET", put_complete=True, kind=Kind.config, - ) + # Shutter box is missing readback so the -GET signal is installed on the VME + # _shutter = Component( + # EpicsSignal, "-PH1:GET", write_pv="-PH1:SET", put_complete=True, kind=Kind.config, + # ) raster = Component(A3200RasterScanner, "", kind=Kind.config) osc = Component(A3200Oscillator, "", kind=Kind.config) - omega = Component(A3200Axis, "-ES-DF1:OMEGA", kind=Kind.hinted) - gmx = Component(A3200Axis, "-ES-DF1:GMX", kind=Kind.hinted) - gmy = Component(A3200Axis, "-ES-DF1:GMY", kind=Kind.hinted) - gmz = Component(A3200Axis, "-ES-DF1:GMZ", kind=Kind.hinted) + # Positioners for the motor axes + omega = Component(A3200Axis, "-DF1:OMEGA", kind=Kind.hinted) + gmx = Component(A3200Axis, "-DF1:GMX", kind=Kind.hinted) + gmy = Component(A3200Axis, "-DF1:GMY", kind=Kind.hinted) + gmz = Component(A3200Axis, "-DF1:GMZ", kind=Kind.hinted) + scan_command = Component(EpicsSignal, "-PSO:CMD", put_complete=True, kind=Kind.omitted) + start_command = Component(EpicsSignal, "-PSO:START-TEST.PROC", put_complete=True, kind=Kind.omitted) + stop_command = Component(EpicsSignal, "-PSO:STOP-TEST.PROC", put_complete=True, kind=Kind.omitted) - scan_command = Component(EpicsSignal, "-ES-PSO:CMD", put_complete=True, kind=Kind.omitted) - start_command = Component(EpicsSignal, "-ES-PSO:START-TEST.PROC", put_complete=True, kind=Kind.omitted) - stop_command = Component(EpicsSignal, "-ES-PSO:STOP-TEST.PROC", put_complete=True, kind=Kind.omitted) - - _var_1 = Component(EpicsSignal, "-ES-PSO:VAR-1", put_complete=True, kind=Kind.omitted) - _var_2 = Component(EpicsSignal, "-ES-PSO:VAR-2", put_complete=True, kind=Kind.omitted) - _var_3 = Component(EpicsSignal, "-ES-PSO:VAR-3", put_complete=True, kind=Kind.omitted) - _var_4 = Component(EpicsSignal, "-ES-PSO:VAR-4", put_complete=True, kind=Kind.omitted) - _var_5 = Component(EpicsSignal, "-ES-PSO:VAR-5", put_complete=True, kind=Kind.omitted) - _var_6 = Component(EpicsSignal, "-ES-PSO:VAR-6", put_complete=True, kind=Kind.omitted) - _var_7 = Component(EpicsSignal, "-ES-PSO:VAR-7", put_complete=True, kind=Kind.omitted) - _var_8 = Component(EpicsSignal, "-ES-PSO:VAR-8", put_complete=True, kind=Kind.omitted) - _var_9 = Component(EpicsSignal, "-ES-PSO:VAR-9", put_complete=True, kind=Kind.omitted) - _var_10 = Component(EpicsSignal, "-ES-PSO:VAR-10", put_complete=True, kind=Kind.omitted) + # Global variables to controll AeroBasic scripts + _var_1 = Component(EpicsSignal, "-PSO:VAR-1", put_complete=True, kind=Kind.omitted) + _var_2 = Component(EpicsSignal, "-PSO:VAR-2", put_complete=True, kind=Kind.omitted) + _var_3 = Component(EpicsSignal, "-PSO:VAR-3", put_complete=True, kind=Kind.omitted) + _var_4 = Component(EpicsSignal, "-PSO:VAR-4", put_complete=True, kind=Kind.omitted) + _var_5 = Component(EpicsSignal, "-PSO:VAR-5", put_complete=True, kind=Kind.omitted) + _var_6 = Component(EpicsSignal, "-PSO:VAR-6", put_complete=True, kind=Kind.omitted) + _var_7 = Component(EpicsSignal, "-PSO:VAR-7", put_complete=True, kind=Kind.omitted) + _var_8 = Component(EpicsSignal, "-PSO:VAR-8", put_complete=True, kind=Kind.omitted) + _var_9 = Component(EpicsSignal, "-PSO:VAR-9", put_complete=True, kind=Kind.omitted) + _var_10 = Component(EpicsSignal, "-PSO:VAR-10", put_complete=True, kind=Kind.omitted) # A few PVs still needed from grid - raster_scan_done = Component(EpicsSignal, "-ES-GRD:SCAN-DONE", kind=Kind.config) - raster_num_rows = Component(EpicsSignal, "-ES-GRD:ROW-DONE", kind=Kind.config) + raster_scan_done = Component(EpicsSignal, "-GRD:SCAN-DONE", kind=Kind.config) + raster_num_rows = Component(EpicsSignal, "-GRD:ROW-DONE", kind=Kind.config) def set_axis_mode(self, mode: str, settle_time=0.1) -> None: if mode=="direct": @@ -184,7 +194,25 @@ class AerotechAbrStage(Device): self.axisAxesMode.set(MEASURING_MODE, settle_time=settle_time).wait() def configure(self, d: dict) -> tuple: + """" Configure the exposure scripts + Performs the configuration of the exposure scrips, i.e. sets the + required global variables. + + Parameters + ---------- + scan_command: + var_1: + var_2: + var_3: + var_4: + var_5: + var_6: + var_7: + var_8: + var_9: + var_10: + """ old = self.read_configuration() # ToDo: Check if idle before reconfiguring @@ -285,25 +313,25 @@ class AerotechAbrStage(Device): def measurement_state(self, value): self.osc.phase.set(value).wait() - @property - def shutter(self): - return self._shutter.get() + # @property + # def shutter(self): + # return self._shutter.get() - @shutter.setter - def shutter(self, value): - if self.axisAxesMode.get(): - print("ABR is not in direct mode; cannot manipulate shutter") - return False - state = str(state).lower() - if state not in ["1", "0", "closed", "open"]: - print("unknown shutter state requested") - return None - elif state in ["1", "open"]: - state = 1 - elif state == ["0", "closed"]: - state = 0 - self._shutter.set(state).wait() - return state == self._shutter.get() + # @shutter.setter + # def shutter(self, value): + # if self.axisAxesMode.get(): + # print("ABR is not in direct mode; cannot manipulate shutter") + # return False + # state = str(state).lower() + # if state not in ["1", "0", "closed", "open"]: + # print("unknown shutter state requested") + # return None + # elif state in ["1", "open"]: + # state = 1 + # elif state == ["0", "closed"]: + # state = 0 + # self._shutter.set(state).wait() + # return state == self._shutter.get() @property def axis_mode(self): @@ -395,5 +423,5 @@ class AerotechAbrStage(Device): if __name__ == "__main__": - abr = AerotechAbrStage(prefix="X06DA-ES-DF1", name="abr") + abr = AerotechAbrStage(prefix="X06DA-ES", name="abr") abr.wait_for_connection() \ No newline at end of file diff --git a/pxiii_bec/devices/__init__.py b/pxiii_bec/devices/__init__.py index e69de29..4031fa7 100644 --- a/pxiii_bec/devices/__init__.py +++ b/pxiii_bec/devices/__init__.py @@ -0,0 +1,2 @@ +from .aeroA3200 import A3200Axis +from .A3200 import AerotechAbrStage \ No newline at end of file diff --git a/pxiii_bec/devices/aeroA3200.py b/pxiii_bec/devices/aeroA3200.py index e319038..34ef135 100644 --- a/pxiii_bec/devices/aeroA3200.py +++ b/pxiii_bec/devices/aeroA3200.py @@ -148,34 +148,34 @@ class A3200RasterScanner(Device): a standard Ophyd positioner for the BEC. It also has some additional functionality for diagnostics.""" - x_start = Component(EpicsSignal, "-ES-GRD:GMX-START", kind=Kind.config) - x_start = Component(EpicsSignal, "-ES-GRD:GMX-END", kind=Kind.config) - omega = Component(EpicsSignal, "-ES-OSC:#M-START", kind=Kind.config) - osc = Component(EpicsSignal, "-ES-GRD:ANGLE", kind=Kind.config) - celltime = Component(EpicsSignal, "-ES-GRD:CELL-TIME", kind=Kind.config) + x_start = Component(EpicsSignal, "-GRD:GMX-START", kind=Kind.config) + x_start = Component(EpicsSignal, "-GRD:GMX-END", kind=Kind.config) + omega = Component(EpicsSignal, "-OSC:#M-START", kind=Kind.config) + osc = Component(EpicsSignal, "-GRD:ANGLE", kind=Kind.config) + celltime = Component(EpicsSignal, "-GRD:CELL-TIME", kind=Kind.config) - y_start = Component(EpicsSignal, "-ES-OSC:#STY-START", kind=Kind.config) - y_end = Component(EpicsSignal, "-ES-OSC:#STY-END", kind=Kind.config) - z_start = Component(EpicsSignal, "-ES-OSC:#STZ-START", kind=Kind.config) - z_end = Component(EpicsSignal, "-ES-OSC:#STZ-END", kind=Kind.config) + y_start = Component(EpicsSignal, "-OSC:#STY-START", kind=Kind.config) + y_end = Component(EpicsSignal, "-OSC:#STY-END", kind=Kind.config) + z_start = Component(EpicsSignal, "-OSC:#STZ-START", kind=Kind.config) + z_end = Component(EpicsSignal, "-OSC:#STZ-END", kind=Kind.config) - columns = Component(EpicsSignal, "-ES-GRD:COLUMNS", kind=Kind.config) - rows = Component(EpicsSignal, "-ES-GRD:ROWS", kind=Kind.config) - delay = Component(EpicsSignal, "-ES-GRD:RAST-DLY", kind=Kind.config) - osc_mode = Component(EpicsSignal, "-ES-GRD:SET-MODE", kind=Kind.config) + columns = Component(EpicsSignal, "-GRD:COLUMNS", kind=Kind.config) + rows = Component(EpicsSignal, "-GRD:ROWS", kind=Kind.config) + delay = Component(EpicsSignal, "-GRD:RAST-DLY", kind=Kind.config) + osc_mode = Component(EpicsSignal, "-GRD:SET-MODE", kind=Kind.config) - velo = Component(EpicsSignal, "-ES-GRD:#X-VEL", kind=Kind.config) - get_ready = Component(EpicsSignal, "-ES-GRD:READY.PROC", kind=Kind.config) - grid_start = Component(EpicsSignal, "-ES-GRD:START.PROC", kind=Kind.config) - grid_next = Component(EpicsSignal, "-ES-GRD:NEXT-ROW", kind=Kind.config) - row_done = Component(EpicsSignal, "-ES-GRD:ROW-DONE", kind=Kind.config) - scan_done = Component(EpicsSignal, "-ES-GRD:SCAN-DONE", kind=Kind.config) - grid_done = Component(EpicsSignal, "-ES-GRD:DONE", kind=Kind.config) + velo = Component(EpicsSignal, "-GRD:#X-VEL", kind=Kind.config) + get_ready = Component(EpicsSignal, "-GRD:READY.PROC", kind=Kind.config) + grid_start = Component(EpicsSignal, "-GRD:START.PROC", kind=Kind.config) + grid_next = Component(EpicsSignal, "-GRD:NEXT-ROW", kind=Kind.config) + row_done = Component(EpicsSignal, "-GRD:ROW-DONE", kind=Kind.config) + scan_done = Component(EpicsSignal, "-GRD:SCAN-DONE", kind=Kind.config) + grid_done = Component(EpicsSignal, "-GRD:DONE", kind=Kind.config) # Also needs the command interface - _zcmd = Component(EpicsSignal, "-ES-PSO:CMD", put_complete=True, kind=Kind.omitted) - _start_command = Component(EpicsSignal, "-ES-PSO:START-TEST.PROC", put_complete=True, kind=Kind.omitted) - _stop_command = Component(EpicsSignal, "-ES-PSO:STOP-TEST.PROC", put_complete=True, kind=Kind.omitted) + _zcmd = Component(EpicsSignal, "-PSO:CMD", put_complete=True, kind=Kind.omitted) + _start_command = Component(EpicsSignal, "-PSO:START-TEST.PROC", put_complete=True, kind=Kind.omitted) + _stop_command = Component(EpicsSignal, "-PSO:STOP-TEST.PROC", put_complete=True, kind=Kind.omitted) def raster_setup(self, positions, columns, angle, etime): @@ -346,12 +346,12 @@ class A3200Oscillator(Device): """No clue what this does, seems to be redundant with the task based grid scanners... """ - ostart_pos = Component(EpicsSignal, "-ES-OSC:START-POS", put_complete=True, kind=Kind.config) - orange = Component(EpicsSignal, "-ES-OSC:RANGE", put_complete=True, kind=Kind.config) - etime = Component(EpicsSignal, "-ES-OSC:ETIME", put_complete=True, kind=Kind.config) - get_ready = Component(EpicsSignal, "-ES-OSC:READY.PROC", put_complete=True, kind=Kind.config) - taskStart = Component(EpicsSignal, "-ES-OSC:START", put_complete=True, kind=Kind.config) - phase = Component(EpicsSignal, "-ES-OSC:DONE", auto_monitor=True, kind=Kind.config) + ostart_pos = Component(EpicsSignal, "-OSC:START-POS", put_complete=True, kind=Kind.config) + orange = Component(EpicsSignal, "-OSC:RANGE", put_complete=True, kind=Kind.config) + etime = Component(EpicsSignal, "-OSC:ETIME", put_complete=True, kind=Kind.config) + get_ready = Component(EpicsSignal, "-OSC:READY.PROC", put_complete=True, kind=Kind.config) + taskStart = Component(EpicsSignal, "-OSC:START", put_complete=True, kind=Kind.config) + phase = Component(EpicsSignal, "-OSC:DONE", auto_monitor=True, kind=Kind.config) @property def is_done(self): diff --git a/pxiii_bec/scans/__init__.py b/pxiii_bec/scans/__init__.py index e69de29..0d5714f 100644 --- a/pxiii_bec/scans/__init__.py +++ b/pxiii_bec/scans/__init__.py @@ -0,0 +1 @@ +from .mx_measurements import MeasureStandardWedge \ No newline at end of file