ophyd-async 0.3.4a1__py3-none-any.whl → 0.5.0__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 +2 -2
- ophyd_async/core/__init__.py +86 -63
- ophyd_async/core/{detector.py → _detector.py} +18 -23
- ophyd_async/core/{device.py → _device.py} +19 -7
- ophyd_async/core/{device_save_loader.py → _device_save_loader.py} +3 -3
- ophyd_async/core/{flyer.py → _flyer.py} +6 -8
- ophyd_async/core/_hdf_dataset.py +97 -0
- ophyd_async/{log.py → core/_log.py} +11 -3
- ophyd_async/core/{mock_signal_backend.py → _mock_signal_backend.py} +3 -3
- ophyd_async/core/{mock_signal_utils.py → _mock_signal_utils.py} +3 -4
- ophyd_async/{protocols.py → core/_protocol.py} +1 -1
- ophyd_async/core/_providers.py +186 -24
- ophyd_async/core/{standard_readable.py → _readable.py} +6 -16
- ophyd_async/core/{signal.py → _signal.py} +39 -16
- ophyd_async/core/{signal_backend.py → _signal_backend.py} +4 -13
- ophyd_async/core/{soft_signal_backend.py → _soft_signal_backend.py} +24 -18
- ophyd_async/core/{async_status.py → _status.py} +3 -11
- ophyd_async/epics/adaravis/__init__.py +9 -0
- ophyd_async/epics/{areadetector/aravis.py → adaravis/_aravis.py} +12 -14
- ophyd_async/epics/{areadetector/controllers/aravis_controller.py → adaravis/_aravis_controller.py} +8 -10
- ophyd_async/epics/{areadetector/drivers/aravis_driver.py → adaravis/_aravis_io.py} +6 -3
- ophyd_async/epics/adcore/__init__.py +36 -0
- ophyd_async/epics/adcore/_core_io.py +114 -0
- ophyd_async/epics/{areadetector/drivers/ad_base.py → adcore/_core_logic.py} +17 -52
- ophyd_async/epics/{areadetector/writers/hdf_writer.py → adcore/_hdf_writer.py} +36 -18
- ophyd_async/epics/{areadetector/single_trigger_det.py → adcore/_single_trigger.py} +5 -6
- ophyd_async/epics/{areadetector/utils.py → adcore/_utils.py} +29 -0
- ophyd_async/epics/adkinetix/__init__.py +9 -0
- ophyd_async/epics/{areadetector/kinetix.py → adkinetix/_kinetix.py} +12 -14
- ophyd_async/epics/{areadetector/controllers/kinetix_controller.py → adkinetix/_kinetix_controller.py} +6 -9
- ophyd_async/epics/{areadetector/drivers/kinetix_driver.py → adkinetix/_kinetix_io.py} +5 -4
- ophyd_async/epics/adpilatus/__init__.py +11 -0
- ophyd_async/epics/{areadetector/pilatus.py → adpilatus/_pilatus.py} +12 -16
- ophyd_async/epics/{areadetector/controllers/pilatus_controller.py → adpilatus/_pilatus_controller.py} +14 -16
- ophyd_async/epics/{areadetector/drivers/pilatus_driver.py → adpilatus/_pilatus_io.py} +5 -3
- ophyd_async/epics/adsimdetector/__init__.py +7 -0
- ophyd_async/epics/adsimdetector/_sim.py +34 -0
- ophyd_async/epics/{areadetector/controllers/ad_sim_controller.py → adsimdetector/_sim_controller.py} +8 -14
- ophyd_async/epics/advimba/__init__.py +9 -0
- ophyd_async/epics/advimba/_vimba.py +43 -0
- ophyd_async/epics/{areadetector/controllers/vimba_controller.py → advimba/_vimba_controller.py} +6 -14
- ophyd_async/epics/{areadetector/drivers/vimba_driver.py → advimba/_vimba_io.py} +5 -4
- ophyd_async/epics/demo/__init__.py +9 -132
- ophyd_async/epics/demo/_mover.py +97 -0
- ophyd_async/epics/demo/_sensor.py +36 -0
- ophyd_async/epics/motor.py +228 -0
- ophyd_async/epics/pvi/__init__.py +2 -2
- ophyd_async/epics/pvi/{pvi.py → _pvi.py} +17 -14
- ophyd_async/epics/signal/__init__.py +7 -1
- ophyd_async/epics/{_backend → signal}/_aioca.py +6 -2
- ophyd_async/epics/{_backend/common.py → signal/_common.py} +4 -2
- ophyd_async/epics/signal/_epics_transport.py +3 -3
- ophyd_async/epics/{_backend → signal}/_p4p.py +53 -4
- ophyd_async/epics/signal/{signal.py → _signal.py} +10 -9
- ophyd_async/fastcs/odin/__init__.py +0 -0
- ophyd_async/{panda → fastcs/panda}/__init__.py +28 -9
- ophyd_async/{panda → fastcs/panda}/_common_blocks.py +24 -3
- ophyd_async/{panda → fastcs/panda}/_hdf_panda.py +6 -9
- ophyd_async/{panda/writers → fastcs/panda}/_hdf_writer.py +24 -14
- ophyd_async/{panda → fastcs/panda}/_panda_controller.py +2 -1
- ophyd_async/{panda → fastcs/panda}/_table.py +20 -18
- ophyd_async/fastcs/panda/_trigger.py +90 -0
- ophyd_async/plan_stubs/__init__.py +2 -2
- ophyd_async/plan_stubs/_ensure_connected.py +26 -0
- ophyd_async/plan_stubs/{fly.py → _fly.py} +67 -12
- ophyd_async/sim/__init__.py +0 -11
- ophyd_async/sim/demo/__init__.py +18 -2
- ophyd_async/sim/demo/_pattern_detector/__init__.py +13 -0
- ophyd_async/sim/demo/_pattern_detector/_pattern_detector.py +42 -0
- ophyd_async/sim/{sim_pattern_detector_control.py → demo/_pattern_detector/_pattern_detector_controller.py} +6 -7
- ophyd_async/sim/{sim_pattern_detector_writer.py → demo/_pattern_detector/_pattern_detector_writer.py} +12 -8
- ophyd_async/sim/demo/_pattern_detector/_pattern_generator.py +211 -0
- ophyd_async/sim/demo/{sim_motor.py → _sim_motor.py} +7 -5
- ophyd_async/sim/testing/__init__.py +0 -0
- ophyd_async/tango/__init__.py +0 -0
- {ophyd_async-0.3.4a1.dist-info → ophyd_async-0.5.0.dist-info}/METADATA +7 -2
- ophyd_async-0.5.0.dist-info/RECORD +89 -0
- {ophyd_async-0.3.4a1.dist-info → ophyd_async-0.5.0.dist-info}/WHEEL +1 -1
- ophyd_async/epics/areadetector/__init__.py +0 -23
- ophyd_async/epics/areadetector/controllers/__init__.py +0 -5
- ophyd_async/epics/areadetector/drivers/__init__.py +0 -23
- ophyd_async/epics/areadetector/vimba.py +0 -43
- ophyd_async/epics/areadetector/writers/__init__.py +0 -5
- ophyd_async/epics/areadetector/writers/_hdfdataset.py +0 -10
- ophyd_async/epics/areadetector/writers/_hdffile.py +0 -54
- ophyd_async/epics/areadetector/writers/nd_file_hdf.py +0 -40
- ophyd_async/epics/areadetector/writers/nd_plugin.py +0 -38
- ophyd_async/epics/demo/demo_ad_sim_detector.py +0 -35
- ophyd_async/epics/motion/__init__.py +0 -3
- ophyd_async/epics/motion/motor.py +0 -97
- ophyd_async/panda/_trigger.py +0 -39
- ophyd_async/panda/writers/__init__.py +0 -3
- ophyd_async/panda/writers/_panda_hdf_file.py +0 -54
- ophyd_async/plan_stubs/ensure_connected.py +0 -22
- ophyd_async/sim/pattern_generator.py +0 -318
- ophyd_async/sim/sim_pattern_generator.py +0 -35
- ophyd_async-0.3.4a1.dist-info/RECORD +0 -86
- /ophyd_async/core/{utils.py → _utils.py} +0 -0
- /ophyd_async/{epics/_backend → fastcs}/__init__.py +0 -0
- /ophyd_async/{panda → fastcs/panda}/_utils.py +0 -0
- {ophyd_async-0.3.4a1.dist-info → ophyd_async-0.5.0.dist-info}/LICENSE +0 -0
- {ophyd_async-0.3.4a1.dist-info → ophyd_async-0.5.0.dist-info}/entry_points.txt +0 -0
- {ophyd_async-0.3.4a1.dist-info → ophyd_async-0.5.0.dist-info}/top_level.txt +0 -0
ophyd_async/_version.py
CHANGED
ophyd_async/core/__init__.py
CHANGED
|
@@ -1,20 +1,13 @@
|
|
|
1
|
-
from .
|
|
2
|
-
DirectoryInfo,
|
|
3
|
-
DirectoryProvider,
|
|
4
|
-
NameProvider,
|
|
5
|
-
ShapeProvider,
|
|
6
|
-
StaticDirectoryProvider,
|
|
7
|
-
)
|
|
8
|
-
from .async_status import AsyncStatus, WatchableAsyncStatus
|
|
9
|
-
from .detector import (
|
|
1
|
+
from ._detector import (
|
|
10
2
|
DetectorControl,
|
|
11
3
|
DetectorTrigger,
|
|
12
4
|
DetectorWriter,
|
|
13
5
|
StandardDetector,
|
|
14
6
|
TriggerInfo,
|
|
15
7
|
)
|
|
16
|
-
from .
|
|
17
|
-
from .
|
|
8
|
+
from ._device import Device, DeviceCollector, DeviceVector
|
|
9
|
+
from ._device_save_loader import (
|
|
10
|
+
all_at_once,
|
|
18
11
|
get_signal_values,
|
|
19
12
|
load_device,
|
|
20
13
|
load_from_yaml,
|
|
@@ -23,9 +16,11 @@ from .device_save_loader import (
|
|
|
23
16
|
set_signal_values,
|
|
24
17
|
walk_rw_signals,
|
|
25
18
|
)
|
|
26
|
-
from .
|
|
27
|
-
from .
|
|
28
|
-
from .
|
|
19
|
+
from ._flyer import StandardFlyer, TriggerLogic
|
|
20
|
+
from ._hdf_dataset import HDFDataset, HDFFile
|
|
21
|
+
from ._log import config_ophyd_async_logging
|
|
22
|
+
from ._mock_signal_backend import MockSignalBackend
|
|
23
|
+
from ._mock_signal_utils import (
|
|
29
24
|
callback_on_mock_put,
|
|
30
25
|
get_mock_put,
|
|
31
26
|
mock_puts_blocked,
|
|
@@ -34,7 +29,22 @@ from .mock_signal_utils import (
|
|
|
34
29
|
set_mock_value,
|
|
35
30
|
set_mock_values,
|
|
36
31
|
)
|
|
37
|
-
from .
|
|
32
|
+
from ._protocol import AsyncConfigurable, AsyncReadable, AsyncStageable
|
|
33
|
+
from ._providers import (
|
|
34
|
+
AutoIncrementFilenameProvider,
|
|
35
|
+
AutoIncrementingPathProvider,
|
|
36
|
+
FilenameProvider,
|
|
37
|
+
NameProvider,
|
|
38
|
+
PathInfo,
|
|
39
|
+
PathProvider,
|
|
40
|
+
ShapeProvider,
|
|
41
|
+
StaticFilenameProvider,
|
|
42
|
+
StaticPathProvider,
|
|
43
|
+
UUIDFilenameProvider,
|
|
44
|
+
YMDPathProvider,
|
|
45
|
+
)
|
|
46
|
+
from ._readable import ConfigSignal, HintedSignal, StandardReadable
|
|
47
|
+
from ._signal import (
|
|
38
48
|
Signal,
|
|
39
49
|
SignalR,
|
|
40
50
|
SignalRW,
|
|
@@ -50,87 +60,100 @@ from .signal import (
|
|
|
50
60
|
soft_signal_rw,
|
|
51
61
|
wait_for_value,
|
|
52
62
|
)
|
|
53
|
-
from .
|
|
54
|
-
from .
|
|
55
|
-
from .
|
|
56
|
-
from .
|
|
63
|
+
from ._signal_backend import RuntimeSubsetEnum, SignalBackend, SubsetEnum
|
|
64
|
+
from ._soft_signal_backend import SignalMetadata, SoftSignalBackend
|
|
65
|
+
from ._status import AsyncStatus, WatchableAsyncStatus
|
|
66
|
+
from ._utils import (
|
|
57
67
|
DEFAULT_TIMEOUT,
|
|
58
68
|
CalculatableTimeout,
|
|
59
69
|
CalculateTimeout,
|
|
60
|
-
Callback,
|
|
61
70
|
NotConnected,
|
|
62
71
|
ReadingValueCallback,
|
|
63
72
|
T,
|
|
73
|
+
WatcherUpdate,
|
|
64
74
|
get_dtype,
|
|
65
75
|
get_unique,
|
|
66
|
-
|
|
76
|
+
in_micros,
|
|
67
77
|
wait_for_connection,
|
|
68
78
|
)
|
|
69
79
|
|
|
70
80
|
__all__ = [
|
|
71
|
-
"AsyncStatus",
|
|
72
|
-
"CalculatableTimeout",
|
|
73
|
-
"CalculateTimeout",
|
|
74
|
-
"Callback",
|
|
75
|
-
"ConfigSignal",
|
|
76
|
-
"DEFAULT_TIMEOUT",
|
|
77
81
|
"DetectorControl",
|
|
78
82
|
"DetectorTrigger",
|
|
79
83
|
"DetectorWriter",
|
|
84
|
+
"StandardDetector",
|
|
85
|
+
"TriggerInfo",
|
|
80
86
|
"Device",
|
|
81
87
|
"DeviceCollector",
|
|
82
88
|
"DeviceVector",
|
|
83
|
-
"
|
|
84
|
-
"
|
|
85
|
-
"
|
|
86
|
-
"
|
|
89
|
+
"all_at_once",
|
|
90
|
+
"get_signal_values",
|
|
91
|
+
"load_device",
|
|
92
|
+
"load_from_yaml",
|
|
93
|
+
"save_device",
|
|
94
|
+
"save_to_yaml",
|
|
95
|
+
"set_signal_values",
|
|
96
|
+
"walk_rw_signals",
|
|
97
|
+
"StandardFlyer",
|
|
98
|
+
"TriggerLogic",
|
|
99
|
+
"HDFDataset",
|
|
100
|
+
"HDFFile",
|
|
101
|
+
"config_ophyd_async_logging",
|
|
87
102
|
"MockSignalBackend",
|
|
103
|
+
"callback_on_mock_put",
|
|
104
|
+
"get_mock_put",
|
|
105
|
+
"mock_puts_blocked",
|
|
106
|
+
"reset_mock_put_calls",
|
|
107
|
+
"set_mock_put_proceeds",
|
|
108
|
+
"set_mock_value",
|
|
109
|
+
"set_mock_values",
|
|
110
|
+
"AsyncConfigurable",
|
|
111
|
+
"AsyncReadable",
|
|
112
|
+
"AsyncStageable",
|
|
113
|
+
"AutoIncrementFilenameProvider",
|
|
114
|
+
"AutoIncrementingPathProvider",
|
|
115
|
+
"FilenameProvider",
|
|
88
116
|
"NameProvider",
|
|
89
|
-
"
|
|
90
|
-
"
|
|
91
|
-
"RuntimeSubsetEnum",
|
|
92
|
-
"SubsetEnum",
|
|
117
|
+
"PathInfo",
|
|
118
|
+
"PathProvider",
|
|
93
119
|
"ShapeProvider",
|
|
120
|
+
"StaticFilenameProvider",
|
|
121
|
+
"StaticPathProvider",
|
|
122
|
+
"UUIDFilenameProvider",
|
|
123
|
+
"YMDPathProvider",
|
|
124
|
+
"ConfigSignal",
|
|
125
|
+
"HintedSignal",
|
|
126
|
+
"StandardReadable",
|
|
94
127
|
"Signal",
|
|
95
|
-
"SignalBackend",
|
|
96
128
|
"SignalR",
|
|
97
129
|
"SignalRW",
|
|
98
130
|
"SignalW",
|
|
99
131
|
"SignalX",
|
|
100
|
-
"SoftSignalBackend",
|
|
101
|
-
"StandardDetector",
|
|
102
|
-
"StandardReadable",
|
|
103
|
-
"StaticDirectoryProvider",
|
|
104
|
-
"T",
|
|
105
|
-
"TriggerInfo",
|
|
106
|
-
"TriggerLogic",
|
|
107
|
-
"WatchableAsyncStatus",
|
|
108
132
|
"assert_configuration",
|
|
109
133
|
"assert_emitted",
|
|
110
|
-
"assert_mock_put_called_with",
|
|
111
134
|
"assert_reading",
|
|
112
135
|
"assert_value",
|
|
113
|
-
"callback_on_mock_put",
|
|
114
|
-
"get_dtype",
|
|
115
|
-
"get_mock_put",
|
|
116
|
-
"get_signal_values",
|
|
117
|
-
"get_unique",
|
|
118
|
-
"load_device",
|
|
119
|
-
"load_from_yaml",
|
|
120
|
-
"merge_gathered_dicts",
|
|
121
|
-
"mock_puts_blocked",
|
|
122
136
|
"observe_value",
|
|
123
|
-
"reset_mock_put_calls",
|
|
124
|
-
"save_device",
|
|
125
|
-
"save_to_yaml",
|
|
126
137
|
"set_and_wait_for_value",
|
|
127
|
-
"set_mock_put_proceeds",
|
|
128
|
-
"set_mock_value",
|
|
129
|
-
"set_mock_values",
|
|
130
|
-
"set_signal_values",
|
|
131
138
|
"soft_signal_r_and_setter",
|
|
132
139
|
"soft_signal_rw",
|
|
133
|
-
"wait_for_connection",
|
|
134
140
|
"wait_for_value",
|
|
135
|
-
"
|
|
141
|
+
"RuntimeSubsetEnum",
|
|
142
|
+
"SignalBackend",
|
|
143
|
+
"SubsetEnum",
|
|
144
|
+
"SignalMetadata",
|
|
145
|
+
"SoftSignalBackend",
|
|
146
|
+
"AsyncStatus",
|
|
147
|
+
"WatchableAsyncStatus",
|
|
148
|
+
"DEFAULT_TIMEOUT",
|
|
149
|
+
"CalculatableTimeout",
|
|
150
|
+
"CalculateTimeout",
|
|
151
|
+
"NotConnected",
|
|
152
|
+
"ReadingValueCallback",
|
|
153
|
+
"T",
|
|
154
|
+
"WatcherUpdate",
|
|
155
|
+
"get_dtype",
|
|
156
|
+
"get_unique",
|
|
157
|
+
"in_micros",
|
|
158
|
+
"wait_for_connection",
|
|
136
159
|
]
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import time
|
|
5
5
|
from abc import ABC, abstractmethod
|
|
6
|
-
from dataclasses import dataclass
|
|
7
6
|
from enum import Enum
|
|
8
7
|
from typing import (
|
|
9
8
|
AsyncGenerator,
|
|
@@ -14,7 +13,6 @@ from typing import (
|
|
|
14
13
|
List,
|
|
15
14
|
Optional,
|
|
16
15
|
Sequence,
|
|
17
|
-
TypeVar,
|
|
18
16
|
)
|
|
19
17
|
|
|
20
18
|
from bluesky.protocols import (
|
|
@@ -28,14 +26,12 @@ from bluesky.protocols import (
|
|
|
28
26
|
Triggerable,
|
|
29
27
|
WritesStreamAssets,
|
|
30
28
|
)
|
|
29
|
+
from pydantic import BaseModel, Field
|
|
31
30
|
|
|
32
|
-
from
|
|
33
|
-
|
|
34
|
-
from .
|
|
35
|
-
from .
|
|
36
|
-
from .utils import DEFAULT_TIMEOUT, WatcherUpdate, merge_gathered_dicts
|
|
37
|
-
|
|
38
|
-
T = TypeVar("T")
|
|
31
|
+
from ._device import Device
|
|
32
|
+
from ._protocol import AsyncConfigurable, AsyncReadable
|
|
33
|
+
from ._status import AsyncStatus, WatchableAsyncStatus
|
|
34
|
+
from ._utils import DEFAULT_TIMEOUT, T, WatcherUpdate, merge_gathered_dicts
|
|
39
35
|
|
|
40
36
|
|
|
41
37
|
class DetectorTrigger(str, Enum):
|
|
@@ -51,20 +47,19 @@ class DetectorTrigger(str, Enum):
|
|
|
51
47
|
variable_gate = "variable_gate"
|
|
52
48
|
|
|
53
49
|
|
|
54
|
-
|
|
55
|
-
class TriggerInfo:
|
|
50
|
+
class TriggerInfo(BaseModel):
|
|
56
51
|
"""Minimal set of information required to setup triggering on a detector"""
|
|
57
52
|
|
|
58
|
-
#: Number of triggers that will be sent
|
|
59
|
-
|
|
53
|
+
#: Number of triggers that will be sent, 0 means infinite
|
|
54
|
+
number: int = Field(gt=0)
|
|
60
55
|
#: Sort of triggers that will be sent
|
|
61
|
-
trigger: DetectorTrigger
|
|
56
|
+
trigger: DetectorTrigger = Field()
|
|
62
57
|
#: What is the minimum deadtime between triggers
|
|
63
|
-
deadtime: float
|
|
58
|
+
deadtime: float = Field(ge=0)
|
|
64
59
|
#: What is the maximum high time of the triggers
|
|
65
|
-
livetime: float
|
|
60
|
+
livetime: float = Field(ge=0)
|
|
66
61
|
#: What is the maximum timeout on waiting for a frame
|
|
67
|
-
frame_timeout: float | None = None
|
|
62
|
+
frame_timeout: float | None = Field(None, gt=0)
|
|
68
63
|
|
|
69
64
|
|
|
70
65
|
class DetectorControl(ABC):
|
|
@@ -243,12 +238,12 @@ class StandardDetector(
|
|
|
243
238
|
async def trigger(self) -> None:
|
|
244
239
|
# set default trigger_info
|
|
245
240
|
self._trigger_info = TriggerInfo(
|
|
246
|
-
|
|
241
|
+
number=1, trigger=DetectorTrigger.internal, deadtime=0.0, livetime=0.0
|
|
247
242
|
)
|
|
248
243
|
# Arm the detector and wait for it to finish.
|
|
249
244
|
indices_written = await self.writer.get_indices_written()
|
|
250
245
|
written_status = await self.controller.arm(
|
|
251
|
-
num=self._trigger_info.
|
|
246
|
+
num=self._trigger_info.number,
|
|
252
247
|
trigger=self._trigger_info.trigger,
|
|
253
248
|
)
|
|
254
249
|
await written_status
|
|
@@ -285,7 +280,7 @@ class StandardDetector(
|
|
|
285
280
|
assert type(value) is TriggerInfo
|
|
286
281
|
self._trigger_info = value
|
|
287
282
|
self._initial_frame = await self.writer.get_indices_written()
|
|
288
|
-
self._last_frame = self._initial_frame + self._trigger_info.
|
|
283
|
+
self._last_frame = self._initial_frame + self._trigger_info.number
|
|
289
284
|
|
|
290
285
|
required = self.controller.get_deadtime(self._trigger_info.livetime)
|
|
291
286
|
assert required <= self._trigger_info.deadtime, (
|
|
@@ -293,7 +288,7 @@ class StandardDetector(
|
|
|
293
288
|
f"but trigger logic provides only {self._trigger_info.deadtime}s"
|
|
294
289
|
)
|
|
295
290
|
self._arm_status = await self.controller.arm(
|
|
296
|
-
num=self._trigger_info.
|
|
291
|
+
num=self._trigger_info.number,
|
|
297
292
|
trigger=self._trigger_info.trigger,
|
|
298
293
|
exposure=self._trigger_info.livetime,
|
|
299
294
|
)
|
|
@@ -320,12 +315,12 @@ class StandardDetector(
|
|
|
320
315
|
name=self.name,
|
|
321
316
|
current=index,
|
|
322
317
|
initial=self._initial_frame,
|
|
323
|
-
target=self._trigger_info.
|
|
318
|
+
target=self._trigger_info.number,
|
|
324
319
|
unit="",
|
|
325
320
|
precision=0,
|
|
326
321
|
time_elapsed=time.monotonic() - self._fly_start,
|
|
327
322
|
)
|
|
328
|
-
if index >= self._trigger_info.
|
|
323
|
+
if index >= self._trigger_info.number:
|
|
329
324
|
break
|
|
330
325
|
|
|
331
326
|
async def describe_collect(self) -> Dict[str, DataKey]:
|
|
@@ -19,7 +19,7 @@ from typing import (
|
|
|
19
19
|
from bluesky.protocols import HasName
|
|
20
20
|
from bluesky.run_engine import call_in_bluesky_event_loop
|
|
21
21
|
|
|
22
|
-
from .
|
|
22
|
+
from ._utils import DEFAULT_TIMEOUT, NotConnected, wait_for_connection
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
class Device(HasName):
|
|
@@ -33,7 +33,10 @@ class Device(HasName):
|
|
|
33
33
|
parent: Optional["Device"] = None
|
|
34
34
|
# None if connect hasn't started, a Task if it has
|
|
35
35
|
_connect_task: Optional[asyncio.Task] = None
|
|
36
|
-
|
|
36
|
+
|
|
37
|
+
# Used to check if the previous connect was mocked,
|
|
38
|
+
# if the next mock value differs then we fail
|
|
39
|
+
_previous_connect_was_mock = None
|
|
37
40
|
|
|
38
41
|
def __init__(self, name: str = "") -> None:
|
|
39
42
|
self.set_name(name)
|
|
@@ -90,11 +93,21 @@ class Device(HasName):
|
|
|
90
93
|
timeout:
|
|
91
94
|
Time to wait before failing with a TimeoutError.
|
|
92
95
|
"""
|
|
96
|
+
|
|
97
|
+
if (
|
|
98
|
+
self._previous_connect_was_mock is not None
|
|
99
|
+
and self._previous_connect_was_mock != mock
|
|
100
|
+
):
|
|
101
|
+
raise RuntimeError(
|
|
102
|
+
f"`connect(mock={mock})` called on a `Device` where the previous "
|
|
103
|
+
f"connect was `mock={self._previous_connect_was_mock}`. Changing mock "
|
|
104
|
+
"value between connects is not permitted."
|
|
105
|
+
)
|
|
106
|
+
self._previous_connect_was_mock = mock
|
|
107
|
+
|
|
93
108
|
# If previous connect with same args has started and not errored, can use it
|
|
94
|
-
can_use_previous_connect = (
|
|
95
|
-
self._connect_task
|
|
96
|
-
and not (self._connect_task.done() and self._connect_task.exception())
|
|
97
|
-
and self._connect_mock_arg == mock
|
|
109
|
+
can_use_previous_connect = self._connect_task and not (
|
|
110
|
+
self._connect_task.done() and self._connect_task.exception()
|
|
98
111
|
)
|
|
99
112
|
if force_reconnect or not can_use_previous_connect:
|
|
100
113
|
# Kick off a connection
|
|
@@ -105,7 +118,6 @@ class Device(HasName):
|
|
|
105
118
|
for name, child_device in self.children()
|
|
106
119
|
}
|
|
107
120
|
self._connect_task = asyncio.create_task(wait_for_connection(**coros))
|
|
108
|
-
self._connect_mock_arg = mock
|
|
109
121
|
|
|
110
122
|
assert self._connect_task, "Connect task not created, this shouldn't happen"
|
|
111
123
|
# Wait for it to complete
|
|
@@ -8,8 +8,8 @@ from bluesky.plan_stubs import abs_set, wait
|
|
|
8
8
|
from bluesky.protocols import Location
|
|
9
9
|
from bluesky.utils import Msg
|
|
10
10
|
|
|
11
|
-
from .
|
|
12
|
-
from .
|
|
11
|
+
from ._device import Device
|
|
12
|
+
from ._signal import SignalRW
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
def ndarray_representer(dumper: yaml.Dumper, array: npt.NDArray[Any]) -> yaml.Node:
|
|
@@ -241,7 +241,7 @@ def save_device(
|
|
|
241
241
|
Therefore, users should consider the order of device loading and write their
|
|
242
242
|
own sorter algorithms accordingly.
|
|
243
243
|
|
|
244
|
-
See :func:`ophyd_async.panda.phase_sorter` for a valid implementation of the
|
|
244
|
+
See :func:`ophyd_async.fastcs.panda.phase_sorter` for a valid implementation of the
|
|
245
245
|
sorter.
|
|
246
246
|
|
|
247
247
|
Parameters
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
from abc import ABC, abstractmethod
|
|
2
|
-
from typing import Dict, Generic, Sequence
|
|
2
|
+
from typing import Dict, Generic, Sequence
|
|
3
3
|
|
|
4
4
|
from bluesky.protocols import DataKey, Flyable, Preparable, Reading, Stageable
|
|
5
5
|
|
|
6
|
-
from .
|
|
7
|
-
from .
|
|
8
|
-
from .
|
|
9
|
-
from .
|
|
10
|
-
|
|
11
|
-
T = TypeVar("T")
|
|
6
|
+
from ._device import Device
|
|
7
|
+
from ._signal import SignalR
|
|
8
|
+
from ._status import AsyncStatus
|
|
9
|
+
from ._utils import T, merge_gathered_dicts
|
|
12
10
|
|
|
13
11
|
|
|
14
12
|
class TriggerLogic(ABC, Generic[T]):
|
|
@@ -29,7 +27,7 @@ class TriggerLogic(ABC, Generic[T]):
|
|
|
29
27
|
"""Stop flying and wait everything to be stopped"""
|
|
30
28
|
|
|
31
29
|
|
|
32
|
-
class
|
|
30
|
+
class StandardFlyer(
|
|
33
31
|
Device,
|
|
34
32
|
Stageable,
|
|
35
33
|
Preparable,
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Iterator, List, Sequence
|
|
4
|
+
from urllib.parse import urlunparse
|
|
5
|
+
|
|
6
|
+
from event_model import (
|
|
7
|
+
ComposeStreamResource,
|
|
8
|
+
ComposeStreamResourceBundle,
|
|
9
|
+
StreamDatum,
|
|
10
|
+
StreamResource,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
from ._providers import PathInfo
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class HDFDataset:
|
|
18
|
+
data_key: str
|
|
19
|
+
dataset: str
|
|
20
|
+
shape: Sequence[int] = field(default_factory=tuple)
|
|
21
|
+
dtype_numpy: str = ""
|
|
22
|
+
multiplier: int = 1
|
|
23
|
+
swmr: bool = False
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
SLICE_NAME = "AD_HDF5_SWMR_SLICE"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class HDFFile:
|
|
30
|
+
"""
|
|
31
|
+
:param directory_info: Contains information about how to construct a StreamResource
|
|
32
|
+
:param full_file_name: Absolute path to the file to be written
|
|
33
|
+
:param datasets: Datasets to write into the file
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
def __init__(
|
|
37
|
+
self,
|
|
38
|
+
path_info: PathInfo,
|
|
39
|
+
full_file_name: Path,
|
|
40
|
+
datasets: List[HDFDataset],
|
|
41
|
+
hostname: str = "localhost",
|
|
42
|
+
) -> None:
|
|
43
|
+
self._last_emitted = 0
|
|
44
|
+
self._hostname = hostname
|
|
45
|
+
|
|
46
|
+
if len(datasets) == 0:
|
|
47
|
+
self._bundles = []
|
|
48
|
+
return None
|
|
49
|
+
|
|
50
|
+
bundler_composer = ComposeStreamResource()
|
|
51
|
+
|
|
52
|
+
uri = urlunparse(
|
|
53
|
+
(
|
|
54
|
+
"file",
|
|
55
|
+
self._hostname,
|
|
56
|
+
str((path_info.root / full_file_name).absolute()),
|
|
57
|
+
"",
|
|
58
|
+
"",
|
|
59
|
+
None,
|
|
60
|
+
)
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
self._bundles: List[ComposeStreamResourceBundle] = [
|
|
64
|
+
bundler_composer(
|
|
65
|
+
mimetype="application/x-hdf5",
|
|
66
|
+
uri=uri,
|
|
67
|
+
data_key=ds.data_key,
|
|
68
|
+
parameters={
|
|
69
|
+
"dataset": ds.dataset,
|
|
70
|
+
"swmr": ds.swmr,
|
|
71
|
+
"multiplier": ds.multiplier,
|
|
72
|
+
},
|
|
73
|
+
uid=None,
|
|
74
|
+
validate=True,
|
|
75
|
+
)
|
|
76
|
+
for ds in datasets
|
|
77
|
+
]
|
|
78
|
+
|
|
79
|
+
def stream_resources(self) -> Iterator[StreamResource]:
|
|
80
|
+
for bundle in self._bundles:
|
|
81
|
+
yield bundle.stream_resource_doc
|
|
82
|
+
|
|
83
|
+
def stream_data(self, indices_written: int) -> Iterator[StreamDatum]:
|
|
84
|
+
# Indices are relative to resource
|
|
85
|
+
if indices_written > self._last_emitted:
|
|
86
|
+
indices = {
|
|
87
|
+
"start": self._last_emitted,
|
|
88
|
+
"stop": indices_written,
|
|
89
|
+
}
|
|
90
|
+
self._last_emitted = indices_written
|
|
91
|
+
for bundle in self._bundles:
|
|
92
|
+
yield bundle.compose_stream_datum(indices)
|
|
93
|
+
return None
|
|
94
|
+
|
|
95
|
+
def close(self) -> None:
|
|
96
|
+
for bundle in self._bundles:
|
|
97
|
+
bundle.close()
|
|
@@ -34,9 +34,7 @@ class ColoredFormatterWithDeviceName(colorlog.ColoredFormatter):
|
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
def _validate_level(level) -> int:
|
|
37
|
-
"""
|
|
38
|
-
Return an int for level comparison
|
|
39
|
-
"""
|
|
37
|
+
"""Return an int for level comparison."""
|
|
40
38
|
if isinstance(level, int):
|
|
41
39
|
levelno = level
|
|
42
40
|
elif isinstance(level, str):
|
|
@@ -80,21 +78,31 @@ def config_ophyd_async_logging(
|
|
|
80
78
|
level : str or int
|
|
81
79
|
Python logging level, given as string or corresponding integer.
|
|
82
80
|
Default is 'WARNING'.
|
|
81
|
+
|
|
83
82
|
Returns
|
|
84
83
|
-------
|
|
85
84
|
handler : logging.Handler
|
|
86
85
|
The handler, which has already been added to the 'ophyd_async' logger.
|
|
86
|
+
|
|
87
87
|
Examples
|
|
88
88
|
--------
|
|
89
89
|
Log to a file.
|
|
90
|
+
|
|
90
91
|
config_ophyd_async_logging(file='/tmp/what_is_happening.txt')
|
|
92
|
+
|
|
91
93
|
Include the date along with the time. (The log messages will always include
|
|
92
94
|
microseconds, which are configured separately, not as part of 'datefmt'.)
|
|
95
|
+
|
|
93
96
|
config_ophyd_async_logging(datefmt="%Y-%m-%d %H:%M:%S")
|
|
97
|
+
|
|
94
98
|
Turn off ANSI color codes.
|
|
99
|
+
|
|
95
100
|
config_ophyd_async_logging(color=False)
|
|
101
|
+
|
|
96
102
|
Increase verbosity: show level DEBUG or higher.
|
|
103
|
+
|
|
97
104
|
config_ophyd_async_logging(level='DEBUG')
|
|
105
|
+
|
|
98
106
|
"""
|
|
99
107
|
global current_handler
|
|
100
108
|
|
|
@@ -5,9 +5,9 @@ from unittest.mock import Mock
|
|
|
5
5
|
|
|
6
6
|
from bluesky.protocols import Descriptor, Reading
|
|
7
7
|
|
|
8
|
-
from
|
|
9
|
-
from
|
|
10
|
-
from
|
|
8
|
+
from ._signal_backend import SignalBackend
|
|
9
|
+
from ._soft_signal_backend import SoftSignalBackend
|
|
10
|
+
from ._utils import DEFAULT_TIMEOUT, ReadingValueCallback, T
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class MockSignalBackend(SignalBackend[T]):
|
|
@@ -2,10 +2,9 @@ from contextlib import asynccontextmanager, contextmanager
|
|
|
2
2
|
from typing import Any, Callable, Iterable
|
|
3
3
|
from unittest.mock import Mock
|
|
4
4
|
|
|
5
|
-
from
|
|
6
|
-
from
|
|
7
|
-
|
|
8
|
-
from .mock_signal_backend import MockSignalBackend
|
|
5
|
+
from ._mock_signal_backend import MockSignalBackend
|
|
6
|
+
from ._signal import Signal
|
|
7
|
+
from ._utils import T
|
|
9
8
|
|
|
10
9
|
|
|
11
10
|
def _get_mock_signal_backend(signal: Signal) -> MockSignalBackend:
|