ophyd-async 0.12__py3-none-any.whl → 0.12.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/_hdf_dataset.py +2 -15
- ophyd_async/core/_providers.py +69 -11
- ophyd_async/core/_soft_signal_backend.py +1 -1
- ophyd_async/epics/adcore/__init__.py +2 -0
- ophyd_async/epics/adcore/_core_io.py +15 -5
- ophyd_async/epics/adcore/_core_writer.py +34 -26
- ophyd_async/epics/adcore/_hdf_writer.py +4 -3
- ophyd_async/epics/adcore/_jpeg_writer.py +3 -3
- ophyd_async/epics/adcore/_tiff_writer.py +3 -3
- ophyd_async/epics/core/_aioca.py +3 -0
- ophyd_async/epics/testing/_utils.py +1 -1
- ophyd_async/fastcs/panda/_writer.py +1 -3
- ophyd_async/sim/__main__.py +2 -1
- ophyd_async/sim/_blob_detector_writer.py +4 -5
- ophyd_async/sim/_pattern_generator.py +3 -3
- {ophyd_async-0.12.dist-info → ophyd_async-0.12.1.dist-info}/METADATA +1 -1
- {ophyd_async-0.12.dist-info → ophyd_async-0.12.1.dist-info}/RECORD +21 -21
- {ophyd_async-0.12.dist-info → ophyd_async-0.12.1.dist-info}/WHEEL +0 -0
- {ophyd_async-0.12.dist-info → ophyd_async-0.12.1.dist-info}/licenses/LICENSE +0 -0
- {ophyd_async-0.12.dist-info → ophyd_async-0.12.1.dist-info}/top_level.txt +0 -0
ophyd_async/_version.py
CHANGED
ophyd_async/core/_hdf_dataset.py
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
from collections.abc import Iterator
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
from urllib.parse import urlunparse
|
|
4
2
|
|
|
5
3
|
from bluesky.protocols import StreamAsset
|
|
6
4
|
from event_model import ( # type: ignore
|
|
@@ -48,22 +46,11 @@ class HDFDocumentComposer:
|
|
|
48
46
|
|
|
49
47
|
def __init__(
|
|
50
48
|
self,
|
|
51
|
-
|
|
49
|
+
file_uri: str,
|
|
52
50
|
datasets: list[HDFDatasetDescription],
|
|
53
|
-
hostname: str = "localhost",
|
|
54
51
|
) -> None:
|
|
55
52
|
self._last_emitted = 0
|
|
56
|
-
|
|
57
|
-
uri = urlunparse(
|
|
58
|
-
(
|
|
59
|
-
"file",
|
|
60
|
-
self._hostname,
|
|
61
|
-
str(full_file_name.absolute()),
|
|
62
|
-
"",
|
|
63
|
-
"",
|
|
64
|
-
None,
|
|
65
|
-
)
|
|
66
|
-
)
|
|
53
|
+
uri = file_uri
|
|
67
54
|
bundler_composer = ComposeStreamResource()
|
|
68
55
|
self._bundles: list[ComposeStreamResourceBundle] = [
|
|
69
56
|
bundler_composer(
|
ophyd_async/core/_providers.py
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import os
|
|
2
1
|
import uuid
|
|
3
2
|
from abc import abstractmethod
|
|
4
3
|
from collections.abc import Callable
|
|
5
4
|
from dataclasses import dataclass
|
|
6
5
|
from datetime import date
|
|
7
|
-
from pathlib import
|
|
6
|
+
from pathlib import PurePath, PureWindowsPath
|
|
8
7
|
from typing import Protocol
|
|
8
|
+
from urllib.parse import urlunparse
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
@dataclass
|
|
@@ -16,11 +16,36 @@ class PathInfo:
|
|
|
16
16
|
:param filename: Base filename to use generated by FilenameProvider, w/o extension
|
|
17
17
|
:param create_dir_depth: Optional depth of directories to create if they do not
|
|
18
18
|
exist
|
|
19
|
+
:param directory_uri: Optional URI to use for reading back resources. If not set,
|
|
20
|
+
it will be generated from the directory path.
|
|
19
21
|
"""
|
|
20
22
|
|
|
21
|
-
directory_path:
|
|
23
|
+
directory_path: PurePath
|
|
22
24
|
filename: str
|
|
23
25
|
create_dir_depth: int = 0
|
|
26
|
+
directory_uri: str | None = None
|
|
27
|
+
|
|
28
|
+
def __post_init__(self):
|
|
29
|
+
if not self.directory_path.is_absolute():
|
|
30
|
+
raise ValueError(
|
|
31
|
+
f"directory_path must be an absolute path, got {self.directory_path}"
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
# If directory uri is not set, set it using the directory path.
|
|
35
|
+
if self.directory_uri is None:
|
|
36
|
+
self.directory_uri = urlunparse(
|
|
37
|
+
(
|
|
38
|
+
"file",
|
|
39
|
+
"localhost",
|
|
40
|
+
f"{self.directory_path.as_posix()}/",
|
|
41
|
+
"",
|
|
42
|
+
"",
|
|
43
|
+
None,
|
|
44
|
+
)
|
|
45
|
+
)
|
|
46
|
+
elif not self.directory_uri.endswith("/"):
|
|
47
|
+
# Ensure the directory URI ends with a slash.
|
|
48
|
+
self.directory_uri += "/"
|
|
24
49
|
|
|
25
50
|
|
|
26
51
|
class FilenameProvider(Protocol):
|
|
@@ -112,11 +137,13 @@ class StaticPathProvider(PathProvider):
|
|
|
112
137
|
def __init__(
|
|
113
138
|
self,
|
|
114
139
|
filename_provider: FilenameProvider,
|
|
115
|
-
directory_path:
|
|
140
|
+
directory_path: PurePath,
|
|
141
|
+
directory_uri: str | None = None,
|
|
116
142
|
create_dir_depth: int = 0,
|
|
117
143
|
) -> None:
|
|
118
144
|
self._filename_provider = filename_provider
|
|
119
|
-
self._directory_path =
|
|
145
|
+
self._directory_path = directory_path
|
|
146
|
+
self._directory_uri = directory_uri
|
|
120
147
|
self._create_dir_depth = create_dir_depth
|
|
121
148
|
|
|
122
149
|
def __call__(self, device_name: str | None = None) -> PathInfo:
|
|
@@ -124,6 +151,7 @@ class StaticPathProvider(PathProvider):
|
|
|
124
151
|
|
|
125
152
|
return PathInfo(
|
|
126
153
|
directory_path=self._directory_path,
|
|
154
|
+
directory_uri=self._directory_uri,
|
|
127
155
|
filename=filename,
|
|
128
156
|
create_dir_depth=self._create_dir_depth,
|
|
129
157
|
)
|
|
@@ -135,7 +163,8 @@ class AutoIncrementingPathProvider(PathProvider):
|
|
|
135
163
|
def __init__(
|
|
136
164
|
self,
|
|
137
165
|
filename_provider: FilenameProvider,
|
|
138
|
-
base_directory_path:
|
|
166
|
+
base_directory_path: PurePath,
|
|
167
|
+
base_directory_uri: str | None = None,
|
|
139
168
|
create_dir_depth: int = 0,
|
|
140
169
|
max_digits: int = 5,
|
|
141
170
|
starting_value: int = 0,
|
|
@@ -146,6 +175,12 @@ class AutoIncrementingPathProvider(PathProvider):
|
|
|
146
175
|
) -> None:
|
|
147
176
|
self._filename_provider = filename_provider
|
|
148
177
|
self._base_directory_path = base_directory_path
|
|
178
|
+
self._base_directory_uri = base_directory_uri
|
|
179
|
+
if (
|
|
180
|
+
self._base_directory_uri is not None
|
|
181
|
+
and not self._base_directory_uri.endswith("/")
|
|
182
|
+
):
|
|
183
|
+
self._base_directory_uri += "/"
|
|
149
184
|
self._create_dir_depth = create_dir_depth
|
|
150
185
|
self._base_name = base_name
|
|
151
186
|
self._starting_value = starting_value
|
|
@@ -174,8 +209,13 @@ class AutoIncrementingPathProvider(PathProvider):
|
|
|
174
209
|
self._inc_counter = 0
|
|
175
210
|
self._current_value += self._increment
|
|
176
211
|
|
|
212
|
+
directory_uri = None
|
|
213
|
+
if self._base_directory_uri is not None:
|
|
214
|
+
directory_uri = f"{self._base_directory_uri}{auto_inc_dir_name}"
|
|
215
|
+
|
|
177
216
|
return PathInfo(
|
|
178
217
|
directory_path=self._base_directory_path / auto_inc_dir_name,
|
|
218
|
+
directory_uri=directory_uri,
|
|
179
219
|
filename=filename,
|
|
180
220
|
create_dir_depth=self._create_dir_depth,
|
|
181
221
|
)
|
|
@@ -187,34 +227,52 @@ class YMDPathProvider(PathProvider):
|
|
|
187
227
|
def __init__(
|
|
188
228
|
self,
|
|
189
229
|
filename_provider: FilenameProvider,
|
|
190
|
-
base_directory_path:
|
|
230
|
+
base_directory_path: PurePath,
|
|
231
|
+
base_directory_uri: str | None = None,
|
|
191
232
|
create_dir_depth: int = -3, # Default to -3 to create YMD dirs
|
|
192
233
|
device_name_as_base_dir: bool = False,
|
|
193
234
|
) -> None:
|
|
194
235
|
self._filename_provider = filename_provider
|
|
195
|
-
self._base_directory_path =
|
|
236
|
+
self._base_directory_path = base_directory_path
|
|
237
|
+
self._base_directory_uri = base_directory_uri
|
|
238
|
+
if (
|
|
239
|
+
self._base_directory_uri is not None
|
|
240
|
+
and not self._base_directory_uri.endswith("/")
|
|
241
|
+
):
|
|
242
|
+
self._base_directory_uri += "/"
|
|
196
243
|
self._create_dir_depth = create_dir_depth
|
|
197
244
|
self._device_name_as_base_dir = device_name_as_base_dir
|
|
198
245
|
|
|
199
246
|
def __call__(self, device_name: str | None = None) -> PathInfo:
|
|
200
|
-
|
|
247
|
+
path_type = type(self._base_directory_path)
|
|
248
|
+
if path_type == PureWindowsPath:
|
|
249
|
+
sep = "\\"
|
|
250
|
+
else:
|
|
251
|
+
sep = "/"
|
|
252
|
+
|
|
201
253
|
current_date = date.today().strftime(f"%Y{sep}%m{sep}%d")
|
|
202
254
|
if device_name is None:
|
|
203
255
|
ymd_dir_path = current_date
|
|
204
256
|
elif self._device_name_as_base_dir:
|
|
205
|
-
ymd_dir_path =
|
|
257
|
+
ymd_dir_path = path_type(
|
|
206
258
|
current_date,
|
|
207
259
|
device_name,
|
|
208
260
|
)
|
|
209
261
|
else:
|
|
210
|
-
ymd_dir_path =
|
|
262
|
+
ymd_dir_path = path_type(
|
|
211
263
|
device_name,
|
|
212
264
|
current_date,
|
|
213
265
|
)
|
|
214
266
|
|
|
215
267
|
filename = self._filename_provider(device_name)
|
|
268
|
+
|
|
269
|
+
directory_uri = None
|
|
270
|
+
if self._base_directory_uri is not None:
|
|
271
|
+
directory_uri = f"{self._base_directory_uri}{ymd_dir_path}"
|
|
272
|
+
|
|
216
273
|
return PathInfo(
|
|
217
274
|
directory_path=self._base_directory_path / ymd_dir_path,
|
|
275
|
+
directory_uri=directory_uri,
|
|
218
276
|
filename=filename,
|
|
219
277
|
create_dir_depth=self._create_dir_depth,
|
|
220
278
|
)
|
|
@@ -148,7 +148,7 @@ class SoftSignalBackend(SignalBackend[SignalDatatypeT]):
|
|
|
148
148
|
"""Set the current value, alarm and timestamp."""
|
|
149
149
|
self.reading = Reading(
|
|
150
150
|
value=self.converter.write_value(value),
|
|
151
|
-
timestamp=time.
|
|
151
|
+
timestamp=time.time(),
|
|
152
152
|
alarm_severity=0,
|
|
153
153
|
)
|
|
154
154
|
if self.callback:
|
|
@@ -14,6 +14,7 @@ from ._core_io import (
|
|
|
14
14
|
NDCBFlushOnSoftTrgMode,
|
|
15
15
|
NDFileHDFIO,
|
|
16
16
|
NDFileIO,
|
|
17
|
+
NDFilePluginIO,
|
|
17
18
|
NDPluginBaseIO,
|
|
18
19
|
NDPluginCBIO,
|
|
19
20
|
NDPluginStatsIO,
|
|
@@ -45,6 +46,7 @@ __all__ = [
|
|
|
45
46
|
"ContAcqAreaDetector",
|
|
46
47
|
"NDArrayBaseIO",
|
|
47
48
|
"NDFileIO",
|
|
49
|
+
"NDFilePluginIO",
|
|
48
50
|
"NDFileHDFIO",
|
|
49
51
|
"NDPluginBaseIO",
|
|
50
52
|
"NDPluginStatsIO",
|
|
@@ -131,11 +131,11 @@ class ADCompression(StrictEnum):
|
|
|
131
131
|
JPEG = "JPEG"
|
|
132
132
|
|
|
133
133
|
|
|
134
|
-
class NDFileIO(
|
|
135
|
-
"""Base class from which file
|
|
134
|
+
class NDFileIO(NDArrayBaseIO):
|
|
135
|
+
"""Base class from which file writing drivers are derived.
|
|
136
136
|
|
|
137
|
-
This mirrors the interface provided by ADCore/
|
|
138
|
-
|
|
137
|
+
This mirrors the interface provided by ADCore/ADApp/Db/NDFile.template.
|
|
138
|
+
It does not include any plugin-related fields, for that see NDFilePluginIO.
|
|
139
139
|
"""
|
|
140
140
|
|
|
141
141
|
file_path: A[SignalRW[str], PvSuffix.rbv("FilePath")]
|
|
@@ -154,7 +154,17 @@ class NDFileIO(NDPluginBaseIO):
|
|
|
154
154
|
create_directory: A[SignalRW[int], PvSuffix("CreateDirectory")]
|
|
155
155
|
|
|
156
156
|
|
|
157
|
-
class
|
|
157
|
+
class NDFilePluginIO(NDPluginBaseIO, NDFileIO):
|
|
158
|
+
"""Base class from which file plugins are derived.
|
|
159
|
+
|
|
160
|
+
This mirrors the interface provided by ADCore/db/NDFilePlugin.template.
|
|
161
|
+
See HTML docs at https://areadetector.github.io/areaDetector/ADCore/NDPluginFile.html
|
|
162
|
+
"""
|
|
163
|
+
|
|
164
|
+
...
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
class NDFileHDFIO(NDFilePluginIO):
|
|
158
168
|
"""Plugin for storing data in HDF5 file format.
|
|
159
169
|
|
|
160
170
|
This mirrors the interface provided by ADCore/db/NDFileHDF5.template.
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
from collections.abc import AsyncGenerator, AsyncIterator
|
|
3
|
-
from pathlib import
|
|
3
|
+
from pathlib import PureWindowsPath
|
|
4
4
|
from typing import Generic, TypeVar, get_args
|
|
5
|
-
from urllib.parse import urlunparse
|
|
6
5
|
|
|
7
6
|
from bluesky.protocols import Hints, StreamAsset
|
|
8
7
|
from event_model import ( # type: ignore
|
|
@@ -13,14 +12,14 @@ from event_model import ( # type: ignore
|
|
|
13
12
|
from pydantic import PositiveInt
|
|
14
13
|
|
|
15
14
|
from ophyd_async.core._detector import DetectorWriter
|
|
16
|
-
from ophyd_async.core._providers import DatasetDescriber, PathProvider
|
|
15
|
+
from ophyd_async.core._providers import DatasetDescriber, PathInfo, PathProvider
|
|
17
16
|
from ophyd_async.core._signal import (
|
|
18
17
|
observe_value,
|
|
19
18
|
set_and_wait_for_value,
|
|
20
19
|
wait_for_value,
|
|
21
20
|
)
|
|
22
21
|
from ophyd_async.core._status import AsyncStatus
|
|
23
|
-
from ophyd_async.core._utils import DEFAULT_TIMEOUT
|
|
22
|
+
from ophyd_async.core._utils import DEFAULT_TIMEOUT, error_if_none
|
|
24
23
|
|
|
25
24
|
# from ophyd_async.epics.adcore._core_logic import ADBaseDatasetDescriber
|
|
26
25
|
from ._core_io import (
|
|
@@ -28,6 +27,7 @@ from ._core_io import (
|
|
|
28
27
|
ADCallbacks,
|
|
29
28
|
NDArrayBaseIO,
|
|
30
29
|
NDFileIO,
|
|
30
|
+
NDFilePluginIO,
|
|
31
31
|
NDPluginBaseIO,
|
|
32
32
|
)
|
|
33
33
|
from ._utils import ADFileWriteMode
|
|
@@ -52,7 +52,8 @@ class ADWriter(DetectorWriter, Generic[NDFileIOT]):
|
|
|
52
52
|
) -> None:
|
|
53
53
|
self._plugins = plugins or {}
|
|
54
54
|
self.fileio = fileio
|
|
55
|
-
self._path_provider = path_provider
|
|
55
|
+
self._path_provider: PathProvider = path_provider
|
|
56
|
+
self._path_info: PathInfo | None = None
|
|
56
57
|
self._dataset_describer = dataset_describer
|
|
57
58
|
self._file_extension = file_extension
|
|
58
59
|
self._mimetype = mimetype
|
|
@@ -82,19 +83,32 @@ class ADWriter(DetectorWriter, Generic[NDFileIOT]):
|
|
|
82
83
|
writer = cls(fileio, path_provider, dataset_describer, plugins=plugins)
|
|
83
84
|
return writer
|
|
84
85
|
|
|
85
|
-
async def
|
|
86
|
-
|
|
86
|
+
async def _begin_capture(self, name: str) -> None:
|
|
87
|
+
path_info = error_if_none(
|
|
88
|
+
self._path_info, "Writer must be opened before beginning capture!"
|
|
89
|
+
)
|
|
87
90
|
|
|
88
|
-
|
|
91
|
+
if isinstance(self.fileio, NDFilePluginIO):
|
|
92
|
+
await self.fileio.enable_callbacks.set(ADCallbacks.ENABLE)
|
|
89
93
|
|
|
90
94
|
# Set the directory creation depth first, since dir creation callback happens
|
|
91
95
|
# when directory path PV is processed.
|
|
92
|
-
await self.fileio.create_directory.set(
|
|
96
|
+
await self.fileio.create_directory.set(path_info.create_dir_depth)
|
|
97
|
+
|
|
98
|
+
# Need to ensure that trailing separator is added to the directory path.
|
|
99
|
+
# When setting the path for windows based AD IOCs, a '/' is added rather than
|
|
100
|
+
# a '\\', which will cause the readback to never register the same value.
|
|
101
|
+
dir_path_as_str = str(path_info.directory_path)
|
|
102
|
+
separator = "/"
|
|
103
|
+
if isinstance(path_info.directory_path, PureWindowsPath):
|
|
104
|
+
separator = "\\"
|
|
105
|
+
|
|
106
|
+
dir_path_as_str += separator
|
|
93
107
|
|
|
94
108
|
await asyncio.gather(
|
|
95
109
|
# See https://github.com/bluesky/ophyd-async/issues/122
|
|
96
|
-
self.fileio.file_path.set(
|
|
97
|
-
self.fileio.file_name.set(
|
|
110
|
+
self.fileio.file_path.set(dir_path_as_str),
|
|
111
|
+
self.fileio.file_name.set(path_info.filename),
|
|
98
112
|
self.fileio.file_write_mode.set(ADFileWriteMode.STREAM),
|
|
99
113
|
# For non-HDF file writers, use AD file templating mechanism
|
|
100
114
|
# for generating multi-image datasets
|
|
@@ -106,7 +120,7 @@ class ADWriter(DetectorWriter, Generic[NDFileIOT]):
|
|
|
106
120
|
)
|
|
107
121
|
|
|
108
122
|
if not await self.fileio.file_path_exists.get_value():
|
|
109
|
-
msg = f"
|
|
123
|
+
msg = f"Path {dir_path_as_str} doesn't exist or not writable!"
|
|
110
124
|
raise FileNotFoundError(msg)
|
|
111
125
|
|
|
112
126
|
# Overwrite num_capture to go forever
|
|
@@ -125,7 +139,9 @@ class ADWriter(DetectorWriter, Generic[NDFileIOT]):
|
|
|
125
139
|
frame_shape = await self._dataset_describer.shape()
|
|
126
140
|
dtype_numpy = await self._dataset_describer.np_datatype()
|
|
127
141
|
|
|
128
|
-
|
|
142
|
+
self._path_info = self._path_provider(device_name=name)
|
|
143
|
+
|
|
144
|
+
await self._begin_capture(name)
|
|
129
145
|
|
|
130
146
|
describe = {
|
|
131
147
|
name: DataKey(
|
|
@@ -152,30 +168,22 @@ class ADWriter(DetectorWriter, Generic[NDFileIOT]):
|
|
|
152
168
|
async def collect_stream_docs(
|
|
153
169
|
self, name: str, indices_written: int
|
|
154
170
|
) -> AsyncIterator[StreamAsset]:
|
|
171
|
+
path_info = error_if_none(
|
|
172
|
+
self._path_info, "Writer must be opened before collecting stream docs!"
|
|
173
|
+
)
|
|
174
|
+
|
|
155
175
|
if indices_written:
|
|
156
176
|
if not self._emitted_resource:
|
|
157
|
-
file_path = Path(await self.fileio.file_path.get_value())
|
|
158
177
|
file_name = await self.fileio.file_name.get_value()
|
|
159
178
|
file_template = file_name + "_{:06d}" + self._file_extension
|
|
160
179
|
|
|
161
180
|
frame_shape = await self._dataset_describer.shape()
|
|
162
181
|
|
|
163
|
-
uri = urlunparse(
|
|
164
|
-
(
|
|
165
|
-
"file",
|
|
166
|
-
"localhost",
|
|
167
|
-
str(file_path.absolute()) + "/",
|
|
168
|
-
"",
|
|
169
|
-
"",
|
|
170
|
-
None,
|
|
171
|
-
)
|
|
172
|
-
)
|
|
173
|
-
|
|
174
182
|
bundler_composer = ComposeStreamResource()
|
|
175
183
|
|
|
176
184
|
self._emitted_resource = bundler_composer(
|
|
177
185
|
mimetype=self._mimetype,
|
|
178
|
-
uri=
|
|
186
|
+
uri=str(path_info.directory_uri),
|
|
179
187
|
# TODO no reference to detector's name
|
|
180
188
|
data_key=name,
|
|
181
189
|
parameters={
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
from collections.abc import AsyncIterator
|
|
3
|
-
from pathlib import Path
|
|
4
3
|
from typing import TypeGuard
|
|
5
4
|
from xml.etree import ElementTree as ET
|
|
6
5
|
|
|
@@ -65,8 +64,10 @@ class ADHDFWriter(ADWriter[NDFileHDFIO]):
|
|
|
65
64
|
self.fileio.xml_file_name.set(""),
|
|
66
65
|
)
|
|
67
66
|
|
|
67
|
+
self._path_info = self._path_provider(device_name=name)
|
|
68
|
+
|
|
68
69
|
# Set common AD file plugin params, begin capturing
|
|
69
|
-
await self.
|
|
70
|
+
await self._begin_capture(name)
|
|
70
71
|
|
|
71
72
|
detector_shape = await self._dataset_describer.shape()
|
|
72
73
|
np_dtype = await self._dataset_describer.np_datatype()
|
|
@@ -100,7 +101,7 @@ class ADHDFWriter(ADWriter[NDFileHDFIO]):
|
|
|
100
101
|
|
|
101
102
|
self._composer = HDFDocumentComposer(
|
|
102
103
|
# See https://github.com/bluesky/ophyd-async/issues/122
|
|
103
|
-
|
|
104
|
+
f"{self._path_info.directory_uri}{self._path_info.filename}{self._file_extension}",
|
|
104
105
|
self._datasets,
|
|
105
106
|
)
|
|
106
107
|
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
from ophyd_async.core import DatasetDescriber, PathProvider
|
|
2
2
|
|
|
3
|
-
from ._core_io import
|
|
3
|
+
from ._core_io import NDFilePluginIO, NDPluginBaseIO
|
|
4
4
|
from ._core_writer import ADWriter
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
class ADJPEGWriter(ADWriter[
|
|
7
|
+
class ADJPEGWriter(ADWriter[NDFilePluginIO]):
|
|
8
8
|
default_suffix: str = "JPEG1:"
|
|
9
9
|
|
|
10
10
|
def __init__(
|
|
11
11
|
self,
|
|
12
|
-
fileio:
|
|
12
|
+
fileio: NDFilePluginIO,
|
|
13
13
|
path_provider: PathProvider,
|
|
14
14
|
dataset_describer: DatasetDescriber,
|
|
15
15
|
plugins: dict[str, NDPluginBaseIO] | None = None,
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
from ophyd_async.core import DatasetDescriber, PathProvider
|
|
2
2
|
|
|
3
|
-
from ._core_io import
|
|
3
|
+
from ._core_io import NDFilePluginIO, NDPluginBaseIO
|
|
4
4
|
from ._core_writer import ADWriter
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
class ADTIFFWriter(ADWriter[
|
|
7
|
+
class ADTIFFWriter(ADWriter[NDFilePluginIO]):
|
|
8
8
|
default_suffix: str = "TIFF1:"
|
|
9
9
|
|
|
10
10
|
def __init__(
|
|
11
11
|
self,
|
|
12
|
-
fileio:
|
|
12
|
+
fileio: NDFilePluginIO,
|
|
13
13
|
path_provider: PathProvider,
|
|
14
14
|
dataset_describer: DatasetDescriber,
|
|
15
15
|
plugins: dict[str, NDPluginBaseIO] | None = None,
|
ophyd_async/epics/core/_aioca.py
CHANGED
|
@@ -250,10 +250,12 @@ class CaSignalBackend(EpicsSignalBackend[SignalDatatypeT]):
|
|
|
250
250
|
datatype: type[SignalDatatypeT] | None,
|
|
251
251
|
read_pv: str = "",
|
|
252
252
|
write_pv: str = "",
|
|
253
|
+
all_updates: bool = True,
|
|
253
254
|
):
|
|
254
255
|
self.converter: CaConverter = DisconnectedCaConverter(float, dbr.DBR_DOUBLE)
|
|
255
256
|
self.initial_values: dict[str, AugmentedValue] = {}
|
|
256
257
|
self.subscription: Subscription | None = None
|
|
258
|
+
self._all_updates = all_updates
|
|
257
259
|
super().__init__(datatype, read_pv, write_pv)
|
|
258
260
|
|
|
259
261
|
def source(self, name: str, read: bool):
|
|
@@ -356,4 +358,5 @@ class CaSignalBackend(EpicsSignalBackend[SignalDatatypeT]):
|
|
|
356
358
|
lambda v: callback(self._make_reading(v)),
|
|
357
359
|
datatype=self.converter.read_dbr,
|
|
358
360
|
format=FORMAT_TIME,
|
|
361
|
+
all_updates=self._all_updates,
|
|
359
362
|
)
|
|
@@ -40,7 +40,7 @@ class TestingIOC:
|
|
|
40
40
|
assert self._process.stdout # noqa: S101 # this is to make Pylance happy
|
|
41
41
|
start_time = time.monotonic()
|
|
42
42
|
while "iocRun: All initialization complete" not in self.output:
|
|
43
|
-
if time.monotonic() - start_time >
|
|
43
|
+
if time.monotonic() - start_time > 15:
|
|
44
44
|
self.stop()
|
|
45
45
|
raise TimeoutError(f"IOC did not start in time:\n{self.output}")
|
|
46
46
|
self.output += self._process.stdout.readline()
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
from collections.abc import AsyncGenerator, AsyncIterator
|
|
3
|
-
from pathlib import Path
|
|
4
3
|
|
|
5
4
|
from bluesky.protocols import StreamAsset
|
|
6
5
|
from event_model import DataKey
|
|
@@ -67,8 +66,7 @@ class PandaHDFWriter(DetectorWriter):
|
|
|
67
66
|
describe = await self._describe(name)
|
|
68
67
|
|
|
69
68
|
self._composer = HDFDocumentComposer(
|
|
70
|
-
|
|
71
|
-
/ Path(await self.panda_data_block.hdf_file_name.get_value()),
|
|
69
|
+
f"{info.directory_uri}{info.filename}.h5",
|
|
72
70
|
self._datasets,
|
|
73
71
|
)
|
|
74
72
|
|
ophyd_async/sim/__main__.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Used for tutorial `Using Devices`."""
|
|
2
2
|
|
|
3
3
|
# Import bluesky and ophyd
|
|
4
|
+
from pathlib import PurePath
|
|
4
5
|
from tempfile import mkdtemp
|
|
5
6
|
|
|
6
7
|
import bluesky.plan_stubs as bps # noqa: F401
|
|
@@ -27,7 +28,7 @@ pattern_generator = sim.PatternGenerator()
|
|
|
27
28
|
|
|
28
29
|
# Make a path provider that makes UUID filenames within a static
|
|
29
30
|
# temporary directory
|
|
30
|
-
path_provider = StaticPathProvider(UUIDFilenameProvider(), mkdtemp())
|
|
31
|
+
path_provider = StaticPathProvider(UUIDFilenameProvider(), PurePath(mkdtemp()))
|
|
31
32
|
|
|
32
33
|
# All Devices created within this block will be
|
|
33
34
|
# connected and named at the end of the with block
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
from collections.abc import AsyncGenerator, AsyncIterator
|
|
2
|
-
from pathlib import Path
|
|
3
2
|
|
|
4
3
|
import numpy as np
|
|
5
4
|
from bluesky.protocols import Hints, StreamAsset
|
|
@@ -26,14 +25,14 @@ class BlobDetectorWriter(DetectorWriter):
|
|
|
26
25
|
) -> None:
|
|
27
26
|
self.pattern_generator = pattern_generator
|
|
28
27
|
self.path_provider = path_provider
|
|
29
|
-
self.path: Path | None = None
|
|
30
28
|
self.composer: HDFDocumentComposer | None = None
|
|
31
29
|
self.datasets: list[HDFDatasetDescription] = []
|
|
32
30
|
|
|
33
31
|
async def open(self, name: str, exposures_per_event: int = 1) -> dict[str, DataKey]:
|
|
34
32
|
path_info = self.path_provider(name)
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
write_path = path_info.directory_path / f"{path_info.filename}.h5"
|
|
34
|
+
read_path_uri = f"{path_info.directory_uri}{path_info.filename}.h5"
|
|
35
|
+
self.pattern_generator.open_file(write_path, WIDTH, HEIGHT)
|
|
37
36
|
self.exposures_per_event = exposures_per_event
|
|
38
37
|
# We know it will write data and sum, so emit those
|
|
39
38
|
self.datasets = [
|
|
@@ -52,7 +51,7 @@ class BlobDetectorWriter(DetectorWriter):
|
|
|
52
51
|
chunk_shape=(1024,),
|
|
53
52
|
),
|
|
54
53
|
]
|
|
55
|
-
self.composer = HDFDocumentComposer(
|
|
54
|
+
self.composer = HDFDocumentComposer(read_path_uri, self.datasets)
|
|
56
55
|
describe = {
|
|
57
56
|
ds.data_key: DataKey(
|
|
58
57
|
source="sim://pattern-generator-hdf-file",
|
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import time
|
|
5
|
-
from pathlib import
|
|
5
|
+
from pathlib import PurePath
|
|
6
6
|
|
|
7
7
|
import h5py
|
|
8
8
|
import numpy as np
|
|
@@ -35,7 +35,7 @@ def generate_interesting_pattern(
|
|
|
35
35
|
class PatternFile:
|
|
36
36
|
def __init__(
|
|
37
37
|
self,
|
|
38
|
-
path:
|
|
38
|
+
path: PurePath,
|
|
39
39
|
width: int = 320,
|
|
40
40
|
height: int = 240,
|
|
41
41
|
):
|
|
@@ -94,7 +94,7 @@ class PatternGenerator:
|
|
|
94
94
|
offset = 100 if high_energy else 10
|
|
95
95
|
return generate_interesting_pattern(self._x, self._y, channel, offset)
|
|
96
96
|
|
|
97
|
-
def open_file(self, path:
|
|
97
|
+
def open_file(self, path: PurePath, width: int, height: int):
|
|
98
98
|
self._file = PatternFile(path, width, height)
|
|
99
99
|
|
|
100
100
|
def _get_file(self) -> PatternFile:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ophyd-async
|
|
3
|
-
Version: 0.12
|
|
3
|
+
Version: 0.12.1
|
|
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
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
ophyd_async/__init__.py,sha256=dcAA3qsj1nNIMe5l-v2tlduZ_ypwBmyuHe45Lsq4k4w,206
|
|
2
2
|
ophyd_async/__main__.py,sha256=n_U4O9bgm97OuboUB_9eK7eFiwy8BZSgXJ0OzbE0DqU,481
|
|
3
3
|
ophyd_async/_docs_parser.py,sha256=gPYrigfSbYCF7QoSf2UvE-cpQu4snSssl7ZWN-kKDzI,352
|
|
4
|
-
ophyd_async/_version.py,sha256=
|
|
4
|
+
ophyd_async/_version.py,sha256=DzB47l1iPNTY8yuA60VuZvneNqNdRBd1svEjKxC37o4,513
|
|
5
5
|
ophyd_async/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
ophyd_async/core/__init__.py,sha256=RtYk6FdJxc7lxoSReRV1D7weTRYFu9ylhNNd3DyN904,4752
|
|
7
7
|
ophyd_async/core/_derived_signal.py,sha256=TuZza_j3J1Bw4QSqBYB9Ta2FyQP5BycO3nSHVtJ890Q,13015
|
|
@@ -10,16 +10,16 @@ ophyd_async/core/_detector.py,sha256=x1o-eSkvemQ-fTk47440owkTmYhuckA2ILNOCoJlHCY
|
|
|
10
10
|
ophyd_async/core/_device.py,sha256=lSm8FBul9NTn9VO0rsAlV9pctJyUsMdU2ztEf5CqH5M,14716
|
|
11
11
|
ophyd_async/core/_device_filler.py,sha256=MDz8eQQ-eEAwo-UEMxfqPfpcBuMG01tLCGR6utwVnmE,14825
|
|
12
12
|
ophyd_async/core/_flyer.py,sha256=8zKyU5aQOr_t59GIUwsYeb8NSabdvBp0swwuRe4v5VQ,3457
|
|
13
|
-
ophyd_async/core/_hdf_dataset.py,sha256=
|
|
13
|
+
ophyd_async/core/_hdf_dataset.py,sha256=0bIX_ZbFSMdXqDwRtEvV-0avHnwXhjPddE5GVNmo7H8,2608
|
|
14
14
|
ophyd_async/core/_log.py,sha256=DxKR4Nz3SgTaTzKBZWqt-w48yT8WUAr_3Qr223TEWRw,3587
|
|
15
15
|
ophyd_async/core/_mock_signal_backend.py,sha256=SPdCbVWss6-iL9C3t9u0IvR_Ln9JeDypVd18WlivdjE,3156
|
|
16
16
|
ophyd_async/core/_protocol.py,sha256=wQ_snxhTprHqEjQb1HgFwBljwolMY6A8C3xgV1PXwdU,4051
|
|
17
|
-
ophyd_async/core/_providers.py,sha256=
|
|
17
|
+
ophyd_async/core/_providers.py,sha256=WBht3QCgvGc0stNcwH6z4Zr6hAz3e01-88NjsYI2w6I,9740
|
|
18
18
|
ophyd_async/core/_readable.py,sha256=iBo1YwA5bsAbzLbznvmSnzKDWUuGkLh850Br3BXsgeU,11707
|
|
19
19
|
ophyd_async/core/_settings.py,sha256=_ZccbXKP7j5rG6-bMKk7aaLr8hChdRDAPY_YSR71XXM,4213
|
|
20
20
|
ophyd_async/core/_signal.py,sha256=wKbDJYpN7zWgRf_jAARFqZwCGXcdzPRDNXwvjGUR6dw,28217
|
|
21
21
|
ophyd_async/core/_signal_backend.py,sha256=PvwTbbSVEGqM-2s5BNRrKGwM_MiYL71qMxYAgyZ7wRM,6930
|
|
22
|
-
ophyd_async/core/_soft_signal_backend.py,sha256=
|
|
22
|
+
ophyd_async/core/_soft_signal_backend.py,sha256=NJUuyaCKtBZjggt8WKi7_lKQRHasToxviuQvl5xbhLU,6222
|
|
23
23
|
ophyd_async/core/_status.py,sha256=h4TtWFM7wFtpxxyAYYSITgcVzArYZdYBHbya6qIX5t0,6553
|
|
24
24
|
ophyd_async/core/_table.py,sha256=ai-_W-_WMZcy9f69BDYRv9vjVl-AVeOPN_uHYoGCSsc,6905
|
|
25
25
|
ophyd_async/core/_utils.py,sha256=fePvt3g7eQ6CRQcMVkMeqxcbvYZboZ2sf1fVVZL-26M,12450
|
|
@@ -35,15 +35,15 @@ ophyd_async/epics/adaravis/__init__.py,sha256=ZQaJVQiwcQn9hUZADrYgBE1sDfFEwjhVBJ
|
|
|
35
35
|
ophyd_async/epics/adaravis/_aravis.py,sha256=Ju2wuebz9_ovl-Kza39s5VQ1pV-Omt_BaIWKqP4kcGA,1315
|
|
36
36
|
ophyd_async/epics/adaravis/_aravis_controller.py,sha256=WiFR7_FAAu6_88zG-yzGLsR9YcO4L6xR73Wnjw9n0i4,1908
|
|
37
37
|
ophyd_async/epics/adaravis/_aravis_io.py,sha256=af5RxeXF2ligvAXwMNMKHA4QHTR_WmNFz-f18qD2dbg,855
|
|
38
|
-
ophyd_async/epics/adcore/__init__.py,sha256=
|
|
38
|
+
ophyd_async/epics/adcore/__init__.py,sha256=sDvQO3TshdXfDvLGqzsSNJT95Wk7tUAmOowDwB00Td0,1625
|
|
39
39
|
ophyd_async/epics/adcore/_core_detector.py,sha256=mRDaHgXCTZF-MIVsU1csoQx9jObutYDpMWayugx2-jI,2631
|
|
40
|
-
ophyd_async/epics/adcore/_core_io.py,sha256=
|
|
40
|
+
ophyd_async/epics/adcore/_core_io.py,sha256=c1GqAUdv8lAQjklbKHtraLMhPOWEttDCsH9ow7M5I0U,7690
|
|
41
41
|
ophyd_async/epics/adcore/_core_logic.py,sha256=IH7iOSVIsVj4e97ClhdBFpmdMkb8TznSaLkd3ohEhUs,8884
|
|
42
|
-
ophyd_async/epics/adcore/_core_writer.py,sha256=
|
|
43
|
-
ophyd_async/epics/adcore/_hdf_writer.py,sha256=
|
|
44
|
-
ophyd_async/epics/adcore/_jpeg_writer.py,sha256=
|
|
42
|
+
ophyd_async/epics/adcore/_core_writer.py,sha256=6OEU8fcn7ATd3dml_aBZ_LmFgVGcdbNFyg1Sx2zqV7s,8522
|
|
43
|
+
ophyd_async/epics/adcore/_hdf_writer.py,sha256=AvCv_5dd2HdQoE12_CR6vH2hig2EdEIWklOu6CbPVlc,5816
|
|
44
|
+
ophyd_async/epics/adcore/_jpeg_writer.py,sha256=VYpUWQGEjrKG2kiRGQZlBCPXVJ1BzWb9GyB9KhxPWgo,688
|
|
45
45
|
ophyd_async/epics/adcore/_single_trigger.py,sha256=tFGLT1b_rZzAvbqWP-hyCccxJMRY26T5IER-VAqKXmc,1275
|
|
46
|
-
ophyd_async/epics/adcore/_tiff_writer.py,sha256=
|
|
46
|
+
ophyd_async/epics/adcore/_tiff_writer.py,sha256=197Ky9ltsJjUKNwl8_OAuoCe8dWIc7zCFs7wautwC7Y,689
|
|
47
47
|
ophyd_async/epics/adcore/_utils.py,sha256=jMmZnyDwRDBq-N_x8qOWjW2RMN9uw2KuoAmukPbb404,4252
|
|
48
48
|
ophyd_async/epics/adkinetix/__init__.py,sha256=A9xq3lGMrmza9lfukRixC0Up_kUDVFII8JguLr2x7Bw,308
|
|
49
49
|
ophyd_async/epics/adkinetix/_kinetix.py,sha256=zZv0JZ8i1RSx7KBDn_1HGNOY0BoIP81mRK5TKq7d4eA,1302
|
|
@@ -62,7 +62,7 @@ ophyd_async/epics/advimba/_vimba.py,sha256=4XlEnsJMGDzHLuYaIDUmaxx0gtOAehn5BKBZM
|
|
|
62
62
|
ophyd_async/epics/advimba/_vimba_controller.py,sha256=v0av2bGnaJ01w9Igksupt2IlkuBEFlAeRCPOVma-Xa4,1980
|
|
63
63
|
ophyd_async/epics/advimba/_vimba_io.py,sha256=cb2Nfp05fBZAcNVXpz-rqRIRS-TiZW5DPUJOmaFyAw0,1589
|
|
64
64
|
ophyd_async/epics/core/__init__.py,sha256=8NoQxEEc2Ny_L9nrD2fnGSf_2gJr1wCR1LwUeLNcIJo,588
|
|
65
|
-
ophyd_async/epics/core/_aioca.py,sha256=
|
|
65
|
+
ophyd_async/epics/core/_aioca.py,sha256=elNR5c2-YcDUoyzuvTEVURoqx92wkVoMDNjwjeZ0WmA,13136
|
|
66
66
|
ophyd_async/epics/core/_epics_connector.py,sha256=S4z_wbj-aogVcjqCyUgjhcq5Y4gDC7y6wXbsSz2nODY,1918
|
|
67
67
|
ophyd_async/epics/core/_epics_device.py,sha256=wGdR24I7GSPh3HmM7jsWKZhBZgt4IyLrCn4Ut7Wx_xo,510
|
|
68
68
|
ophyd_async/epics/core/_p4p.py,sha256=uWh3oWPme74G4YfeJ6k8ZlHdKOwcf8Xp1J82b9aa_JI,16407
|
|
@@ -85,7 +85,7 @@ ophyd_async/epics/pmac/__init__.py,sha256=RWqo5nYE2MMBdwvMxdeVG213MN38b9VPlpDHQW
|
|
|
85
85
|
ophyd_async/epics/pmac/_pmac_io.py,sha256=yMQpZ0Osh4l8VRd2aqWQE9ebJDfh5FwM_0pp1pe8-C0,3564
|
|
86
86
|
ophyd_async/epics/testing/__init__.py,sha256=aTIv4D2DYrpnGco5RQF8QuLG1SfFkIlTyM2uYEKXltA,522
|
|
87
87
|
ophyd_async/epics/testing/_example_ioc.py,sha256=uUmfMXV_Pd2SMFyb0y_4uTc6gkGRUqU1cJ-XQC2ROW8,3915
|
|
88
|
-
ophyd_async/epics/testing/_utils.py,sha256=
|
|
88
|
+
ophyd_async/epics/testing/_utils.py,sha256=9gxpwaWX0HGtacu1LTupcw7viXN8G78RmuNciU_-cjs,1702
|
|
89
89
|
ophyd_async/epics/testing/test_records.db,sha256=SgWQPZgtmc__JiLkH2VPwe5KZOua6ZCIgTLGT_5SDDc,3589
|
|
90
90
|
ophyd_async/epics/testing/test_records_pva.db,sha256=HJAJSvLtPWG5B5dKv8OZ0_hPJxRFrDoYp6ROcF2lqyA,4202
|
|
91
91
|
ophyd_async/fastcs/__init__.py,sha256=qlIM9-pjJ8yWfnzTM9-T9cw7zQLKjeeNROQTni5Dr6M,80
|
|
@@ -101,7 +101,7 @@ ophyd_async/fastcs/panda/_control.py,sha256=xtW3dH_MLQoycgP-4vJtYx1M9alHjWo13iu9
|
|
|
101
101
|
ophyd_async/fastcs/panda/_hdf_panda.py,sha256=tL_OWHxlMQcMZGq9sxHLSeag6hP9MRIbTPn1W0u0iNI,1237
|
|
102
102
|
ophyd_async/fastcs/panda/_table.py,sha256=maKGoKypEuYqTSVWGgDO6GMEKOtlDm9Dn5YiYdBzu6c,2486
|
|
103
103
|
ophyd_async/fastcs/panda/_trigger.py,sha256=TLd0ST-ZgsCGpONGUe76qHOaH74TlZNIGNkh-10eRa8,3404
|
|
104
|
-
ophyd_async/fastcs/panda/_writer.py,sha256=
|
|
104
|
+
ophyd_async/fastcs/panda/_writer.py,sha256=UqsU44u0uIqkDNky3mIzhW3OhLeZ8TSqFS666qrRdmA,6181
|
|
105
105
|
ophyd_async/plan_stubs/__init__.py,sha256=sRe1Jna_6i7aKjE3pPzsP4iNMWeWdtiptLnOq9pov9M,619
|
|
106
106
|
ophyd_async/plan_stubs/_ensure_connected.py,sha256=YR6VRj7koccJ4x35NV-Ugl4ZbxgAoGN9PjVIjhv0gpw,894
|
|
107
107
|
ophyd_async/plan_stubs/_fly.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -111,14 +111,14 @@ ophyd_async/plan_stubs/_settings.py,sha256=e3dGVSUV-Htay_9fKXyQTAQLdjunetGI3OBYp
|
|
|
111
111
|
ophyd_async/plan_stubs/_utils.py,sha256=zClRo5ve8RGia7wQnby41W-Zprj-slOA5da1LfYnuhw,45
|
|
112
112
|
ophyd_async/plan_stubs/_wait_for_awaitable.py,sha256=PGct_dGezKrLhm0W_GD83dwevSccG_vsmj0WSlMNVWc,364
|
|
113
113
|
ophyd_async/sim/__init__.py,sha256=TC86iJGt4u5UtRJniNEaUJbYB2C03kmjZF-jr2zPExY,709
|
|
114
|
-
ophyd_async/sim/__main__.py,sha256=
|
|
114
|
+
ophyd_async/sim/__main__.py,sha256=TPN2nc4qYdBEKpNq4FYsRMvW5a0TEFx1sM92ScIybow,1732
|
|
115
115
|
ophyd_async/sim/_blob_detector.py,sha256=bJa-G2JF6pPLJx4YIEvFTG07DvQ18ZNSYbtde6qnWPY,1033
|
|
116
116
|
ophyd_async/sim/_blob_detector_controller.py,sha256=y1aSNQJUPnsT2qnj2sk254Mp18anmgQy7ctHlYQZ_B0,1788
|
|
117
|
-
ophyd_async/sim/_blob_detector_writer.py,sha256
|
|
117
|
+
ophyd_async/sim/_blob_detector_writer.py,sha256=_Pd0OaP4_mZfwxtUF35v7hsktLP_wYljR4nylr5CzJo,3346
|
|
118
118
|
ophyd_async/sim/_mirror_horizontal.py,sha256=Jsqa8Snjy1jQDboZtAQFJjGor5uKk8FBC7OCe-GoZDw,1478
|
|
119
119
|
ophyd_async/sim/_mirror_vertical.py,sha256=HUD44mYT0jQ0GKiQKxD7k_7y6o6OdE6TztgdPUJIK_g,2085
|
|
120
120
|
ophyd_async/sim/_motor.py,sha256=7s2jBNwWm4CI6I6l_LEpe7z61QdWy82JdZBKSFOnYe4,8994
|
|
121
|
-
ophyd_async/sim/_pattern_generator.py,sha256=
|
|
121
|
+
ophyd_async/sim/_pattern_generator.py,sha256=kuxvyX2gIxrywhQRhaO1g8YluBT7LBkE20IsurZS-6o,3734
|
|
122
122
|
ophyd_async/sim/_point_detector.py,sha256=nXgL_1aJZciNBw8Zr2wMYaMbzzAEKXV3yV8FQz2nS_4,2940
|
|
123
123
|
ophyd_async/sim/_stage.py,sha256=qaeyZbUVL1v2pTHJiZxq-y6BKpA1l_DAKyzAQppQx70,772
|
|
124
124
|
ophyd_async/tango/__init__.py,sha256=g9xzjlzPpUAP12YI-kYwfAoLSYPAQdL1S11R2c-cius,60
|
|
@@ -145,8 +145,8 @@ ophyd_async/testing/_one_of_everything.py,sha256=Di0hPoKwrDOSsx50-2UdSHM2EbIKrPG
|
|
|
145
145
|
ophyd_async/testing/_single_derived.py,sha256=5-HOTzgePcZ354NK_ssVpyIbJoJmKyjVQCxSwQXUC-4,2730
|
|
146
146
|
ophyd_async/testing/_utils.py,sha256=zClRo5ve8RGia7wQnby41W-Zprj-slOA5da1LfYnuhw,45
|
|
147
147
|
ophyd_async/testing/_wait_for_pending.py,sha256=YZAR48n-CW0GsPey3zFRzMJ4byDAr3HvMIoawjmTrHw,732
|
|
148
|
-
ophyd_async-0.12.dist-info/licenses/LICENSE,sha256=pU5shZcsvWgz701EbT7yjFZ8rMvZcWgRH54CRt8ld_c,1517
|
|
149
|
-
ophyd_async-0.12.dist-info/METADATA,sha256=
|
|
150
|
-
ophyd_async-0.12.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
151
|
-
ophyd_async-0.12.dist-info/top_level.txt,sha256=-hjorMsv5Rmjo3qrgqhjpal1N6kW5vMxZO3lD4iEaXs,12
|
|
152
|
-
ophyd_async-0.12.dist-info/RECORD,,
|
|
148
|
+
ophyd_async-0.12.1.dist-info/licenses/LICENSE,sha256=pU5shZcsvWgz701EbT7yjFZ8rMvZcWgRH54CRt8ld_c,1517
|
|
149
|
+
ophyd_async-0.12.1.dist-info/METADATA,sha256=Vn04AobiRZJ4KZJ7Na9c3whRj0M1eEmWBbtWuW03i3I,7112
|
|
150
|
+
ophyd_async-0.12.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
151
|
+
ophyd_async-0.12.1.dist-info/top_level.txt,sha256=-hjorMsv5Rmjo3qrgqhjpal1N6kW5vMxZO3lD4iEaXs,12
|
|
152
|
+
ophyd_async-0.12.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|