ABR with latest BEC
This commit is contained in:
@@ -57,7 +57,7 @@ sldi_sizex:
|
||||
softwareTrigger: false
|
||||
sldi_ceny:
|
||||
description: FE slit-diaphragm vertical center
|
||||
deviceClass: ophyd_devices.EpicsMotorEC
|
||||
deviceClass: ophyd.EpicsMotor
|
||||
deviceConfig: {prefix: 'X06DA-FE-SLDI:CENTERY'}
|
||||
onFailure: buffer
|
||||
enabled: true
|
||||
|
||||
@@ -51,9 +51,9 @@ Examples
|
||||
"""
|
||||
|
||||
import time
|
||||
from ophyd import Component, EpicsSignal, EpicsSignalRO, Kind
|
||||
from ophyd import Device, Component, EpicsSignal, EpicsSignalRO, Kind
|
||||
from ophyd.status import SubscriptionStatus
|
||||
from ophyd_devices.interfaces.base_classes.bec_device_base import BECDeviceBase, CustomPrepare
|
||||
from ophyd_devices.interfaces.base_classes.psi_device_base import PSIDeviceBase
|
||||
|
||||
try:
|
||||
from .A3200enums import AbrCmd, AbrMode
|
||||
@@ -67,90 +67,7 @@ logger = bec_logger.logger
|
||||
|
||||
|
||||
# pylint: disable=logging-fstring-interpolation
|
||||
class AerotechAbrMixin(CustomPrepare):
|
||||
"""Configuration class for the Aerotech A3200 controller for the ABR stage"""
|
||||
|
||||
def on_stage(self):
|
||||
"""
|
||||
|
||||
NOTE: Zac's request is that stage is essentially ARM, i.e. get ready and don't do anything.
|
||||
"""
|
||||
|
||||
logger.warning(f"Configuring {self.parent.scaninfo.scan_msg.info['scan_name']} on ABR")
|
||||
|
||||
d = {}
|
||||
if self.parent.scaninfo.scan_type in ("measure", "measurement", "fly"):
|
||||
scanargs = self.parent.scaninfo.scan_msg.info["kwargs"]
|
||||
scanname = self.parent.scaninfo.scan_msg.info["scan_name"]
|
||||
|
||||
if scanname in (
|
||||
"standardscan",
|
||||
"helicalscan",
|
||||
"helicalscan1",
|
||||
"helicalscan2",
|
||||
"helicalscan3",
|
||||
):
|
||||
d["scan_command"] = AbrCmd.MEASURE_STANDARD
|
||||
d["var_1"] = scanargs["start"]
|
||||
d["var_2"] = scanargs["range"]
|
||||
d["var_3"] = scanargs["move_time"]
|
||||
d["var_4"] = scanargs.get("ready_rate", 500)
|
||||
d["var_5"] = 0
|
||||
d["var_6"] = 0
|
||||
d["var_7"] = 0
|
||||
# d["var_8"] = 0
|
||||
# d["var_9"] = 0
|
||||
if scanname in ("verticallinescan", "vlinescan"):
|
||||
d["scan_command"] = AbrCmd.VERTICAL_LINE_SCAN
|
||||
d["var_1"] = scanargs["range"] / scanargs["steps"]
|
||||
d["var_2"] = scanargs["steps"]
|
||||
d["var_3"] = scanargs["exp_time"]
|
||||
d["var_4"] = 0
|
||||
d["var_5"] = 0
|
||||
d["var_6"] = 0
|
||||
d["var_7"] = 0
|
||||
# d["var_8"] = 0
|
||||
# d["var_9"] = 0
|
||||
if scanname in ("screeningscan"):
|
||||
d["scan_command"] = AbrCmd.SCREENING
|
||||
d["var_1"] = scanargs["start"]
|
||||
d["var_2"] = scanargs["oscrange"]
|
||||
d["var_3"] = scanargs["exp_time"]
|
||||
d["var_4"] = scanargs["range"] / scanargs["steps"]
|
||||
d["var_5"] = scanargs["steps"]
|
||||
d["var_6"] = scanargs.get("delta", 0.5)
|
||||
d["var_7"] = 0
|
||||
# d["var_8"] = 0
|
||||
# d["var_9"] = 0
|
||||
if scanname in ("rasterscan", "rastersimplescan"):
|
||||
d["scan_command"] = AbrCmd.RASTER_SCAN_SIMPLE
|
||||
d["var_1"] = scanargs["exp_time"]
|
||||
d["var_2"] = scanargs["range_x"] / scanargs["steps_x"]
|
||||
d["var_3"] = scanargs["range_y"] / scanargs["steps_y"]
|
||||
d["var_4"] = scanargs["steps_x"]
|
||||
d["var_5"] = scanargs["steps_y"]
|
||||
d["var_6"] = 0
|
||||
d["var_7"] = 0
|
||||
# d["var_8"] = 0
|
||||
# d["var_9"] = 0
|
||||
|
||||
# Reconfigure if got a valid scan config
|
||||
if len(d) > 0:
|
||||
self.parent.configure(d)
|
||||
|
||||
# Stage the parent
|
||||
self.parent.bluestage()
|
||||
|
||||
def on_kickoff(self):
|
||||
"""Kick off parent"""
|
||||
self.parent.bluekickoff()
|
||||
|
||||
def on_unstage(self):
|
||||
"""Unstage the ABR controller"""
|
||||
self.parent.blueunstage()
|
||||
|
||||
|
||||
class AerotechAbrStage(BECDeviceBase):
|
||||
class AerotechAbrStage(PSIDeviceBase, Device):
|
||||
"""Standard PX stage on A3200 controller
|
||||
|
||||
This is the wrapper class for the standard rotation stage layout for the PX
|
||||
@@ -161,8 +78,7 @@ class AerotechAbrStage(BECDeviceBase):
|
||||
it via 10+1 global variables.
|
||||
"""
|
||||
|
||||
custom_prepare_cls = AerotechAbrMixin
|
||||
USER_ACCESS = ["reset", "kickoff", "bluekickoff", "complete", "set_axis_mode", "arm", "disarm"]
|
||||
USER_ACCESS = ["reset", "kickoff", "complete", "set_axis_mode", "arm", "disarm"]
|
||||
|
||||
taskStop = Component(EpicsSignal, "-AERO:TSK-STOP", put_complete=True, kind=Kind.omitted)
|
||||
status = Component(EpicsSignal, "-AERO:STAT", put_complete=True, kind=Kind.omitted)
|
||||
@@ -214,6 +130,30 @@ class AerotechAbrStage(BECDeviceBase):
|
||||
task4 = Component(EpicsSignalRO, "-AERO:TSK4-DONE", auto_monitor=True)
|
||||
scan_done = Component(EpicsSignal, "-GRD:SCAN-DONE", kind=Kind.config)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
prefix="",
|
||||
*,
|
||||
name,
|
||||
kind=None,
|
||||
read_attrs=None,
|
||||
configuration_attrs=None,
|
||||
parent=None,
|
||||
scan_info=None,
|
||||
**kwargs,
|
||||
):
|
||||
# super() will call the mixin class
|
||||
super().__init__(
|
||||
prefix=prefix,
|
||||
name=name,
|
||||
kind=kind,
|
||||
read_attrs=read_attrs,
|
||||
configuration_attrs=configuration_attrs,
|
||||
parent=parent,
|
||||
scan_info=scan_info,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
def set_axis_mode(self, mode: str, settle_time=0.1) -> None:
|
||||
"""Set axis mode to direct/measurement mode.
|
||||
|
||||
@@ -230,6 +170,86 @@ class AerotechAbrStage(BECDeviceBase):
|
||||
if mode == "measuring":
|
||||
self.axisAxesMode.set(AbrMode.MEASURING, settle_time=settle_time).wait()
|
||||
|
||||
def on_stage(self):
|
||||
"""
|
||||
|
||||
NOTE: Zac's request is that stage is essentially ARM, i.e. get ready and don't do anything.
|
||||
"""
|
||||
|
||||
logger.warning(f"Configuring {self.scaninfo.scan_msg.info['scan_name']} on ABR")
|
||||
|
||||
d = {}
|
||||
if self.scan_info.scan_type in ("measure", "measurement", "fly"):
|
||||
# FIXME: I don't care about how we fish out config parameters from scan info
|
||||
scan_args = {
|
||||
**self.scan_info.msg.request_inputs["inputs"],
|
||||
**self.scan_info.msg.request_inputs["kwargs"],
|
||||
**self.scan_info.msg.scan_parameters,
|
||||
}
|
||||
scanname = self.scan_info.scan_msg.info["scan_name"]
|
||||
|
||||
if scanname in (
|
||||
"standardscan",
|
||||
"helicalscan",
|
||||
"helicalscan1",
|
||||
"helicalscan2",
|
||||
"helicalscan3",
|
||||
):
|
||||
d["scan_command"] = AbrCmd.MEASURE_STANDARD
|
||||
d["var_1"] = scan_args["start"]
|
||||
d["var_2"] = scan_args["range"]
|
||||
d["var_3"] = scan_args["move_time"]
|
||||
d["var_4"] = scan_args.get("ready_rate", 500)
|
||||
d["var_5"] = 0
|
||||
d["var_6"] = 0
|
||||
d["var_7"] = 0
|
||||
# d["var_8"] = 0
|
||||
# d["var_9"] = 0
|
||||
if scanname in ("verticallinescan", "vlinescan"):
|
||||
d["scan_command"] = AbrCmd.VERTICAL_LINE_SCAN
|
||||
d["var_1"] = scan_args["range"] / scan_args["steps"]
|
||||
d["var_2"] = scan_args["steps"]
|
||||
d["var_3"] = scan_args["exp_time"]
|
||||
d["var_4"] = 0
|
||||
d["var_5"] = 0
|
||||
d["var_6"] = 0
|
||||
d["var_7"] = 0
|
||||
# d["var_8"] = 0
|
||||
# d["var_9"] = 0
|
||||
if scanname in ("screeningscan"):
|
||||
d["scan_command"] = AbrCmd.SCREENING
|
||||
d["var_1"] = scan_args["start"]
|
||||
d["var_2"] = scan_args["oscrange"]
|
||||
d["var_3"] = scan_args["exp_time"]
|
||||
d["var_4"] = scan_args["range"] / scan_args["steps"]
|
||||
d["var_5"] = scan_args["steps"]
|
||||
d["var_6"] = scan_args.get("delta", 0.5)
|
||||
d["var_7"] = 0
|
||||
# d["var_8"] = 0
|
||||
# d["var_9"] = 0
|
||||
if scanname in ("rasterscan", "rastersimplescan"):
|
||||
d["scan_command"] = AbrCmd.RASTER_SCAN_SIMPLE
|
||||
d["var_1"] = scan_args["exp_time"]
|
||||
d["var_2"] = scan_args["range_x"] / scan_args["steps_x"]
|
||||
d["var_3"] = scan_args["range_y"] / scan_args["steps_y"]
|
||||
d["var_4"] = scan_args["steps_x"]
|
||||
d["var_5"] = scan_args["steps_y"]
|
||||
d["var_6"] = 0
|
||||
d["var_7"] = 0
|
||||
# d["var_8"] = 0
|
||||
# d["var_9"] = 0
|
||||
|
||||
# Reconfigure if got a valid scan config
|
||||
if len(d) > 0:
|
||||
self.configure(d)
|
||||
|
||||
# Stage the ABR stage
|
||||
self.arm()
|
||||
|
||||
def on_unstage(self):
|
||||
"""Unstage the ABR controller"""
|
||||
self.disarm()
|
||||
|
||||
def configure(self, d: dict) -> tuple:
|
||||
""" " Configure the exposure scripts
|
||||
|
||||
@@ -284,14 +304,14 @@ class AerotechAbrStage(BECDeviceBase):
|
||||
new = self.read_configuration()
|
||||
return old, new
|
||||
|
||||
def bluestage(self):
|
||||
def arm(self):
|
||||
"""Bluesky-style stage
|
||||
|
||||
Since configuration synchronization is not guaranteed, this does
|
||||
nothing. The script launched by kickoff().
|
||||
"""
|
||||
|
||||
def bluekickoff(self, timeout=1) -> SubscriptionStatus:
|
||||
def on_kickoff(self, timeout=1) -> SubscriptionStatus:
|
||||
"""Kick off the set program"""
|
||||
self.start_command.set(1).wait()
|
||||
|
||||
@@ -304,7 +324,7 @@ class AerotechAbrStage(BECDeviceBase):
|
||||
status.wait()
|
||||
# return status
|
||||
|
||||
def blueunstage(self, settle_time=0.1):
|
||||
def disarm(self, settle_time=0.1):
|
||||
"""Stops current script and releases the axes"""
|
||||
# Disarm commands
|
||||
self.scan_command.set(AbrCmd.NONE, settle_time=settle_time).wait()
|
||||
|
||||
Reference in New Issue
Block a user