Flaking
This commit is contained in:
parent
1b328d31de
commit
1dda0e04ba
@ -8,38 +8,72 @@ import time
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
from .AerotechAutomation1Enums import *
|
from .AerotechAutomation1Enums import *
|
||||||
from .AerotechAutomation1Enums import (DataCollectionMode, DataCollectionFrequency,
|
from .AerotechAutomation1Enums import (
|
||||||
AxisDataSignal, PsoWindowInput, DriveDataCaptureInput, DriveDataCaptureTrigger,
|
DataCollectionMode,
|
||||||
TaskDataSignal, SystemDataSignal, TomcatSequencerState)
|
DataCollectionFrequency,
|
||||||
|
AxisDataSignal,
|
||||||
|
PsoWindowInput,
|
||||||
|
DriveDataCaptureInput,
|
||||||
|
DriveDataCaptureTrigger,
|
||||||
|
TaskDataSignal,
|
||||||
|
SystemDataSignal,
|
||||||
|
TomcatSequencerState,
|
||||||
|
)
|
||||||
except:
|
except:
|
||||||
from AerotechAutomation1Enums import *
|
from AerotechAutomation1Enums import *
|
||||||
from AerotechAutomation1Enums import (DataCollectionMode, DataCollectionFrequency,
|
from AerotechAutomation1Enums import (
|
||||||
AxisDataSignal, PsoWindowInput, DriveDataCaptureInput, DriveDataCaptureTrigger,
|
DataCollectionMode,
|
||||||
TaskDataSignal, SystemDataSignal, TomcatSequencerState)
|
DataCollectionFrequency,
|
||||||
|
AxisDataSignal,
|
||||||
|
PsoWindowInput,
|
||||||
|
DriveDataCaptureInput,
|
||||||
|
DriveDataCaptureTrigger,
|
||||||
|
TaskDataSignal,
|
||||||
|
SystemDataSignal,
|
||||||
|
TomcatSequencerState,
|
||||||
|
)
|
||||||
|
|
||||||
from typing import Union
|
from typing import Union
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class EpicsMotorX(EpicsMotor):
|
class EpicsMotorX(EpicsMotor):
|
||||||
""" Special motor class that provides flyer interface and progress bar.
|
""" Special motor class that provides flyer interface and progress bar.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
SUB_PROGRESS = "progress"
|
SUB_PROGRESS = "progress"
|
||||||
|
|
||||||
def __init__(self, prefix="", *, name, kind=None, read_attrs=None, configuration_attrs=None, parent=None, **kwargs):
|
def __init__(
|
||||||
super().__init__(prefix=prefix, name=name, kind=kind, read_attrs=read_attrs, configuration_attrs=configuration_attrs, parent=parent, **kwargs)
|
self,
|
||||||
|
prefix="",
|
||||||
|
*,
|
||||||
|
name,
|
||||||
|
kind=None,
|
||||||
|
read_attrs=None,
|
||||||
|
configuration_attrs=None,
|
||||||
|
parent=None,
|
||||||
|
**kwargs,
|
||||||
|
):
|
||||||
|
super().__init__(
|
||||||
|
prefix=prefix,
|
||||||
|
name=name,
|
||||||
|
kind=kind,
|
||||||
|
read_attrs=read_attrs,
|
||||||
|
configuration_attrs=configuration_attrs,
|
||||||
|
parent=parent,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
self._startPosition = None
|
self._startPosition = None
|
||||||
self._targetPosition = None
|
self._targetPosition = None
|
||||||
self.subscribe(self._progress_update, run=False)
|
self.subscribe(self._progress_update, run=False)
|
||||||
|
|
||||||
def configure(self, d: dict):
|
def configure(self, d: dict):
|
||||||
if "target" in d:
|
if "target" in d:
|
||||||
self._targetPosition = d['target']
|
self._targetPosition = d["target"]
|
||||||
del d['target']
|
del d["target"]
|
||||||
if "position" in d:
|
if "position" in d:
|
||||||
self._targetPosition = d['position']
|
self._targetPosition = d["position"]
|
||||||
del d['position']
|
del d["position"]
|
||||||
return super().configure(d)
|
return super().configure(d)
|
||||||
|
|
||||||
def kickoff(self):
|
def kickoff(self):
|
||||||
@ -53,19 +87,27 @@ class EpicsMotorX(EpicsMotor):
|
|||||||
def _progress_update(self, value, **kwargs) -> None:
|
def _progress_update(self, value, **kwargs) -> None:
|
||||||
"""Progress update on the scan"""
|
"""Progress update on the scan"""
|
||||||
if (self._startPosition is None) or (self._targetPosition is None) or (not self.moving):
|
if (self._startPosition is None) or (self._targetPosition is None) or (not self.moving):
|
||||||
self._run_subs( sub_type=self.SUB_PROGRESS, value=1, max_value=1, done=1, )
|
self._run_subs(
|
||||||
|
sub_type=self.SUB_PROGRESS, value=1, max_value=1, done=1,
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
progress = np.abs( (value-self._startPosition)/(self._targetPosition-self._startPosition) )
|
progress = np.abs(
|
||||||
|
(value - self._startPosition) / (self._targetPosition - self._startPosition)
|
||||||
|
)
|
||||||
max_value = 100
|
max_value = 100
|
||||||
self._run_subs(
|
self._run_subs(
|
||||||
sub_type=self.SUB_PROGRESS,
|
sub_type=self.SUB_PROGRESS,
|
||||||
value=int(100*progress), max_value=max_value, done=int(np.isclose(max_value, progress, 1e-3)), )
|
value=int(100 * progress),
|
||||||
|
max_value=max_value,
|
||||||
|
done=int(np.isclose(max_value, progress, 1e-3)),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class EpicsPassiveRO(EpicsSignalRO):
|
class EpicsPassiveRO(EpicsSignalRO):
|
||||||
""" Small helper class to read PVs that need to be processed first.
|
""" Small helper class to read PVs that need to be processed first.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, read_pv, *, string=False, name=None, **kwargs):
|
def __init__(self, read_pv, *, string=False, name=None, **kwargs):
|
||||||
super().__init__(read_pv, string=string, name=name, **kwargs)
|
super().__init__(read_pv, string=string, name=name, **kwargs)
|
||||||
self._proc = EpicsSignal(read_pv + ".PROC", kind=Kind.omitted, put_complete=True)
|
self._proc = EpicsSignal(read_pv + ".PROC", kind=Kind.omitted, put_complete=True)
|
||||||
@ -83,10 +125,9 @@ class EpicsPassiveRO(EpicsSignalRO):
|
|||||||
return super().value
|
return super().value
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class aa1Controller(Device):
|
class aa1Controller(Device):
|
||||||
"""Ophyd proxy class for the Aerotech Automation 1's core controller functionality"""
|
"""Ophyd proxy class for the Aerotech Automation 1's core controller functionality"""
|
||||||
|
|
||||||
controllername = Component(EpicsSignalRO, "NAME", kind=Kind.config)
|
controllername = Component(EpicsSignalRO, "NAME", kind=Kind.config)
|
||||||
serialnumber = Component(EpicsSignalRO, "SN", kind=Kind.config)
|
serialnumber = Component(EpicsSignalRO, "SN", kind=Kind.config)
|
||||||
apiversion = Component(EpicsSignalRO, "API_VERSION", kind=Kind.config)
|
apiversion = Component(EpicsSignalRO, "API_VERSION", kind=Kind.config)
|
||||||
@ -94,8 +135,28 @@ class aa1Controller(Device):
|
|||||||
taskcount = Component(EpicsSignalRO, "TASKCOUNT", kind=Kind.config)
|
taskcount = Component(EpicsSignalRO, "TASKCOUNT", kind=Kind.config)
|
||||||
fastpoll = Component(EpicsSignalRO, "POLLTIME", auto_monitor=True, kind=Kind.hinted)
|
fastpoll = Component(EpicsSignalRO, "POLLTIME", auto_monitor=True, kind=Kind.hinted)
|
||||||
slowpoll = Component(EpicsSignalRO, "DRVPOLLTIME", auto_monitor=True, kind=Kind.hinted)
|
slowpoll = Component(EpicsSignalRO, "DRVPOLLTIME", auto_monitor=True, kind=Kind.hinted)
|
||||||
def __init__(self, prefix="", *, name, kind=None, read_attrs=None, configuration_attrs=None, parent=None, **kwargs):
|
|
||||||
super().__init__(prefix=prefix, name=name, kind=kind, read_attrs=read_attrs, configuration_attrs=configuration_attrs, parent=parent, **kwargs)
|
def __init__(
|
||||||
|
self,
|
||||||
|
prefix="",
|
||||||
|
*,
|
||||||
|
name,
|
||||||
|
kind=None,
|
||||||
|
read_attrs=None,
|
||||||
|
configuration_attrs=None,
|
||||||
|
parent=None,
|
||||||
|
**kwargs,
|
||||||
|
):
|
||||||
|
super().__init__(
|
||||||
|
prefix=prefix,
|
||||||
|
name=name,
|
||||||
|
kind=kind,
|
||||||
|
read_attrs=read_attrs,
|
||||||
|
configuration_attrs=configuration_attrs,
|
||||||
|
parent=parent,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class aa1Tasks(Device):
|
class aa1Tasks(Device):
|
||||||
""" Task management API
|
""" Task management API
|
||||||
@ -127,6 +188,7 @@ class aa1Tasks(Device):
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
SUB_PROGRESS = "progress"
|
SUB_PROGRESS = "progress"
|
||||||
_failure = Component(EpicsSignalRO, "FAILURE", auto_monitor=True, kind=Kind.hinted)
|
_failure = Component(EpicsSignalRO, "FAILURE", auto_monitor=True, kind=Kind.hinted)
|
||||||
errStatus = Component(EpicsSignalRO, "ERRW", auto_monitor=True, kind=Kind.hinted)
|
errStatus = Component(EpicsSignalRO, "ERRW", auto_monitor=True, kind=Kind.hinted)
|
||||||
@ -140,11 +202,31 @@ class aa1Tasks(Device):
|
|||||||
|
|
||||||
fileName = Component(EpicsSignal, "FILENAME", string=True, kind=Kind.omitted, put_complete=True)
|
fileName = Component(EpicsSignal, "FILENAME", string=True, kind=Kind.omitted, put_complete=True)
|
||||||
_fileRead = Component(EpicsPassiveRO, "FILEREAD", string=True, kind=Kind.omitted)
|
_fileRead = Component(EpicsPassiveRO, "FILEREAD", string=True, kind=Kind.omitted)
|
||||||
_fileWrite = Component(EpicsSignal, "FILEWRITE", string=True, kind=Kind.omitted, put_complete=True)
|
_fileWrite = Component(
|
||||||
|
EpicsSignal, "FILEWRITE", string=True, kind=Kind.omitted, put_complete=True
|
||||||
|
)
|
||||||
|
|
||||||
def __init__(self, prefix="", *, name, kind=None, read_attrs=None, configuration_attrs=None, parent=None, **kwargs):
|
def __init__(
|
||||||
|
self,
|
||||||
|
prefix="",
|
||||||
|
*,
|
||||||
|
name,
|
||||||
|
kind=None,
|
||||||
|
read_attrs=None,
|
||||||
|
configuration_attrs=None,
|
||||||
|
parent=None,
|
||||||
|
**kwargs,
|
||||||
|
):
|
||||||
""" __init__ MUST have a full argument list"""
|
""" __init__ MUST have a full argument list"""
|
||||||
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._currentTask = None
|
self._currentTask = None
|
||||||
self._textToExecute = None
|
self._textToExecute = None
|
||||||
self._isConfigured = False
|
self._isConfigured = False
|
||||||
@ -154,7 +236,9 @@ class aa1Tasks(Device):
|
|||||||
def _progress_update(self, value, **kwargs) -> None:
|
def _progress_update(self, value, **kwargs) -> None:
|
||||||
"""Progress update on the scan"""
|
"""Progress update on the scan"""
|
||||||
value = self.progress()
|
value = self.progress()
|
||||||
self._run_subs( sub_type=self.SUB_PROGRESS, value=value, max_value=1, done=1, )
|
self._run_subs(
|
||||||
|
sub_type=self.SUB_PROGRESS, value=value, max_value=1, done=1,
|
||||||
|
)
|
||||||
|
|
||||||
def _progress(self) -> None:
|
def _progress(self) -> None:
|
||||||
"""Progress update on the scan"""
|
"""Progress update on the scan"""
|
||||||
@ -185,7 +269,7 @@ class aa1Tasks(Device):
|
|||||||
def runScript(self, filename: str, taskIndex: int == 2, filetext=None, settle_time=0.5) -> None:
|
def runScript(self, filename: str, taskIndex: int == 2, filetext=None, settle_time=0.5) -> None:
|
||||||
""" Run a script file that either exists, or is newly created and compiled"""
|
""" Run a script file that either exists, or is newly created and compiled"""
|
||||||
|
|
||||||
self.configure({'text': filetext, 'filename': filename, 'taskIndex': taskIndex})
|
self.configure({"text": filetext, "filename": filename, "taskIndex": taskIndex})
|
||||||
print("Runscript configured")
|
print("Runscript configured")
|
||||||
self.trigger().wait()
|
self.trigger().wait()
|
||||||
print("Runscript waited")
|
print("Runscript waited")
|
||||||
@ -194,7 +278,7 @@ class aa1Tasks(Device):
|
|||||||
""" Run a short text command on the Automation1 controller"""
|
""" Run a short text command on the Automation1 controller"""
|
||||||
|
|
||||||
print(f"Executing program on task: {taskIndex}")
|
print(f"Executing program on task: {taskIndex}")
|
||||||
self.configure({'text': text, 'taskIndex': taskIndex, 'mode': mode})
|
self.configure({"text": text, "taskIndex": taskIndex, "mode": mode})
|
||||||
self.kickoff().wait()
|
self.kickoff().wait()
|
||||||
|
|
||||||
if mode in [0, "None", None]:
|
if mode in [0, "None", None]:
|
||||||
@ -207,12 +291,12 @@ class aa1Tasks(Device):
|
|||||||
""" Configuration interface for flying
|
""" Configuration interface for flying
|
||||||
"""
|
"""
|
||||||
# Unrolling the configuration dict
|
# Unrolling the configuration dict
|
||||||
text = str(d['text']) if 'text' in d else None
|
text = str(d["text"]) if "text" in d else None
|
||||||
filename = str(d['filename']) if 'filename' in d else None
|
filename = str(d["filename"]) if "filename" in d else None
|
||||||
taskIndex = int(d['taskIndex']) if 'taskIndex' in d else 4
|
taskIndex = int(d["taskIndex"]) if "taskIndex" in d else 4
|
||||||
settle_time = float(d['settle_time']) if 'settle_time' in d else None
|
settle_time = float(d["settle_time"]) if "settle_time" in d else None
|
||||||
mode = d['mode'] if 'mode' in d else None
|
mode = d["mode"] if "mode" in d else None
|
||||||
self._isStepConfig = d['stepper'] if 'stepper' in d else False
|
self._isStepConfig = d["stepper"] if "stepper" in d else False
|
||||||
|
|
||||||
# Validation
|
# Validation
|
||||||
if taskIndex < 1 or taskIndex > 31:
|
if taskIndex < 1 or taskIndex > 31:
|
||||||
@ -302,6 +386,7 @@ class aa1Tasks(Device):
|
|||||||
print("Called aa1Task.complete()")
|
print("Called aa1Task.complete()")
|
||||||
timestamp_ = 0
|
timestamp_ = 0
|
||||||
taskIdx = int(self.taskIndex.get())
|
taskIdx = int(self.taskIndex.get())
|
||||||
|
|
||||||
def notRunning2(*args, old_value, value, timestamp, **kwargs):
|
def notRunning2(*args, old_value, value, timestamp, **kwargs):
|
||||||
nonlocal timestamp_
|
nonlocal timestamp_
|
||||||
result = False if value[taskIdx] in ["Running", 4] else True
|
result = False if value[taskIdx] in ["Running", 4] else True
|
||||||
@ -315,7 +400,14 @@ class aa1Tasks(Device):
|
|||||||
|
|
||||||
def describe_collect(self) -> OrderedDict:
|
def describe_collect(self) -> OrderedDict:
|
||||||
dd = OrderedDict()
|
dd = OrderedDict()
|
||||||
dd['success'] = {'source': "internal", 'dtype': 'integer', 'shape': [], 'units': '', 'lower_ctrl_limit': 0, 'upper_ctrl_limit': 0}
|
dd["success"] = {
|
||||||
|
"source": "internal",
|
||||||
|
"dtype": "integer",
|
||||||
|
"shape": [],
|
||||||
|
"units": "",
|
||||||
|
"lower_ctrl_limit": 0,
|
||||||
|
"upper_ctrl_limit": 0,
|
||||||
|
}
|
||||||
return {self.name: dd}
|
return {self.name: dd}
|
||||||
|
|
||||||
def collect(self) -> OrderedDict:
|
def collect(self) -> OrderedDict:
|
||||||
@ -331,6 +423,7 @@ class aa1TaskState(Device):
|
|||||||
This is the task state monitoring interface for Automation1 tasks. It
|
This is the task state monitoring interface for Automation1 tasks. It
|
||||||
does not launch execution, but can wait for the execution to complete.
|
does not launch execution, but can wait for the execution to complete.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
index = Component(EpicsSignalRO, "INDEX", kind=Kind.config)
|
index = Component(EpicsSignalRO, "INDEX", kind=Kind.config)
|
||||||
status = Component(EpicsSignalRO, "STATUS", auto_monitor=True, kind=Kind.hinted)
|
status = Component(EpicsSignalRO, "STATUS", auto_monitor=True, kind=Kind.hinted)
|
||||||
errorCode = Component(EpicsSignalRO, "ERROR", auto_monitor=True, kind=Kind.hinted)
|
errorCode = Component(EpicsSignalRO, "ERROR", auto_monitor=True, kind=Kind.hinted)
|
||||||
@ -341,6 +434,7 @@ class aa1TaskState(Device):
|
|||||||
print("Called aa1TaskState.complete()")
|
print("Called aa1TaskState.complete()")
|
||||||
# Define wait until the busy flag goes down (excluding initial update)
|
# Define wait until the busy flag goes down (excluding initial update)
|
||||||
timestamp_ = 0
|
timestamp_ = 0
|
||||||
|
|
||||||
def notRunning(*args, old_value, value, timestamp, **kwargs):
|
def notRunning(*args, old_value, value, timestamp, **kwargs):
|
||||||
nonlocal timestamp_
|
nonlocal timestamp_
|
||||||
result = False if (timestamp_ == 0) else (value not in ["Running", 4])
|
result = False if (timestamp_ == 0) else (value not in ["Running", 4])
|
||||||
@ -359,7 +453,14 @@ class aa1TaskState(Device):
|
|||||||
|
|
||||||
def describe_collect(self) -> OrderedDict:
|
def describe_collect(self) -> OrderedDict:
|
||||||
dd = OrderedDict()
|
dd = OrderedDict()
|
||||||
dd['success'] = {'source': "internal", 'dtype': 'integer', 'shape': [], 'units': '', 'lower_ctrl_limit': 0, 'upper_ctrl_limit': 0}
|
dd["success"] = {
|
||||||
|
"source": "internal",
|
||||||
|
"dtype": "integer",
|
||||||
|
"shape": [],
|
||||||
|
"units": "",
|
||||||
|
"lower_ctrl_limit": 0,
|
||||||
|
"upper_ctrl_limit": 0,
|
||||||
|
}
|
||||||
return dd
|
return dd
|
||||||
|
|
||||||
def collect(self) -> OrderedDict:
|
def collect(self) -> OrderedDict:
|
||||||
@ -381,6 +482,7 @@ class aa1DataAcquisition(Device):
|
|||||||
3. Start your data collection
|
3. Start your data collection
|
||||||
4. Read back the recorded data with "readback"
|
4. Read back the recorded data with "readback"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Status monitoring
|
# Status monitoring
|
||||||
status = Component(EpicsSignalRO, "RUNNING", auto_monitor=True, kind=Kind.hinted)
|
status = Component(EpicsSignalRO, "RUNNING", auto_monitor=True, kind=Kind.hinted)
|
||||||
points_max = Component(EpicsSignal, "MAXPOINTS", kind=Kind.config, put_complete=True)
|
points_max = Component(EpicsSignal, "MAXPOINTS", kind=Kind.config, put_complete=True)
|
||||||
@ -486,7 +588,6 @@ class aa1DataAcquisition(Device):
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class aa1GlobalVariables(Device):
|
class aa1GlobalVariables(Device):
|
||||||
""" Global variables
|
""" Global variables
|
||||||
|
|
||||||
@ -505,6 +606,7 @@ class aa1GlobalVariables(Device):
|
|||||||
ret_arr = var.readFloat(1000, 1024)
|
ret_arr = var.readFloat(1000, 1024)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Status monitoring
|
# Status monitoring
|
||||||
num_real = Component(EpicsSignalRO, "NUM-REAL_RBV", kind=Kind.config)
|
num_real = Component(EpicsSignalRO, "NUM-REAL_RBV", kind=Kind.config)
|
||||||
num_int = Component(EpicsSignalRO, "NUM-INT_RBV", kind=Kind.config)
|
num_int = Component(EpicsSignalRO, "NUM-INT_RBV", kind=Kind.config)
|
||||||
@ -559,7 +661,6 @@ class aa1GlobalVariables(Device):
|
|||||||
else:
|
else:
|
||||||
raise RuntimeError("Unsupported integer value type: {type(value)}")
|
raise RuntimeError("Unsupported integer value type: {type(value)}")
|
||||||
|
|
||||||
|
|
||||||
def readFloat(self, address: int, size: int = None) -> float:
|
def readFloat(self, address: int, size: int = None) -> float:
|
||||||
""" Read a 64-bit double global variable """
|
""" Read a 64-bit double global variable """
|
||||||
if address > self.num_real.get():
|
if address > self.num_real.get():
|
||||||
@ -613,7 +714,6 @@ class aa1GlobalVariables(Device):
|
|||||||
raise RuntimeError("Unsupported string value type: {type(value)}")
|
raise RuntimeError("Unsupported string value type: {type(value)}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class aa1GlobalVariableBindings(Device):
|
class aa1GlobalVariableBindings(Device):
|
||||||
""" Polled global variables
|
""" Polled global variables
|
||||||
|
|
||||||
@ -621,30 +721,124 @@ class aa1GlobalVariableBindings(Device):
|
|||||||
on the Automation1 controller. These variables are continuously polled
|
on the Automation1 controller. These variables are continuously polled
|
||||||
and are thus a convenient way to interface scripts with the outside word.
|
and are thus a convenient way to interface scripts with the outside word.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
int0 = Component(EpicsSignalRO, "INT0_RBV", auto_monitor=True, name="int0", kind=Kind.hinted)
|
int0 = Component(EpicsSignalRO, "INT0_RBV", auto_monitor=True, name="int0", kind=Kind.hinted)
|
||||||
int1 = Component(EpicsSignalRO, "INT1_RBV", auto_monitor=True, name="int1", kind=Kind.hinted)
|
int1 = Component(EpicsSignalRO, "INT1_RBV", auto_monitor=True, name="int1", kind=Kind.hinted)
|
||||||
int2 = Component(EpicsSignalRO, "INT2_RBV", auto_monitor=True, name="int2", kind=Kind.hinted)
|
int2 = Component(EpicsSignalRO, "INT2_RBV", auto_monitor=True, name="int2", kind=Kind.hinted)
|
||||||
int3 = Component(EpicsSignalRO, "INT3_RBV", auto_monitor=True, name="int3", kind=Kind.hinted)
|
int3 = Component(EpicsSignalRO, "INT3_RBV", auto_monitor=True, name="int3", kind=Kind.hinted)
|
||||||
int8 = Component(EpicsSignal, "INT8_RBV", put_complete=True, write_pv="INT8", auto_monitor=True, name="int8", kind=Kind.hinted)
|
int8 = Component(
|
||||||
int9 = Component(EpicsSignal, "INT9_RBV", put_complete=True, write_pv="INT9", auto_monitor=True, name="int9", kind=Kind.hinted)
|
EpicsSignal,
|
||||||
int10 = Component(EpicsSignal, "INT10_RBV", put_complete=True, write_pv="INT10", auto_monitor=True, name="int10", kind=Kind.hinted)
|
"INT8_RBV",
|
||||||
int11 = Component(EpicsSignal, "INT11_RBV", put_complete=True, write_pv="INT11", auto_monitor=True, name="int11", kind=Kind.hinted)
|
put_complete=True,
|
||||||
|
write_pv="INT8",
|
||||||
|
auto_monitor=True,
|
||||||
|
name="int8",
|
||||||
|
kind=Kind.hinted,
|
||||||
|
)
|
||||||
|
int9 = Component(
|
||||||
|
EpicsSignal,
|
||||||
|
"INT9_RBV",
|
||||||
|
put_complete=True,
|
||||||
|
write_pv="INT9",
|
||||||
|
auto_monitor=True,
|
||||||
|
name="int9",
|
||||||
|
kind=Kind.hinted,
|
||||||
|
)
|
||||||
|
int10 = Component(
|
||||||
|
EpicsSignal,
|
||||||
|
"INT10_RBV",
|
||||||
|
put_complete=True,
|
||||||
|
write_pv="INT10",
|
||||||
|
auto_monitor=True,
|
||||||
|
name="int10",
|
||||||
|
kind=Kind.hinted,
|
||||||
|
)
|
||||||
|
int11 = Component(
|
||||||
|
EpicsSignal,
|
||||||
|
"INT11_RBV",
|
||||||
|
put_complete=True,
|
||||||
|
write_pv="INT11",
|
||||||
|
auto_monitor=True,
|
||||||
|
name="int11",
|
||||||
|
kind=Kind.hinted,
|
||||||
|
)
|
||||||
|
|
||||||
float0 = Component(EpicsSignalRO, "REAL0_RBV", auto_monitor=True, name="float0", kind=Kind.hinted)
|
float0 = Component(
|
||||||
float1 = Component(EpicsSignalRO, "REAL1_RBV", auto_monitor=True, name="float1", kind=Kind.hinted)
|
EpicsSignalRO, "REAL0_RBV", auto_monitor=True, name="float0", kind=Kind.hinted
|
||||||
float2 = Component(EpicsSignalRO, "REAL2_RBV", auto_monitor=True, name="float2", kind=Kind.hinted)
|
)
|
||||||
float3 = Component(EpicsSignalRO, "REAL3_RBV", auto_monitor=True, name="float3", kind=Kind.hinted)
|
float1 = Component(
|
||||||
float16 = Component(EpicsSignal, "REAL16_RBV", write_pv="REAL16", put_complete=True, auto_monitor=True, name="float16", kind=Kind.hinted)
|
EpicsSignalRO, "REAL1_RBV", auto_monitor=True, name="float1", kind=Kind.hinted
|
||||||
float17 = Component(EpicsSignal, "REAL17_RBV", write_pv="REAL17", put_complete=True, auto_monitor=True, name="float17", kind=Kind.hinted)
|
)
|
||||||
float18 = Component(EpicsSignal, "REAL18_RBV", write_pv="REAL18", put_complete=True, auto_monitor=True, name="float18", kind=Kind.hinted)
|
float2 = Component(
|
||||||
float19 = Component(EpicsSignal, "REAL19_RBV", write_pv="REAL19", put_complete=True, auto_monitor=True, name="float19", kind=Kind.hinted)
|
EpicsSignalRO, "REAL2_RBV", auto_monitor=True, name="float2", kind=Kind.hinted
|
||||||
|
)
|
||||||
|
float3 = Component(
|
||||||
|
EpicsSignalRO, "REAL3_RBV", auto_monitor=True, name="float3", kind=Kind.hinted
|
||||||
|
)
|
||||||
|
float16 = Component(
|
||||||
|
EpicsSignal,
|
||||||
|
"REAL16_RBV",
|
||||||
|
write_pv="REAL16",
|
||||||
|
put_complete=True,
|
||||||
|
auto_monitor=True,
|
||||||
|
name="float16",
|
||||||
|
kind=Kind.hinted,
|
||||||
|
)
|
||||||
|
float17 = Component(
|
||||||
|
EpicsSignal,
|
||||||
|
"REAL17_RBV",
|
||||||
|
write_pv="REAL17",
|
||||||
|
put_complete=True,
|
||||||
|
auto_monitor=True,
|
||||||
|
name="float17",
|
||||||
|
kind=Kind.hinted,
|
||||||
|
)
|
||||||
|
float18 = Component(
|
||||||
|
EpicsSignal,
|
||||||
|
"REAL18_RBV",
|
||||||
|
write_pv="REAL18",
|
||||||
|
put_complete=True,
|
||||||
|
auto_monitor=True,
|
||||||
|
name="float18",
|
||||||
|
kind=Kind.hinted,
|
||||||
|
)
|
||||||
|
float19 = Component(
|
||||||
|
EpicsSignal,
|
||||||
|
"REAL19_RBV",
|
||||||
|
write_pv="REAL19",
|
||||||
|
put_complete=True,
|
||||||
|
auto_monitor=True,
|
||||||
|
name="float19",
|
||||||
|
kind=Kind.hinted,
|
||||||
|
)
|
||||||
|
|
||||||
# BEC LiveTable crashes on non-numeric values
|
# BEC LiveTable crashes on non-numeric values
|
||||||
str0 = Component(EpicsSignalRO, "STR0_RBV", auto_monitor=True, string=True, name="str0", kind=Kind.config)
|
str0 = Component(
|
||||||
str1 = Component(EpicsSignalRO, "STR1_RBV", auto_monitor=True, string=True, name="str1", kind=Kind.config)
|
EpicsSignalRO, "STR0_RBV", auto_monitor=True, string=True, name="str0", kind=Kind.config
|
||||||
str4 = Component(EpicsSignal, "STR4_RBV", put_complete=True, string=True, auto_monitor=True, write_pv="STR4", name="str4", kind=Kind.config)
|
)
|
||||||
str5 = Component(EpicsSignal, "STR5_RBV", put_complete=True, string=True, auto_monitor=True, write_pv="STR5", name="str5", kind=Kind.config)
|
str1 = Component(
|
||||||
|
EpicsSignalRO, "STR1_RBV", auto_monitor=True, string=True, name="str1", kind=Kind.config
|
||||||
|
)
|
||||||
|
str4 = Component(
|
||||||
|
EpicsSignal,
|
||||||
|
"STR4_RBV",
|
||||||
|
put_complete=True,
|
||||||
|
string=True,
|
||||||
|
auto_monitor=True,
|
||||||
|
write_pv="STR4",
|
||||||
|
name="str4",
|
||||||
|
kind=Kind.config,
|
||||||
|
)
|
||||||
|
str5 = Component(
|
||||||
|
EpicsSignal,
|
||||||
|
"STR5_RBV",
|
||||||
|
put_complete=True,
|
||||||
|
string=True,
|
||||||
|
auto_monitor=True,
|
||||||
|
write_pv="STR5",
|
||||||
|
name="str5",
|
||||||
|
kind=Kind.config,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class aa1AxisIo(Device):
|
class aa1AxisIo(Device):
|
||||||
@ -655,6 +849,7 @@ class aa1AxisIo(Device):
|
|||||||
should be done in AeroScript. Only one pin can be writen directly but
|
should be done in AeroScript. Only one pin can be writen directly but
|
||||||
several can be polled!
|
several can be polled!
|
||||||
"""
|
"""
|
||||||
|
|
||||||
polllvl = Component(EpicsSignal, "POLLLVL", put_complete=True, kind=Kind.config)
|
polllvl = Component(EpicsSignal, "POLLLVL", put_complete=True, kind=Kind.config)
|
||||||
ai0 = Component(EpicsSignalRO, "AI0-RBV", auto_monitor=True, kind=Kind.hinted)
|
ai0 = Component(EpicsSignalRO, "AI0-RBV", auto_monitor=True, kind=Kind.hinted)
|
||||||
ai1 = Component(EpicsSignalRO, "AI1-RBV", auto_monitor=True, kind=Kind.hinted)
|
ai1 = Component(EpicsSignalRO, "AI1-RBV", auto_monitor=True, kind=Kind.hinted)
|
||||||
@ -692,7 +887,6 @@ class aa1AxisIo(Device):
|
|||||||
self.do.set(value, settle_time=settle_time).wait()
|
self.do.set(value, settle_time=settle_time).wait()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class aa1AxisPsoBase(Device):
|
class aa1AxisPsoBase(Device):
|
||||||
""" Position Sensitive Output - Base class
|
""" Position Sensitive Output - Base class
|
||||||
|
|
||||||
@ -708,6 +902,7 @@ class aa1AxisPsoBase(Device):
|
|||||||
|
|
||||||
Specific operation modes should be implemented in child classes.
|
Specific operation modes should be implemented in child classes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# ########################################################################
|
# ########################################################################
|
||||||
# General module status
|
# General module status
|
||||||
status = Component(EpicsSignalRO, "STATUS", auto_monitor=True, kind=Kind.hinted)
|
status = Component(EpicsSignalRO, "STATUS", auto_monitor=True, kind=Kind.hinted)
|
||||||
@ -722,7 +917,9 @@ class aa1AxisPsoBase(Device):
|
|||||||
dstCounterEna = Component(EpicsSignal, "DIST:COUNTER", put_complete=True, kind=Kind.omitted)
|
dstCounterEna = Component(EpicsSignal, "DIST:COUNTER", put_complete=True, kind=Kind.omitted)
|
||||||
dstCounterVal = Component(EpicsSignalRO, "DIST:CTR0_RBV", auto_monitor=True, kind=Kind.hinted)
|
dstCounterVal = Component(EpicsSignalRO, "DIST:CTR0_RBV", auto_monitor=True, kind=Kind.hinted)
|
||||||
dstArrayIdx = Component(EpicsSignalRO, "DIST:IDX_RBV", auto_monitor=True, kind=Kind.hinted)
|
dstArrayIdx = Component(EpicsSignalRO, "DIST:IDX_RBV", auto_monitor=True, kind=Kind.hinted)
|
||||||
dstArrayDepleted = Component(EpicsSignalRO, "DIST:ARRAY-DEPLETED-RBV", auto_monitor=True, kind=Kind.hinted)
|
dstArrayDepleted = Component(
|
||||||
|
EpicsSignalRO, "DIST:ARRAY-DEPLETED-RBV", auto_monitor=True, kind=Kind.hinted
|
||||||
|
)
|
||||||
|
|
||||||
dstDirection = Component(EpicsSignal, "DIST:EVENTDIR", put_complete=True, kind=Kind.omitted)
|
dstDirection = Component(EpicsSignal, "DIST:EVENTDIR", put_complete=True, kind=Kind.omitted)
|
||||||
dstDistance = Component(EpicsSignal, "DIST:DISTANCE", put_complete=True, kind=Kind.hinted)
|
dstDistance = Component(EpicsSignal, "DIST:DISTANCE", put_complete=True, kind=Kind.hinted)
|
||||||
@ -767,9 +964,6 @@ class aa1AxisPsoBase(Device):
|
|||||||
self.waveMode.set(orig_waveMode).wait()
|
self.waveMode.set(orig_waveMode).wait()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class aa1AxisPsoDistance(aa1AxisPsoBase):
|
class aa1AxisPsoDistance(aa1AxisPsoBase):
|
||||||
""" Position Sensitive Output - Distance mode
|
""" Position Sensitive Output - Distance mode
|
||||||
|
|
||||||
@ -802,11 +996,30 @@ class aa1AxisPsoDistance(aa1AxisPsoBase):
|
|||||||
pso.configure(d={'distance': 1.8, 'wmode': "pulsed", 'n_pulse': 5})
|
pso.configure(d={'distance': 1.8, 'wmode': "pulsed", 'n_pulse': 5})
|
||||||
pso.kickoff().wait()
|
pso.kickoff().wait()
|
||||||
"""
|
"""
|
||||||
|
|
||||||
SUB_PROGRESS = "progress"
|
SUB_PROGRESS = "progress"
|
||||||
|
|
||||||
def __init__(self, prefix="", *, name, kind=None, read_attrs=None, configuration_attrs=None, parent=None, **kwargs):
|
def __init__(
|
||||||
|
self,
|
||||||
|
prefix="",
|
||||||
|
*,
|
||||||
|
name,
|
||||||
|
kind=None,
|
||||||
|
read_attrs=None,
|
||||||
|
configuration_attrs=None,
|
||||||
|
parent=None,
|
||||||
|
**kwargs,
|
||||||
|
):
|
||||||
""" __init__ MUST have a full argument list"""
|
""" __init__ MUST have a full argument list"""
|
||||||
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._Vdistance = 3.141592
|
self._Vdistance = 3.141592
|
||||||
self.subscribe(self._progress_update, "progress", run=False)
|
self.subscribe(self._progress_update, "progress", run=False)
|
||||||
|
|
||||||
@ -814,7 +1027,9 @@ class aa1AxisPsoDistance(aa1AxisPsoBase):
|
|||||||
"""Progress update on the scan"""
|
"""Progress update on the scan"""
|
||||||
if self.dstArrayDepleted.value:
|
if self.dstArrayDepleted.value:
|
||||||
print("PSO array depleted")
|
print("PSO array depleted")
|
||||||
self._run_subs( sub_type=self.SUB_PROGRESS, value=1, max_value=1, done=1, )
|
self._run_subs(
|
||||||
|
sub_type=self.SUB_PROGRESS, value=1, max_value=1, done=1,
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
progress = 1
|
progress = 1
|
||||||
@ -822,7 +1037,10 @@ class aa1AxisPsoDistance(aa1AxisPsoBase):
|
|||||||
print(f"PSO array proggress: {progress}")
|
print(f"PSO array proggress: {progress}")
|
||||||
self._run_subs(
|
self._run_subs(
|
||||||
sub_type=self.SUB_PROGRESS,
|
sub_type=self.SUB_PROGRESS,
|
||||||
value=int(progress), max_value=max_value, done=int(np.isclose(max_value, progress, 1e-3)), )
|
value=int(progress),
|
||||||
|
max_value=max_value,
|
||||||
|
done=int(np.isclose(max_value, progress, 1e-3)),
|
||||||
|
)
|
||||||
|
|
||||||
# ########################################################################
|
# ########################################################################
|
||||||
# PSO high level interface
|
# PSO high level interface
|
||||||
@ -833,12 +1051,11 @@ class aa1AxisPsoDistance(aa1AxisPsoBase):
|
|||||||
:param distance: The trigger distance or the array of distances between subsequent points.
|
:param distance: The trigger distance or the array of distances between subsequent points.
|
||||||
:param wmode: Waveform mode configuration, usually pulsed/toggled.
|
:param wmode: Waveform mode configuration, usually pulsed/toggled.
|
||||||
"""
|
"""
|
||||||
distance = d['distance']
|
distance = d["distance"]
|
||||||
wmode = str(d['wmode'])
|
wmode = str(d["wmode"])
|
||||||
t_pulse = float(d['t_pulse']) if 't_pulse' in d else 100
|
t_pulse = float(d["t_pulse"]) if "t_pulse" in d else 100
|
||||||
w_pulse = float(d['w_pulse']) if 'w_pulse' in d else 200
|
w_pulse = float(d["w_pulse"]) if "w_pulse" in d else 200
|
||||||
n_pulse = float(d['n_pulse']) if 'n_pulse' in d else 1
|
n_pulse = float(d["n_pulse"]) if "n_pulse" in d else 1
|
||||||
|
|
||||||
|
|
||||||
# Validate input parameters
|
# Validate input parameters
|
||||||
if wmode not in ["pulse", "pulsed", "toggle", "toggled"]:
|
if wmode not in ["pulse", "pulsed", "toggle", "toggled"]:
|
||||||
@ -908,11 +1125,14 @@ class aa1AxisPsoDistance(aa1AxisPsoBase):
|
|||||||
self.dstEventsEna.set("Off").wait()
|
self.dstEventsEna.set("Off").wait()
|
||||||
self.dstCounterEna.set("Off").wait()
|
self.dstCounterEna.set("Off").wait()
|
||||||
return super().unstage()
|
return super().unstage()
|
||||||
|
|
||||||
# ########################################################################
|
# ########################################################################
|
||||||
# Bluesky flyer interface
|
# Bluesky flyer interface
|
||||||
def kickoff(self) -> DeviceStatus:
|
def kickoff(self) -> DeviceStatus:
|
||||||
# Rearm the configured array
|
# Rearm the configured array
|
||||||
if hasattr(self, "_distanceValue") and isinstance(self._distanceValue, (np.ndarray, list, tuple)):
|
if hasattr(self, "_distanceValue") and isinstance(
|
||||||
|
self._distanceValue, (np.ndarray, list, tuple)
|
||||||
|
):
|
||||||
self.dstArrayRearm.set(1).wait()
|
self.dstArrayRearm.set(1).wait()
|
||||||
# Start monitoring the counters
|
# Start monitoring the counters
|
||||||
self.dstEventsEna.set("On").wait()
|
self.dstEventsEna.set("On").wait()
|
||||||
@ -925,9 +1145,12 @@ class aa1AxisPsoDistance(aa1AxisPsoBase):
|
|||||||
def complete(self) -> DeviceStatus:
|
def complete(self) -> DeviceStatus:
|
||||||
""" Bluesky flyer interface"""
|
""" Bluesky flyer interface"""
|
||||||
# Array mode waits until the buffer is empty
|
# Array mode waits until the buffer is empty
|
||||||
if hasattr(self, "_distanceValue") and isinstance(self._distanceValue, (np.ndarray, list, tuple)):
|
if hasattr(self, "_distanceValue") and isinstance(
|
||||||
|
self._distanceValue, (np.ndarray, list, tuple)
|
||||||
|
):
|
||||||
# Define wait until the busy flag goes down (excluding initial update)
|
# Define wait until the busy flag goes down (excluding initial update)
|
||||||
timestamp_ = 0
|
timestamp_ = 0
|
||||||
|
|
||||||
def notRunning(*args, old_value, value, timestamp, **kwargs):
|
def notRunning(*args, old_value, value, timestamp, **kwargs):
|
||||||
nonlocal timestamp_
|
nonlocal timestamp_
|
||||||
result = False if (timestamp_ == 0) else bool(int(value) & 0x1000)
|
result = False if (timestamp_ == 0) else bool(int(value) & 0x1000)
|
||||||
@ -948,7 +1171,14 @@ class aa1AxisPsoDistance(aa1AxisPsoBase):
|
|||||||
|
|
||||||
def describe_collect(self) -> OrderedDict:
|
def describe_collect(self) -> OrderedDict:
|
||||||
ret = OrderedDict()
|
ret = OrderedDict()
|
||||||
ret['index'] = {'source': "internal", 'dtype': 'integer', 'shape': [], 'units': '', 'lower_ctrl_limit': 0, 'upper_ctrl_limit': 0}
|
ret["index"] = {
|
||||||
|
"source": "internal",
|
||||||
|
"dtype": "integer",
|
||||||
|
"shape": [],
|
||||||
|
"units": "",
|
||||||
|
"lower_ctrl_limit": 0,
|
||||||
|
"upper_ctrl_limit": 0,
|
||||||
|
}
|
||||||
return {self.name: ret}
|
return {self.name: ret}
|
||||||
|
|
||||||
def collect(self) -> OrderedDict:
|
def collect(self) -> OrderedDict:
|
||||||
@ -958,8 +1188,6 @@ class aa1AxisPsoDistance(aa1AxisPsoBase):
|
|||||||
yield ret
|
yield ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class aa1AxisPsoWindow(aa1AxisPsoBase):
|
class aa1AxisPsoWindow(aa1AxisPsoBase):
|
||||||
""" Position Sensitive Output - Window mode
|
""" Position Sensitive Output - Window mode
|
||||||
|
|
||||||
@ -979,9 +1207,28 @@ class aa1AxisPsoWindow(aa1AxisPsoBase):
|
|||||||
For a more detailed description of additional signals and masking plase
|
For a more detailed description of additional signals and masking plase
|
||||||
refer to Automation1's online manual.
|
refer to Automation1's online manual.
|
||||||
"""
|
"""
|
||||||
def __init__(self, prefix="", *, name, kind=None, read_attrs=None, configuration_attrs=None, parent=None, **kwargs):
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
prefix="",
|
||||||
|
*,
|
||||||
|
name,
|
||||||
|
kind=None,
|
||||||
|
read_attrs=None,
|
||||||
|
configuration_attrs=None,
|
||||||
|
parent=None,
|
||||||
|
**kwargs,
|
||||||
|
):
|
||||||
""" __init__ MUST have a full argument list"""
|
""" __init__ MUST have a full argument list"""
|
||||||
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._mode = "output"
|
self._mode = "output"
|
||||||
self._eventMode = "Enter"
|
self._eventMode = "Enter"
|
||||||
|
|
||||||
@ -994,12 +1241,12 @@ class aa1AxisPsoWindow(aa1AxisPsoBase):
|
|||||||
:param distance: The trigger distance or the array of distances between subsequent points.
|
:param distance: The trigger distance or the array of distances between subsequent points.
|
||||||
:param wmode: Waveform mode configuration, usually output/pulsed/toggled.
|
:param wmode: Waveform mode configuration, usually output/pulsed/toggled.
|
||||||
"""
|
"""
|
||||||
bounds = d['distance']
|
bounds = d["distance"]
|
||||||
wmode = str(d['wmode'])
|
wmode = str(d["wmode"])
|
||||||
emode = str(d['emode'])
|
emode = str(d["emode"])
|
||||||
t_pulse = float(d['t_pulse']) if 't_pulse' in d else None
|
t_pulse = float(d["t_pulse"]) if "t_pulse" in d else None
|
||||||
w_pulse = float(d['w_pulse']) if 'w_pulse' in d else None
|
w_pulse = float(d["w_pulse"]) if "w_pulse" in d else None
|
||||||
n_pulse = float(d['n_pulse']) if 'n_pulse' in d else None
|
n_pulse = float(d["n_pulse"]) if "n_pulse" in d else None
|
||||||
|
|
||||||
# Validate input parameters
|
# Validate input parameters
|
||||||
if wmode not in ["pulse", "pulsed", "toggle", "toggled", "output", "flag"]:
|
if wmode not in ["pulse", "pulsed", "toggle", "toggled", "output", "flag"]:
|
||||||
@ -1080,11 +1327,6 @@ class aa1AxisPsoWindow(aa1AxisPsoBase):
|
|||||||
return super().unstage()
|
return super().unstage()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class aa1AxisDriveDataCollection(Device):
|
class aa1AxisDriveDataCollection(Device):
|
||||||
""" Axis data collection
|
""" Axis data collection
|
||||||
|
|
||||||
@ -1125,29 +1367,50 @@ class aa1AxisDriveDataCollection(Device):
|
|||||||
|
|
||||||
SUB_PROGRESS = "progress"
|
SUB_PROGRESS = "progress"
|
||||||
|
|
||||||
def __init__(self, prefix="", *, name, kind=None, read_attrs=None, configuration_attrs=None, parent=None, **kwargs):
|
def __init__(
|
||||||
super().__init__(prefix=prefix, name=name, kind=kind, read_attrs=read_attrs, configuration_attrs=configuration_attrs, parent=parent, **kwargs)
|
self,
|
||||||
|
prefix="",
|
||||||
|
*,
|
||||||
|
name,
|
||||||
|
kind=None,
|
||||||
|
read_attrs=None,
|
||||||
|
configuration_attrs=None,
|
||||||
|
parent=None,
|
||||||
|
**kwargs,
|
||||||
|
):
|
||||||
|
super().__init__(
|
||||||
|
prefix=prefix,
|
||||||
|
name=name,
|
||||||
|
kind=kind,
|
||||||
|
read_attrs=read_attrs,
|
||||||
|
configuration_attrs=configuration_attrs,
|
||||||
|
parent=parent,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
self.subscribe(self._progress_update, "progress", run=False)
|
self.subscribe(self._progress_update, "progress", run=False)
|
||||||
|
|
||||||
def _progress_update(self, value, **kwargs) -> None:
|
def _progress_update(self, value, **kwargs) -> None:
|
||||||
"""Progress update on the scan"""
|
"""Progress update on the scan"""
|
||||||
if self.state.value not in (2, "Acquiring"):
|
if self.state.value not in (2, "Acquiring"):
|
||||||
self._run_subs( sub_type=self.SUB_PROGRESS, value=1, max_value=1, done=1, )
|
self._run_subs(
|
||||||
|
sub_type=self.SUB_PROGRESS, value=1, max_value=1, done=1,
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
progress = 1
|
progress = 1
|
||||||
max_value = 1
|
max_value = 1
|
||||||
self._run_subs(
|
self._run_subs(
|
||||||
sub_type=self.SUB_PROGRESS,
|
sub_type=self.SUB_PROGRESS,
|
||||||
value=int(progress), max_value=max_value, done=int(np.isclose(max_value, progress, 1e-3)), )
|
value=int(progress),
|
||||||
|
max_value=max_value,
|
||||||
|
done=int(np.isclose(max_value, progress, 1e-3)),
|
||||||
|
)
|
||||||
|
|
||||||
def configure(self, d: dict = {}) -> tuple:
|
def configure(self, d: dict = {}) -> tuple:
|
||||||
npoints = int(d['npoints'])
|
npoints = int(d["npoints"])
|
||||||
trigger = int(d['trigger']) if 'trigger' in d else DriveDataCaptureTrigger.PsoOutput
|
trigger = int(d["trigger"]) if "trigger" in d else DriveDataCaptureTrigger.PsoOutput
|
||||||
source0 = int(d['source0']) if 'source0' in d else DriveDataCaptureInput.PrimaryFeedback
|
source0 = int(d["source0"]) if "source0" in d else DriveDataCaptureInput.PrimaryFeedback
|
||||||
source1 = int(d['source1']) if 'source1' in d else DriveDataCaptureInput.PositionCommand
|
source1 = int(d["source1"]) if "source1" in d else DriveDataCaptureInput.PositionCommand
|
||||||
|
|
||||||
old = self.read_configuration()
|
old = self.read_configuration()
|
||||||
|
|
||||||
@ -1194,6 +1457,7 @@ class aa1AxisDriveDataCollection(Device):
|
|||||||
|
|
||||||
# Define wait until the busy flag goes down (excluding initial update)
|
# Define wait until the busy flag goes down (excluding initial update)
|
||||||
timestamp_ = 0
|
timestamp_ = 0
|
||||||
|
|
||||||
def negEdge(*args, old_value, value, timestamp, **kwargs):
|
def negEdge(*args, old_value, value, timestamp, **kwargs):
|
||||||
nonlocal timestamp_
|
nonlocal timestamp_
|
||||||
result = False if (timestamp_ == 0) else (old_value == 1 and value == 0)
|
result = False if (timestamp_ == 0) else (old_value == 1 and value == 0)
|
||||||
@ -1212,11 +1476,24 @@ class aa1AxisDriveDataCollection(Device):
|
|||||||
status.wait()
|
status.wait()
|
||||||
return status
|
return status
|
||||||
|
|
||||||
|
|
||||||
def describe_collect(self) -> OrderedDict:
|
def describe_collect(self) -> OrderedDict:
|
||||||
ret = OrderedDict()
|
ret = OrderedDict()
|
||||||
ret['buffer0'] = {'source': "internal", 'dtype': 'array', 'shape': [], 'units': '', 'lower_ctrl_limit': 0, 'upper_ctrl_limit': 0}
|
ret["buffer0"] = {
|
||||||
ret['buffer1'] = {'source': "internal", 'dtype': 'array', 'shape': [], 'units': '', 'lower_ctrl_limit': 0, 'upper_ctrl_limit': 0}
|
"source": "internal",
|
||||||
|
"dtype": "array",
|
||||||
|
"shape": [],
|
||||||
|
"units": "",
|
||||||
|
"lower_ctrl_limit": 0,
|
||||||
|
"upper_ctrl_limit": 0,
|
||||||
|
}
|
||||||
|
ret["buffer1"] = {
|
||||||
|
"source": "internal",
|
||||||
|
"dtype": "array",
|
||||||
|
"shape": [],
|
||||||
|
"units": "",
|
||||||
|
"lower_ctrl_limit": 0,
|
||||||
|
"upper_ctrl_limit": 0,
|
||||||
|
}
|
||||||
return {self.name: ret}
|
return {self.name: ret}
|
||||||
|
|
||||||
def collect(self) -> OrderedDict:
|
def collect(self) -> OrderedDict:
|
||||||
@ -1232,9 +1509,6 @@ class aa1AxisDriveDataCollection(Device):
|
|||||||
yield ret
|
yield ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Automatically start simulation if directly invoked
|
# Automatically start simulation if directly invoked
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
AA1_IOC_NAME = "X02DA-ES1-SMP1"
|
AA1_IOC_NAME = "X02DA-ES1-SMP1"
|
||||||
@ -1250,6 +1524,3 @@ if __name__ == "__main__":
|
|||||||
globb.describe()
|
globb.describe()
|
||||||
mot = EpicsMotor(AA1_IOC_NAME + ":" + AA1_AXIS_NAME, name="x")
|
mot = EpicsMotor(AA1_IOC_NAME + ":" + AA1_AXIS_NAME, name="x")
|
||||||
mot.wait_for_connection()
|
mot.wait_for_connection()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -383,9 +383,6 @@ class TaskDataSignal:
|
|||||||
CommandQueueExecutedCount = 424
|
CommandQueueExecutedCount = 424
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SystemDataSignal:
|
class SystemDataSignal:
|
||||||
VirtualBinaryInput = 46
|
VirtualBinaryInput = 46
|
||||||
VirtualBinaryOutput = 47
|
VirtualBinaryOutput = 47
|
||||||
@ -442,7 +439,6 @@ class SystemDataSignal:
|
|||||||
ModbusServerEnabled = 439
|
ModbusServerEnabled = 439
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class DataCollectionFrequency:
|
class DataCollectionFrequency:
|
||||||
Undefined = 0
|
Undefined = 0
|
||||||
Fixed1kHz = 1
|
Fixed1kHz = 1
|
||||||
@ -482,11 +478,12 @@ class PsoWindowInput:
|
|||||||
XC4eSyncPortA = 137
|
XC4eSyncPortA = 137
|
||||||
XC4eSyncPortB = 138
|
XC4eSyncPortB = 138
|
||||||
XC4eDrivePulseStream = 139
|
XC4eDrivePulseStream = 139
|
||||||
XL5ePrimaryFeedback = 145,
|
XL5ePrimaryFeedback = (145,)
|
||||||
XL5eAuxiliaryFeedback = 146,
|
XL5eAuxiliaryFeedback = (146,)
|
||||||
XL5eSyncPortA = 147,
|
XL5eSyncPortA = (147,)
|
||||||
XL5eSyncPortB = 148,
|
XL5eSyncPortB = (148,)
|
||||||
XL5eDrivePulseStream = 149,
|
XL5eDrivePulseStream = (149,)
|
||||||
|
|
||||||
|
|
||||||
# @brief Specifies the PSO output pin settings for each drive.
|
# @brief Specifies the PSO output pin settings for each drive.
|
||||||
class XC4ePsoOutputPin:
|
class XC4ePsoOutputPin:
|
||||||
@ -494,6 +491,7 @@ class XC4ePsoOutputPin:
|
|||||||
AuxiliaryMarkerDifferential = 112
|
AuxiliaryMarkerDifferential = 112
|
||||||
AuxiliaryMarkerSingleEnded = 113
|
AuxiliaryMarkerSingleEnded = 113
|
||||||
|
|
||||||
|
|
||||||
class XC4PsoOutputPin:
|
class XC4PsoOutputPin:
|
||||||
DedicatedOutput = 108
|
DedicatedOutput = 108
|
||||||
AuxiliaryMarkerDifferential = 109
|
AuxiliaryMarkerDifferential = 109
|
||||||
@ -854,61 +852,50 @@ class DriveDataCaptureTrigger:
|
|||||||
AuxiliaryMarkerFallingEdge = 7
|
AuxiliaryMarkerFallingEdge = 7
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class PsoOutputPin:
|
class PsoOutputPin:
|
||||||
GL4None = 100,
|
GL4None = (100,)
|
||||||
GL4LaserOutput0 = 101,
|
GL4LaserOutput0 = (101,)
|
||||||
XL4sNone = 102,
|
XL4sNone = (102,)
|
||||||
XL4sLaserOutput0 = 103,
|
XL4sLaserOutput0 = (103,)
|
||||||
XR3None = 104,
|
XR3None = (104,)
|
||||||
XR3PsoOutput1 = 105,
|
XR3PsoOutput1 = (105,)
|
||||||
XR3PsoOutput2 = 106,
|
XR3PsoOutput2 = (106,)
|
||||||
XR3PsoOutput3 = 107,
|
XR3PsoOutput3 = (107,)
|
||||||
XC4DedicatedOutput = 108,
|
XC4DedicatedOutput = (108,)
|
||||||
XC4AuxiliaryMarkerDifferential = 109,
|
XC4AuxiliaryMarkerDifferential = (109,)
|
||||||
XC4AuxiliaryMarkerSingleEnded = 110,
|
XC4AuxiliaryMarkerSingleEnded = (110,)
|
||||||
XC4eDedicatedOutput = 111,
|
XC4eDedicatedOutput = (111,)
|
||||||
XC4eAuxiliaryMarkerDifferential = 112,
|
XC4eAuxiliaryMarkerDifferential = (112,)
|
||||||
XC4eAuxiliaryMarkerSingleEnded = 113,
|
XC4eAuxiliaryMarkerSingleEnded = (113,)
|
||||||
XC6eDedicatedOutput = 114,
|
XC6eDedicatedOutput = (114,)
|
||||||
XC6eAuxiliaryMarkerDifferential = 115,
|
XC6eAuxiliaryMarkerDifferential = (115,)
|
||||||
XC6eAuxiliaryMarkerSingleEnded = 116,
|
XC6eAuxiliaryMarkerSingleEnded = (116,)
|
||||||
XL5eDedicatedOutput = 117,
|
XL5eDedicatedOutput = (117,)
|
||||||
XL5eAuxiliaryMarkerDifferential = 118,
|
XL5eAuxiliaryMarkerDifferential = (118,)
|
||||||
XL5eAuxiliaryMarkerSingleEnded = 119,
|
XL5eAuxiliaryMarkerSingleEnded = (119,)
|
||||||
XC2DedicatedOutput = 120,
|
XC2DedicatedOutput = (120,)
|
||||||
XC2eDedicatedOutput = 121,
|
XC2eDedicatedOutput = (121,)
|
||||||
XL2eDedicatedOutput = 122,
|
XL2eDedicatedOutput = (122,)
|
||||||
XI4DedicatedOutput = 123,
|
XI4DedicatedOutput = (123,)
|
||||||
iXC4DedicatedOutput = 124,
|
iXC4DedicatedOutput = (124,)
|
||||||
iXC4AuxiliaryMarkerDifferential = 125,
|
iXC4AuxiliaryMarkerDifferential = (125,)
|
||||||
iXC4AuxiliaryMarkerSingleEnded = 126,
|
iXC4AuxiliaryMarkerSingleEnded = (126,)
|
||||||
iXC4eDedicatedOutput = 127,
|
iXC4eDedicatedOutput = (127,)
|
||||||
iXC4eAuxiliaryMarkerDifferential = 128,
|
iXC4eAuxiliaryMarkerDifferential = (128,)
|
||||||
iXC4eAuxiliaryMarkerSingleEnded = 129,
|
iXC4eAuxiliaryMarkerSingleEnded = (129,)
|
||||||
iXC6eDedicatedOutput = 130,
|
iXC6eDedicatedOutput = (130,)
|
||||||
iXC6eAuxiliaryMarkerDifferential = 131,
|
iXC6eAuxiliaryMarkerDifferential = (131,)
|
||||||
iXC6eAuxiliaryMarkerSingleEnded = 132,
|
iXC6eAuxiliaryMarkerSingleEnded = (132,)
|
||||||
iXL5eDedicatedOutput = 133,
|
iXL5eDedicatedOutput = (133,)
|
||||||
iXL5eAuxiliaryMarkerDifferential = 134,
|
iXL5eAuxiliaryMarkerDifferential = (134,)
|
||||||
iXL5eAuxiliaryMarkerSingleEnded = 135,
|
iXL5eAuxiliaryMarkerSingleEnded = (135,)
|
||||||
iXR3None = 136,
|
iXR3None = (136,)
|
||||||
iXR3PsoOutput1 = 137,
|
iXR3PsoOutput1 = (137,)
|
||||||
iXR3PsoOutput2 = 138,
|
iXR3PsoOutput2 = (138,)
|
||||||
iXR3PsoOutput3 = 139,
|
iXR3PsoOutput3 = (139,)
|
||||||
GI4None = 140,
|
GI4None = (140,)
|
||||||
GI4LaserOutput0 = 141,
|
GI4LaserOutput0 = (141,)
|
||||||
iXC2DedicatedOutput = 142,
|
iXC2DedicatedOutput = (142,)
|
||||||
iXC2eDedicatedOutput = 143,
|
iXC2eDedicatedOutput = (143,)
|
||||||
iXL2eDedicatedOutput = 144,
|
iXL2eDedicatedOutput = (144,)
|
||||||
iXI4DedicatedOutput = 145,
|
iXI4DedicatedOutput = (145,)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user