Both ABR stage and scan instantiates, need Zac to test it safely

This commit is contained in:
Unknown MX Person
2024-09-09 13:23:03 +02:00
parent 602317faa8
commit 3bf21ff647
6 changed files with 151 additions and 98 deletions
+13 -6
View File
@@ -66,19 +66,19 @@ ssxbpm_try:
ssslit_trxr: ssslit_trxr:
deviceClass: ophyd.EpicsMotor deviceClass: ophyd.EpicsMotor
deviceConfig: deviceConfig:
prefix: 'X06DA-ES-SSSH1:TRXR' prefix: 'X06DA-ES-SSSLH1:TRXR'
ssslit_trxw: ssslit_trxw:
deviceClass: ophyd.EpicsMotor deviceClass: ophyd.EpicsMotor
deviceConfig: deviceConfig:
prefix: 'X06DA-ES-SSSH1:TRXW' prefix: 'X06DA-ES-SSSLH1:TRXW'
ssslit_tryt: ssslit_tryt:
deviceClass: ophyd.EpicsMotor deviceClass: ophyd.EpicsMotor
deviceConfig: deviceConfig:
prefix: 'X06DA-ES-SSSV1:TRYT' prefix: 'X06DA-ES-SSSLV1:TRYT'
ssslit_tryb: ssslit_tryb:
deviceClass: ophyd.EpicsMotor deviceClass: ophyd.EpicsMotor
deviceConfig: deviceConfig:
prefix: 'X06DA-ES-SSSV1:TRYB' prefix: 'X06DA-ES-SSSLV1:TRYB'
ssxi1_trx: ssxi1_trx:
deviceClass: ophyd.EpicsMotor deviceClass: ophyd.EpicsMotor
deviceConfig: deviceConfig:
@@ -195,5 +195,12 @@ bstop_diode:
prefix: 'X06DA-ES-BS:READOUT' 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'
@@ -1,4 +1,3 @@
slh_trxr: slh_trxr:
deviceClass: ophyd.EpicsMotor deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-OP-SLH:TRXR'} deviceConfig: {prefix: 'X06DA-OP-SLH:TRXR'}
@@ -63,6 +62,14 @@ dccm_energy2:
readoutPriority: monitored readoutPriority: monitored
readOnly: false readOnly: false
softwareTrigger: 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: dccm_energy:
description: Monochromator energy using ECMC virtual motors description: Monochromator energy using ECMC virtual motors
deviceClass: ophyd.EpicsMotor deviceClass: ophyd.EpicsMotor
@@ -73,7 +80,7 @@ dccm_energy:
readOnly: false readOnly: false
softwareTrigger: false softwareTrigger: false
dccm_eoffset: dccm_eoffset:
description: Monochromator energy offset between crystals using ECMC virtual motors description: Monochromator energy offset for ECMC virtual motors
deviceClass: ophyd.EpicsMotor deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-OP-DCCM:_EOFFSET'} deviceConfig: {prefix: 'X06DA-OP-DCCM:_EOFFSET'}
onFailure: buffer onFailure: buffer
@@ -81,14 +88,6 @@ dccm_eoffset:
readoutPriority: monitored readoutPriority: monitored
readOnly: false readOnly: false
softwareTrigger: 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: ssxbpm_trx:
deviceClass: ophyd.EpicsMotor deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSBPM1:TRX'} deviceConfig: {prefix: 'X06DA-ES-SSBPM1:TRX'}
@@ -107,7 +106,7 @@ ssxbpm_try:
softwareTrigger: false softwareTrigger: false
ssslit_trxr: ssslit_trxr:
deviceClass: ophyd.EpicsMotor deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSSH1:TRXR'} deviceConfig: {prefix: 'X06DA-ES-SSSLH1:TRXR'}
onFailure: buffer onFailure: buffer
enabled: true enabled: true
readoutPriority: monitored readoutPriority: monitored
@@ -115,7 +114,7 @@ ssslit_trxr:
softwareTrigger: false softwareTrigger: false
ssslit_trxw: ssslit_trxw:
deviceClass: ophyd.EpicsMotor deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSSH1:TRXW'} deviceConfig: {prefix: 'X06DA-ES-SSSLH1:TRXW'}
onFailure: buffer onFailure: buffer
enabled: true enabled: true
readoutPriority: monitored readoutPriority: monitored
@@ -123,7 +122,7 @@ ssslit_trxw:
softwareTrigger: false softwareTrigger: false
ssslit_tryt: ssslit_tryt:
deviceClass: ophyd.EpicsMotor deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSSV1:TRYT'} deviceConfig: {prefix: 'X06DA-ES-SSSLV1:TRYT'}
onFailure: buffer onFailure: buffer
enabled: true enabled: true
readoutPriority: monitored readoutPriority: monitored
@@ -131,7 +130,7 @@ ssslit_tryt:
softwareTrigger: false softwareTrigger: false
ssslit_tryb: ssslit_tryb:
deviceClass: ophyd.EpicsMotor deviceClass: ophyd.EpicsMotor
deviceConfig: {prefix: 'X06DA-ES-SSSV1:TRYB'} deviceConfig: {prefix: 'X06DA-ES-SSSLV1:TRYB'}
onFailure: buffer onFailure: buffer
enabled: true enabled: true
readoutPriority: monitored readoutPriority: monitored
@@ -329,3 +328,19 @@ bstop_diode:
readoutPriority: monitored readoutPriority: monitored
readOnly: true readOnly: true
softwareTrigger: false 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
+77 -49
View File
@@ -85,7 +85,7 @@ from ophyd import Component, Device, EpicsSignal, EpicsSignalRO, Kind
from ophyd.status import MoveStatus, SubscriptionStatus, DeviceStatus from ophyd.status import MoveStatus, SubscriptionStatus, DeviceStatus
from aeroA3200 import A3200Axis, A3200RasterScanner, A3200Oscillator from .aeroA3200 import A3200Axis, A3200RasterScanner, A3200Oscillator
ABR_DONE = 0 ABR_DONE = 0
@@ -136,46 +136,56 @@ AXIS_STZ = 6
class AerotechAbrStage(Device): class AerotechAbrStage(Device):
""" Standard PX stage on A3200 controller
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) 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) # 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) axisModeLocked = Component(EpicsSignal, "-DF1:LOCK", put_complete=True, kind=Kind.omitted)
axisModeDirect = Component(EpicsSignal, "-ES-DF1:MODE-DIRECT", put_complete=True, kind=Kind.omitted) axisModeDirect = Component(EpicsSignal, "-DF1:MODE-DIRECT", put_complete=True, kind=Kind.omitted)
axisAxesMode = Component(EpicsSignal, "-ES-DF1:AXES-MODE", put_complete=True, kind=Kind.omitted) axisAxesMode = Component(EpicsSignal, "-DF1:AXES-MODE", put_complete=True, kind=Kind.omitted)
_shutter = Component( # Shutter box is missing readback so the -GET signal is installed on the VME
EpicsSignal, "-ES-PH1:GET", write_pv="-ES-PH1:SET", put_complete=True, kind=Kind.config, # _shutter = Component(
) # EpicsSignal, "-PH1:GET", write_pv="-PH1:SET", put_complete=True, kind=Kind.config,
# )
raster = Component(A3200RasterScanner, "", kind=Kind.config) raster = Component(A3200RasterScanner, "", kind=Kind.config)
osc = Component(A3200Oscillator, "", kind=Kind.config) osc = Component(A3200Oscillator, "", kind=Kind.config)
omega = Component(A3200Axis, "-ES-DF1:OMEGA", kind=Kind.hinted) # Positioners for the motor axes
gmx = Component(A3200Axis, "-ES-DF1:GMX", kind=Kind.hinted) omega = Component(A3200Axis, "-DF1:OMEGA", kind=Kind.hinted)
gmy = Component(A3200Axis, "-ES-DF1:GMY", kind=Kind.hinted) gmx = Component(A3200Axis, "-DF1:GMX", kind=Kind.hinted)
gmz = Component(A3200Axis, "-ES-DF1:GMZ", 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) # Global variables to controll AeroBasic scripts
start_command = Component(EpicsSignal, "-ES-PSO:START-TEST.PROC", put_complete=True, kind=Kind.omitted) _var_1 = Component(EpicsSignal, "-PSO:VAR-1", put_complete=True, kind=Kind.omitted)
stop_command = Component(EpicsSignal, "-ES-PSO:STOP-TEST.PROC", 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_1 = Component(EpicsSignal, "-ES-PSO:VAR-1", put_complete=True, kind=Kind.omitted) _var_4 = Component(EpicsSignal, "-PSO:VAR-4", put_complete=True, kind=Kind.omitted)
_var_2 = Component(EpicsSignal, "-ES-PSO:VAR-2", put_complete=True, kind=Kind.omitted) _var_5 = Component(EpicsSignal, "-PSO:VAR-5", put_complete=True, kind=Kind.omitted)
_var_3 = Component(EpicsSignal, "-ES-PSO:VAR-3", put_complete=True, kind=Kind.omitted) _var_6 = Component(EpicsSignal, "-PSO:VAR-6", put_complete=True, kind=Kind.omitted)
_var_4 = Component(EpicsSignal, "-ES-PSO:VAR-4", put_complete=True, kind=Kind.omitted) _var_7 = Component(EpicsSignal, "-PSO:VAR-7", put_complete=True, kind=Kind.omitted)
_var_5 = Component(EpicsSignal, "-ES-PSO:VAR-5", put_complete=True, kind=Kind.omitted) _var_8 = Component(EpicsSignal, "-PSO:VAR-8", put_complete=True, kind=Kind.omitted)
_var_6 = Component(EpicsSignal, "-ES-PSO:VAR-6", put_complete=True, kind=Kind.omitted) _var_9 = Component(EpicsSignal, "-PSO:VAR-9", put_complete=True, kind=Kind.omitted)
_var_7 = Component(EpicsSignal, "-ES-PSO:VAR-7", put_complete=True, kind=Kind.omitted) _var_10 = Component(EpicsSignal, "-PSO:VAR-10", 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)
# A few PVs still needed from grid # A few PVs still needed from grid
raster_scan_done = Component(EpicsSignal, "-ES-GRD:SCAN-DONE", kind=Kind.config) raster_scan_done = Component(EpicsSignal, "-GRD:SCAN-DONE", kind=Kind.config)
raster_num_rows = Component(EpicsSignal, "-ES-GRD:ROW-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: def set_axis_mode(self, mode: str, settle_time=0.1) -> None:
if mode=="direct": if mode=="direct":
@@ -184,7 +194,25 @@ class AerotechAbrStage(Device):
self.axisAxesMode.set(MEASURING_MODE, settle_time=settle_time).wait() self.axisAxesMode.set(MEASURING_MODE, settle_time=settle_time).wait()
def configure(self, d: dict) -> tuple: 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() old = self.read_configuration()
# ToDo: Check if idle before reconfiguring # ToDo: Check if idle before reconfiguring
@@ -285,25 +313,25 @@ class AerotechAbrStage(Device):
def measurement_state(self, value): def measurement_state(self, value):
self.osc.phase.set(value).wait() self.osc.phase.set(value).wait()
@property # @property
def shutter(self): # def shutter(self):
return self._shutter.get() # return self._shutter.get()
@shutter.setter # @shutter.setter
def shutter(self, value): # def shutter(self, value):
if self.axisAxesMode.get(): # if self.axisAxesMode.get():
print("ABR is not in direct mode; cannot manipulate shutter") # print("ABR is not in direct mode; cannot manipulate shutter")
return False # return False
state = str(state).lower() # state = str(state).lower()
if state not in ["1", "0", "closed", "open"]: # if state not in ["1", "0", "closed", "open"]:
print("unknown shutter state requested") # print("unknown shutter state requested")
return None # return None
elif state in ["1", "open"]: # elif state in ["1", "open"]:
state = 1 # state = 1
elif state == ["0", "closed"]: # elif state == ["0", "closed"]:
state = 0 # state = 0
self._shutter.set(state).wait() # self._shutter.set(state).wait()
return state == self._shutter.get() # return state == self._shutter.get()
@property @property
def axis_mode(self): def axis_mode(self):
@@ -395,5 +423,5 @@ class AerotechAbrStage(Device):
if __name__ == "__main__": if __name__ == "__main__":
abr = AerotechAbrStage(prefix="X06DA-ES-DF1", name="abr") abr = AerotechAbrStage(prefix="X06DA-ES", name="abr")
abr.wait_for_connection() abr.wait_for_connection()
+2
View File
@@ -0,0 +1,2 @@
from .aeroA3200 import A3200Axis
from .A3200 import AerotechAbrStage
+29 -29
View File
@@ -148,34 +148,34 @@ class A3200RasterScanner(Device):
a standard Ophyd positioner for the BEC. It also has some additional a standard Ophyd positioner for the BEC. It also has some additional
functionality for diagnostics.""" functionality for diagnostics."""
x_start = Component(EpicsSignal, "-ES-GRD:GMX-START", kind=Kind.config) x_start = Component(EpicsSignal, "-GRD:GMX-START", kind=Kind.config)
x_start = Component(EpicsSignal, "-ES-GRD:GMX-END", kind=Kind.config) x_start = Component(EpicsSignal, "-GRD:GMX-END", kind=Kind.config)
omega = Component(EpicsSignal, "-ES-OSC:#M-START", kind=Kind.config) omega = Component(EpicsSignal, "-OSC:#M-START", kind=Kind.config)
osc = Component(EpicsSignal, "-ES-GRD:ANGLE", kind=Kind.config) osc = Component(EpicsSignal, "-GRD:ANGLE", kind=Kind.config)
celltime = Component(EpicsSignal, "-ES-GRD:CELL-TIME", kind=Kind.config) celltime = Component(EpicsSignal, "-GRD:CELL-TIME", kind=Kind.config)
y_start = Component(EpicsSignal, "-ES-OSC:#STY-START", kind=Kind.config) y_start = Component(EpicsSignal, "-OSC:#STY-START", kind=Kind.config)
y_end = Component(EpicsSignal, "-ES-OSC:#STY-END", kind=Kind.config) y_end = Component(EpicsSignal, "-OSC:#STY-END", kind=Kind.config)
z_start = Component(EpicsSignal, "-ES-OSC:#STZ-START", kind=Kind.config) z_start = Component(EpicsSignal, "-OSC:#STZ-START", kind=Kind.config)
z_end = Component(EpicsSignal, "-ES-OSC:#STZ-END", kind=Kind.config) z_end = Component(EpicsSignal, "-OSC:#STZ-END", kind=Kind.config)
columns = Component(EpicsSignal, "-ES-GRD:COLUMNS", kind=Kind.config) columns = Component(EpicsSignal, "-GRD:COLUMNS", kind=Kind.config)
rows = Component(EpicsSignal, "-ES-GRD:ROWS", kind=Kind.config) rows = Component(EpicsSignal, "-GRD:ROWS", kind=Kind.config)
delay = Component(EpicsSignal, "-ES-GRD:RAST-DLY", kind=Kind.config) delay = Component(EpicsSignal, "-GRD:RAST-DLY", kind=Kind.config)
osc_mode = Component(EpicsSignal, "-ES-GRD:SET-MODE", kind=Kind.config) osc_mode = Component(EpicsSignal, "-GRD:SET-MODE", kind=Kind.config)
velo = Component(EpicsSignal, "-ES-GRD:#X-VEL", kind=Kind.config) velo = Component(EpicsSignal, "-GRD:#X-VEL", kind=Kind.config)
get_ready = Component(EpicsSignal, "-ES-GRD:READY.PROC", kind=Kind.config) get_ready = Component(EpicsSignal, "-GRD:READY.PROC", kind=Kind.config)
grid_start = Component(EpicsSignal, "-ES-GRD:START.PROC", kind=Kind.config) grid_start = Component(EpicsSignal, "-GRD:START.PROC", kind=Kind.config)
grid_next = Component(EpicsSignal, "-ES-GRD:NEXT-ROW", kind=Kind.config) grid_next = Component(EpicsSignal, "-GRD:NEXT-ROW", kind=Kind.config)
row_done = Component(EpicsSignal, "-ES-GRD:ROW-DONE", kind=Kind.config) row_done = Component(EpicsSignal, "-GRD:ROW-DONE", kind=Kind.config)
scan_done = Component(EpicsSignal, "-ES-GRD:SCAN-DONE", kind=Kind.config) scan_done = Component(EpicsSignal, "-GRD:SCAN-DONE", kind=Kind.config)
grid_done = Component(EpicsSignal, "-ES-GRD:DONE", kind=Kind.config) grid_done = Component(EpicsSignal, "-GRD:DONE", kind=Kind.config)
# Also needs the command interface # Also needs the command interface
_zcmd = Component(EpicsSignal, "-ES-PSO:CMD", put_complete=True, kind=Kind.omitted) _zcmd = Component(EpicsSignal, "-PSO:CMD", put_complete=True, kind=Kind.omitted)
_start_command = Component(EpicsSignal, "-ES-PSO:START-TEST.PROC", put_complete=True, kind=Kind.omitted) _start_command = Component(EpicsSignal, "-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) _stop_command = Component(EpicsSignal, "-PSO:STOP-TEST.PROC", put_complete=True, kind=Kind.omitted)
def raster_setup(self, positions, columns, angle, etime): 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... """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) ostart_pos = Component(EpicsSignal, "-OSC:START-POS", put_complete=True, kind=Kind.config)
orange = Component(EpicsSignal, "-ES-OSC:RANGE", put_complete=True, kind=Kind.config) orange = Component(EpicsSignal, "-OSC:RANGE", put_complete=True, kind=Kind.config)
etime = Component(EpicsSignal, "-ES-OSC:ETIME", put_complete=True, kind=Kind.config) etime = Component(EpicsSignal, "-OSC:ETIME", put_complete=True, kind=Kind.config)
get_ready = Component(EpicsSignal, "-ES-OSC:READY.PROC", put_complete=True, kind=Kind.config) get_ready = Component(EpicsSignal, "-OSC:READY.PROC", put_complete=True, kind=Kind.config)
taskStart = Component(EpicsSignal, "-ES-OSC:START", put_complete=True, kind=Kind.config) taskStart = Component(EpicsSignal, "-OSC:START", put_complete=True, kind=Kind.config)
phase = Component(EpicsSignal, "-ES-OSC:DONE", auto_monitor=True, kind=Kind.config) phase = Component(EpicsSignal, "-OSC:DONE", auto_monitor=True, kind=Kind.config)
@property @property
def is_done(self): def is_done(self):
+1
View File
@@ -0,0 +1 @@
from .mx_measurements import MeasureStandardWedge