Flaking
This commit is contained in:
parent
7baf9ec118
commit
4b5a270071
@ -8,67 +8,109 @@ import time
|
||||
|
||||
try:
|
||||
from .AerotechAutomation1Enums import *
|
||||
from .AerotechAutomation1Enums import (DataCollectionMode, DataCollectionFrequency,
|
||||
AxisDataSignal, PsoWindowInput, DriveDataCaptureInput, DriveDataCaptureTrigger,
|
||||
TaskDataSignal, SystemDataSignal, TomcatSequencerState)
|
||||
from .AerotechAutomation1Enums import (
|
||||
DataCollectionMode,
|
||||
DataCollectionFrequency,
|
||||
AxisDataSignal,
|
||||
PsoWindowInput,
|
||||
DriveDataCaptureInput,
|
||||
DriveDataCaptureTrigger,
|
||||
TaskDataSignal,
|
||||
SystemDataSignal,
|
||||
TomcatSequencerState,
|
||||
)
|
||||
except:
|
||||
from AerotechAutomation1Enums import *
|
||||
from AerotechAutomation1Enums import (DataCollectionMode, DataCollectionFrequency,
|
||||
AxisDataSignal, PsoWindowInput, DriveDataCaptureInput, DriveDataCaptureTrigger,
|
||||
TaskDataSignal, SystemDataSignal, TomcatSequencerState)
|
||||
from AerotechAutomation1Enums import (
|
||||
DataCollectionMode,
|
||||
DataCollectionFrequency,
|
||||
AxisDataSignal,
|
||||
PsoWindowInput,
|
||||
DriveDataCaptureInput,
|
||||
DriveDataCaptureTrigger,
|
||||
TaskDataSignal,
|
||||
SystemDataSignal,
|
||||
TomcatSequencerState,
|
||||
)
|
||||
|
||||
from typing import Union
|
||||
from collections import OrderedDict
|
||||
|
||||
|
||||
|
||||
class EpicsMotorX(EpicsMotor):
|
||||
""" Special motor class that provides flyer interface and progress bar.
|
||||
"""
|
||||
|
||||
SUB_PROGRESS = "progress"
|
||||
|
||||
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,
|
||||
)
|
||||
self._startPosition = None
|
||||
self._targetPosition = None
|
||||
self.subscribe(self._progress_update, run=False)
|
||||
|
||||
def configure(self, d: dict):
|
||||
if "target" in d:
|
||||
self._targetPosition = d['target']
|
||||
del d['target']
|
||||
self._targetPosition = d["target"]
|
||||
del d["target"]
|
||||
if "position" in d:
|
||||
self._targetPosition = d['position']
|
||||
del d['position']
|
||||
self._targetPosition = d["position"]
|
||||
del d["position"]
|
||||
return super().configure(d)
|
||||
|
||||
def kickoff(self):
|
||||
self._startPosition = float( self.position)
|
||||
self._startPosition = float(self.position)
|
||||
return self.move(self._targetPosition, wait=False)
|
||||
|
||||
def move(self, position, wait=True, **kwargs):
|
||||
self._startPosition = float( self.position)
|
||||
self._startPosition = float(self.position)
|
||||
return super().move(position, wait, **kwargs)
|
||||
|
||||
def _progress_update(self, value, **kwargs) -> None:
|
||||
"""Progress update on the scan"""
|
||||
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
|
||||
|
||||
progress = np.abs( (value-self._startPosition)/(self._targetPosition-self._startPosition) )
|
||||
progress = np.abs(
|
||||
(value - self._startPosition) / (self._targetPosition - self._startPosition)
|
||||
)
|
||||
max_value = 100
|
||||
self._run_subs(
|
||||
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):
|
||||
""" Small helper class to read PVs that need to be processed first.
|
||||
"""
|
||||
|
||||
def __init__(self, read_pv, *, string=False, name=None, **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)
|
||||
|
||||
def wait_for_connection(self, *args, **kwargs):
|
||||
super().wait_for_connection(*args, **kwargs)
|
||||
@ -83,10 +125,9 @@ class EpicsPassiveRO(EpicsSignalRO):
|
||||
return super().value
|
||||
|
||||
|
||||
|
||||
|
||||
class aa1Controller(Device):
|
||||
"""Ophyd proxy class for the Aerotech Automation 1's core controller functionality"""
|
||||
|
||||
controllername = Component(EpicsSignalRO, "NAME", kind=Kind.config)
|
||||
serialnumber = Component(EpicsSignalRO, "SN", 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)
|
||||
fastpoll = Component(EpicsSignalRO, "POLLTIME", 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):
|
||||
""" Task management API
|
||||
@ -127,6 +188,7 @@ class aa1Tasks(Device):
|
||||
'''
|
||||
|
||||
"""
|
||||
|
||||
SUB_PROGRESS = "progress"
|
||||
_failure = Component(EpicsSignalRO, "FAILURE", 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)
|
||||
_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"""
|
||||
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._textToExecute = None
|
||||
self._isConfigured = False
|
||||
@ -154,7 +236,9 @@ class aa1Tasks(Device):
|
||||
def _progress_update(self, value, **kwargs) -> None:
|
||||
"""Progress update on the scan"""
|
||||
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:
|
||||
"""Progress update on the scan"""
|
||||
@ -172,7 +256,7 @@ class aa1Tasks(Device):
|
||||
self.fileName.set(filename).wait()
|
||||
filebytes = self._fileRead.get()
|
||||
# C-strings terminate with trailing zero
|
||||
if filebytes[-1]==0:
|
||||
if filebytes[-1] == 0:
|
||||
filebytes = filebytes[:-1]
|
||||
filetext = filebytes
|
||||
return filetext
|
||||
@ -182,19 +266,19 @@ class aa1Tasks(Device):
|
||||
self.fileName.set(filename).wait()
|
||||
self._fileWrite.set(filetext).wait()
|
||||
|
||||
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"""
|
||||
|
||||
self.configure({'text': filetext, 'filename': filename, 'taskIndex': taskIndex})
|
||||
self.configure({"text": filetext, "filename": filename, "taskIndex": taskIndex})
|
||||
print("Runscript configured")
|
||||
self.trigger().wait()
|
||||
print("Runscript waited")
|
||||
|
||||
def execute(self, text: str, taskIndex: int=3, mode: str=0, settle_time=0.5):
|
||||
def execute(self, text: str, taskIndex: int = 3, mode: str = 0, settle_time=0.5):
|
||||
""" Run a short text command on the Automation1 controller"""
|
||||
|
||||
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()
|
||||
|
||||
if mode in [0, "None", None]:
|
||||
@ -203,16 +287,16 @@ class aa1Tasks(Device):
|
||||
raw = self._executeReply.get()
|
||||
return raw
|
||||
|
||||
def configure(self, d: dict={}) -> tuple:
|
||||
def configure(self, d: dict = {}) -> tuple:
|
||||
""" Configuration interface for flying
|
||||
"""
|
||||
# Unrolling the configuration dict
|
||||
text = str(d['text']) if 'text' in d else None
|
||||
filename = str(d['filename']) if 'filename' in d else None
|
||||
taskIndex = int(d['taskIndex']) if 'taskIndex' in d else 4
|
||||
settle_time = float(d['settle_time']) if 'settle_time' in d else None
|
||||
mode = d['mode'] if 'mode' in d else None
|
||||
self._isStepConfig = d['stepper'] if 'stepper' in d else False
|
||||
text = str(d["text"]) if "text" in d else None
|
||||
filename = str(d["filename"]) if "filename" in d else None
|
||||
taskIndex = int(d["taskIndex"]) if "taskIndex" in d else 4
|
||||
settle_time = float(d["settle_time"]) if "settle_time" in d else None
|
||||
mode = d["mode"] if "mode" in d else None
|
||||
self._isStepConfig = d["stepper"] if "stepper" in d else False
|
||||
|
||||
# Validation
|
||||
if taskIndex < 1 or taskIndex > 31:
|
||||
@ -302,6 +386,7 @@ class aa1Tasks(Device):
|
||||
print("Called aa1Task.complete()")
|
||||
timestamp_ = 0
|
||||
taskIdx = int(self.taskIndex.get())
|
||||
|
||||
def notRunning2(*args, old_value, value, timestamp, **kwargs):
|
||||
nonlocal timestamp_
|
||||
result = False if value[taskIdx] in ["Running", 4] else True
|
||||
@ -315,7 +400,14 @@ class aa1Tasks(Device):
|
||||
|
||||
def describe_collect(self) -> 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}
|
||||
|
||||
def collect(self) -> OrderedDict:
|
||||
@ -331,6 +423,7 @@ class aa1TaskState(Device):
|
||||
This is the task state monitoring interface for Automation1 tasks. It
|
||||
does not launch execution, but can wait for the execution to complete.
|
||||
"""
|
||||
|
||||
index = Component(EpicsSignalRO, "INDEX", kind=Kind.config)
|
||||
status = Component(EpicsSignalRO, "STATUS", auto_monitor=True, kind=Kind.hinted)
|
||||
errorCode = Component(EpicsSignalRO, "ERROR", auto_monitor=True, kind=Kind.hinted)
|
||||
@ -341,9 +434,10 @@ class aa1TaskState(Device):
|
||||
print("Called aa1TaskState.complete()")
|
||||
# Define wait until the busy flag goes down (excluding initial update)
|
||||
timestamp_ = 0
|
||||
|
||||
def notRunning(*args, old_value, value, timestamp, **kwargs):
|
||||
nonlocal timestamp_
|
||||
result = False if (timestamp_== 0) else (value not in ["Running", 4])
|
||||
result = False if (timestamp_ == 0) else (value not in ["Running", 4])
|
||||
timestamp_ = timestamp
|
||||
print(result)
|
||||
return result
|
||||
@ -359,7 +453,14 @@ class aa1TaskState(Device):
|
||||
|
||||
def describe_collect(self) -> 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
|
||||
|
||||
def collect(self) -> OrderedDict:
|
||||
@ -381,6 +482,7 @@ class aa1DataAcquisition(Device):
|
||||
3. Start your data collection
|
||||
4. Read back the recorded data with "readback"
|
||||
"""
|
||||
|
||||
# Status monitoring
|
||||
status = Component(EpicsSignalRO, "RUNNING", auto_monitor=True, kind=Kind.hinted)
|
||||
points_max = Component(EpicsSignal, "MAXPOINTS", kind=Kind.config, put_complete=True)
|
||||
@ -388,7 +490,7 @@ class aa1DataAcquisition(Device):
|
||||
|
||||
points_total = Component(EpicsSignalRO, "NTOTAL", auto_monitor=True, kind=Kind.hinted)
|
||||
points_collected = Component(EpicsSignalRO, "NCOLLECTED", auto_monitor=True, kind=Kind.hinted)
|
||||
points_retrieved= Component(EpicsSignalRO, "NRETRIEVED", auto_monitor=True, kind=Kind.hinted)
|
||||
points_retrieved = Component(EpicsSignalRO, "NRETRIEVED", auto_monitor=True, kind=Kind.hinted)
|
||||
overflow = Component(EpicsSignalRO, "OVERFLOW", auto_monitor=True, kind=Kind.hinted)
|
||||
runmode = Component(EpicsSignalRO, "MODE_RBV", auto_monitor=True, kind=Kind.hinted)
|
||||
# DAQ setup
|
||||
@ -448,7 +550,7 @@ class aa1DataAcquisition(Device):
|
||||
self._switch.set("START").wait()
|
||||
# Wait for finishing acquisition
|
||||
# Note: this is very bad blocking sleep
|
||||
while self.status.value!=0:
|
||||
while self.status.value != 0:
|
||||
sleep(0.1)
|
||||
sleep(0.1)
|
||||
|
||||
@ -456,7 +558,7 @@ class aa1DataAcquisition(Device):
|
||||
data = self.data_rb.get()
|
||||
rows = self.data_rows.get()
|
||||
cols = self.data_cols.get()
|
||||
if len(data)==0 or rows==0 or cols==0:
|
||||
if len(data) == 0 or rows == 0 or cols == 0:
|
||||
sleep(0.5)
|
||||
data = self.data_rb.get()
|
||||
rows = self.data_rows.get()
|
||||
@ -476,7 +578,7 @@ class aa1DataAcquisition(Device):
|
||||
data = self.data_rb.get()
|
||||
rows = self.data_rows.get()
|
||||
cols = self.data_cols.get()
|
||||
if len(data)==0 or rows==0 or cols==0:
|
||||
if len(data) == 0 or rows == 0 or cols == 0:
|
||||
sleep(0.2)
|
||||
data = self.data_rb.get()
|
||||
rows = self.data_rows.get()
|
||||
@ -486,7 +588,6 @@ class aa1DataAcquisition(Device):
|
||||
return data
|
||||
|
||||
|
||||
|
||||
class aa1GlobalVariables(Device):
|
||||
""" Global variables
|
||||
|
||||
@ -505,6 +606,7 @@ class aa1GlobalVariables(Device):
|
||||
ret_arr = var.readFloat(1000, 1024)
|
||||
|
||||
"""
|
||||
|
||||
# Status monitoring
|
||||
num_real = Component(EpicsSignalRO, "NUM-REAL_RBV", kind=Kind.config)
|
||||
num_int = Component(EpicsSignalRO, "NUM-INT_RBV", kind=Kind.config)
|
||||
@ -528,7 +630,7 @@ class aa1GlobalVariables(Device):
|
||||
string = Component(EpicsSignal, "STRING", string=True, kind=Kind.omitted, put_complete=True)
|
||||
string_rb = Component(EpicsPassiveRO, "STRING-RBV", string=True, kind=Kind.omitted)
|
||||
|
||||
def readInt(self, address: int, size: int=None) -> int:
|
||||
def readInt(self, address: int, size: int = None) -> int:
|
||||
""" Read a 64-bit integer global variable """
|
||||
if address > self.num_int.get():
|
||||
raise RuntimeError("Integer address {address} is out of range")
|
||||
@ -559,8 +661,7 @@ class aa1GlobalVariables(Device):
|
||||
else:
|
||||
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 """
|
||||
if address > self.num_real.get():
|
||||
raise RuntimeError("Floating point address {address} is out of range")
|
||||
@ -613,7 +714,6 @@ class aa1GlobalVariables(Device):
|
||||
raise RuntimeError("Unsupported string value type: {type(value)}")
|
||||
|
||||
|
||||
|
||||
class aa1GlobalVariableBindings(Device):
|
||||
""" Polled global variables
|
||||
|
||||
@ -621,30 +721,124 @@ class aa1GlobalVariableBindings(Device):
|
||||
on the Automation1 controller. These variables are continuously polled
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
int8 = Component(
|
||||
EpicsSignal,
|
||||
"INT8_RBV",
|
||||
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)
|
||||
float1 = Component(EpicsSignalRO, "REAL1_RBV", auto_monitor=True, name="float1", 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)
|
||||
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)
|
||||
float0 = Component(
|
||||
EpicsSignalRO, "REAL0_RBV", auto_monitor=True, name="float0", kind=Kind.hinted
|
||||
)
|
||||
float1 = Component(
|
||||
EpicsSignalRO, "REAL1_RBV", auto_monitor=True, name="float1", 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
|
||||
)
|
||||
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
|
||||
str0 = Component(EpicsSignalRO, "STR0_RBV", auto_monitor=True, string=True, name="str0", 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)
|
||||
|
||||
str0 = Component(
|
||||
EpicsSignalRO, "STR0_RBV", auto_monitor=True, string=True, name="str0", 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):
|
||||
@ -655,6 +849,7 @@ class aa1AxisIo(Device):
|
||||
should be done in AeroScript. Only one pin can be writen directly but
|
||||
several can be polled!
|
||||
"""
|
||||
|
||||
polllvl = Component(EpicsSignal, "POLLLVL", put_complete=True, kind=Kind.config)
|
||||
ai0 = Component(EpicsSignalRO, "AI0-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()
|
||||
|
||||
|
||||
|
||||
class aa1AxisPsoBase(Device):
|
||||
""" Position Sensitive Output - Base class
|
||||
|
||||
@ -708,6 +902,7 @@ class aa1AxisPsoBase(Device):
|
||||
|
||||
Specific operation modes should be implemented in child classes.
|
||||
"""
|
||||
|
||||
# ########################################################################
|
||||
# General module status
|
||||
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)
|
||||
dstCounterVal = Component(EpicsSignalRO, "DIST:CTR0_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)
|
||||
dstDistance = Component(EpicsSignal, "DIST:DISTANCE", put_complete=True, kind=Kind.hinted)
|
||||
@ -742,10 +939,10 @@ class aa1AxisPsoBase(Device):
|
||||
# PSO waveform module
|
||||
waveEnable = Component(EpicsSignal, "WAVE:ENABLE", put_complete=True, kind=Kind.omitted)
|
||||
waveMode = Component(EpicsSignal, "WAVE:MODE", put_complete=True, kind=Kind.omitted)
|
||||
#waveDelay = Component(EpicsSignal, "WAVE:DELAY", put_complete=True, kind=Kind.omitted)
|
||||
# waveDelay = Component(EpicsSignal, "WAVE:DELAY", put_complete=True, kind=Kind.omitted)
|
||||
|
||||
# PSO waveform pulse output
|
||||
#pulseTrunc = Component(EpicsSignal, "WAVE:PULSE:TRUNC", put_complete=True, kind=Kind.omitted)
|
||||
# pulseTrunc = Component(EpicsSignal, "WAVE:PULSE:TRUNC", put_complete=True, kind=Kind.omitted)
|
||||
pulseOnTime = Component(EpicsSignal, "WAVE:PULSE:ONTIME", put_complete=True, kind=Kind.omitted)
|
||||
pulseWindow = Component(EpicsSignal, "WAVE:PULSE:PERIOD", put_complete=True, kind=Kind.omitted)
|
||||
pulseCount = Component(EpicsSignal, "WAVE:PULSE:COUNT", put_complete=True, kind=Kind.omitted)
|
||||
@ -767,9 +964,6 @@ class aa1AxisPsoBase(Device):
|
||||
self.waveMode.set(orig_waveMode).wait()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class aa1AxisPsoDistance(aa1AxisPsoBase):
|
||||
""" Position Sensitive Output - Distance mode
|
||||
|
||||
@ -802,11 +996,30 @@ class aa1AxisPsoDistance(aa1AxisPsoBase):
|
||||
pso.configure(d={'distance': 1.8, 'wmode': "pulsed", 'n_pulse': 5})
|
||||
pso.kickoff().wait()
|
||||
"""
|
||||
|
||||
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"""
|
||||
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.subscribe(self._progress_update, "progress", run=False)
|
||||
|
||||
@ -814,7 +1027,9 @@ class aa1AxisPsoDistance(aa1AxisPsoBase):
|
||||
"""Progress update on the scan"""
|
||||
if self.dstArrayDepleted.value:
|
||||
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
|
||||
|
||||
progress = 1
|
||||
@ -822,23 +1037,25 @@ class aa1AxisPsoDistance(aa1AxisPsoBase):
|
||||
print(f"PSO array proggress: {progress}")
|
||||
self._run_subs(
|
||||
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
|
||||
def configure(self, d: dict={}) -> tuple:
|
||||
def configure(self, d: dict = {}) -> tuple:
|
||||
""" Simplified configuration interface to access the most common
|
||||
functionality for distance mode PSO.
|
||||
|
||||
:param distance: The trigger distance or the array of distances between subsequent points.
|
||||
:param wmode: Waveform mode configuration, usually pulsed/toggled.
|
||||
"""
|
||||
distance = d['distance']
|
||||
wmode = str(d['wmode'])
|
||||
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
|
||||
n_pulse = float(d['n_pulse']) if 'n_pulse' in d else 1
|
||||
|
||||
distance = d["distance"]
|
||||
wmode = str(d["wmode"])
|
||||
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
|
||||
n_pulse = float(d["n_pulse"]) if "n_pulse" in d else 1
|
||||
|
||||
# Validate input parameters
|
||||
if wmode not in ["pulse", "pulsed", "toggle", "toggled"]:
|
||||
@ -908,11 +1125,14 @@ class aa1AxisPsoDistance(aa1AxisPsoBase):
|
||||
self.dstEventsEna.set("Off").wait()
|
||||
self.dstCounterEna.set("Off").wait()
|
||||
return super().unstage()
|
||||
|
||||
# ########################################################################
|
||||
# Bluesky flyer interface
|
||||
def kickoff(self) -> DeviceStatus:
|
||||
# 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()
|
||||
# Start monitoring the counters
|
||||
self.dstEventsEna.set("On").wait()
|
||||
@ -925,18 +1145,21 @@ class aa1AxisPsoDistance(aa1AxisPsoBase):
|
||||
def complete(self) -> DeviceStatus:
|
||||
""" Bluesky flyer interface"""
|
||||
# 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)
|
||||
timestamp_ = 0
|
||||
|
||||
def notRunning(*args, old_value, value, timestamp, **kwargs):
|
||||
nonlocal timestamp_
|
||||
result = False if (timestamp_== 0) else bool(int(value) & 0x1000)
|
||||
result = False if (timestamp_ == 0) else bool(int(value) & 0x1000)
|
||||
print(f"Old {old_value}\tNew: {value}\tResult: {result}")
|
||||
timestamp_ = timestamp
|
||||
return result
|
||||
|
||||
# Subscribe and wait for update
|
||||
#status = SubscriptionStatus(self.status, notRunning, settle_time=0.5)
|
||||
# status = SubscriptionStatus(self.status, notRunning, settle_time=0.5)
|
||||
# Data capture can be stopped any time
|
||||
status = DeviceStatus(self)
|
||||
status.set_finished()
|
||||
@ -948,18 +1171,23 @@ class aa1AxisPsoDistance(aa1AxisPsoBase):
|
||||
|
||||
def describe_collect(self) -> 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}
|
||||
|
||||
def collect(self) -> OrderedDict:
|
||||
ret = OrderedDict()
|
||||
ret["timestamps"] = {"index": time.time()}
|
||||
ret["data"] = {"index": self.dstCounterVal.value }
|
||||
ret["data"] = {"index": self.dstCounterVal.value}
|
||||
yield ret
|
||||
|
||||
|
||||
|
||||
|
||||
class aa1AxisPsoWindow(aa1AxisPsoBase):
|
||||
""" Position Sensitive Output - Window mode
|
||||
|
||||
@ -979,27 +1207,46 @@ class aa1AxisPsoWindow(aa1AxisPsoBase):
|
||||
For a more detailed description of additional signals and masking plase
|
||||
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"""
|
||||
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._eventMode = "Enter"
|
||||
|
||||
# ########################################################################
|
||||
# PSO high level interface
|
||||
def configure(self, d: dict={}) -> tuple:
|
||||
def configure(self, d: dict = {}) -> tuple:
|
||||
""" Simplified configuration interface to access the most common
|
||||
functionality for distance mode PSO.
|
||||
|
||||
:param distance: The trigger distance or the array of distances between subsequent points.
|
||||
:param wmode: Waveform mode configuration, usually output/pulsed/toggled.
|
||||
"""
|
||||
bounds = d['distance']
|
||||
wmode = str(d['wmode'])
|
||||
emode = str(d['emode'])
|
||||
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
|
||||
n_pulse = float(d['n_pulse']) if 'n_pulse' in d else None
|
||||
bounds = d["distance"]
|
||||
wmode = str(d["wmode"])
|
||||
emode = str(d["emode"])
|
||||
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
|
||||
n_pulse = float(d["n_pulse"]) if "n_pulse" in d else None
|
||||
|
||||
# Validate input parameters
|
||||
if wmode not in ["pulse", "pulsed", "toggle", "toggled", "output", "flag"]:
|
||||
@ -1080,11 +1327,6 @@ class aa1AxisPsoWindow(aa1AxisPsoBase):
|
||||
return super().unstage()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class aa1AxisDriveDataCollection(Device):
|
||||
""" Axis data collection
|
||||
|
||||
@ -1125,29 +1367,50 @@ class aa1AxisDriveDataCollection(Device):
|
||||
|
||||
SUB_PROGRESS = "progress"
|
||||
|
||||
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,
|
||||
)
|
||||
self.subscribe(self._progress_update, "progress", run=False)
|
||||
|
||||
def _progress_update(self, value, **kwargs) -> None:
|
||||
"""Progress update on the scan"""
|
||||
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
|
||||
|
||||
progress = 1
|
||||
max_value = 1
|
||||
self._run_subs(
|
||||
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:
|
||||
npoints = int(d['npoints'])
|
||||
trigger = int(d['trigger']) if 'trigger' in d else DriveDataCaptureTrigger.PsoOutput
|
||||
source0 = int(d['source0']) if 'source0' in d else DriveDataCaptureInput.PrimaryFeedback
|
||||
source1 = int(d['source1']) if 'source1' in d else DriveDataCaptureInput.PositionCommand
|
||||
def configure(self, d: dict = {}) -> tuple:
|
||||
npoints = int(d["npoints"])
|
||||
trigger = int(d["trigger"]) if "trigger" in d else DriveDataCaptureTrigger.PsoOutput
|
||||
source0 = int(d["source0"]) if "source0" in d else DriveDataCaptureInput.PrimaryFeedback
|
||||
source1 = int(d["source1"]) if "source1" in d else DriveDataCaptureInput.PositionCommand
|
||||
|
||||
old = self.read_configuration()
|
||||
|
||||
@ -1194,17 +1457,18 @@ class aa1AxisDriveDataCollection(Device):
|
||||
|
||||
# Define wait until the busy flag goes down (excluding initial update)
|
||||
timestamp_ = 0
|
||||
|
||||
def negEdge(*args, old_value, value, timestamp, **kwargs):
|
||||
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)
|
||||
# print(f"\nBuffer1 status:\t{old_value} ({timestamp_}) to {value} ({timestamp}) Result: {result}")
|
||||
timestamp_ = timestamp
|
||||
return result
|
||||
|
||||
if index==0:
|
||||
if index == 0:
|
||||
status = SubscriptionStatus(self._readstatus0, negEdge, settle_time=0.5)
|
||||
self._readback0.set(1).wait()
|
||||
elif index==1:
|
||||
elif index == 1:
|
||||
status = SubscriptionStatus(self._readstatus1, negEdge, settle_time=0.5)
|
||||
self._readback1.set(1).wait()
|
||||
|
||||
@ -1212,11 +1476,24 @@ class aa1AxisDriveDataCollection(Device):
|
||||
status.wait()
|
||||
return status
|
||||
|
||||
|
||||
def describe_collect(self) -> OrderedDict:
|
||||
ret = OrderedDict()
|
||||
ret['buffer0'] = {'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}
|
||||
ret["buffer0"] = {
|
||||
"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}
|
||||
|
||||
def collect(self) -> OrderedDict:
|
||||
@ -1227,29 +1504,23 @@ class aa1AxisDriveDataCollection(Device):
|
||||
b0 = self._buffer0.value
|
||||
b1 = self._buffer1.value
|
||||
ret = OrderedDict()
|
||||
ret["timestamps"] = {"buffer0": time.time(), "buffer1": time.time() }
|
||||
ret["data"] = {"buffer0": b0, "buffer1": b1 }
|
||||
ret["timestamps"] = {"buffer0": time.time(), "buffer1": time.time()}
|
||||
ret["data"] = {"buffer0": b0, "buffer1": b1}
|
||||
yield ret
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Automatically start simulation if directly invoked
|
||||
if __name__ == "__main__":
|
||||
AA1_IOC_NAME = "X02DA-ES1-SMP1"
|
||||
AA1_AXIS_NAME = "ROTY"
|
||||
# Drive data collection
|
||||
task = aa1Tasks(AA1_IOC_NAME+":TASK:", name="tsk")
|
||||
task = aa1Tasks(AA1_IOC_NAME + ":TASK:", name="tsk")
|
||||
task.wait_for_connection()
|
||||
task.describe()
|
||||
ddc = aa1AxisDriveDataCollection("X02DA-ES1-SMP1:ROTY:DDC:", name="ddc")
|
||||
ddc.wait_for_connection()
|
||||
globb = aa1GlobalVariableBindings(AA1_IOC_NAME+":VAR:", name="globb")
|
||||
globb = aa1GlobalVariableBindings(AA1_IOC_NAME + ":VAR:", name="globb")
|
||||
globb.wait_for_connection()
|
||||
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()
|
||||
|
||||
|
||||
|
||||
|
@ -383,9 +383,6 @@ class TaskDataSignal:
|
||||
CommandQueueExecutedCount = 424
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class SystemDataSignal:
|
||||
VirtualBinaryInput = 46
|
||||
VirtualBinaryOutput = 47
|
||||
@ -442,7 +439,6 @@ class SystemDataSignal:
|
||||
ModbusServerEnabled = 439
|
||||
|
||||
|
||||
|
||||
class DataCollectionFrequency:
|
||||
Undefined = 0
|
||||
Fixed1kHz = 1
|
||||
@ -482,11 +478,12 @@ class PsoWindowInput:
|
||||
XC4eSyncPortA = 137
|
||||
XC4eSyncPortB = 138
|
||||
XC4eDrivePulseStream = 139
|
||||
XL5ePrimaryFeedback = 145,
|
||||
XL5eAuxiliaryFeedback = 146,
|
||||
XL5eSyncPortA = 147,
|
||||
XL5eSyncPortB = 148,
|
||||
XL5eDrivePulseStream = 149,
|
||||
XL5ePrimaryFeedback = (145,)
|
||||
XL5eAuxiliaryFeedback = (146,)
|
||||
XL5eSyncPortA = (147,)
|
||||
XL5eSyncPortB = (148,)
|
||||
XL5eDrivePulseStream = (149,)
|
||||
|
||||
|
||||
# @brief Specifies the PSO output pin settings for each drive.
|
||||
class XC4ePsoOutputPin:
|
||||
@ -494,6 +491,7 @@ class XC4ePsoOutputPin:
|
||||
AuxiliaryMarkerDifferential = 112
|
||||
AuxiliaryMarkerSingleEnded = 113
|
||||
|
||||
|
||||
class XC4PsoOutputPin:
|
||||
DedicatedOutput = 108
|
||||
AuxiliaryMarkerDifferential = 109
|
||||
@ -854,61 +852,50 @@ class DriveDataCaptureTrigger:
|
||||
AuxiliaryMarkerFallingEdge = 7
|
||||
|
||||
|
||||
|
||||
|
||||
class PsoOutputPin:
|
||||
GL4None = 100,
|
||||
GL4LaserOutput0 = 101,
|
||||
XL4sNone = 102,
|
||||
XL4sLaserOutput0 = 103,
|
||||
XR3None = 104,
|
||||
XR3PsoOutput1 = 105,
|
||||
XR3PsoOutput2 = 106,
|
||||
XR3PsoOutput3 = 107,
|
||||
XC4DedicatedOutput = 108,
|
||||
XC4AuxiliaryMarkerDifferential = 109,
|
||||
XC4AuxiliaryMarkerSingleEnded = 110,
|
||||
XC4eDedicatedOutput = 111,
|
||||
XC4eAuxiliaryMarkerDifferential = 112,
|
||||
XC4eAuxiliaryMarkerSingleEnded = 113,
|
||||
XC6eDedicatedOutput = 114,
|
||||
XC6eAuxiliaryMarkerDifferential = 115,
|
||||
XC6eAuxiliaryMarkerSingleEnded = 116,
|
||||
XL5eDedicatedOutput = 117,
|
||||
XL5eAuxiliaryMarkerDifferential = 118,
|
||||
XL5eAuxiliaryMarkerSingleEnded = 119,
|
||||
XC2DedicatedOutput = 120,
|
||||
XC2eDedicatedOutput = 121,
|
||||
XL2eDedicatedOutput = 122,
|
||||
XI4DedicatedOutput = 123,
|
||||
iXC4DedicatedOutput = 124,
|
||||
iXC4AuxiliaryMarkerDifferential = 125,
|
||||
iXC4AuxiliaryMarkerSingleEnded = 126,
|
||||
iXC4eDedicatedOutput = 127,
|
||||
iXC4eAuxiliaryMarkerDifferential = 128,
|
||||
iXC4eAuxiliaryMarkerSingleEnded = 129,
|
||||
iXC6eDedicatedOutput = 130,
|
||||
iXC6eAuxiliaryMarkerDifferential = 131,
|
||||
iXC6eAuxiliaryMarkerSingleEnded = 132,
|
||||
iXL5eDedicatedOutput = 133,
|
||||
iXL5eAuxiliaryMarkerDifferential = 134,
|
||||
iXL5eAuxiliaryMarkerSingleEnded = 135,
|
||||
iXR3None = 136,
|
||||
iXR3PsoOutput1 = 137,
|
||||
iXR3PsoOutput2 = 138,
|
||||
iXR3PsoOutput3 = 139,
|
||||
GI4None = 140,
|
||||
GI4LaserOutput0 = 141,
|
||||
iXC2DedicatedOutput = 142,
|
||||
iXC2eDedicatedOutput = 143,
|
||||
iXL2eDedicatedOutput = 144,
|
||||
iXI4DedicatedOutput = 145,
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
GL4None = (100,)
|
||||
GL4LaserOutput0 = (101,)
|
||||
XL4sNone = (102,)
|
||||
XL4sLaserOutput0 = (103,)
|
||||
XR3None = (104,)
|
||||
XR3PsoOutput1 = (105,)
|
||||
XR3PsoOutput2 = (106,)
|
||||
XR3PsoOutput3 = (107,)
|
||||
XC4DedicatedOutput = (108,)
|
||||
XC4AuxiliaryMarkerDifferential = (109,)
|
||||
XC4AuxiliaryMarkerSingleEnded = (110,)
|
||||
XC4eDedicatedOutput = (111,)
|
||||
XC4eAuxiliaryMarkerDifferential = (112,)
|
||||
XC4eAuxiliaryMarkerSingleEnded = (113,)
|
||||
XC6eDedicatedOutput = (114,)
|
||||
XC6eAuxiliaryMarkerDifferential = (115,)
|
||||
XC6eAuxiliaryMarkerSingleEnded = (116,)
|
||||
XL5eDedicatedOutput = (117,)
|
||||
XL5eAuxiliaryMarkerDifferential = (118,)
|
||||
XL5eAuxiliaryMarkerSingleEnded = (119,)
|
||||
XC2DedicatedOutput = (120,)
|
||||
XC2eDedicatedOutput = (121,)
|
||||
XL2eDedicatedOutput = (122,)
|
||||
XI4DedicatedOutput = (123,)
|
||||
iXC4DedicatedOutput = (124,)
|
||||
iXC4AuxiliaryMarkerDifferential = (125,)
|
||||
iXC4AuxiliaryMarkerSingleEnded = (126,)
|
||||
iXC4eDedicatedOutput = (127,)
|
||||
iXC4eAuxiliaryMarkerDifferential = (128,)
|
||||
iXC4eAuxiliaryMarkerSingleEnded = (129,)
|
||||
iXC6eDedicatedOutput = (130,)
|
||||
iXC6eAuxiliaryMarkerDifferential = (131,)
|
||||
iXC6eAuxiliaryMarkerSingleEnded = (132,)
|
||||
iXL5eDedicatedOutput = (133,)
|
||||
iXL5eAuxiliaryMarkerDifferential = (134,)
|
||||
iXL5eAuxiliaryMarkerSingleEnded = (135,)
|
||||
iXR3None = (136,)
|
||||
iXR3PsoOutput1 = (137,)
|
||||
iXR3PsoOutput2 = (138,)
|
||||
iXR3PsoOutput3 = (139,)
|
||||
GI4None = (140,)
|
||||
GI4LaserOutput0 = (141,)
|
||||
iXC2DedicatedOutput = (142,)
|
||||
iXC2eDedicatedOutput = (143,)
|
||||
iXL2eDedicatedOutput = (144,)
|
||||
iXI4DedicatedOutput = (145,)
|
||||
|
Loading…
x
Reference in New Issue
Block a user