ophyd-async 0.4.0__py3-none-any.whl → 0.5.1__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 -73
- ophyd_async/core/{detector.py → _detector.py} +42 -36
- ophyd_async/core/{device.py → _device.py} +1 -1
- ophyd_async/core/{device_save_loader.py → _device_save_loader.py} +3 -3
- ophyd_async/core/{flyer.py → _flyer.py} +6 -8
- ophyd_async/{epics/areadetector/writers/general_hdffile.py → core/_hdf_dataset.py} +4 -8
- 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} +7 -7
- ophyd_async/{protocols.py → core/_protocol.py} +1 -1
- ophyd_async/core/_providers.py +24 -37
- ophyd_async/core/{standard_readable.py → _readable.py} +6 -16
- ophyd_async/core/{signal.py → _signal.py} +79 -35
- ophyd_async/core/{signal_backend.py → _signal_backend.py} +4 -13
- ophyd_async/core/{soft_signal_backend.py → _soft_signal_backend.py} +3 -12
- 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} +9 -11
- ophyd_async/epics/{areadetector/controllers/aravis_controller.py → adaravis/_aravis_controller.py} +7 -10
- ophyd_async/epics/{areadetector/drivers/aravis_driver.py → adaravis/_aravis_io.py} +6 -3
- ophyd_async/epics/adcore/__init__.py +47 -0
- ophyd_async/epics/adcore/_core_io.py +138 -0
- ophyd_async/epics/{areadetector/drivers/ad_base.py → adcore/_core_logic.py} +16 -52
- ophyd_async/epics/{areadetector/writers/hdf_writer.py → adcore/_hdf_writer.py} +54 -29
- ophyd_async/epics/{areadetector/single_trigger_det.py → adcore/_single_trigger.py} +5 -6
- ophyd_async/epics/adcore/_utils.py +132 -0
- ophyd_async/epics/adkinetix/__init__.py +9 -0
- ophyd_async/epics/{areadetector/kinetix.py → adkinetix/_kinetix.py} +9 -11
- 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} +9 -5
- ophyd_async/epics/adpilatus/__init__.py +11 -0
- ophyd_async/epics/{areadetector/pilatus.py → adpilatus/_pilatus.py} +10 -14
- ophyd_async/epics/{areadetector/controllers/pilatus_controller.py → adpilatus/_pilatus_controller.py} +15 -17
- ophyd_async/epics/{areadetector/drivers/pilatus_driver.py → adpilatus/_pilatus_io.py} +6 -4
- ophyd_async/epics/adsimdetector/__init__.py +7 -0
- ophyd_async/epics/{demo/demo_ad_sim_detector.py → adsimdetector/_sim.py} +10 -11
- 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/{areadetector/vimba.py → advimba/_vimba.py} +9 -9
- ophyd_async/epics/{areadetector/controllers/vimba_controller.py → advimba/_vimba_controller.py} +9 -17
- ophyd_async/epics/{areadetector/drivers/vimba_driver.py → advimba/_vimba_io.py} +11 -8
- 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/{motion/motor.py → motor.py} +28 -14
- 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 +15 -7
- ophyd_async/epics/{_backend/common.py → signal/_common.py} +2 -2
- ophyd_async/epics/signal/_epics_transport.py +3 -3
- ophyd_async/epics/{_backend → signal}/_p4p.py +18 -14
- 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 +20 -15
- ophyd_async/{panda/_common_blocks.py → fastcs/panda/_block.py} +5 -3
- ophyd_async/{panda/_panda_controller.py → fastcs/panda/_control.py} +2 -1
- ophyd_async/{panda → fastcs/panda}/_hdf_panda.py +5 -10
- ophyd_async/{panda → fastcs/panda}/_trigger.py +3 -7
- ophyd_async/{panda/writers/_hdf_writer.py → fastcs/panda/_writer.py} +36 -28
- ophyd_async/plan_stubs/__init__.py +5 -2
- ophyd_async/plan_stubs/{ensure_connected.py → _ensure_connected.py} +1 -2
- ophyd_async/plan_stubs/{fly.py → _fly.py} +13 -9
- ophyd_async/plan_stubs/_nd_attributes.py +63 -0
- 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/{sim_pattern_generator.py → demo/_pattern_detector/_pattern_detector.py} +8 -8
- ophyd_async/sim/{sim_pattern_detector_control.py → demo/_pattern_detector/_pattern_detector_controller.py} +9 -7
- ophyd_async/sim/{sim_pattern_detector_writer.py → demo/_pattern_detector/_pattern_detector_writer.py} +4 -4
- ophyd_async/sim/{pattern_generator.py → demo/_pattern_detector/_pattern_generator.py} +13 -11
- 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.4.0.dist-info → ophyd_async-0.5.1.dist-info}/METADATA +46 -44
- ophyd_async-0.5.1.dist-info/RECORD +90 -0
- {ophyd_async-0.4.0.dist-info → ophyd_async-0.5.1.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/utils.py +0 -104
- ophyd_async/epics/areadetector/writers/__init__.py +0 -5
- ophyd_async/epics/areadetector/writers/nd_file_hdf.py +0 -43
- ophyd_async/epics/areadetector/writers/nd_plugin.py +0 -68
- ophyd_async/epics/motion/__init__.py +0 -3
- ophyd_async/panda/writers/__init__.py +0 -3
- ophyd_async-0.4.0.dist-info/RECORD +0 -84
- /ophyd_async/core/{utils.py → _utils.py} +0 -0
- /ophyd_async/{epics/_backend → fastcs}/__init__.py +0 -0
- /ophyd_async/{panda → fastcs/panda}/_table.py +0 -0
- /ophyd_async/{panda → fastcs/panda}/_utils.py +0 -0
- {ophyd_async-0.4.0.dist-info → ophyd_async-0.5.1.dist-info}/LICENSE +0 -0
- {ophyd_async-0.4.0.dist-info → ophyd_async-0.5.1.dist-info}/entry_points.txt +0 -0
- {ophyd_async-0.4.0.dist-info → ophyd_async-0.5.1.dist-info}/top_level.txt +0 -0
ophyd_async/_version.py
CHANGED
ophyd_async/core/__init__.py
CHANGED
|
@@ -1,26 +1,13 @@
|
|
|
1
|
-
from .
|
|
2
|
-
AutoIncrementFilenameProvider,
|
|
3
|
-
AutoIncrementingPathProvider,
|
|
4
|
-
FilenameProvider,
|
|
5
|
-
NameProvider,
|
|
6
|
-
PathInfo,
|
|
7
|
-
PathProvider,
|
|
8
|
-
ShapeProvider,
|
|
9
|
-
StaticFilenameProvider,
|
|
10
|
-
StaticPathProvider,
|
|
11
|
-
UUIDFilenameProvider,
|
|
12
|
-
YMDPathProvider,
|
|
13
|
-
)
|
|
14
|
-
from .async_status import AsyncStatus, WatchableAsyncStatus
|
|
15
|
-
from .detector import (
|
|
1
|
+
from ._detector import (
|
|
16
2
|
DetectorControl,
|
|
17
3
|
DetectorTrigger,
|
|
18
4
|
DetectorWriter,
|
|
19
5
|
StandardDetector,
|
|
20
6
|
TriggerInfo,
|
|
21
7
|
)
|
|
22
|
-
from .
|
|
23
|
-
from .
|
|
8
|
+
from ._device import Device, DeviceCollector, DeviceVector
|
|
9
|
+
from ._device_save_loader import (
|
|
10
|
+
all_at_once,
|
|
24
11
|
get_signal_values,
|
|
25
12
|
load_device,
|
|
26
13
|
load_from_yaml,
|
|
@@ -29,9 +16,11 @@ from .device_save_loader import (
|
|
|
29
16
|
set_signal_values,
|
|
30
17
|
walk_rw_signals,
|
|
31
18
|
)
|
|
32
|
-
from .
|
|
33
|
-
from .
|
|
34
|
-
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 (
|
|
35
24
|
callback_on_mock_put,
|
|
36
25
|
get_mock_put,
|
|
37
26
|
mock_puts_blocked,
|
|
@@ -40,7 +29,22 @@ from .mock_signal_utils import (
|
|
|
40
29
|
set_mock_value,
|
|
41
30
|
set_mock_values,
|
|
42
31
|
)
|
|
43
|
-
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 (
|
|
44
48
|
Signal,
|
|
45
49
|
SignalR,
|
|
46
50
|
SignalRW,
|
|
@@ -51,98 +55,107 @@ from .signal import (
|
|
|
51
55
|
assert_reading,
|
|
52
56
|
assert_value,
|
|
53
57
|
observe_value,
|
|
58
|
+
set_and_wait_for_other_value,
|
|
54
59
|
set_and_wait_for_value,
|
|
55
60
|
soft_signal_r_and_setter,
|
|
56
61
|
soft_signal_rw,
|
|
57
62
|
wait_for_value,
|
|
58
63
|
)
|
|
59
|
-
from .
|
|
60
|
-
from .
|
|
61
|
-
from .
|
|
62
|
-
from .
|
|
64
|
+
from ._signal_backend import RuntimeSubsetEnum, SignalBackend, SubsetEnum
|
|
65
|
+
from ._soft_signal_backend import SignalMetadata, SoftSignalBackend
|
|
66
|
+
from ._status import AsyncStatus, WatchableAsyncStatus
|
|
67
|
+
from ._utils import (
|
|
63
68
|
DEFAULT_TIMEOUT,
|
|
64
69
|
CalculatableTimeout,
|
|
65
70
|
CalculateTimeout,
|
|
66
|
-
Callback,
|
|
67
71
|
NotConnected,
|
|
68
72
|
ReadingValueCallback,
|
|
69
73
|
T,
|
|
74
|
+
WatcherUpdate,
|
|
70
75
|
get_dtype,
|
|
71
76
|
get_unique,
|
|
72
|
-
|
|
77
|
+
in_micros,
|
|
73
78
|
wait_for_connection,
|
|
74
79
|
)
|
|
75
80
|
|
|
76
81
|
__all__ = [
|
|
77
|
-
"AsyncStatus",
|
|
78
|
-
"AutoIncrementFilenameProvider",
|
|
79
|
-
"AutoIncrementingPathProvider",
|
|
80
|
-
"CalculatableTimeout",
|
|
81
|
-
"CalculateTimeout",
|
|
82
|
-
"Callback",
|
|
83
|
-
"ConfigSignal",
|
|
84
|
-
"DEFAULT_TIMEOUT",
|
|
85
82
|
"DetectorControl",
|
|
86
83
|
"DetectorTrigger",
|
|
87
84
|
"DetectorWriter",
|
|
85
|
+
"StandardDetector",
|
|
86
|
+
"TriggerInfo",
|
|
88
87
|
"Device",
|
|
89
88
|
"DeviceCollector",
|
|
90
89
|
"DeviceVector",
|
|
91
|
-
"
|
|
92
|
-
"
|
|
93
|
-
"
|
|
90
|
+
"all_at_once",
|
|
91
|
+
"get_signal_values",
|
|
92
|
+
"load_device",
|
|
93
|
+
"load_from_yaml",
|
|
94
|
+
"save_device",
|
|
95
|
+
"save_to_yaml",
|
|
96
|
+
"set_signal_values",
|
|
97
|
+
"walk_rw_signals",
|
|
98
|
+
"StandardFlyer",
|
|
99
|
+
"TriggerLogic",
|
|
100
|
+
"HDFDataset",
|
|
101
|
+
"HDFFile",
|
|
102
|
+
"config_ophyd_async_logging",
|
|
94
103
|
"MockSignalBackend",
|
|
104
|
+
"callback_on_mock_put",
|
|
105
|
+
"get_mock_put",
|
|
106
|
+
"mock_puts_blocked",
|
|
107
|
+
"reset_mock_put_calls",
|
|
108
|
+
"set_mock_put_proceeds",
|
|
109
|
+
"set_mock_value",
|
|
110
|
+
"set_mock_values",
|
|
111
|
+
"AsyncConfigurable",
|
|
112
|
+
"AsyncReadable",
|
|
113
|
+
"AsyncStageable",
|
|
114
|
+
"AutoIncrementFilenameProvider",
|
|
115
|
+
"AutoIncrementingPathProvider",
|
|
116
|
+
"FilenameProvider",
|
|
95
117
|
"NameProvider",
|
|
96
|
-
"NotConnected",
|
|
97
118
|
"PathInfo",
|
|
98
119
|
"PathProvider",
|
|
99
|
-
"ReadingValueCallback",
|
|
100
|
-
"RuntimeSubsetEnum",
|
|
101
120
|
"ShapeProvider",
|
|
121
|
+
"StaticFilenameProvider",
|
|
122
|
+
"StaticPathProvider",
|
|
123
|
+
"UUIDFilenameProvider",
|
|
124
|
+
"YMDPathProvider",
|
|
125
|
+
"ConfigSignal",
|
|
126
|
+
"HintedSignal",
|
|
127
|
+
"StandardReadable",
|
|
102
128
|
"Signal",
|
|
103
|
-
"SignalBackend",
|
|
104
129
|
"SignalR",
|
|
105
130
|
"SignalRW",
|
|
106
131
|
"SignalW",
|
|
107
132
|
"SignalX",
|
|
108
|
-
"SoftSignalBackend",
|
|
109
|
-
"StandardDetector",
|
|
110
|
-
"StandardReadable",
|
|
111
|
-
"StaticFilenameProvider",
|
|
112
|
-
"StaticPathProvider",
|
|
113
|
-
"SubsetEnum",
|
|
114
|
-
"T",
|
|
115
|
-
"TriggerInfo",
|
|
116
|
-
"TriggerLogic",
|
|
117
|
-
"UUIDFilenameProvider",
|
|
118
|
-
"WatchableAsyncStatus",
|
|
119
|
-
"YMDPathProvider",
|
|
120
|
-
# Lower-cased imports
|
|
121
133
|
"assert_configuration",
|
|
122
134
|
"assert_emitted",
|
|
123
135
|
"assert_reading",
|
|
124
136
|
"assert_value",
|
|
125
|
-
"callback_on_mock_put",
|
|
126
|
-
"get_dtype",
|
|
127
|
-
"get_mock_put",
|
|
128
|
-
"get_signal_values",
|
|
129
|
-
"get_unique",
|
|
130
|
-
"load_device",
|
|
131
|
-
"load_from_yaml",
|
|
132
|
-
"merge_gathered_dicts",
|
|
133
|
-
"mock_puts_blocked",
|
|
134
137
|
"observe_value",
|
|
135
|
-
"reset_mock_put_calls",
|
|
136
|
-
"save_device",
|
|
137
|
-
"save_to_yaml",
|
|
138
138
|
"set_and_wait_for_value",
|
|
139
|
-
"
|
|
140
|
-
"set_mock_value",
|
|
141
|
-
"set_mock_values",
|
|
142
|
-
"set_signal_values",
|
|
139
|
+
"set_and_wait_for_other_value",
|
|
143
140
|
"soft_signal_r_and_setter",
|
|
144
141
|
"soft_signal_rw",
|
|
145
|
-
"wait_for_connection",
|
|
146
142
|
"wait_for_value",
|
|
147
|
-
"
|
|
143
|
+
"RuntimeSubsetEnum",
|
|
144
|
+
"SignalBackend",
|
|
145
|
+
"SubsetEnum",
|
|
146
|
+
"SignalMetadata",
|
|
147
|
+
"SoftSignalBackend",
|
|
148
|
+
"AsyncStatus",
|
|
149
|
+
"WatchableAsyncStatus",
|
|
150
|
+
"DEFAULT_TIMEOUT",
|
|
151
|
+
"CalculatableTimeout",
|
|
152
|
+
"CalculateTimeout",
|
|
153
|
+
"NotConnected",
|
|
154
|
+
"ReadingValueCallback",
|
|
155
|
+
"T",
|
|
156
|
+
"WatcherUpdate",
|
|
157
|
+
"get_dtype",
|
|
158
|
+
"get_unique",
|
|
159
|
+
"in_micros",
|
|
160
|
+
"wait_for_connection",
|
|
148
161
|
]
|
|
@@ -13,7 +13,6 @@ from typing import (
|
|
|
13
13
|
List,
|
|
14
14
|
Optional,
|
|
15
15
|
Sequence,
|
|
16
|
-
TypeVar,
|
|
17
16
|
)
|
|
18
17
|
|
|
19
18
|
from bluesky.protocols import (
|
|
@@ -29,13 +28,10 @@ from bluesky.protocols import (
|
|
|
29
28
|
)
|
|
30
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):
|
|
@@ -59,11 +55,16 @@ class TriggerInfo(BaseModel):
|
|
|
59
55
|
#: Sort of triggers that will be sent
|
|
60
56
|
trigger: DetectorTrigger = Field()
|
|
61
57
|
#: What is the minimum deadtime between triggers
|
|
62
|
-
deadtime: float = Field(ge=0)
|
|
58
|
+
deadtime: float | None = Field(ge=0)
|
|
63
59
|
#: What is the maximum high time of the triggers
|
|
64
|
-
livetime: float = Field(ge=0)
|
|
60
|
+
livetime: float | None = Field(ge=0)
|
|
65
61
|
#: What is the maximum timeout on waiting for a frame
|
|
66
62
|
frame_timeout: float | None = Field(None, gt=0)
|
|
63
|
+
#: How many triggers make up a single StreamDatum index, to allow multiple frames
|
|
64
|
+
#: from a faster detector to be zipped with a single frame from a slow detector
|
|
65
|
+
#: e.g. if num=10 and multiplier=5 then the detector will take 10 frames,
|
|
66
|
+
#: but publish 2 indices, and describe() will show a shape of (5, h, w)
|
|
67
|
+
multiplier: int = 1
|
|
67
68
|
|
|
68
69
|
|
|
69
70
|
class DetectorControl(ABC):
|
|
@@ -73,7 +74,7 @@ class DetectorControl(ABC):
|
|
|
73
74
|
"""
|
|
74
75
|
|
|
75
76
|
@abstractmethod
|
|
76
|
-
def get_deadtime(self, exposure: float) -> float:
|
|
77
|
+
def get_deadtime(self, exposure: float | None) -> float:
|
|
77
78
|
"""For a given exposure, how long should the time between exposures be"""
|
|
78
79
|
|
|
79
80
|
@abstractmethod
|
|
@@ -200,10 +201,10 @@ class StandardDetector(
|
|
|
200
201
|
|
|
201
202
|
@AsyncStatus.wrap
|
|
202
203
|
async def stage(self) -> None:
|
|
203
|
-
# Disarm the detector, stop filewriting
|
|
204
|
+
# Disarm the detector, stop filewriting.
|
|
204
205
|
await self._check_config_sigs()
|
|
205
206
|
await asyncio.gather(self.writer.close(), self.controller.disarm())
|
|
206
|
-
self.
|
|
207
|
+
self._trigger_info = None
|
|
207
208
|
|
|
208
209
|
async def _check_config_sigs(self):
|
|
209
210
|
"""Checks configuration signals are named and connected."""
|
|
@@ -216,7 +217,7 @@ class StandardDetector(
|
|
|
216
217
|
await signal.get_value()
|
|
217
218
|
except NotImplementedError:
|
|
218
219
|
raise Exception(
|
|
219
|
-
f"config signal {signal.
|
|
220
|
+
f"config signal {signal.name} must be connected before it is "
|
|
220
221
|
+ "passed to the detector"
|
|
221
222
|
)
|
|
222
223
|
|
|
@@ -240,10 +241,15 @@ class StandardDetector(
|
|
|
240
241
|
|
|
241
242
|
@AsyncStatus.wrap
|
|
242
243
|
async def trigger(self) -> None:
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
244
|
+
if self._trigger_info is None:
|
|
245
|
+
await self.prepare(
|
|
246
|
+
TriggerInfo(
|
|
247
|
+
number=1,
|
|
248
|
+
trigger=DetectorTrigger.internal,
|
|
249
|
+
deadtime=None,
|
|
250
|
+
livetime=None,
|
|
251
|
+
)
|
|
252
|
+
)
|
|
247
253
|
# Arm the detector and wait for it to finish.
|
|
248
254
|
indices_written = await self.writer.get_indices_written()
|
|
249
255
|
written_status = await self.controller.arm(
|
|
@@ -254,19 +260,15 @@ class StandardDetector(
|
|
|
254
260
|
end_observation = indices_written + 1
|
|
255
261
|
|
|
256
262
|
async for index in self.writer.observe_indices_written(
|
|
257
|
-
DEFAULT_TIMEOUT
|
|
263
|
+
DEFAULT_TIMEOUT
|
|
264
|
+
+ (self._trigger_info.livetime or 0)
|
|
265
|
+
+ (self._trigger_info.deadtime or 0)
|
|
258
266
|
):
|
|
259
267
|
if index >= end_observation:
|
|
260
268
|
break
|
|
261
269
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
value: T,
|
|
265
|
-
) -> AsyncStatus:
|
|
266
|
-
# Just arm detector for the time being
|
|
267
|
-
return AsyncStatus(self._prepare(value))
|
|
268
|
-
|
|
269
|
-
async def _prepare(self, value: T) -> None:
|
|
270
|
+
@AsyncStatus.wrap
|
|
271
|
+
async def prepare(self, value: TriggerInfo) -> None:
|
|
270
272
|
"""
|
|
271
273
|
Arm detector.
|
|
272
274
|
|
|
@@ -281,22 +283,26 @@ class StandardDetector(
|
|
|
281
283
|
Args:
|
|
282
284
|
value: TriggerInfo describing how to trigger the detector
|
|
283
285
|
"""
|
|
284
|
-
assert type(value) is TriggerInfo
|
|
285
286
|
self._trigger_info = value
|
|
287
|
+
if value.trigger != DetectorTrigger.internal:
|
|
288
|
+
assert (
|
|
289
|
+
value.deadtime
|
|
290
|
+
), "Deadtime must be supplied when in externally triggered mode"
|
|
291
|
+
if value.deadtime:
|
|
292
|
+
required = self.controller.get_deadtime(self._trigger_info.livetime)
|
|
293
|
+
assert required <= value.deadtime, (
|
|
294
|
+
f"Detector {self.controller} needs at least {required}s deadtime, "
|
|
295
|
+
f"but trigger logic provides only {value.deadtime}s"
|
|
296
|
+
)
|
|
286
297
|
self._initial_frame = await self.writer.get_indices_written()
|
|
287
298
|
self._last_frame = self._initial_frame + self._trigger_info.number
|
|
288
|
-
|
|
289
|
-
required = self.controller.get_deadtime(self._trigger_info.livetime)
|
|
290
|
-
assert required <= self._trigger_info.deadtime, (
|
|
291
|
-
f"Detector {self.controller} needs at least {required}s deadtime, "
|
|
292
|
-
f"but trigger logic provides only {self._trigger_info.deadtime}s"
|
|
293
|
-
)
|
|
294
299
|
self._arm_status = await self.controller.arm(
|
|
295
300
|
num=self._trigger_info.number,
|
|
296
301
|
trigger=self._trigger_info.trigger,
|
|
297
302
|
exposure=self._trigger_info.livetime,
|
|
298
303
|
)
|
|
299
304
|
self._fly_start = time.monotonic()
|
|
305
|
+
self._describe = await self.writer.open(value.multiplier)
|
|
300
306
|
|
|
301
307
|
@AsyncStatus.wrap
|
|
302
308
|
async def kickoff(self):
|
|
@@ -311,8 +317,8 @@ class StandardDetector(
|
|
|
311
317
|
self._trigger_info.frame_timeout
|
|
312
318
|
or (
|
|
313
319
|
DEFAULT_TIMEOUT
|
|
314
|
-
+ self._trigger_info.livetime
|
|
315
|
-
+ self._trigger_info.deadtime
|
|
320
|
+
+ (self._trigger_info.livetime or 0)
|
|
321
|
+
+ (self._trigger_info.deadtime or 0)
|
|
316
322
|
)
|
|
317
323
|
):
|
|
318
324
|
yield WatcherUpdate(
|
|
@@ -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):
|
|
@@ -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,
|
|
@@ -10,11 +10,9 @@ from event_model import (
|
|
|
10
10
|
StreamResource,
|
|
11
11
|
)
|
|
12
12
|
|
|
13
|
-
from ophyd_async.core import PathInfo
|
|
14
|
-
|
|
15
13
|
|
|
16
14
|
@dataclass
|
|
17
|
-
class
|
|
15
|
+
class HDFDataset:
|
|
18
16
|
data_key: str
|
|
19
17
|
dataset: str
|
|
20
18
|
shape: Sequence[int] = field(default_factory=tuple)
|
|
@@ -26,18 +24,16 @@ class _HDFDataset:
|
|
|
26
24
|
SLICE_NAME = "AD_HDF5_SWMR_SLICE"
|
|
27
25
|
|
|
28
26
|
|
|
29
|
-
class
|
|
27
|
+
class HDFFile:
|
|
30
28
|
"""
|
|
31
|
-
:param directory_info: Contains information about how to construct a StreamResource
|
|
32
29
|
:param full_file_name: Absolute path to the file to be written
|
|
33
30
|
:param datasets: Datasets to write into the file
|
|
34
31
|
"""
|
|
35
32
|
|
|
36
33
|
def __init__(
|
|
37
34
|
self,
|
|
38
|
-
path_info: PathInfo,
|
|
39
35
|
full_file_name: Path,
|
|
40
|
-
datasets: List[
|
|
36
|
+
datasets: List[HDFDataset],
|
|
41
37
|
hostname: str = "localhost",
|
|
42
38
|
) -> None:
|
|
43
39
|
self._last_emitted = 0
|
|
@@ -53,7 +49,7 @@ class _HDFFile:
|
|
|
53
49
|
(
|
|
54
50
|
"file",
|
|
55
51
|
self._hostname,
|
|
56
|
-
str(
|
|
52
|
+
str(full_file_name.absolute()),
|
|
57
53
|
"",
|
|
58
54
|
"",
|
|
59
55
|
None,
|
|
@@ -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,18 +2,18 @@ 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:
|
|
12
|
-
|
|
11
|
+
backend = signal._backend # noqa:SLF001
|
|
12
|
+
assert isinstance(backend, MockSignalBackend), (
|
|
13
13
|
"Expected to receive a `MockSignalBackend`, instead "
|
|
14
|
-
f" received {type(
|
|
14
|
+
f" received {type(backend)}. "
|
|
15
15
|
)
|
|
16
|
-
return
|
|
16
|
+
return backend
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
def set_mock_value(signal: Signal[T], value: T):
|