ophyd-async 0.3a2__py3-none-any.whl → 0.3a4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ophyd_async/_version.py +1 -1
- ophyd_async/core/__init__.py +35 -11
- ophyd_async/core/async_status.py +2 -0
- ophyd_async/core/detector.py +8 -9
- ophyd_async/core/device.py +22 -9
- ophyd_async/core/flyer.py +2 -2
- ophyd_async/core/mock_signal_backend.py +86 -0
- ophyd_async/core/mock_signal_utils.py +149 -0
- ophyd_async/core/signal.py +140 -49
- ophyd_async/core/signal_backend.py +2 -2
- ophyd_async/core/{sim_signal_backend.py → soft_signal_backend.py} +29 -39
- ophyd_async/core/standard_readable.py +211 -24
- ophyd_async/epics/_backend/_aioca.py +17 -13
- ophyd_async/epics/_backend/_p4p.py +28 -18
- ophyd_async/epics/_backend/common.py +17 -17
- ophyd_async/epics/areadetector/__init__.py +4 -4
- ophyd_async/epics/areadetector/aravis.py +7 -9
- ophyd_async/epics/areadetector/controllers/__init__.py +2 -1
- ophyd_async/epics/areadetector/controllers/kinetix_controller.py +49 -0
- ophyd_async/epics/areadetector/controllers/vimba_controller.py +66 -0
- ophyd_async/epics/areadetector/drivers/__init__.py +6 -0
- ophyd_async/epics/areadetector/drivers/ad_base.py +12 -10
- ophyd_async/epics/areadetector/drivers/aravis_driver.py +7 -5
- ophyd_async/epics/areadetector/drivers/kinetix_driver.py +27 -0
- ophyd_async/epics/areadetector/drivers/pilatus_driver.py +5 -2
- ophyd_async/epics/areadetector/drivers/vimba_driver.py +63 -0
- ophyd_async/epics/areadetector/kinetix.py +46 -0
- ophyd_async/epics/areadetector/pilatus.py +7 -12
- ophyd_async/epics/areadetector/single_trigger_det.py +14 -6
- ophyd_async/epics/areadetector/utils.py +2 -12
- ophyd_async/epics/areadetector/vimba.py +43 -0
- ophyd_async/epics/areadetector/writers/hdf_writer.py +6 -3
- ophyd_async/epics/areadetector/writers/nd_file_hdf.py +21 -18
- ophyd_async/epics/areadetector/writers/nd_plugin.py +6 -7
- ophyd_async/epics/demo/__init__.py +19 -22
- ophyd_async/epics/motion/motor.py +16 -13
- ophyd_async/epics/pvi/pvi.py +11 -11
- ophyd_async/epics/signal/signal.py +1 -1
- ophyd_async/log.py +130 -0
- ophyd_async/panda/_hdf_panda.py +3 -3
- ophyd_async/panda/writers/_hdf_writer.py +3 -3
- ophyd_async/protocols.py +26 -3
- ophyd_async/sim/demo/sim_motor.py +14 -12
- ophyd_async/sim/pattern_generator.py +9 -9
- ophyd_async/sim/sim_pattern_detector_writer.py +2 -2
- ophyd_async/sim/sim_pattern_generator.py +2 -2
- {ophyd_async-0.3a2.dist-info → ophyd_async-0.3a4.dist-info}/METADATA +20 -3
- ophyd_async-0.3a4.dist-info/RECORD +85 -0
- ophyd_async-0.3a2.dist-info/RECORD +0 -76
- {ophyd_async-0.3a2.dist-info → ophyd_async-0.3a4.dist-info}/LICENSE +0 -0
- {ophyd_async-0.3a2.dist-info → ophyd_async-0.3a4.dist-info}/WHEEL +0 -0
- {ophyd_async-0.3a2.dist-info → ophyd_async-0.3a4.dist-info}/entry_points.txt +0 -0
- {ophyd_async-0.3a2.dist-info → ophyd_async-0.3a4.dist-info}/top_level.txt +0 -0
|
@@ -4,7 +4,7 @@ from typing import Callable, List, Optional
|
|
|
4
4
|
|
|
5
5
|
from bluesky.protocols import Movable, Stoppable
|
|
6
6
|
|
|
7
|
-
from ophyd_async.core import AsyncStatus, StandardReadable
|
|
7
|
+
from ophyd_async.core import AsyncStatus, ConfigSignal, HintedSignal, StandardReadable
|
|
8
8
|
|
|
9
9
|
from ..signal.signal import epics_signal_r, epics_signal_rw, epics_signal_x
|
|
10
10
|
|
|
@@ -14,26 +14,25 @@ class Motor(StandardReadable, Movable, Stoppable):
|
|
|
14
14
|
|
|
15
15
|
def __init__(self, prefix: str, name="") -> None:
|
|
16
16
|
# Define some signals
|
|
17
|
+
with self.add_children_as_readables(ConfigSignal):
|
|
18
|
+
self.motor_egu = epics_signal_r(str, prefix + ".EGU")
|
|
19
|
+
self.velocity = epics_signal_rw(float, prefix + ".VELO")
|
|
20
|
+
|
|
21
|
+
with self.add_children_as_readables(HintedSignal):
|
|
22
|
+
self.user_readback = epics_signal_r(float, prefix + ".RBV")
|
|
23
|
+
|
|
17
24
|
self.user_setpoint = epics_signal_rw(float, prefix + ".VAL")
|
|
18
|
-
self.user_readback = epics_signal_r(float, prefix + ".RBV")
|
|
19
|
-
self.velocity = epics_signal_rw(float, prefix + ".VELO")
|
|
20
25
|
self.max_velocity = epics_signal_r(float, prefix + ".VMAX")
|
|
21
26
|
self.acceleration_time = epics_signal_rw(float, prefix + ".ACCL")
|
|
22
|
-
self.motor_egu = epics_signal_r(str, prefix + ".EGU")
|
|
23
27
|
self.precision = epics_signal_r(int, prefix + ".PREC")
|
|
24
28
|
self.deadband = epics_signal_r(float, prefix + ".RDBD")
|
|
25
|
-
self.motor_done_move = epics_signal_r(
|
|
26
|
-
self.low_limit_travel = epics_signal_rw(
|
|
27
|
-
self.high_limit_travel = epics_signal_rw(
|
|
29
|
+
self.motor_done_move = epics_signal_r(int, prefix + ".DMOV")
|
|
30
|
+
self.low_limit_travel = epics_signal_rw(float, prefix + ".LLM")
|
|
31
|
+
self.high_limit_travel = epics_signal_rw(float, prefix + ".HLM")
|
|
28
32
|
|
|
29
33
|
self.motor_stop = epics_signal_x(prefix + ".STOP")
|
|
30
34
|
# Whether set() should complete successfully or not
|
|
31
35
|
self._set_success = True
|
|
32
|
-
# Set name and signals for read() and read_configuration()
|
|
33
|
-
self.set_readable_signals(
|
|
34
|
-
read=[self.user_readback],
|
|
35
|
-
config=[self.velocity, self.motor_egu],
|
|
36
|
-
)
|
|
37
36
|
super().__init__(name=name)
|
|
38
37
|
|
|
39
38
|
def set_name(self, name: str):
|
|
@@ -41,7 +40,11 @@ class Motor(StandardReadable, Movable, Stoppable):
|
|
|
41
40
|
# Readback should be named the same as its parent in read()
|
|
42
41
|
self.user_readback.set_name(name)
|
|
43
42
|
|
|
44
|
-
async def _move(
|
|
43
|
+
async def _move(
|
|
44
|
+
self, new_position: float, watchers: Optional[List[Callable]] = None
|
|
45
|
+
):
|
|
46
|
+
if watchers is None:
|
|
47
|
+
watchers = []
|
|
45
48
|
self._set_success = True
|
|
46
49
|
start = time.monotonic()
|
|
47
50
|
old_position, units, precision = await asyncio.gather(
|
ophyd_async/epics/pvi/pvi.py
CHANGED
|
@@ -17,7 +17,7 @@ from typing import (
|
|
|
17
17
|
get_type_hints,
|
|
18
18
|
)
|
|
19
19
|
|
|
20
|
-
from ophyd_async.core import Device, DeviceVector,
|
|
20
|
+
from ophyd_async.core import Device, DeviceVector, SoftSignalBackend
|
|
21
21
|
from ophyd_async.core.signal import Signal
|
|
22
22
|
from ophyd_async.core.utils import DEFAULT_TIMEOUT
|
|
23
23
|
from ophyd_async.epics._backend._p4p import PvaSignalBackend
|
|
@@ -156,7 +156,7 @@ def _parse_type(
|
|
|
156
156
|
return is_device_vector, is_signal, signal_dtype, device_cls
|
|
157
157
|
|
|
158
158
|
|
|
159
|
-
def
|
|
159
|
+
def _mock_common_blocks(device: Device, stripped_type: Optional[Type] = None):
|
|
160
160
|
device_t = stripped_type or type(device)
|
|
161
161
|
sub_devices = (
|
|
162
162
|
(field, field_type)
|
|
@@ -175,23 +175,23 @@ def _sim_common_blocks(device: Device, stripped_type: Optional[Type] = None):
|
|
|
175
175
|
|
|
176
176
|
if is_device_vector:
|
|
177
177
|
if is_signal:
|
|
178
|
-
sub_device_1 = device_cls(
|
|
179
|
-
sub_device_2 = device_cls(
|
|
178
|
+
sub_device_1 = device_cls(SoftSignalBackend(signal_dtype))
|
|
179
|
+
sub_device_2 = device_cls(SoftSignalBackend(signal_dtype))
|
|
180
180
|
sub_device = DeviceVector({1: sub_device_1, 2: sub_device_2})
|
|
181
181
|
else:
|
|
182
182
|
sub_device = DeviceVector({1: device_cls(), 2: device_cls()})
|
|
183
183
|
|
|
184
184
|
for sub_device_in_vector in sub_device.values():
|
|
185
|
-
|
|
185
|
+
_mock_common_blocks(sub_device_in_vector, stripped_type=device_cls)
|
|
186
186
|
|
|
187
187
|
for value in sub_device.values():
|
|
188
188
|
value.parent = sub_device
|
|
189
189
|
else:
|
|
190
190
|
if is_signal:
|
|
191
|
-
sub_device = device_cls(
|
|
191
|
+
sub_device = device_cls(SoftSignalBackend(signal_dtype))
|
|
192
192
|
else:
|
|
193
193
|
sub_device = getattr(device, device_name, device_cls())
|
|
194
|
-
|
|
194
|
+
_mock_common_blocks(sub_device, stripped_type=device_cls)
|
|
195
195
|
|
|
196
196
|
setattr(device, device_name, sub_device)
|
|
197
197
|
sub_device.parent = device
|
|
@@ -269,16 +269,16 @@ def _set_device_attributes(entry: PVIEntry):
|
|
|
269
269
|
|
|
270
270
|
|
|
271
271
|
async def fill_pvi_entries(
|
|
272
|
-
device: Device, root_pv: str, timeout=DEFAULT_TIMEOUT,
|
|
272
|
+
device: Device, root_pv: str, timeout=DEFAULT_TIMEOUT, mock=False
|
|
273
273
|
):
|
|
274
274
|
"""
|
|
275
275
|
Fills a ``device`` with signals from a the ``root_pvi:PVI`` table.
|
|
276
276
|
|
|
277
277
|
If the device names match with parent devices of ``device`` then types are used.
|
|
278
278
|
"""
|
|
279
|
-
if
|
|
280
|
-
# set up
|
|
281
|
-
|
|
279
|
+
if mock:
|
|
280
|
+
# set up mock signals for the common annotations
|
|
281
|
+
_mock_common_blocks(device)
|
|
282
282
|
else:
|
|
283
283
|
# check the pvi table for devices and fill the device with them
|
|
284
284
|
root_entry = PVIEntry(
|
ophyd_async/log.py
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
import colorlog
|
|
5
|
+
|
|
6
|
+
__all__ = (
|
|
7
|
+
"config_ophyd_async_logging",
|
|
8
|
+
"logger",
|
|
9
|
+
"set_handler",
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
DEFAULT_FORMAT = (
|
|
13
|
+
"%(log_color)s[%(levelname)1.1s %(asctime)s.%(msecs)03d "
|
|
14
|
+
"%(module)s:%(lineno)d] %(message)s"
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
DEFAULT_DATE_FORMAT = "%y%m%d %H:%M:%S"
|
|
18
|
+
|
|
19
|
+
DEFAULT_LOG_COLORS = {
|
|
20
|
+
"DEBUG": "cyan",
|
|
21
|
+
"INFO": "green",
|
|
22
|
+
"WARNING": "yellow",
|
|
23
|
+
"ERROR": "red",
|
|
24
|
+
"CRITICAL": "red,bg_white",
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class ColoredFormatterWithDeviceName(colorlog.ColoredFormatter):
|
|
29
|
+
def format(self, record):
|
|
30
|
+
message = super().format(record)
|
|
31
|
+
if hasattr(record, "ophyd_async_device_name"):
|
|
32
|
+
message = f"[{record.ophyd_async_device_name}]{message}"
|
|
33
|
+
return message
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _validate_level(level) -> int:
|
|
37
|
+
"""
|
|
38
|
+
Return an int for level comparison
|
|
39
|
+
"""
|
|
40
|
+
if isinstance(level, int):
|
|
41
|
+
levelno = level
|
|
42
|
+
elif isinstance(level, str):
|
|
43
|
+
levelno = logging.getLevelName(level)
|
|
44
|
+
|
|
45
|
+
if isinstance(levelno, int):
|
|
46
|
+
return levelno
|
|
47
|
+
else:
|
|
48
|
+
raise ValueError(
|
|
49
|
+
"Your level is illegal, please use "
|
|
50
|
+
"'CRITICAL', 'FATAL', 'ERROR', 'WARNING', 'INFO', or 'DEBUG'."
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
logger = logging.getLogger("ophyd_async")
|
|
55
|
+
|
|
56
|
+
current_handler = None # overwritten below
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def config_ophyd_async_logging(
|
|
60
|
+
file=sys.stdout,
|
|
61
|
+
fmt=DEFAULT_FORMAT,
|
|
62
|
+
datefmt=DEFAULT_DATE_FORMAT,
|
|
63
|
+
color=True,
|
|
64
|
+
level="WARNING",
|
|
65
|
+
):
|
|
66
|
+
"""
|
|
67
|
+
Set a new handler on the ``logging.getLogger('ophyd_async')`` logger.
|
|
68
|
+
If this is called more than once, the handler from the previous invocation
|
|
69
|
+
is removed (if still present) and replaced.
|
|
70
|
+
|
|
71
|
+
Parameters
|
|
72
|
+
----------
|
|
73
|
+
file : object with ``write`` method or filename string
|
|
74
|
+
Default is ``sys.stdout``.
|
|
75
|
+
fmt : Overall logging format
|
|
76
|
+
datefmt : string
|
|
77
|
+
Date format. Default is ``'%H:%M:%S'``.
|
|
78
|
+
color : boolean
|
|
79
|
+
Use ANSI color codes. True by default.
|
|
80
|
+
level : str or int
|
|
81
|
+
Python logging level, given as string or corresponding integer.
|
|
82
|
+
Default is 'WARNING'.
|
|
83
|
+
Returns
|
|
84
|
+
-------
|
|
85
|
+
handler : logging.Handler
|
|
86
|
+
The handler, which has already been added to the 'ophyd_async' logger.
|
|
87
|
+
Examples
|
|
88
|
+
--------
|
|
89
|
+
Log to a file.
|
|
90
|
+
config_ophyd_async_logging(file='/tmp/what_is_happening.txt')
|
|
91
|
+
Include the date along with the time. (The log messages will always include
|
|
92
|
+
microseconds, which are configured separately, not as part of 'datefmt'.)
|
|
93
|
+
config_ophyd_async_logging(datefmt="%Y-%m-%d %H:%M:%S")
|
|
94
|
+
Turn off ANSI color codes.
|
|
95
|
+
config_ophyd_async_logging(color=False)
|
|
96
|
+
Increase verbosity: show level DEBUG or higher.
|
|
97
|
+
config_ophyd_async_logging(level='DEBUG')
|
|
98
|
+
"""
|
|
99
|
+
global current_handler
|
|
100
|
+
|
|
101
|
+
if isinstance(file, str):
|
|
102
|
+
handler = logging.FileHandler(file)
|
|
103
|
+
formatter = ColoredFormatterWithDeviceName(
|
|
104
|
+
fmt=fmt, datefmt=datefmt, no_color=True
|
|
105
|
+
)
|
|
106
|
+
else:
|
|
107
|
+
handler = colorlog.StreamHandler(file)
|
|
108
|
+
formatter = ColoredFormatterWithDeviceName(
|
|
109
|
+
fmt=fmt, datefmt=datefmt, log_colors=DEFAULT_LOG_COLORS, no_color=color
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
levelno = _validate_level(level)
|
|
113
|
+
handler.setFormatter(formatter)
|
|
114
|
+
handler.setLevel(levelno)
|
|
115
|
+
|
|
116
|
+
if current_handler in logger.handlers:
|
|
117
|
+
logger.removeHandler(current_handler)
|
|
118
|
+
logger.addHandler(handler)
|
|
119
|
+
|
|
120
|
+
current_handler = handler
|
|
121
|
+
|
|
122
|
+
if logger.getEffectiveLevel() > levelno:
|
|
123
|
+
logger.setLevel(levelno)
|
|
124
|
+
try:
|
|
125
|
+
return handler
|
|
126
|
+
finally:
|
|
127
|
+
handler.close()
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
set_handler = config_ophyd_async_logging # for back-compat
|
ophyd_async/panda/_hdf_panda.py
CHANGED
|
@@ -42,7 +42,7 @@ class HDFPanda(CommonPandaBlocks, StandardDetector):
|
|
|
42
42
|
)
|
|
43
43
|
|
|
44
44
|
async def connect(
|
|
45
|
-
self,
|
|
45
|
+
self, mock: bool = False, timeout: float = DEFAULT_TIMEOUT
|
|
46
46
|
) -> None:
|
|
47
|
-
await fill_pvi_entries(self, self._prefix + "PVI", timeout=timeout,
|
|
48
|
-
await super().connect(
|
|
47
|
+
await fill_pvi_entries(self, self._prefix + "PVI", timeout=timeout, mock=mock)
|
|
48
|
+
await super().connect(mock=mock, timeout=timeout)
|
|
@@ -4,7 +4,7 @@ from enum import Enum
|
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
from typing import Any, AsyncGenerator, AsyncIterator, Dict, List, Optional
|
|
6
6
|
|
|
7
|
-
from bluesky.protocols import
|
|
7
|
+
from bluesky.protocols import DataKey, StreamAsset
|
|
8
8
|
from p4p.client.thread import Context
|
|
9
9
|
|
|
10
10
|
from ophyd_async.core import (
|
|
@@ -107,7 +107,7 @@ class PandaHDFWriter(DetectorWriter):
|
|
|
107
107
|
self._multiplier = 1
|
|
108
108
|
|
|
109
109
|
# Triggered on PCAP arm
|
|
110
|
-
async def open(self, multiplier: int = 1) -> Dict[str,
|
|
110
|
+
async def open(self, multiplier: int = 1) -> Dict[str, DataKey]:
|
|
111
111
|
"""Retrieve and get descriptor of all PandA signals marked for capture"""
|
|
112
112
|
|
|
113
113
|
# Get capture PVs by looking at panda. Gives mapping of dotted attribute path
|
|
@@ -162,7 +162,7 @@ class PandaHDFWriter(DetectorWriter):
|
|
|
162
162
|
)
|
|
163
163
|
|
|
164
164
|
describe = {
|
|
165
|
-
ds.name:
|
|
165
|
+
ds.name: DataKey(
|
|
166
166
|
source=self.panda_device.data.hdf_directory.source,
|
|
167
167
|
shape=ds.shape,
|
|
168
168
|
dtype="array" if ds.shape != [1] else "number",
|
ophyd_async/protocols.py
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
from abc import abstractmethod
|
|
2
2
|
from typing import Dict, Protocol, runtime_checkable
|
|
3
3
|
|
|
4
|
-
from bluesky.protocols import
|
|
4
|
+
from bluesky.protocols import DataKey, HasName, Reading
|
|
5
|
+
|
|
6
|
+
from ophyd_async.core.async_status import AsyncStatus
|
|
5
7
|
|
|
6
8
|
|
|
7
9
|
@runtime_checkable
|
|
@@ -23,7 +25,7 @@ class AsyncReadable(HasName, Protocol):
|
|
|
23
25
|
...
|
|
24
26
|
|
|
25
27
|
@abstractmethod
|
|
26
|
-
async def describe(self) -> Dict[str,
|
|
28
|
+
async def describe(self) -> Dict[str, DataKey]:
|
|
27
29
|
"""Return an OrderedDict with exactly the same keys as the ``read``
|
|
28
30
|
method, here mapped to per-scan metadata about each field.
|
|
29
31
|
|
|
@@ -53,7 +55,7 @@ class AsyncConfigurable(Protocol):
|
|
|
53
55
|
...
|
|
54
56
|
|
|
55
57
|
@abstractmethod
|
|
56
|
-
async def describe_configuration(self) -> Dict[str,
|
|
58
|
+
async def describe_configuration(self) -> Dict[str, DataKey]:
|
|
57
59
|
"""Same API as ``describe``, but corresponding to the keys in
|
|
58
60
|
``read_configuration``.
|
|
59
61
|
"""
|
|
@@ -71,3 +73,24 @@ class AsyncPausable(Protocol):
|
|
|
71
73
|
async def resume(self) -> None:
|
|
72
74
|
"""Perform device-specific work when the RunEngine resumes after a pause."""
|
|
73
75
|
...
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@runtime_checkable
|
|
79
|
+
class AsyncStageable(Protocol):
|
|
80
|
+
@abstractmethod
|
|
81
|
+
def stage(self) -> AsyncStatus:
|
|
82
|
+
"""An optional hook for "setting up" the device for acquisition.
|
|
83
|
+
|
|
84
|
+
It should return a ``Status`` that is marked done when the device is
|
|
85
|
+
done staging.
|
|
86
|
+
"""
|
|
87
|
+
...
|
|
88
|
+
|
|
89
|
+
@abstractmethod
|
|
90
|
+
def unstage(self) -> AsyncStatus:
|
|
91
|
+
"""A hook for "cleaning up" the device after acquisition.
|
|
92
|
+
|
|
93
|
+
It should return a ``Status`` that is marked done when the device is finished
|
|
94
|
+
unstaging.
|
|
95
|
+
"""
|
|
96
|
+
...
|
|
@@ -6,7 +6,8 @@ from bluesky.protocols import Movable, Stoppable
|
|
|
6
6
|
|
|
7
7
|
from ophyd_async.core import StandardReadable
|
|
8
8
|
from ophyd_async.core.async_status import AsyncStatus
|
|
9
|
-
from ophyd_async.core.signal import
|
|
9
|
+
from ophyd_async.core.signal import soft_signal_r_and_setter, soft_signal_rw
|
|
10
|
+
from ophyd_async.core.standard_readable import ConfigSignal, HintedSignal
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
class SimMotor(StandardReadable, Movable, Stoppable):
|
|
@@ -19,20 +20,21 @@ class SimMotor(StandardReadable, Movable, Stoppable):
|
|
|
19
20
|
- name: str: name of device
|
|
20
21
|
- instant: bool: whether to move instantly, or with a delay
|
|
21
22
|
"""
|
|
23
|
+
with self.add_children_as_readables(HintedSignal):
|
|
24
|
+
self.user_readback, self._user_readback_set = soft_signal_r_and_setter(
|
|
25
|
+
float, 0
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
with self.add_children_as_readables(ConfigSignal):
|
|
29
|
+
self.velocity = soft_signal_rw(float, 1.0)
|
|
30
|
+
self.egu = soft_signal_rw(float, "mm")
|
|
31
|
+
|
|
22
32
|
self._instant = instant
|
|
23
33
|
self._move_task: Optional[asyncio.Task] = None
|
|
24
34
|
|
|
25
35
|
# Define some signals
|
|
26
36
|
self.user_setpoint = soft_signal_rw(float, 0)
|
|
27
|
-
|
|
28
|
-
self.velocity = soft_signal_rw(float, 1.0)
|
|
29
|
-
self.egu = soft_signal_rw(float, "mm")
|
|
30
|
-
|
|
31
|
-
# Set name and signals for read() and read_configuration()
|
|
32
|
-
self.set_readable_signals(
|
|
33
|
-
read=[self.user_readback],
|
|
34
|
-
config=[self.velocity, self.egu],
|
|
35
|
-
)
|
|
37
|
+
|
|
36
38
|
super().__init__(name=name)
|
|
37
39
|
|
|
38
40
|
# Whether set() should complete successfully or not
|
|
@@ -82,7 +84,7 @@ class SimMotor(StandardReadable, Movable, Stoppable):
|
|
|
82
84
|
# update position based on time elapsed
|
|
83
85
|
if time_elapsed >= travel_time:
|
|
84
86
|
# successfully reached our target position
|
|
85
|
-
|
|
87
|
+
self._user_readback_set(new_position)
|
|
86
88
|
self._set_success = True
|
|
87
89
|
break
|
|
88
90
|
else:
|
|
@@ -90,7 +92,7 @@ class SimMotor(StandardReadable, Movable, Stoppable):
|
|
|
90
92
|
old_position + distance * time_elapsed / travel_time
|
|
91
93
|
)
|
|
92
94
|
|
|
93
|
-
|
|
95
|
+
self._user_readback_set(current_position)
|
|
94
96
|
|
|
95
97
|
# notify watchers of the new position
|
|
96
98
|
for watcher in watchers:
|
|
@@ -13,7 +13,7 @@ from typing import (
|
|
|
13
13
|
|
|
14
14
|
import h5py
|
|
15
15
|
import numpy as np
|
|
16
|
-
from bluesky.protocols import
|
|
16
|
+
from bluesky.protocols import DataKey, StreamAsset
|
|
17
17
|
from event_model import (
|
|
18
18
|
ComposeStreamResource,
|
|
19
19
|
ComposeStreamResourceBundle,
|
|
@@ -23,8 +23,8 @@ from event_model import (
|
|
|
23
23
|
)
|
|
24
24
|
|
|
25
25
|
from ophyd_async.core import DirectoryInfo, DirectoryProvider
|
|
26
|
+
from ophyd_async.core.mock_signal_backend import MockSignalBackend
|
|
26
27
|
from ophyd_async.core.signal import SignalR, observe_value
|
|
27
|
-
from ophyd_async.core.sim_signal_backend import SimSignalBackend
|
|
28
28
|
from ophyd_async.core.utils import DEFAULT_TIMEOUT
|
|
29
29
|
|
|
30
30
|
# raw data path
|
|
@@ -52,12 +52,12 @@ class DatasetConfig:
|
|
|
52
52
|
def get_full_file_description(
|
|
53
53
|
datasets: List[DatasetConfig], outer_shape: tuple[int, ...]
|
|
54
54
|
):
|
|
55
|
-
full_file_description: Dict[str,
|
|
55
|
+
full_file_description: Dict[str, DataKey] = {}
|
|
56
56
|
for d in datasets:
|
|
57
57
|
source = f"soft://{d.name}"
|
|
58
58
|
shape = outer_shape + tuple(d.shape)
|
|
59
59
|
dtype = "number" if d.shape == [1] else "array"
|
|
60
|
-
descriptor =
|
|
60
|
+
descriptor = DataKey(
|
|
61
61
|
source=source, shape=shape, dtype=dtype, external="STREAM:"
|
|
62
62
|
)
|
|
63
63
|
key = d.name.replace("/", "_")
|
|
@@ -158,8 +158,8 @@ class PatternGenerator:
|
|
|
158
158
|
self.written_images_counter: int = 0
|
|
159
159
|
|
|
160
160
|
# it automatically initializes to 0
|
|
161
|
-
self.signal_backend =
|
|
162
|
-
self.
|
|
161
|
+
self.signal_backend = MockSignalBackend(int)
|
|
162
|
+
self.mock_signal = SignalR(self.signal_backend)
|
|
163
163
|
blob = np.array(
|
|
164
164
|
generate_gaussian_blob(width=detector_width, height=detector_height)
|
|
165
165
|
* MAX_UINT8_VALUE
|
|
@@ -219,8 +219,8 @@ class PatternGenerator:
|
|
|
219
219
|
|
|
220
220
|
async def open_file(
|
|
221
221
|
self, directory: DirectoryProvider, multiplier: int = 1
|
|
222
|
-
) -> Dict[str,
|
|
223
|
-
await self.
|
|
222
|
+
) -> Dict[str, DataKey]:
|
|
223
|
+
await self.mock_signal.connect()
|
|
224
224
|
|
|
225
225
|
self.target_path = self._get_new_path(directory)
|
|
226
226
|
|
|
@@ -314,5 +314,5 @@ class PatternGenerator:
|
|
|
314
314
|
async def observe_indices_written(
|
|
315
315
|
self, timeout=DEFAULT_TIMEOUT
|
|
316
316
|
) -> AsyncGenerator[int, None]:
|
|
317
|
-
async for num_captured in observe_value(self.
|
|
317
|
+
async for num_captured in observe_value(self.mock_signal, timeout=timeout):
|
|
318
318
|
yield num_captured // self.multiplier
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from typing import AsyncGenerator, AsyncIterator, Dict
|
|
2
2
|
|
|
3
|
-
from bluesky.protocols import
|
|
3
|
+
from bluesky.protocols import DataKey
|
|
4
4
|
|
|
5
5
|
from ophyd_async.core import DirectoryProvider
|
|
6
6
|
from ophyd_async.core.detector import DetectorWriter
|
|
@@ -16,7 +16,7 @@ class SimPatternDetectorWriter(DetectorWriter):
|
|
|
16
16
|
self.pattern_generator = pattern_generator
|
|
17
17
|
self.directory_provider = directoryProvider
|
|
18
18
|
|
|
19
|
-
async def open(self, multiplier: int = 1) -> Dict[str,
|
|
19
|
+
async def open(self, multiplier: int = 1) -> Dict[str, DataKey]:
|
|
20
20
|
return await self.pattern_generator.open_file(
|
|
21
21
|
self.directory_provider, multiplier
|
|
22
22
|
)
|
|
@@ -3,7 +3,7 @@ from typing import Sequence
|
|
|
3
3
|
|
|
4
4
|
from ophyd_async.core import DirectoryProvider, StaticDirectoryProvider
|
|
5
5
|
from ophyd_async.core.detector import StandardDetector
|
|
6
|
-
from ophyd_async.
|
|
6
|
+
from ophyd_async.protocols import AsyncReadable
|
|
7
7
|
from ophyd_async.sim.pattern_generator import PatternGenerator
|
|
8
8
|
|
|
9
9
|
from .sim_pattern_detector_control import SimPatternDetectorControl
|
|
@@ -14,7 +14,7 @@ class SimPatternDetector(StandardDetector):
|
|
|
14
14
|
def __init__(
|
|
15
15
|
self,
|
|
16
16
|
path: Path,
|
|
17
|
-
config_sigs: Sequence[
|
|
17
|
+
config_sigs: Sequence[AsyncReadable] = [],
|
|
18
18
|
name: str = "sim_pattern_detector",
|
|
19
19
|
writer_timeout: float = 1,
|
|
20
20
|
) -> None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ophyd-async
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3a4
|
|
4
4
|
Summary: Asynchronous Bluesky hardware abstraction code, compatible with control systems like EPICS and Tango
|
|
5
5
|
Author-email: Tom Cobb <tom.cobb@diamond.ac.uk>
|
|
6
6
|
License: BSD 3-Clause License
|
|
@@ -48,6 +48,7 @@ Requires-Dist: bluesky >=1.13.0a3
|
|
|
48
48
|
Requires-Dist: event-model <1.21.0
|
|
49
49
|
Requires-Dist: p4p
|
|
50
50
|
Requires-Dist: pyyaml
|
|
51
|
+
Requires-Dist: colorlog
|
|
51
52
|
Provides-Extra: ca
|
|
52
53
|
Requires-Dist: aioca >=1.6 ; extra == 'ca'
|
|
53
54
|
Provides-Extra: dev
|
|
@@ -70,7 +71,7 @@ Requires-Dist: pipdeptree ; extra == 'dev'
|
|
|
70
71
|
Requires-Dist: pre-commit ; extra == 'dev'
|
|
71
72
|
Requires-Dist: pydata-sphinx-theme >=0.12 ; extra == 'dev'
|
|
72
73
|
Requires-Dist: pyepics >=3.4.2 ; extra == 'dev'
|
|
73
|
-
Requires-Dist: pyside6 ==6.
|
|
74
|
+
Requires-Dist: pyside6 ==6.7.0 ; extra == 'dev'
|
|
74
75
|
Requires-Dist: pytest ; extra == 'dev'
|
|
75
76
|
Requires-Dist: pytest-asyncio ; extra == 'dev'
|
|
76
77
|
Requires-Dist: pytest-cov ; extra == 'dev'
|
|
@@ -79,6 +80,7 @@ Requires-Dist: pytest-rerunfailures ; extra == 'dev'
|
|
|
79
80
|
Requires-Dist: pytest-timeout ; extra == 'dev'
|
|
80
81
|
Requires-Dist: ruff ; extra == 'dev'
|
|
81
82
|
Requires-Dist: sphinx-autobuild ; extra == 'dev'
|
|
83
|
+
Requires-Dist: sphinxcontrib-mermaid ; extra == 'dev'
|
|
82
84
|
Requires-Dist: sphinx-copybutton ; extra == 'dev'
|
|
83
85
|
Requires-Dist: sphinx-design ; extra == 'dev'
|
|
84
86
|
Requires-Dist: tox-direct ; extra == 'dev'
|
|
@@ -92,7 +94,7 @@ Requires-Dist: p4p ; extra == 'pva'
|
|
|
92
94
|
[](https://pypi.org/project/ophyd-async)
|
|
93
95
|
[](https://opensource.org/licenses/BSD-3-Clause)
|
|
94
96
|
|
|
95
|
-
#
|
|
97
|
+
# ophyd-async
|
|
96
98
|
|
|
97
99
|
Asynchronous Bluesky hardware abstraction code, compatible with control systems like EPICS and Tango
|
|
98
100
|
|
|
@@ -102,6 +104,21 @@ Asynchronous Bluesky hardware abstraction code, compatible with control systems
|
|
|
102
104
|
| Documentation | <https://bluesky.github.io/ophyd-async> |
|
|
103
105
|
| Releases | <https://github.com/bluesky/ophyd-async/releases> |
|
|
104
106
|
|
|
107
|
+
Ophyd-async is a Python library for asynchronously interfacing with hardware, intended to
|
|
108
|
+
be used as an abstraction layer that enables experiment orchestration and data acquisition code to operate above the specifics of particular devices and control
|
|
109
|
+
systems.
|
|
110
|
+
|
|
111
|
+
Both ophyd and ophyd-async are typically used with the [Bluesky Run Engine][] for experiment orchestration and data acquisition.
|
|
112
|
+
|
|
113
|
+
While [EPICS][] is the most common control system layer that ophyd-async can interface with, support for other control systems like [Tango][] will be supported in the future. The focus of ophyd-async is:
|
|
114
|
+
|
|
115
|
+
* Asynchronous signal access, opening the possibility for hardware-triggered scanning (also known as fly-scanning)
|
|
116
|
+
* Simpler instantiation of devices (groupings of signals) with less reliance upon complex class hierarchies
|
|
117
|
+
|
|
118
|
+
[Bluesky Run Engine]: http://blueskyproject.io/bluesky
|
|
119
|
+
[EPICS]: http://www.aps.anl.gov/epics/
|
|
120
|
+
[Tango]: https://www.tango-controls.org/
|
|
121
|
+
|
|
105
122
|
<!-- README only content. Anything below this line won't be included in index.md -->
|
|
106
123
|
|
|
107
124
|
See https://bluesky.github.io/ophyd-async for more detailed documentation.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
ophyd_async/__init__.py,sha256=v-rRiDOgZ3sQSMQKq0vgUQZvpeOkoHFXissAx6Ktg84,61
|
|
2
|
+
ophyd_async/__main__.py,sha256=G-Zcv_G9zK7Nhx6o5L5w-wyhMxdl_WgyMELu8IMFqAE,328
|
|
3
|
+
ophyd_async/_version.py,sha256=KnUL22nu-ueGx6I5b6OJXJXe49pxXyZLEJ7g8y71WnM,408
|
|
4
|
+
ophyd_async/log.py,sha256=DbMjt0bkfUOLHIinZYt0Q0FHZmCXXi5x8y0uFiEmqoQ,3587
|
|
5
|
+
ophyd_async/protocols.py,sha256=48jqS78KAMvy6LmenL21ARoTAD8oOL9YdVmIlI0E0VA,2890
|
|
6
|
+
ophyd_async/core/__init__.py,sha256=h1jha-uq0_QfQx2ZD8wit5a58doHfNebyK1mxHMKTUI,2843
|
|
7
|
+
ophyd_async/core/_providers.py,sha256=LrlTMPHKXWOPVkpAOw-pqBq0kip-c3C9ZZPoFfiaV4M,2212
|
|
8
|
+
ophyd_async/core/async_status.py,sha256=7cf5vfOaP6qZ8GW7sl--IZOi8CaLfPM5ULa8H1K3aeA,2803
|
|
9
|
+
ophyd_async/core/detector.py,sha256=OkdaaJnj2v8DKF4k7VsTo8ReAvIzyFjBqbqdiYf7FBE,11179
|
|
10
|
+
ophyd_async/core/device.py,sha256=xoxz0Iz4vovOWwpUzecDFLtLyJb_aLVi2EBnwxMyeMQ,6209
|
|
11
|
+
ophyd_async/core/device_save_loader.py,sha256=RXA3dPUPihAR2ZGDStlGiA-TAsr_xqL0snsCjMsMnfA,9138
|
|
12
|
+
ophyd_async/core/flyer.py,sha256=LfO3EQTW2zMeNqZh8TLXvE92E30Duds2RXskRYAdJ_4,2299
|
|
13
|
+
ophyd_async/core/mock_signal_backend.py,sha256=MZQr1oGv2ssnAK9WxItthiZogCh8rw4BL2N4YoHCgww,3041
|
|
14
|
+
ophyd_async/core/mock_signal_utils.py,sha256=weaH1PnjyzIxo2FmhLwx4o5i-X71srvvvsHsN3C4XqY,4267
|
|
15
|
+
ophyd_async/core/signal.py,sha256=zjfS_QuPNx9bm8K4tpZYrxqba5A1CHAlRPYg1kokrAQ,14674
|
|
16
|
+
ophyd_async/core/signal_backend.py,sha256=qDdWz8X4CWStuYknxcj4G76BLq4TzrAIyZO1NOEq9ao,1519
|
|
17
|
+
ophyd_async/core/soft_signal_backend.py,sha256=56zvcEi4c8n1yYbafTbp7X0VhSkhoehm3L8RBhu2fik,5596
|
|
18
|
+
ophyd_async/core/standard_readable.py,sha256=uVG3vs3s7-Kzg5dRCtT4I2mhZPqwVGYy2dxNmaOpDVU,8980
|
|
19
|
+
ophyd_async/core/utils.py,sha256=AVF5e42CVG_GaLoHJSI82iC4KAO60fb9fEJMISHBCNM,5043
|
|
20
|
+
ophyd_async/epics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
|
+
ophyd_async/epics/_backend/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
|
+
ophyd_async/epics/_backend/_aioca.py,sha256=cpPNZmRMi7FnAh2-3ec5uklLVFOqsmEmpI1nh5Ud1Ls,8794
|
|
23
|
+
ophyd_async/epics/_backend/_p4p.py,sha256=lIKx7kQ2o8h3M4wPwrq8JBo8xuDnasJxpDH2ATVBY78,12257
|
|
24
|
+
ophyd_async/epics/_backend/common.py,sha256=16mAuxDwA3eZFjUW8DHMabaW3CtEI0Qe8DLpP2xlW7Y,814
|
|
25
|
+
ophyd_async/epics/areadetector/__init__.py,sha256=ViKzx-wUxkRyNR33wfpL11QB97o0J47_KMyI2C_NphI,510
|
|
26
|
+
ophyd_async/epics/areadetector/aravis.py,sha256=ujO82hYZ5D5GIaBhz0JNC2G5uVSgowY8xxsY2tunzi4,2277
|
|
27
|
+
ophyd_async/epics/areadetector/kinetix.py,sha256=7rE2MLnz9DEmeiN9pCekDfpXuZ2DErnMajRp_9eoLZY,1359
|
|
28
|
+
ophyd_async/epics/areadetector/pilatus.py,sha256=ki-BOBCEIiUD2wAtmujBIB1eX-nbXB4yMLJK_Q3opRM,1398
|
|
29
|
+
ophyd_async/epics/areadetector/single_trigger_det.py,sha256=U92dqhioIfnve3jtCThq9gXBCdEzzqzY4ezk6rZV19g,1182
|
|
30
|
+
ophyd_async/epics/areadetector/utils.py,sha256=p66UbVdKRFj6Sm1Qvm23kmlVyBMMqIvXFxA3x17YnSk,2824
|
|
31
|
+
ophyd_async/epics/areadetector/vimba.py,sha256=IxG8KLzfb84iLtzf6ZoX9JikqZLP49lwkWu33bkDV9Y,1291
|
|
32
|
+
ophyd_async/epics/areadetector/controllers/__init__.py,sha256=af58ci7X2z2s_FyUwR3IGQrws8q4TKcBw7vFyIS5FoI,217
|
|
33
|
+
ophyd_async/epics/areadetector/controllers/ad_sim_controller.py,sha256=mthZ6WxajMEgUKptq3bnkIctbLhjzTagV66i1auB8cg,1587
|
|
34
|
+
ophyd_async/epics/areadetector/controllers/aravis_controller.py,sha256=vRiSexnFzijG8eEwowMAFIe730xFNMmgjjbXQVi4zrc,2394
|
|
35
|
+
ophyd_async/epics/areadetector/controllers/kinetix_controller.py,sha256=9QmydX85QOXfQL_UX49M9EQ2b2hUZPVzLxgGQn-A9Oc,1611
|
|
36
|
+
ophyd_async/epics/areadetector/controllers/pilatus_controller.py,sha256=cd1CKkaXlwkpQ0I1VL7nN0U8R4VweTsa08WhvHYI4nY,2243
|
|
37
|
+
ophyd_async/epics/areadetector/controllers/vimba_controller.py,sha256=Eh4Hr9rWgq1mKvE93JzgixntjPHxF3_07GTFqiOdZqE,2123
|
|
38
|
+
ophyd_async/epics/areadetector/drivers/__init__.py,sha256=-Ib0Lz4fFQQmB7K0uFxMDvAerkLxadMQERH7lNAvrs4,495
|
|
39
|
+
ophyd_async/epics/areadetector/drivers/ad_base.py,sha256=cE7I-IsfQz3UR9yqghy4czAxHeHERTTKe080GB9sCFQ,3847
|
|
40
|
+
ophyd_async/epics/areadetector/drivers/aravis_driver.py,sha256=2KbfcsAN2lYXWDc773KS0tE37Fw5gs7IATbDBOyLD-8,5704
|
|
41
|
+
ophyd_async/epics/areadetector/drivers/kinetix_driver.py,sha256=yIV23BkGBJ4i0VskLiLL7AFbadCCR6Ch1UwUDJ9r2YM,743
|
|
42
|
+
ophyd_async/epics/areadetector/drivers/pilatus_driver.py,sha256=0DsUu9vAPXDa2v8_V0f_kPjBtLu3y4_EkmFfFjYO4Gk,553
|
|
43
|
+
ophyd_async/epics/areadetector/drivers/vimba_driver.py,sha256=J54VtWkOklfbSqZYxGWH1e6Uzm9_Gph_ZbCf9Zax0LU,1713
|
|
44
|
+
ophyd_async/epics/areadetector/writers/__init__.py,sha256=tpPcrYd1hs8WS7C0gmCnR2EBwjE5RzCljI7WwZ2V_LM,191
|
|
45
|
+
ophyd_async/epics/areadetector/writers/_hdfdataset.py,sha256=E0C9VgsPyY35h7k0mvcIhjsIVNavApLxizqNWlM388w,167
|
|
46
|
+
ophyd_async/epics/areadetector/writers/_hdffile.py,sha256=YtUgOKX53m0TaFEGBW671qXqNuuEKxEyLV5Ein1fjvo,1799
|
|
47
|
+
ophyd_async/epics/areadetector/writers/hdf_writer.py,sha256=e7EbusP3Ell-2npdLtDWcZ_kDIRidUwHeqcbeMx4mlU,5427
|
|
48
|
+
ophyd_async/epics/areadetector/writers/nd_file_hdf.py,sha256=whKDkvKnU1qiDym4xQq4Fd1jHEhtDu552xhhGSnB--w,1910
|
|
49
|
+
ophyd_async/epics/areadetector/writers/nd_plugin.py,sha256=sG4XZAS_k065g88n9U3IJGtYI4PPHfyJMcVqh9hVAa4,979
|
|
50
|
+
ophyd_async/epics/demo/__init__.py,sha256=D-jYrorqa5C3gLzIi2Hkn8f8uaE9wb5S-WX3YYuHV48,6052
|
|
51
|
+
ophyd_async/epics/demo/demo_ad_sim_detector.py,sha256=06y65yvaqXvL2rDocjYyLz9kTVzuwV-LeuPhEfExdOA,944
|
|
52
|
+
ophyd_async/epics/demo/mover.db,sha256=RFz0rxZue689Wh1sWTZwWeFMUrH04ttPq2u5xJH_Fp4,998
|
|
53
|
+
ophyd_async/epics/demo/sensor.db,sha256=AVtiydrdtwAz2EFurO2Ult9SSRtre3r0akOBbL98LT0,554
|
|
54
|
+
ophyd_async/epics/motion/__init__.py,sha256=tnmVRIwKa9PdN_xonJdAUD04UpEceh-hoD7XI62yDB0,46
|
|
55
|
+
ophyd_async/epics/motion/motor.py,sha256=9sWF2oawtKLL1JZIT8FZc8WtKhrZVKfmwgyQv0x48B4,3826
|
|
56
|
+
ophyd_async/epics/pvi/__init__.py,sha256=TbOQNY4enQWgtr1T7x129vpo2p7FIFlr8cyZqqv5Lk4,158
|
|
57
|
+
ophyd_async/epics/pvi/pvi.py,sha256=5Hd9BkULbVv9mCmEn3LFafs2oz77xqlGHn-X48nJ-4o,11331
|
|
58
|
+
ophyd_async/epics/signal/__init__.py,sha256=wb93RTqvSbGKVFQj8OHykbVLGLmwKHU72oi5xYu2UaY,188
|
|
59
|
+
ophyd_async/epics/signal/_epics_transport.py,sha256=DEIL0iYUAWssysVEgWGu1fHSM1l-ATV2kjUgPtDN9LY,858
|
|
60
|
+
ophyd_async/epics/signal/signal.py,sha256=M8ZVG_zLdYJfroCRX-u_w8c3yIhswSRw8e3RkW2szio,3166
|
|
61
|
+
ophyd_async/panda/__init__.py,sha256=ZaD1nRgGKAGFGdpP1WWF-FnX3wcGuYqqq0QRZbaSBYQ,692
|
|
62
|
+
ophyd_async/panda/_common_blocks.py,sha256=n0PPc1rar43oDSIA-yNubTc8fR5YCW1tyjQU58whsg0,1038
|
|
63
|
+
ophyd_async/panda/_hdf_panda.py,sha256=QjfZyYos0ZBlIqBiZ5UbyEd_wuh_cGzwV8QE9jvLiIY,1419
|
|
64
|
+
ophyd_async/panda/_panda_controller.py,sha256=dIqcjmaIHVrki8UXSoDx46kk6I2Lhpe2o3sXNg5f-RQ,1238
|
|
65
|
+
ophyd_async/panda/_table.py,sha256=dLoRP4zYNOkD_s0Vkp2wVYAwkjVG8nNdf8-FaXOTfPo,5655
|
|
66
|
+
ophyd_async/panda/_trigger.py,sha256=tBH8uq_4o1ASG9yofVxq3tjf5v8LPzniDTRL4yjramI,1195
|
|
67
|
+
ophyd_async/panda/_utils.py,sha256=VHW5kPVISyEkmse_qQcyisBkkEwMO6GG2Ago-CH1AFA,487
|
|
68
|
+
ophyd_async/panda/writers/__init__.py,sha256=xy7BguVQG4HNIDBfKPjMj0KQo1tptC9LbCpEuMcVGaM,70
|
|
69
|
+
ophyd_async/panda/writers/_hdf_writer.py,sha256=_KlawqQHuWXLCvhGg1N6S4dQ8LhM88NbHsbXryxPvPA,7617
|
|
70
|
+
ophyd_async/panda/writers/_panda_hdf_file.py,sha256=42iHaTax4JjOBpNC7d4nkNL9SM14OTnFPTIcXv2jg-4,1759
|
|
71
|
+
ophyd_async/planstubs/__init__.py,sha256=G9B80_d87lnOThUsGbAYPqzMw9xDelq2TbS7dkB692o,188
|
|
72
|
+
ophyd_async/planstubs/prepare_trigger_and_dets.py,sha256=0c4XDAxVkSanyDKtaMda0VgPEbk2jM0geVzAx707DhI,1772
|
|
73
|
+
ophyd_async/sim/__init__.py,sha256=ScjH1g7FMo5yPACfJRZE6xGBWCHU4bKDzNQk1tqObnA,366
|
|
74
|
+
ophyd_async/sim/pattern_generator.py,sha256=pvSk2zb82D08j2jiKAMqMAfRohGnYd_rpjUraLrCD6c,10640
|
|
75
|
+
ophyd_async/sim/sim_pattern_detector_control.py,sha256=Ypz8IuRYAY2J243IhVbNyGr_Z-XtpJZ1qxma6NR3TgM,1838
|
|
76
|
+
ophyd_async/sim/sim_pattern_detector_writer.py,sha256=ESpcVyHd1TP7Cojznv2hJAwLinu3XbgAiVKfX12FCII,1237
|
|
77
|
+
ophyd_async/sim/sim_pattern_generator.py,sha256=fbcwWxTPYKLK33OzIY15vGylnonOO8HIudz1y_56GZU,1336
|
|
78
|
+
ophyd_async/sim/demo/__init__.py,sha256=9mxKpslrL89cfSj4g3og8Br3O--pMj3hhWZS-Xu6kyA,56
|
|
79
|
+
ophyd_async/sim/demo/sim_motor.py,sha256=knpfyrqeNr7HnlV54TQGUr3pLnDyg84vfj_4vKB9UYc,4065
|
|
80
|
+
ophyd_async-0.3a4.dist-info/LICENSE,sha256=pU5shZcsvWgz701EbT7yjFZ8rMvZcWgRH54CRt8ld_c,1517
|
|
81
|
+
ophyd_async-0.3a4.dist-info/METADATA,sha256=wPoVN6LuWFSMlFzEaAriOPfJD-XncaJHVzpao8HUBlg,6284
|
|
82
|
+
ophyd_async-0.3a4.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
83
|
+
ophyd_async-0.3a4.dist-info/entry_points.txt,sha256=O0YNJTEufO0w9BozXi-JurTy2U1_o0ypeCgJLQ727Jk,58
|
|
84
|
+
ophyd_async-0.3a4.dist-info/top_level.txt,sha256=-hjorMsv5Rmjo3qrgqhjpal1N6kW5vMxZO3lD4iEaXs,12
|
|
85
|
+
ophyd_async-0.3a4.dist-info/RECORD,,
|