Daily commit mit some patching
This commit is contained in:
@@ -15,6 +15,7 @@ slh_trxw:
|
|||||||
readOnly: false
|
readOnly: false
|
||||||
softwareTrigger: false
|
softwareTrigger: false
|
||||||
fi1_try:
|
fi1_try:
|
||||||
|
description: Beam attenuator in OP
|
||||||
deviceClass: ophyd.EpicsMotor
|
deviceClass: ophyd.EpicsMotor
|
||||||
deviceConfig: {prefix: 'X06DA-OP-FI1:TRY'}
|
deviceConfig: {prefix: 'X06DA-OP-FI1:TRY'}
|
||||||
onFailure: buffer
|
onFailure: buffer
|
||||||
@@ -193,6 +194,7 @@ vfm_trydw:
|
|||||||
readOnly: false
|
readOnly: false
|
||||||
softwareTrigger: false
|
softwareTrigger: false
|
||||||
vfm_pitch:
|
vfm_pitch:
|
||||||
|
description: KB mirror vertical steering
|
||||||
deviceClass: ophyd.EpicsMotor
|
deviceClass: ophyd.EpicsMotor
|
||||||
deviceConfig: {prefix: 'X06DA-ES1-VFM:PITCH'}
|
deviceConfig: {prefix: 'X06DA-ES1-VFM:PITCH'}
|
||||||
onFailure: buffer
|
onFailure: buffer
|
||||||
@@ -273,6 +275,7 @@ hfm_trydr:
|
|||||||
readOnly: false
|
readOnly: false
|
||||||
softwareTrigger: false
|
softwareTrigger: false
|
||||||
hfm_pitch:
|
hfm_pitch:
|
||||||
|
description: KB mirror horizontal steering
|
||||||
deviceClass: ophyd.EpicsMotor
|
deviceClass: ophyd.EpicsMotor
|
||||||
deviceConfig: {prefix: 'X06DA-ES1-HFM:PITCH'}
|
deviceConfig: {prefix: 'X06DA-ES1-HFM:PITCH'}
|
||||||
enabled: false
|
enabled: false
|
||||||
@@ -313,6 +316,7 @@ hfm_try:
|
|||||||
readOnly: false
|
readOnly: false
|
||||||
softwareTrigger: false
|
softwareTrigger: false
|
||||||
xbox_diode:
|
xbox_diode:
|
||||||
|
description: Exposure box diode
|
||||||
deviceClass: ophyd.EpicsSignalRO
|
deviceClass: ophyd.EpicsSignalRO
|
||||||
deviceConfig: {read_pv: 'X06DA-ES-DI1:READOUT'}
|
deviceConfig: {read_pv: 'X06DA-ES-DI1:READOUT'}
|
||||||
onFailure: buffer
|
onFailure: buffer
|
||||||
@@ -321,6 +325,7 @@ xbox_diode:
|
|||||||
readOnly: true
|
readOnly: true
|
||||||
softwareTrigger: false
|
softwareTrigger: false
|
||||||
bstop_diode:
|
bstop_diode:
|
||||||
|
description: Beamstop diode
|
||||||
deviceClass: ophyd.EpicsSignalRO
|
deviceClass: ophyd.EpicsSignalRO
|
||||||
deviceConfig: {read_pv: 'X06DA-ES-BS:READOUT'}
|
deviceConfig: {read_pv: 'X06DA-ES-BS:READOUT'}
|
||||||
onFailure: buffer
|
onFailure: buffer
|
||||||
@@ -329,14 +334,16 @@ bstop_diode:
|
|||||||
readOnly: true
|
readOnly: true
|
||||||
softwareTrigger: false
|
softwareTrigger: false
|
||||||
omega:
|
omega:
|
||||||
|
description: ABR rotation stage
|
||||||
deviceClass: pxiii_bec.devices.A3200Axis
|
deviceClass: pxiii_bec.devices.A3200Axis
|
||||||
deviceConfig: {prefix: 'X06DA-ES-DF1:OMEGA'}
|
deviceConfig: {prefix: 'X06DA-ES-DF1:OMEGA', base_pv: 'X06DA-ES'}
|
||||||
onFailure: buffer
|
onFailure: buffer
|
||||||
enabled: true
|
enabled: true
|
||||||
readoutPriority: monitored
|
readoutPriority: monitored
|
||||||
readOnly: false
|
readOnly: false
|
||||||
softwareTrigger: false
|
softwareTrigger: false
|
||||||
abr:
|
abr:
|
||||||
|
description: Aerotech ABR motion system
|
||||||
deviceClass: pxiii_bec.devices.AerotechAbrStage
|
deviceClass: pxiii_bec.devices.AerotechAbrStage
|
||||||
deviceConfig: {prefix: X06DA-ES}
|
deviceConfig: {prefix: X06DA-ES}
|
||||||
onFailure: buffer
|
onFailure: buffer
|
||||||
|
|||||||
@@ -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 .A3200utils import A3200Axis, A3200RasterScanner, A3200Oscillator
|
||||||
|
|
||||||
|
|
||||||
ABR_DONE = 0
|
ABR_DONE = 0
|
||||||
@@ -145,6 +145,8 @@ class AerotechAbrStage(Device):
|
|||||||
an AeroBasic program on the controller and we communicate to it via 10+1
|
an AeroBasic program on the controller and we communicate to it via 10+1
|
||||||
global variables.
|
global variables.
|
||||||
"""
|
"""
|
||||||
|
USER_ACCESS = ['reset', 'kickoff', 'complete']
|
||||||
|
|
||||||
taskStop = Component(EpicsSignal, "-AERO:TSK-STOP", put_complete=True, kind=Kind.omitted)
|
taskStop = Component(EpicsSignal, "-AERO:TSK-STOP", put_complete=True, kind=Kind.omitted)
|
||||||
status = Component(EpicsSignal, "-AERO:STAT", put_complete=True, kind=Kind.omitted)
|
status = Component(EpicsSignal, "-AERO:STAT", put_complete=True, kind=Kind.omitted)
|
||||||
|
|
||||||
@@ -196,12 +198,17 @@ class AerotechAbrStage(Device):
|
|||||||
def configure(self, d: dict) -> tuple:
|
def configure(self, d: dict) -> tuple:
|
||||||
"""" Configure the exposure scripts
|
"""" Configure the exposure scripts
|
||||||
|
|
||||||
Performs the configuration of the exposure scrips, i.e. sets the
|
Script execution at the PX beamlines is based on scripts that are always
|
||||||
required global variables.
|
running on the controller that execute commands when commanded by
|
||||||
|
setting a pre-defined set of global variables. This method performs the
|
||||||
|
configuration of the exposure scrips by setting the required global
|
||||||
|
variables.
|
||||||
|
|
||||||
Parameters
|
Parameters in d: dict
|
||||||
----------
|
---------------------
|
||||||
scan_command:
|
scan_command: int
|
||||||
|
The index of the desired AeroBasic program to be executed.
|
||||||
|
Usually supported values are taken from an Enum.
|
||||||
var_1:
|
var_1:
|
||||||
var_2:
|
var_2:
|
||||||
var_3:
|
var_3:
|
||||||
@@ -218,8 +225,7 @@ class AerotechAbrStage(Device):
|
|||||||
# ToDo: Check if idle before reconfiguring
|
# ToDo: Check if idle before reconfiguring
|
||||||
|
|
||||||
# Set the corresponding global variables
|
# Set the corresponding global variables
|
||||||
if "scan_command" in d:
|
self.scan_command.set(d['scan_command']).wait()
|
||||||
self.scan_command.set(d['scan_command']).wait()
|
|
||||||
if "var_1" in d and d['var_1'] is not None:
|
if "var_1" in d and d['var_1'] is not None:
|
||||||
self._var_1.set(d['var_1']).wait()
|
self._var_1.set(d['var_1']).wait()
|
||||||
if "var_2" in d and d['var_2'] is not None:
|
if "var_2" in d and d['var_2'] is not None:
|
||||||
@@ -271,11 +277,12 @@ class AerotechAbrStage(Device):
|
|||||||
|
|
||||||
Executes the homing procedure and waits (default) until it is completed.
|
Executes the homing procedure and waits (default) until it is completed.
|
||||||
|
|
||||||
|
TODO: Return a status object to do this wwith futures and monitoring.
|
||||||
|
|
||||||
PARAMETERS
|
PARAMETERS
|
||||||
`wait` true / false if the routine is to wait for the homing to finish.
|
`wait` true / false if the routine is to wait for the homing to finish.
|
||||||
"""
|
"""
|
||||||
self.omega.home.set(1, settle_time=1).wait()
|
self.omega.home.set(1, settle_time=1).wait()
|
||||||
poll(1.0)
|
|
||||||
if not wait:
|
if not wait:
|
||||||
return
|
return
|
||||||
while not self.omega.is_homed():
|
while not self.omega.is_homed():
|
||||||
|
|||||||
@@ -4,11 +4,15 @@ Created on Tue Jun 11 11:28:38 2024
|
|||||||
|
|
||||||
@author: mohacsi_i
|
@author: mohacsi_i
|
||||||
"""
|
"""
|
||||||
|
import types
|
||||||
from ophyd import Component, PVPositioner, Device, Signal, EpicsSignal, EpicsSignalRO, Kind
|
from ophyd import Component, PVPositioner, Device, Signal, EpicsSignal, EpicsSignalRO, Kind, PositionerBase
|
||||||
from ophyd.status import Status, MoveStatus, SubscriptionStatus, DeviceStatus
|
from ophyd.status import Status, MoveStatus, SubscriptionStatus, DeviceStatus
|
||||||
|
|
||||||
|
|
||||||
|
from bec_lib import bec_logger
|
||||||
|
logger = bec_logger.logger
|
||||||
|
|
||||||
|
|
||||||
ABR_DONE = 0
|
ABR_DONE = 0
|
||||||
ABR_READY = 1
|
ABR_READY = 1
|
||||||
ABR_BUSY = 2
|
ABR_BUSY = 2
|
||||||
@@ -24,7 +28,13 @@ class A3200Axis(PVPositioner):
|
|||||||
"""Positioner wrapper for motors on the Aerotech A3200 controller. As the
|
"""Positioner wrapper for motors on the Aerotech A3200 controller. As the
|
||||||
IOC does not provide a motor record, this class simply wraps axes into
|
IOC does not provide a motor record, this class simply wraps axes into
|
||||||
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.
|
||||||
|
"""
|
||||||
|
USER_ACCESS = ['omove']
|
||||||
|
|
||||||
|
abr_mode_direct = Component(EpicsSignal, "-DF1:MODE-DIRECT", put_complete=True, kind=Kind.omitted)
|
||||||
|
abr_mode = Component(EpicsSignal, "-DF1:AXES-MODE", auto_monitor=True, put_complete=True, kind=Kind.omitted)
|
||||||
|
|
||||||
# Basic PV positioner interface
|
# Basic PV positioner interface
|
||||||
done = Component(EpicsSignalRO, "-DONE", auto_monitor=True, kind=Kind.config)
|
done = Component(EpicsSignalRO, "-DONE", auto_monitor=True, kind=Kind.config)
|
||||||
readback = Component(EpicsSignalRO, "-RBV", auto_monitor=True, kind=Kind.hinted)
|
readback = Component(EpicsSignalRO, "-RBV", auto_monitor=True, kind=Kind.hinted)
|
||||||
@@ -58,52 +68,51 @@ class A3200Axis(PVPositioner):
|
|||||||
vmax = Component(Signal, kind=Kind.config)
|
vmax = Component(Signal, kind=Kind.config)
|
||||||
offset = Component(EpicsSignal, "-OFF", put_complete=True, kind=Kind.config)
|
offset = Component(EpicsSignal, "-OFF", put_complete=True, kind=Kind.config)
|
||||||
|
|
||||||
def __init__(self, prefix="", *, name, kind=None, read_attrs=None, configuration_attrs=None, parent=None, llm=0, hlm=0, vmin=0, vmax=0, **kwargs):
|
def __init__(self, prefix="", *, name, base_pv="", kind=None, read_attrs=None, configuration_attrs=None, parent=None, llm=0, hlm=0, vmin=0, vmax=0, **kwargs):
|
||||||
""" __init__ MUST have a full argument list"""
|
""" __init__ MUST have a full argument list"""
|
||||||
|
|
||||||
|
""" Patching the parent's PVs into the axis class to check for direct/locked mode"""
|
||||||
|
if parent is None:
|
||||||
|
def maybe_add_prefix(self, instance, kw, suffix):
|
||||||
|
""" Patched not to enforce parent prefix"""
|
||||||
|
if kw in self.add_prefix:
|
||||||
|
return suffix
|
||||||
|
return suffix
|
||||||
|
self.__class__.__dict__["abr_mode"].maybe_add_prefix = types.MethodType(maybe_add_prefix, self.__class__.__dict__["abr_mode"])
|
||||||
|
self.__class__.__dict__["abr_mode_direct"].maybe_add_prefix = types.MethodType(maybe_add_prefix, self.__class__.__dict__["abr_mode_direct"])
|
||||||
|
logger.info(self.__class__.__dict__["abr_mode"].kwargs)
|
||||||
|
self.__class__.__dict__["abr_mode"].suffix = base_pv + "-DF1:AXES-MODE"
|
||||||
|
self.__class__.__dict__["abr_mode_direct"].suffix = base_pv + "-DF1:MODE-DIRECT"
|
||||||
|
|
||||||
super().__init__(prefix=prefix, name=name, kind=kind, read_attrs=read_attrs, configuration_attrs=configuration_attrs, parent=parent, **kwargs)
|
super().__init__(prefix=prefix, name=name, kind=kind, read_attrs=read_attrs, configuration_attrs=configuration_attrs, parent=parent, **kwargs)
|
||||||
self.llm.set(llm).wait()
|
self.llm.set(llm).wait()
|
||||||
self.hlm.set(hlm).wait()
|
self.hlm.set(hlm).wait()
|
||||||
self.vmin.set(vmin).wait()
|
self.vmin.set(vmin).wait()
|
||||||
self.vmax.set(vmax).wait()
|
self.vmax.set(vmax).wait()
|
||||||
|
|
||||||
|
def move(self, position, velocity=None, wait=True, relative=False, direct=False, timeout=None, **kwargs) -> MoveStatus:
|
||||||
def move(self, position, velocity=None, wait=True, relative=False, direct=False, **kwargs) -> MoveStatus:
|
""" Native absolute/relative movement on the A3200 """
|
||||||
""" Native absolute movement on the A3200 """
|
|
||||||
|
|
||||||
# ToDo: Ensure we can stop (if a stop_signal is configured).
|
|
||||||
|
|
||||||
# Check if we're in direct movement mode
|
# Check if we're in direct movement mode
|
||||||
if self.parent is not None:
|
if self.abr_mode.value not in (DIRECT_MODE, "DIRECT"):
|
||||||
if self.parent.mode != DIRECT_MODE:
|
if direct:
|
||||||
if direct:
|
self.abr_mode_direct.set(1).wait()
|
||||||
self.parent.set_direct_mode()
|
else:
|
||||||
else:
|
raise RuntimeError(f"ABR axis not in direct mode: {self.abr_mode.value}")
|
||||||
raise RuntimeError("ABR is not in direct mode!")
|
|
||||||
|
|
||||||
# Set velocity if provided
|
|
||||||
if velocity is not None:
|
|
||||||
self.velo.set(velocity).wait()
|
|
||||||
|
|
||||||
# Set up relative motion
|
|
||||||
if relative:
|
|
||||||
raise NotImplementedError("Relative movement is not yet supported by the ophyd device")
|
|
||||||
|
|
||||||
return super().move(position, wait=wait, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def rmove(self, distance, wait=True, velo=None, timeout=None, moved_cb=None) -> Status:
|
|
||||||
""" Native relative movement on the A3200 """
|
|
||||||
|
|
||||||
# Before moving, ensure we can stop (if a stop_signal is configured).
|
# Before moving, ensure we can stop (if a stop_signal is configured).
|
||||||
if self.stop_signal is not None:
|
if self.stop_signal is not None:
|
||||||
self.stop_signal.wait_for_connection()
|
self.stop_signal.wait_for_connection()
|
||||||
|
|
||||||
if velo is not None:
|
# Set velocity if provided
|
||||||
self.velo.set(velo).wait()
|
if velocity is not None:
|
||||||
|
self.velocity.set(velocity).wait()
|
||||||
|
|
||||||
# Issue move command
|
# This is adapted from pv_positioner.py
|
||||||
status = super().move(position=distance, timeout=timeout, moved_cb=moved_cb)
|
self.check_value(position)
|
||||||
|
|
||||||
|
# Get MoveStatus from parent of parent
|
||||||
|
status = PositionerBase.move(self, position=position, timeout=timeout)
|
||||||
|
|
||||||
has_done = self.done is not None
|
has_done = self.done is not None
|
||||||
if not has_done:
|
if not has_done:
|
||||||
@@ -112,16 +121,24 @@ class A3200Axis(PVPositioner):
|
|||||||
self._move_changed(value=moving_val)
|
self._move_changed(value=moving_val)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Relative movement instead of setpoint
|
if relative:
|
||||||
self.relmove.put(distance)
|
# Relative movement instead of setpoint
|
||||||
|
self.relmove.put(position, wait=True)
|
||||||
|
else:
|
||||||
|
# Standard absolute movement
|
||||||
|
self.setpoint.put(position, wait=True)
|
||||||
if wait:
|
if wait:
|
||||||
status.wait()
|
status.wait()
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
self.stop()
|
self.stop()
|
||||||
raise
|
raise
|
||||||
|
|
||||||
return status
|
return status
|
||||||
|
|
||||||
|
|
||||||
|
def omove(self, position, velocity=None, wait=True, relative=False, direct=False, **kwargs) -> MoveStatus:
|
||||||
|
""" Exposes the ophyd move command through BEC abstraction"""
|
||||||
|
return self.move(position, velocity, wait, relative, direct, **kwargs)
|
||||||
|
|
||||||
def rock(self, distance, counts: int, velocity=None, wait=True) -> Status:
|
def rock(self, distance, counts: int, velocity=None, wait=True) -> Status:
|
||||||
""" Repeated single axis zigzag scan I guess PSO should be configured for this"""
|
""" Repeated single axis zigzag scan I guess PSO should be configured for this"""
|
||||||
|
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
from .aeroA3200 import A3200Axis
|
from .A3200 import AerotechAbrStage
|
||||||
from .A3200 import AerotechAbrStage
|
from .A3200utils import A3200Axis
|
||||||
|
|||||||
@@ -23,18 +23,18 @@ class AbrCmd:
|
|||||||
VERTICAL_LINE_SCAN = 3
|
VERTICAL_LINE_SCAN = 3
|
||||||
SCREENING = 4
|
SCREENING = 4
|
||||||
SUPER_FAST_OMEGA = 5
|
SUPER_FAST_OMEGA = 5
|
||||||
STILL_WEDGE = 6
|
STILL_WEDGE = 6 # NOTE: Unused
|
||||||
STILLS = 7
|
STILLS = 7 # NOTE: Unused
|
||||||
REPEAT_SINGLE_OSCILLATION = 8
|
REPEAT_SINGLE_OSCILLATION = 8 # NOTE: Unused
|
||||||
SINGLE_OSCILLATION = 9
|
SINGLE_OSCILLATION = 9
|
||||||
OLD_FASHIONED = 10
|
OLD_FASHIONED = 10 # NOTE: Unused
|
||||||
RASTER_SCAN = 11
|
RASTER_SCAN = 11
|
||||||
JET_ROTATION = 12
|
JET_ROTATION = 12 # NOTE: Unused
|
||||||
X_HELICAL = 13
|
X_HELICAL = 13 # NOTE: Unused
|
||||||
X_RUNSEQ = 14
|
X_RUNSEQ = 14 # NOTE: Unused
|
||||||
JUNGFRAU = 15
|
JUNGFRAU = 15
|
||||||
MSOX = 16
|
MSOX = 16 # NOTE: Unused
|
||||||
SLIT_SCAN = 17
|
SLIT_SCAN = 17 # NOTE: Unused
|
||||||
RASTER_SCAN_STILL = 18
|
RASTER_SCAN_STILL = 18
|
||||||
SCAN_SASTT = 19
|
SCAN_SASTT = 19
|
||||||
SCAN_SASTT_V2 = 20
|
SCAN_SASTT_V2 = 20
|
||||||
@@ -87,6 +87,12 @@ class AerotechFlyscanBase(AsyncFlyScanBase):
|
|||||||
|
|
||||||
def pre_scan(self):
|
def pre_scan(self):
|
||||||
# ToDo: Move roughly to start position
|
# ToDo: Move roughly to start position
|
||||||
|
stat = yield from self.stubs.send_rpc_and_wait("abr","status.get")
|
||||||
|
if stat not in (0, "OK"):
|
||||||
|
raise RuntimeError("Aerotech ABR seems to be in error state {stat}, please reset")
|
||||||
|
|
||||||
|
if self.abr_reset:
|
||||||
|
yield from self.stubs.send_rpc_and_wait("abr", "reset")
|
||||||
|
|
||||||
# Reset the scan engine
|
# Reset the scan engine
|
||||||
if self.abr_reset:
|
if self.abr_reset:
|
||||||
|
|||||||
Reference in New Issue
Block a user