ewoksdata 0.3.0__tar.gz → 0.4.1__tar.gz
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.
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/PKG-INFO +19 -2
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/setup.cfg +3 -1
- ewoksdata-0.4.1/src/ewoksdata/__init__.py +1 -0
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/src/ewoksdata/data/bliss.py +3 -104
- ewoksdata-0.4.1/src/ewoksdata/data/blissdata/__init__.py +36 -0
- ewoksdata-0.4.1/src/ewoksdata/data/blissdata/blissdatav0.py +112 -0
- ewoksdata-0.4.1/src/ewoksdata/data/blissdata/blissdatav1.py +84 -0
- ewoksdata-0.4.1/src/ewoksdata/data/blissdata/blissdatavid31.py +97 -0
- ewoksdata-0.4.1/src/ewoksdata/data/blissdata/exceptions.py +4 -0
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/src/ewoksdata/data/hdf5/dataset_writer.py +3 -3
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/src/ewoksdata.egg-info/PKG-INFO +19 -2
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/src/ewoksdata.egg-info/SOURCES.txt +5 -0
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/src/ewoksdata.egg-info/requires.txt +6 -0
- ewoksdata-0.3.0/src/ewoksdata/__init__.py +0 -1
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/LICENSE.md +0 -0
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/README.md +0 -0
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/pyproject.toml +0 -0
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/setup.py +0 -0
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/src/ewoksdata/data/__init__.py +0 -0
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/src/ewoksdata/data/hdf5/__init__.py +0 -0
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/src/ewoksdata/data/hdf5/config.py +0 -0
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/src/ewoksdata/data/hdf5/types.py +0 -0
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/src/ewoksdata/data/nexus.py +0 -0
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/src/ewoksdata/data/url.py +0 -0
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/src/ewoksdata/data/utils.py +0 -0
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/src/ewoksdata/tests/__init__.py +0 -0
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/src/ewoksdata/tests/conftest.py +0 -0
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/src/ewoksdata/tests/data/__init__.py +0 -0
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/src/ewoksdata/tests/data/bliss_scans.py +0 -0
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/src/ewoksdata/tests/test_data_bliss.py +0 -0
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/src/ewoksdata/tests/test_data_hdf5.py +0 -0
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/src/ewoksdata/tests/test_data_nexus.py +0 -0
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/src/ewoksdata/tests/test_dataset_writer.py +0 -0
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/src/ewoksdata.egg-info/dependency_links.txt +0 -0
- {ewoksdata-0.3.0 → ewoksdata-0.4.1}/src/ewoksdata.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ewoksdata
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: Ewoks tasks for data access
|
|
5
5
|
Home-page: https://gitlab.esrf.fr/workflow/ewoksapps/ewoksdata/
|
|
6
6
|
Author: ESRF
|
|
@@ -14,11 +14,28 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
14
14
|
Classifier: Programming Language :: Python :: 3
|
|
15
15
|
Requires-Python: >=3.7
|
|
16
16
|
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE.md
|
|
18
|
+
Requires-Dist: h5py>=2.8
|
|
19
|
+
Requires-Dist: silx>=1.1.0
|
|
20
|
+
Requires-Dist: hdf5plugin
|
|
21
|
+
Requires-Dist: blissdata<1.0.1; python_version < "3.8"
|
|
22
|
+
Requires-Dist: blissdata; python_version >= "3.8"
|
|
23
|
+
Requires-Dist: redis
|
|
17
24
|
Provides-Extra: online
|
|
25
|
+
Requires-Dist: blissdata[tango]; extra == "online"
|
|
18
26
|
Provides-Extra: test
|
|
27
|
+
Requires-Dist: blissdata[tango]; extra == "test"
|
|
28
|
+
Requires-Dist: pytest>=7; extra == "test"
|
|
19
29
|
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: blissdata[tango]; extra == "dev"
|
|
31
|
+
Requires-Dist: pytest>=7; extra == "dev"
|
|
32
|
+
Requires-Dist: black>=22; extra == "dev"
|
|
33
|
+
Requires-Dist: flake8>=4; extra == "dev"
|
|
20
34
|
Provides-Extra: doc
|
|
21
|
-
|
|
35
|
+
Requires-Dist: blissdata[tango]; extra == "doc"
|
|
36
|
+
Requires-Dist: pytest>=7; extra == "doc"
|
|
37
|
+
Requires-Dist: sphinx>=4.5; extra == "doc"
|
|
38
|
+
Requires-Dist: sphinx-autodoc-typehints>=1.16; extra == "doc"
|
|
22
39
|
|
|
23
40
|
# ewoksdata
|
|
24
41
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.4.1"
|
|
@@ -10,14 +10,10 @@ from numpy.typing import ArrayLike
|
|
|
10
10
|
from silx.io import h5py_utils
|
|
11
11
|
from silx.utils import retry as retrymod
|
|
12
12
|
from silx.io.utils import get_data as silx_get_data
|
|
13
|
-
from blissdata.h5api import dynamic_hdf5
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
from blissdata.data.events.lima import ImageNotSaved
|
|
19
|
-
except ImportError:
|
|
20
|
-
get_node = None
|
|
14
|
+
from .blissdata import iter_bliss_scan_data_from_memory # noqa F401
|
|
15
|
+
from .blissdata import last_lima_image # noqa F401
|
|
16
|
+
from .blissdata import dynamic_hdf5
|
|
21
17
|
|
|
22
18
|
from . import hdf5
|
|
23
19
|
from . import nexus
|
|
@@ -140,100 +136,3 @@ def iter_bliss_data(
|
|
|
140
136
|
|
|
141
137
|
def _is_bliss_file(h5item: Union[h5py.Dataset, h5py.Group]) -> bool:
|
|
142
138
|
return h5item.file.attrs.get("creator", "").lower() == "bliss"
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
def last_lima_image(db_name: str) -> ArrayLike:
|
|
146
|
-
"""Get last lima image from memory"""
|
|
147
|
-
node = _get_node(db_name, "lima")
|
|
148
|
-
node.from_stream = True
|
|
149
|
-
dataview = node.get(-1)
|
|
150
|
-
try:
|
|
151
|
-
image = dataview.get_last_live_image()
|
|
152
|
-
except AttributeError:
|
|
153
|
-
image = None
|
|
154
|
-
if image is None or image.data is None:
|
|
155
|
-
raise RuntimeError("Cannot get last image from lima")
|
|
156
|
-
return image.data
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
def iter_bliss_scan_data_from_memory(
|
|
160
|
-
db_name: str,
|
|
161
|
-
lima_names: List[str],
|
|
162
|
-
counter_names: List[str],
|
|
163
|
-
retry_timeout: Optional[Number] = None,
|
|
164
|
-
retry_period: Optional[Number] = None,
|
|
165
|
-
):
|
|
166
|
-
scan_node = _get_node(
|
|
167
|
-
db_name, "scan", retry_timeout=retry_timeout, retry_period=retry_period
|
|
168
|
-
)
|
|
169
|
-
indices = {name: 0 for name in lima_names + counter_names}
|
|
170
|
-
buffers = {name: list() for name in lima_names + counter_names}
|
|
171
|
-
lima_acq_nb = dict()
|
|
172
|
-
for event_type, node, event_data in scan_node.walk_events():
|
|
173
|
-
if node.type == "lima":
|
|
174
|
-
name = node.db_name.split(":")[-2]
|
|
175
|
-
if name not in lima_names:
|
|
176
|
-
continue
|
|
177
|
-
dataview = _get_lima_dataview(
|
|
178
|
-
node,
|
|
179
|
-
indices[name],
|
|
180
|
-
retry_timeout=retry_timeout,
|
|
181
|
-
retry_period=retry_period,
|
|
182
|
-
)
|
|
183
|
-
current_lima_acq_nb = dataview.status_event.status["lima_acq_nb"]
|
|
184
|
-
first_lima_acq_nb = lima_acq_nb.setdefault(name, current_lima_acq_nb)
|
|
185
|
-
if first_lima_acq_nb != current_lima_acq_nb:
|
|
186
|
-
logger.warning("lima is already acquiring the next scan")
|
|
187
|
-
continue
|
|
188
|
-
try:
|
|
189
|
-
data = list(dataview)
|
|
190
|
-
except ImageNotSaved:
|
|
191
|
-
logger.warning(
|
|
192
|
-
"cannot read lima data from file because images are not being saved"
|
|
193
|
-
)
|
|
194
|
-
continue
|
|
195
|
-
except Exception as e:
|
|
196
|
-
logger.warning("cannot read lima data (%s)", str(e))
|
|
197
|
-
continue
|
|
198
|
-
indices[name] += len(data)
|
|
199
|
-
buffers[name].extend(data)
|
|
200
|
-
elif node.type == "channel":
|
|
201
|
-
name = node.db_name.split(":")[-1]
|
|
202
|
-
if name not in counter_names:
|
|
203
|
-
continue
|
|
204
|
-
if event_data:
|
|
205
|
-
data = event_data.data
|
|
206
|
-
else:
|
|
207
|
-
data = node.get_as_array(indices[name], -1)
|
|
208
|
-
indices[name] += len(data)
|
|
209
|
-
buffers[name].extend(data)
|
|
210
|
-
nyield = min(len(v) for v in buffers.values())
|
|
211
|
-
if nyield:
|
|
212
|
-
for i in range(nyield):
|
|
213
|
-
yield {name: values[i] for name, values in buffers.items()}
|
|
214
|
-
buffers = {name: values[nyield:] for name, values in buffers.items()}
|
|
215
|
-
if event_type == event_type.END_SCAN:
|
|
216
|
-
break
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
@retrymod.retry()
|
|
220
|
-
def _get_node(db_name: str, node_type: str):
|
|
221
|
-
if get_node is None:
|
|
222
|
-
raise ModuleNotFoundError("No module named 'blissdata'")
|
|
223
|
-
node = get_node(db_name)
|
|
224
|
-
if node is None:
|
|
225
|
-
raise retrymod.RetryError(f"Redis node {db_name} does not exist")
|
|
226
|
-
if node.type != node_type:
|
|
227
|
-
raise RuntimeError(f"Not a Redis {node_type} node")
|
|
228
|
-
return node
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
@retrymod.retry()
|
|
232
|
-
def _get_lima_dataview(node, start_index: int):
|
|
233
|
-
dataview = node.get(start_index, -1)
|
|
234
|
-
try:
|
|
235
|
-
if dataview.status_event.proxy is None:
|
|
236
|
-
raise retrymod.RetryError("Lima proxy not known (yet)")
|
|
237
|
-
except Exception:
|
|
238
|
-
raise retrymod.RetryError("Lima proxy not known (yet)")
|
|
239
|
-
return dataview
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from .exceptions import VersionError
|
|
2
|
+
|
|
3
|
+
try:
|
|
4
|
+
# blissdata >=1
|
|
5
|
+
from .blissdatav1 import iter_bliss_scan_data_from_memory
|
|
6
|
+
from .blissdatav1 import last_lima_image
|
|
7
|
+
from blissdata.h5api import dynamic_hdf5
|
|
8
|
+
except VersionError as exc:
|
|
9
|
+
try:
|
|
10
|
+
# blissdata >0.3.3,<1 (unreleased, branch id31_2.0)
|
|
11
|
+
from .blissdatavid31 import iter_bliss_scan_data_from_memory
|
|
12
|
+
from .blissdatavid31 import last_lima_image
|
|
13
|
+
from blissdata.h5api import dynamic_hdf5
|
|
14
|
+
except VersionError:
|
|
15
|
+
try:
|
|
16
|
+
# blissdata <=0.3.3
|
|
17
|
+
from .blissdatav0 import iter_bliss_scan_data_from_memory
|
|
18
|
+
from .blissdatav0 import last_lima_image
|
|
19
|
+
from blissdata.h5api import dynamic_hdf5
|
|
20
|
+
except VersionError: # noqa F841
|
|
21
|
+
_EXC = exc
|
|
22
|
+
|
|
23
|
+
def _reraise(*_, **kw):
|
|
24
|
+
raise _EXC
|
|
25
|
+
|
|
26
|
+
class BlissDataVersionNotSupported:
|
|
27
|
+
def __getattr__(self, *_):
|
|
28
|
+
return _reraise
|
|
29
|
+
|
|
30
|
+
dynamic_hdf5 = BlissDataVersionNotSupported()
|
|
31
|
+
|
|
32
|
+
def iter_bliss_scan_data_from_memory(*_, **kw):
|
|
33
|
+
raise _EXC
|
|
34
|
+
|
|
35
|
+
def last_lima_image(*_, **kw):
|
|
36
|
+
raise _EXC
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from numbers import Number
|
|
3
|
+
from typing import List, Optional
|
|
4
|
+
|
|
5
|
+
from numpy.typing import ArrayLike
|
|
6
|
+
from silx.utils import retry as retrymod
|
|
7
|
+
|
|
8
|
+
from .exceptions import VersionError
|
|
9
|
+
|
|
10
|
+
try:
|
|
11
|
+
from blissdata.data.node import get_node
|
|
12
|
+
from blissdata.data.events.lima import ImageNotSaved
|
|
13
|
+
except ImportError as e:
|
|
14
|
+
raise VersionError(str(e)) from e
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def iter_bliss_scan_data_from_memory(
|
|
21
|
+
db_name: str,
|
|
22
|
+
lima_names: List[str],
|
|
23
|
+
counter_names: List[str],
|
|
24
|
+
retry_timeout: Optional[Number] = None,
|
|
25
|
+
retry_period: Optional[Number] = None,
|
|
26
|
+
):
|
|
27
|
+
scan_node = _get_node(
|
|
28
|
+
db_name, "scan", retry_timeout=retry_timeout, retry_period=retry_period
|
|
29
|
+
)
|
|
30
|
+
indices = {name: 0 for name in lima_names + counter_names}
|
|
31
|
+
buffers = {name: list() for name in lima_names + counter_names}
|
|
32
|
+
lima_acq_nb = dict()
|
|
33
|
+
for event_type, node, event_data in scan_node.walk_events():
|
|
34
|
+
if node.type == "lima":
|
|
35
|
+
name = node.db_name.split(":")[-2]
|
|
36
|
+
if name not in lima_names:
|
|
37
|
+
continue
|
|
38
|
+
dataview = _get_lima_dataview(
|
|
39
|
+
node,
|
|
40
|
+
indices[name],
|
|
41
|
+
retry_timeout=retry_timeout,
|
|
42
|
+
retry_period=retry_period,
|
|
43
|
+
)
|
|
44
|
+
current_lima_acq_nb = dataview.status_event.status["lima_acq_nb"]
|
|
45
|
+
first_lima_acq_nb = lima_acq_nb.setdefault(name, current_lima_acq_nb)
|
|
46
|
+
if first_lima_acq_nb != current_lima_acq_nb:
|
|
47
|
+
logger.warning("lima is already acquiring the next scan")
|
|
48
|
+
continue
|
|
49
|
+
try:
|
|
50
|
+
data = list(dataview)
|
|
51
|
+
except ImageNotSaved:
|
|
52
|
+
logger.warning(
|
|
53
|
+
"cannot read lima data from file because images are not being saved"
|
|
54
|
+
)
|
|
55
|
+
continue
|
|
56
|
+
except Exception as e:
|
|
57
|
+
logger.warning("cannot read lima data (%s)", str(e))
|
|
58
|
+
continue
|
|
59
|
+
indices[name] += len(data)
|
|
60
|
+
buffers[name].extend(data)
|
|
61
|
+
elif node.type == "channel":
|
|
62
|
+
name = node.db_name.split(":")[-1]
|
|
63
|
+
if name not in counter_names:
|
|
64
|
+
continue
|
|
65
|
+
if event_data:
|
|
66
|
+
data = event_data.data
|
|
67
|
+
else:
|
|
68
|
+
data = node.get_as_array(indices[name], -1)
|
|
69
|
+
indices[name] += len(data)
|
|
70
|
+
buffers[name].extend(data)
|
|
71
|
+
nyield = min(len(v) for v in buffers.values())
|
|
72
|
+
if nyield:
|
|
73
|
+
for i in range(nyield):
|
|
74
|
+
yield {name: values[i] for name, values in buffers.items()}
|
|
75
|
+
buffers = {name: values[nyield:] for name, values in buffers.items()}
|
|
76
|
+
if event_type == event_type.END_SCAN:
|
|
77
|
+
break
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def last_lima_image(db_name: str) -> ArrayLike:
|
|
81
|
+
"""Get last lima image from memory"""
|
|
82
|
+
node = _get_node(db_name, "lima")
|
|
83
|
+
node.from_stream = True
|
|
84
|
+
dataview = node.get(-1)
|
|
85
|
+
try:
|
|
86
|
+
image = dataview.get_last_live_image()
|
|
87
|
+
except AttributeError:
|
|
88
|
+
image = None
|
|
89
|
+
if image is None or image.data is None:
|
|
90
|
+
raise RuntimeError("Cannot get last image from lima")
|
|
91
|
+
return image.data
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
@retrymod.retry()
|
|
95
|
+
def _get_node(db_name: str, node_type: str):
|
|
96
|
+
node = get_node(db_name)
|
|
97
|
+
if node is None:
|
|
98
|
+
raise retrymod.RetryError(f"Redis node {db_name} does not exist")
|
|
99
|
+
if node.type != node_type:
|
|
100
|
+
raise RuntimeError(f"Not a Redis {node_type} node")
|
|
101
|
+
return node
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
@retrymod.retry()
|
|
105
|
+
def _get_lima_dataview(node, start_index: int):
|
|
106
|
+
dataview = node.get(start_index, -1)
|
|
107
|
+
try:
|
|
108
|
+
if dataview.status_event.proxy is None:
|
|
109
|
+
raise retrymod.RetryError("Lima proxy not known (yet)")
|
|
110
|
+
except Exception:
|
|
111
|
+
raise retrymod.RetryError("Lima proxy not known (yet)")
|
|
112
|
+
return dataview
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
from numbers import Number
|
|
2
|
+
from typing import List, Optional
|
|
3
|
+
|
|
4
|
+
from numpy.typing import ArrayLike
|
|
5
|
+
|
|
6
|
+
from .exceptions import VersionError
|
|
7
|
+
|
|
8
|
+
try:
|
|
9
|
+
from blissdata.beacon.data import BeaconData
|
|
10
|
+
from blissdata.redis_engine.store import DataStore
|
|
11
|
+
from blissdata.redis_engine.scan import Scan
|
|
12
|
+
from blissdata.redis_engine.scan import ScanState
|
|
13
|
+
from blissdata.redis_engine.stream import StreamingClient
|
|
14
|
+
from blissdata.redis_engine.exceptions import EndOfStream
|
|
15
|
+
from blissdata.redis_engine.exceptions import IndexNoMoreThereError
|
|
16
|
+
from blissdata.lima.client import lima_client_factory
|
|
17
|
+
except ImportError as e:
|
|
18
|
+
raise VersionError(str(e)) from e
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def iter_bliss_scan_data_from_memory(
|
|
22
|
+
db_name: str,
|
|
23
|
+
lima_names: List[str],
|
|
24
|
+
counter_names: List[str],
|
|
25
|
+
retry_timeout: Optional[Number] = None,
|
|
26
|
+
retry_period: Optional[Number] = None,
|
|
27
|
+
):
|
|
28
|
+
data_store = _get_data_store()
|
|
29
|
+
scan = data_store.load_scan(db_name, scan_cls=Scan)
|
|
30
|
+
buffers = {name: list() for name in lima_names + counter_names}
|
|
31
|
+
|
|
32
|
+
while scan.state < ScanState.PREPARED:
|
|
33
|
+
scan.update()
|
|
34
|
+
|
|
35
|
+
lima_streams = dict()
|
|
36
|
+
lima_clients = dict()
|
|
37
|
+
counter_streams = dict()
|
|
38
|
+
for name, stream in scan.streams.items():
|
|
39
|
+
if stream.encoding["type"] == "json" and "lima" in stream.info["format"]:
|
|
40
|
+
if name.split(":")[-2] in lima_names:
|
|
41
|
+
lima_streams[name] = stream
|
|
42
|
+
lima_clients[name] = lima_client_factory(data_store, stream.info)
|
|
43
|
+
elif name.split(":")[-1] in counter_names:
|
|
44
|
+
counter_streams[name] = stream
|
|
45
|
+
|
|
46
|
+
client = StreamingClient({**lima_streams, **counter_streams})
|
|
47
|
+
|
|
48
|
+
while True:
|
|
49
|
+
try:
|
|
50
|
+
output = client.read()
|
|
51
|
+
except EndOfStream:
|
|
52
|
+
break
|
|
53
|
+
else:
|
|
54
|
+
for stream, data in output.items():
|
|
55
|
+
_, payload = data # drop index
|
|
56
|
+
if stream.name in lima_streams:
|
|
57
|
+
lima_client = lima_clients[stream.name]
|
|
58
|
+
prev_len = len(lima_client)
|
|
59
|
+
lima_client.update(**payload[-1])
|
|
60
|
+
try:
|
|
61
|
+
data = lima_client[prev_len - 1 :]
|
|
62
|
+
except IndexNoMoreThereError:
|
|
63
|
+
continue
|
|
64
|
+
buffers[stream.name.split(":")[-2]].extend(data)
|
|
65
|
+
else:
|
|
66
|
+
buffers[stream.name.split(":")[-1]].extend(payload)
|
|
67
|
+
|
|
68
|
+
nyield = min(len(v) for v in buffers.values())
|
|
69
|
+
if nyield:
|
|
70
|
+
for i in range(nyield):
|
|
71
|
+
yield {name: values[i] for name, values in buffers.items()}
|
|
72
|
+
buffers = {name: values[nyield:] for name, values in buffers.items()}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def last_lima_image(channel_info: dict) -> ArrayLike:
|
|
76
|
+
"""Get last lima image from memory"""
|
|
77
|
+
data_store = _get_data_store()
|
|
78
|
+
lima_client = lima_client_factory(data_store, channel_info)
|
|
79
|
+
return lima_client.get_last_live_image().array
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _get_data_store() -> None:
|
|
83
|
+
redis_url = BeaconData().get_redis_data_db()
|
|
84
|
+
return DataStore(redis_url)
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
from numbers import Number
|
|
2
|
+
from typing import List, Optional
|
|
3
|
+
|
|
4
|
+
from numpy.typing import ArrayLike
|
|
5
|
+
|
|
6
|
+
from .exceptions import VersionError
|
|
7
|
+
|
|
8
|
+
try:
|
|
9
|
+
from blissdata.redis_engine.scan import Scan
|
|
10
|
+
from blissdata.redis_engine.stream import StreamingClient
|
|
11
|
+
from blissdata.redis_engine.models import ScanState
|
|
12
|
+
from blissdata.redis_engine.exceptions import EndOfStream
|
|
13
|
+
from blissdata.lima.client import lima_client_factory
|
|
14
|
+
from blissdata.beacon.data import BeaconData
|
|
15
|
+
from blissdata import redis_engine
|
|
16
|
+
except ImportError as e:
|
|
17
|
+
raise VersionError(str(e)) from e
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def iter_bliss_scan_data_from_memory(
|
|
21
|
+
db_name: str,
|
|
22
|
+
lima_names: List[str],
|
|
23
|
+
counter_names: List[str],
|
|
24
|
+
retry_timeout: Optional[Number] = None,
|
|
25
|
+
retry_period: Optional[Number] = None,
|
|
26
|
+
):
|
|
27
|
+
_ensure_redis()
|
|
28
|
+
scan = Scan.load(db_name)
|
|
29
|
+
buffers = {name: list() for name in lima_names + counter_names}
|
|
30
|
+
|
|
31
|
+
while scan.state < ScanState.PREPARED:
|
|
32
|
+
scan.update()
|
|
33
|
+
if scan.state is ScanState.ABORTED:
|
|
34
|
+
return
|
|
35
|
+
|
|
36
|
+
lima_streams = dict()
|
|
37
|
+
lima_clients = dict()
|
|
38
|
+
counter_streams = dict()
|
|
39
|
+
for name, stream in scan.streams.items():
|
|
40
|
+
if stream.encoding["type"] == "json" and "lima" in stream.info["format"]:
|
|
41
|
+
if name.split(":")[-2] in lima_names:
|
|
42
|
+
lima_streams[name] = stream
|
|
43
|
+
lima_clients[name] = lima_client_factory(stream.info)
|
|
44
|
+
elif name.split(":")[-1] in counter_names:
|
|
45
|
+
counter_streams[name] = stream
|
|
46
|
+
|
|
47
|
+
client = StreamingClient({**lima_streams, **counter_streams})
|
|
48
|
+
|
|
49
|
+
while True:
|
|
50
|
+
try:
|
|
51
|
+
output = client.read()
|
|
52
|
+
except EndOfStream:
|
|
53
|
+
break
|
|
54
|
+
else:
|
|
55
|
+
for stream, data in output.items():
|
|
56
|
+
_, payload = data # drop index
|
|
57
|
+
if stream.name in lima_streams:
|
|
58
|
+
lima_client = lima_clients[stream.name]
|
|
59
|
+
prev_len = len(lima_client)
|
|
60
|
+
lima_client.update(**payload[-1])
|
|
61
|
+
data = lima_client[prev_len - 1 :]
|
|
62
|
+
buffers[stream.name.split(":")[-2]].extend(data)
|
|
63
|
+
else:
|
|
64
|
+
buffers[stream.name.split(":")[-1]].extend(payload)
|
|
65
|
+
|
|
66
|
+
nyield = min(len(v) for v in buffers.values())
|
|
67
|
+
if nyield:
|
|
68
|
+
for i in range(nyield):
|
|
69
|
+
yield {name: values[i] for name, values in buffers.items()}
|
|
70
|
+
buffers = {name: values[nyield:] for name, values in buffers.items()}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def last_lima_image(channel_info: dict) -> ArrayLike:
|
|
74
|
+
"""Get last lima image from memory"""
|
|
75
|
+
_ensure_redis()
|
|
76
|
+
lima_client = lima_client_factory(channel_info)
|
|
77
|
+
return lima_client.get_last_live_image().array
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _ensure_redis() -> None:
|
|
81
|
+
url = BeaconData().get_redis_data_db()
|
|
82
|
+
current_url = _current_redis_url()
|
|
83
|
+
if current_url:
|
|
84
|
+
if url == current_url:
|
|
85
|
+
return
|
|
86
|
+
raise RuntimeError("The Redis URL has changed. Restart the Nexus writer.")
|
|
87
|
+
redis_engine.set_redis_url(url)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _current_redis_url() -> Optional[str]:
|
|
91
|
+
if redis_engine._redis is None:
|
|
92
|
+
return
|
|
93
|
+
kwargs = redis_engine._redis.connection_pool.connection_kwargs
|
|
94
|
+
if "path" in kwargs:
|
|
95
|
+
return f"unix://{kwargs['path']}"
|
|
96
|
+
else:
|
|
97
|
+
return f"redis://{kwargs['host']}:{kwargs['port']}"
|
|
@@ -262,9 +262,9 @@ class StackDatasetWriter(_DatasetWriterBase):
|
|
|
262
262
|
istart0_dim1,
|
|
263
263
|
nflush_dim1,
|
|
264
264
|
):
|
|
265
|
-
self._dataset[
|
|
266
|
-
|
|
267
|
-
|
|
265
|
+
self._dataset[i_dim0, istart_dim1 : istart_dim1 + n_dim1, ...] = (
|
|
266
|
+
buffer[:n_dim1]
|
|
267
|
+
)
|
|
268
268
|
self._buffers = [
|
|
269
269
|
buffer[n_dim1:] for buffer, n_dim1 in zip(self._buffers, nflush)
|
|
270
270
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ewoksdata
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: Ewoks tasks for data access
|
|
5
5
|
Home-page: https://gitlab.esrf.fr/workflow/ewoksapps/ewoksdata/
|
|
6
6
|
Author: ESRF
|
|
@@ -14,11 +14,28 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
14
14
|
Classifier: Programming Language :: Python :: 3
|
|
15
15
|
Requires-Python: >=3.7
|
|
16
16
|
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE.md
|
|
18
|
+
Requires-Dist: h5py>=2.8
|
|
19
|
+
Requires-Dist: silx>=1.1.0
|
|
20
|
+
Requires-Dist: hdf5plugin
|
|
21
|
+
Requires-Dist: blissdata<1.0.1; python_version < "3.8"
|
|
22
|
+
Requires-Dist: blissdata; python_version >= "3.8"
|
|
23
|
+
Requires-Dist: redis
|
|
17
24
|
Provides-Extra: online
|
|
25
|
+
Requires-Dist: blissdata[tango]; extra == "online"
|
|
18
26
|
Provides-Extra: test
|
|
27
|
+
Requires-Dist: blissdata[tango]; extra == "test"
|
|
28
|
+
Requires-Dist: pytest>=7; extra == "test"
|
|
19
29
|
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: blissdata[tango]; extra == "dev"
|
|
31
|
+
Requires-Dist: pytest>=7; extra == "dev"
|
|
32
|
+
Requires-Dist: black>=22; extra == "dev"
|
|
33
|
+
Requires-Dist: flake8>=4; extra == "dev"
|
|
20
34
|
Provides-Extra: doc
|
|
21
|
-
|
|
35
|
+
Requires-Dist: blissdata[tango]; extra == "doc"
|
|
36
|
+
Requires-Dist: pytest>=7; extra == "doc"
|
|
37
|
+
Requires-Dist: sphinx>=4.5; extra == "doc"
|
|
38
|
+
Requires-Dist: sphinx-autodoc-typehints>=1.16; extra == "doc"
|
|
22
39
|
|
|
23
40
|
# ewoksdata
|
|
24
41
|
|
|
@@ -14,6 +14,11 @@ src/ewoksdata/data/bliss.py
|
|
|
14
14
|
src/ewoksdata/data/nexus.py
|
|
15
15
|
src/ewoksdata/data/url.py
|
|
16
16
|
src/ewoksdata/data/utils.py
|
|
17
|
+
src/ewoksdata/data/blissdata/__init__.py
|
|
18
|
+
src/ewoksdata/data/blissdata/blissdatav0.py
|
|
19
|
+
src/ewoksdata/data/blissdata/blissdatav1.py
|
|
20
|
+
src/ewoksdata/data/blissdata/blissdatavid31.py
|
|
21
|
+
src/ewoksdata/data/blissdata/exceptions.py
|
|
17
22
|
src/ewoksdata/data/hdf5/__init__.py
|
|
18
23
|
src/ewoksdata/data/hdf5/config.py
|
|
19
24
|
src/ewoksdata/data/hdf5/dataset_writer.py
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.3.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|