blissdata-lima2 2.0.2__tar.gz → 2.0.3__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.
- {blissdata_lima2-2.0.2 → blissdata_lima2-2.0.3}/PKG-INFO +2 -2
- blissdata_lima2-2.0.3/pyproject.toml +70 -0
- {blissdata_lima2-2.0.2 → blissdata_lima2-2.0.3}/src/blissdata_lima2/stream.py +20 -44
- {blissdata_lima2-2.0.2 → blissdata_lima2-2.0.3}/src/blissdata_lima2/tests/test_lima2_stream.py +134 -120
- {blissdata_lima2-2.0.2 → blissdata_lima2-2.0.3}/src/blissdata_lima2.egg-info/PKG-INFO +2 -2
- {blissdata_lima2-2.0.2 → blissdata_lima2-2.0.3}/src/blissdata_lima2.egg-info/requires.txt +1 -1
- blissdata_lima2-2.0.2/pyproject.toml +0 -28
- {blissdata_lima2-2.0.2 → blissdata_lima2-2.0.3}/LICENSE.md +0 -0
- {blissdata_lima2-2.0.2 → blissdata_lima2-2.0.3}/README.md +0 -0
- {blissdata_lima2-2.0.2 → blissdata_lima2-2.0.3}/setup.cfg +0 -0
- {blissdata_lima2-2.0.2 → blissdata_lima2-2.0.3}/src/blissdata_lima2/__init__.py +0 -0
- {blissdata_lima2-2.0.2 → blissdata_lima2-2.0.3}/src/blissdata_lima2/tests/__init__.py +0 -0
- {blissdata_lima2-2.0.2 → blissdata_lima2-2.0.3}/src/blissdata_lima2/tests/conftest.py +0 -0
- {blissdata_lima2-2.0.2 → blissdata_lima2-2.0.3}/src/blissdata_lima2.egg-info/SOURCES.txt +0 -0
- {blissdata_lima2-2.0.2 → blissdata_lima2-2.0.3}/src/blissdata_lima2.egg-info/dependency_links.txt +0 -0
- {blissdata_lima2-2.0.2 → blissdata_lima2-2.0.3}/src/blissdata_lima2.egg-info/entry_points.txt +0 -0
- {blissdata_lima2-2.0.2 → blissdata_lima2-2.0.3}/src/blissdata_lima2.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: blissdata-lima2
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.3
|
|
4
4
|
Summary: Lima2 plugin for blissdata
|
|
5
5
|
Maintainer: BCU (ESRF)
|
|
6
6
|
License-Expression: MIT
|
|
@@ -11,7 +11,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
11
11
|
Requires-Python: >=3.10
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
License-File: LICENSE.md
|
|
14
|
-
Requires-Dist: blissdata~=2.
|
|
14
|
+
Requires-Dist: blissdata~=2.4
|
|
15
15
|
Requires-Dist: lima2-client~=4.1
|
|
16
16
|
Provides-Extra: dev
|
|
17
17
|
Requires-Dist: black; extra == "dev"
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "blissdata-lima2"
|
|
7
|
+
version = "2.0.3"
|
|
8
|
+
description = "Lima2 plugin for blissdata"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
license-files = ["LICENSE.md"]
|
|
12
|
+
maintainers = [{ name = "BCU (ESRF)" }]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Intended Audience :: Science/Research",
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
]
|
|
17
|
+
keywords = ["blissdata", "lima2"]
|
|
18
|
+
requires-python = ">=3.10"
|
|
19
|
+
dependencies = ["blissdata~=2.4", "lima2-client~=4.1"]
|
|
20
|
+
|
|
21
|
+
[project.urls]
|
|
22
|
+
Repository = "https://gitlab.esrf.fr/bliss/blissdata-lima2"
|
|
23
|
+
|
|
24
|
+
[project.optional-dependencies]
|
|
25
|
+
dev = ["black", "flake8", "mypy", "pytest", "pytest-cov", "pytest-redis"]
|
|
26
|
+
|
|
27
|
+
[project.entry-points.blissdata]
|
|
28
|
+
lima2 = "blissdata_lima2"
|
|
29
|
+
|
|
30
|
+
[tool.pixi.workspace]
|
|
31
|
+
channels = ["conda-forge", "esrf-bcu"]
|
|
32
|
+
platforms = ["linux-64"]
|
|
33
|
+
|
|
34
|
+
[tool.pixi.dependencies]
|
|
35
|
+
python = ">=3.10,<3.15"
|
|
36
|
+
|
|
37
|
+
[tool.pixi.pypi-dependencies]
|
|
38
|
+
blissdata-lima2 = { path = ".", editable = true }
|
|
39
|
+
|
|
40
|
+
[tool.pixi.environments]
|
|
41
|
+
default = { solve-group = "default" }
|
|
42
|
+
test = { features = ["test"], solve-group = "default" }
|
|
43
|
+
dev = { features = ["dev"], no-default-feature = true }
|
|
44
|
+
build = { features = ["build"], no-default-feature = true }
|
|
45
|
+
|
|
46
|
+
[dependency-groups]
|
|
47
|
+
test = ["blissdata-lima2[dev]"]
|
|
48
|
+
build = ["build"]
|
|
49
|
+
|
|
50
|
+
[tool.pixi.feature.test.dependencies]
|
|
51
|
+
redis-server = "7.*"
|
|
52
|
+
redisearch = ">=2.6.5"
|
|
53
|
+
redisjson = ">=2.4.5"
|
|
54
|
+
|
|
55
|
+
[tool.pixi.feature.test.tasks]
|
|
56
|
+
test = { cmd = "pytest -v", description = "Run tests" }
|
|
57
|
+
|
|
58
|
+
[tool.pixi.feature.dev.dependencies]
|
|
59
|
+
python = ">=3.10"
|
|
60
|
+
|
|
61
|
+
[tool.pixi.feature.dev.tasks]
|
|
62
|
+
style = { cmd = "black . --check", description = "Check the style of the source code" }
|
|
63
|
+
fix-style = { cmd = "black .", description = "Fixes the style of the source code" }
|
|
64
|
+
lint = { cmd = "flake8", description = "Check the linting" }
|
|
65
|
+
|
|
66
|
+
[tool.pixi.feature.build.dependencies]
|
|
67
|
+
python = ">=3.10"
|
|
68
|
+
|
|
69
|
+
[tool.pixi.feature.build.tasks]
|
|
70
|
+
build = { cmd = "python -m build .", description = "Build packages" }
|
|
@@ -10,6 +10,7 @@ from collections.abc import Sequence
|
|
|
10
10
|
|
|
11
11
|
import lima2.client.services as l2s
|
|
12
12
|
import numpy as np
|
|
13
|
+
from functools import cached_property
|
|
13
14
|
from blissdata.exceptions import (
|
|
14
15
|
EmptyViewException,
|
|
15
16
|
EndOfStream,
|
|
@@ -52,18 +53,12 @@ def get_frame(
|
|
|
52
53
|
class Lima2View(BaseView):
|
|
53
54
|
def __init__(
|
|
54
55
|
self,
|
|
55
|
-
|
|
56
|
-
acq_uuid: str,
|
|
57
|
-
source: str,
|
|
56
|
+
stream: Lima2Stream,
|
|
58
57
|
start: int,
|
|
59
58
|
stop: int,
|
|
60
59
|
) -> None:
|
|
61
|
-
self.
|
|
62
|
-
"""Lima2
|
|
63
|
-
self._acq_uuid = acq_uuid
|
|
64
|
-
"""Lima2 acquisition id."""
|
|
65
|
-
self._source = source
|
|
66
|
-
"""Frame source name."""
|
|
60
|
+
self._stream = stream
|
|
61
|
+
"""Lima2 stream."""
|
|
67
62
|
self._idx_range = range(start, stop)
|
|
68
63
|
"""Range of absolute frame indices accessible via this view."""
|
|
69
64
|
|
|
@@ -75,29 +70,10 @@ class Lima2View(BaseView):
|
|
|
75
70
|
return len(self._idx_range)
|
|
76
71
|
|
|
77
72
|
def get_data(self, start: int | None = None, stop: int | None = None) -> np.ndarray:
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
get_frame(
|
|
83
|
-
services=self._services,
|
|
84
|
-
acq_uuid=self._acq_uuid,
|
|
85
|
-
source=self._source,
|
|
86
|
-
frame_idx=idx,
|
|
87
|
-
).array
|
|
88
|
-
)
|
|
89
|
-
except RuntimeError as e:
|
|
90
|
-
# Raise if any frame can't be accessed
|
|
91
|
-
raise IndexNoMoreThereError(
|
|
92
|
-
f"Can't fetch {self._source} {self._idx_range[start:stop]}: {e}"
|
|
93
|
-
) from e
|
|
94
|
-
except ValueError as e:
|
|
95
|
-
# Frame source has no associated memory buffer (raw_frame)
|
|
96
|
-
raise IndexNoMoreThereError(
|
|
97
|
-
f"Can't fetch {self._source}: no associated live data"
|
|
98
|
-
) from e
|
|
99
|
-
|
|
100
|
-
return np.asarray(frames)
|
|
73
|
+
stream_range = self._idx_range[start:stop]
|
|
74
|
+
return self._stream._fetch_online(
|
|
75
|
+
stream_range.start, stream_range.stop, stream_range.step
|
|
76
|
+
)
|
|
101
77
|
|
|
102
78
|
|
|
103
79
|
class Lima2Stream(BaseStream, LimaDirectAccess):
|
|
@@ -130,23 +106,25 @@ class Lima2Stream(BaseStream, LimaDirectAccess):
|
|
|
130
106
|
self._source = str(event_stream.info["source_name"])
|
|
131
107
|
self._master_file: tuple[str, str] | None = event_stream.info["master_file"]
|
|
132
108
|
|
|
133
|
-
self._services = l2s.init(
|
|
134
|
-
hostname=str(event_stream.info["conductor_hostname"]),
|
|
135
|
-
port=int(event_stream.info["conductor_port"]),
|
|
136
|
-
)
|
|
137
|
-
"""Lima2 client session."""
|
|
138
|
-
|
|
139
109
|
self._length = 0
|
|
140
110
|
"""Current number of accessible frames."""
|
|
141
111
|
|
|
142
112
|
self._cursor = Stream(event_stream).cursor()
|
|
143
113
|
|
|
144
|
-
self._services.handshake()
|
|
145
|
-
|
|
146
114
|
####################################################################################
|
|
147
115
|
# BaseStream
|
|
148
116
|
####################################################################################
|
|
149
117
|
|
|
118
|
+
@cached_property
|
|
119
|
+
def _services(self):
|
|
120
|
+
"""Lima2 client session."""
|
|
121
|
+
services = l2s.init(
|
|
122
|
+
hostname=str(self._event_stream.info["conductor_hostname"]),
|
|
123
|
+
port=int(self._event_stream.info["conductor_port"]),
|
|
124
|
+
)
|
|
125
|
+
services.handshake()
|
|
126
|
+
return services
|
|
127
|
+
|
|
150
128
|
@property
|
|
151
129
|
def kind(self) -> str:
|
|
152
130
|
return "array"
|
|
@@ -262,9 +240,7 @@ class Lima2Stream(BaseStream, LimaDirectAccess):
|
|
|
262
240
|
raise EmptyViewException
|
|
263
241
|
|
|
264
242
|
return Lima2View(
|
|
265
|
-
|
|
266
|
-
acq_uuid=self._acq_uuid,
|
|
267
|
-
source=self._source,
|
|
243
|
+
stream=self,
|
|
268
244
|
start=stop_idx - 1 if last_only else index,
|
|
269
245
|
stop=stop_idx,
|
|
270
246
|
)
|
|
@@ -337,7 +313,7 @@ class Lima2Stream(BaseStream, LimaDirectAccess):
|
|
|
337
313
|
f"Can't fetch {self._source}: no associated live data"
|
|
338
314
|
) from e
|
|
339
315
|
|
|
340
|
-
return np.asarray(frames)
|
|
316
|
+
return np.asarray(frames).reshape(-1, *self.shape)
|
|
341
317
|
|
|
342
318
|
def _fetch_from_disk(
|
|
343
319
|
self, filepath: str, datapath: str, start: int, stop: int, step: int
|
{blissdata_lima2-2.0.2 → blissdata_lima2-2.0.3}/src/blissdata_lima2/tests/test_lima2_stream.py
RENAMED
|
@@ -66,45 +66,23 @@ def test_lima2_get_sparse_frame():
|
|
|
66
66
|
|
|
67
67
|
|
|
68
68
|
def test_lima2_view(monkeypatch):
|
|
69
|
-
|
|
70
|
-
uuid = str(uuid1())
|
|
69
|
+
stream = Mock()
|
|
71
70
|
view = Lima2View(
|
|
72
|
-
|
|
73
|
-
acq_uuid=uuid,
|
|
74
|
-
source="cafe",
|
|
71
|
+
stream=stream,
|
|
75
72
|
start=0,
|
|
76
73
|
stop=42,
|
|
77
74
|
)
|
|
78
75
|
assert len(view) == 42
|
|
79
76
|
assert view.index == 0
|
|
80
77
|
|
|
81
|
-
|
|
82
|
-
assert len(frames) == len(view)
|
|
83
|
-
|
|
84
|
-
services.pipeline.get_frame.assert_has_calls(
|
|
85
|
-
[call(uuid=uuid, source="cafe", frame_idx=i) for i in range(42)]
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
# RuntimeError
|
|
89
|
-
def mock_get_frame_runtime_error(services, acq_uuid, source, frame_idx):
|
|
90
|
-
raise RuntimeError("frame has left the buffer")
|
|
78
|
+
_ = view.get_data()
|
|
91
79
|
|
|
92
|
-
|
|
93
|
-
|
|
80
|
+
stream._fetch_online.assert_has_calls(
|
|
81
|
+
[
|
|
82
|
+
call(0, 42, 1),
|
|
83
|
+
]
|
|
94
84
|
)
|
|
95
85
|
|
|
96
|
-
with pytest.raises(IndexNoMoreThereError):
|
|
97
|
-
frames = view.get_data()
|
|
98
|
-
|
|
99
|
-
# ValueError
|
|
100
|
-
def mock_get_frame_value_error(services, acq_uuid, source, frame_idx):
|
|
101
|
-
raise ValueError("no such frame buffer")
|
|
102
|
-
|
|
103
|
-
monkeypatch.setattr("blissdata_lima2.stream.get_frame", mock_get_frame_value_error)
|
|
104
|
-
|
|
105
|
-
with pytest.raises(IndexNoMoreThereError):
|
|
106
|
-
frames = view.get_data()
|
|
107
|
-
|
|
108
86
|
|
|
109
87
|
def test_lima2_protocol(data_store):
|
|
110
88
|
uuid = str(uuid1())
|
|
@@ -141,7 +119,7 @@ def lima2_stream(data_store, mock_handshake):
|
|
|
141
119
|
acq_uuid=uuid,
|
|
142
120
|
master_file=None,
|
|
143
121
|
dtype=np.float128, # fat pixels >:)
|
|
144
|
-
shape=(
|
|
122
|
+
shape=(),
|
|
145
123
|
)
|
|
146
124
|
model = data_store._stream_model(
|
|
147
125
|
encoding=stream_def.encoder.info(), info=stream_def.info
|
|
@@ -150,162 +128,152 @@ def lima2_stream(data_store, mock_handshake):
|
|
|
150
128
|
event_stream = EventStream.create(data_store, stream_def.name, model)
|
|
151
129
|
stream = Lima2Stream(event_stream=event_stream)
|
|
152
130
|
|
|
153
|
-
return
|
|
131
|
+
return stream
|
|
154
132
|
|
|
155
133
|
|
|
156
134
|
def test_lima2_stream_attributes(lima2_stream):
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
assert
|
|
160
|
-
assert
|
|
161
|
-
assert
|
|
162
|
-
assert
|
|
163
|
-
assert stream._need_last_only(last_only=True)
|
|
164
|
-
assert stream._need_last_only(last_only=False)
|
|
135
|
+
assert lima2_stream.plugin == "lima2"
|
|
136
|
+
assert lima2_stream.shape == lima2_stream.info["shape"]
|
|
137
|
+
assert lima2_stream.kind == "array"
|
|
138
|
+
assert lima2_stream.dtype == lima2_stream._dtype
|
|
139
|
+
assert lima2_stream._need_last_only(last_only=True)
|
|
140
|
+
assert lima2_stream._need_last_only(last_only=False)
|
|
165
141
|
|
|
166
142
|
|
|
167
143
|
def test_lima2_stream_indexing(lima2_stream, monkeypatch):
|
|
168
|
-
stream_def, event_stream, stream = lima2_stream
|
|
169
|
-
|
|
170
144
|
# Feed the event stream
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
assert len(
|
|
145
|
+
lima2_stream.send(np.uint32(42))
|
|
146
|
+
lima2_stream.join()
|
|
147
|
+
assert len(lima2_stream) == 42
|
|
174
148
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
assert len(
|
|
149
|
+
lima2_stream.send(np.uint32(123))
|
|
150
|
+
lima2_stream.join()
|
|
151
|
+
assert len(lima2_stream) == 123
|
|
178
152
|
|
|
179
153
|
mock_get_frame = Mock()
|
|
180
154
|
monkeypatch.setattr("blissdata_lima2.stream.get_frame", mock_get_frame)
|
|
181
155
|
|
|
182
156
|
# Indexing
|
|
183
|
-
_ =
|
|
157
|
+
_ = lima2_stream[0]
|
|
184
158
|
mock_get_frame.assert_called_with(
|
|
185
|
-
services=
|
|
186
|
-
acq_uuid=
|
|
159
|
+
services=lima2_stream._services,
|
|
160
|
+
acq_uuid=lima2_stream._acq_uuid,
|
|
187
161
|
source="cafe",
|
|
188
162
|
frame_idx=0,
|
|
189
163
|
)
|
|
190
164
|
|
|
191
165
|
with pytest.raises(IndexNotYetThereError):
|
|
192
|
-
_ =
|
|
166
|
+
_ = lima2_stream[-1]
|
|
193
167
|
|
|
194
168
|
with pytest.raises(IndexNotYetThereError):
|
|
195
|
-
_ =
|
|
169
|
+
_ = lima2_stream[123123] # wayyy out of bounds, but we're not sealed yet
|
|
196
170
|
|
|
197
171
|
with monkeypatch.context() as mpc:
|
|
198
|
-
mpc.setattr(
|
|
172
|
+
mpc.setattr(lima2_stream, "is_sealed", lambda: True)
|
|
199
173
|
|
|
200
174
|
with pytest.raises(IndexWontBeThereError):
|
|
201
|
-
_ =
|
|
175
|
+
_ = lima2_stream[123123] # wayyy out of bounds and we're sealed
|
|
202
176
|
|
|
203
|
-
|
|
204
|
-
event_stream.join()
|
|
177
|
+
lima2_stream.seal()
|
|
205
178
|
|
|
206
|
-
_ =
|
|
179
|
+
_ = lima2_stream[-3]
|
|
207
180
|
assert mock_get_frame.mock_calls[-1] == call(
|
|
208
|
-
services=
|
|
209
|
-
acq_uuid=
|
|
181
|
+
services=lima2_stream._services,
|
|
182
|
+
acq_uuid=lima2_stream._acq_uuid,
|
|
210
183
|
source="cafe",
|
|
211
184
|
frame_idx=123 - 3,
|
|
212
185
|
)
|
|
213
186
|
|
|
214
187
|
|
|
215
188
|
def test_lima2_stream_slicing(lima2_stream, monkeypatch):
|
|
216
|
-
|
|
189
|
+
# Feed the stream
|
|
190
|
+
lima2_stream.send(np.uint32(42))
|
|
191
|
+
lima2_stream.join()
|
|
192
|
+
assert len(lima2_stream) == 42
|
|
217
193
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
assert len(stream) == 42
|
|
222
|
-
|
|
223
|
-
event_stream.send(np.uint32(123))
|
|
224
|
-
event_stream.join()
|
|
225
|
-
assert len(stream) == 123
|
|
194
|
+
lima2_stream.send(np.uint32(123))
|
|
195
|
+
lima2_stream.join()
|
|
196
|
+
assert len(lima2_stream) == 123
|
|
226
197
|
|
|
227
198
|
mock_get_frame = Mock()
|
|
228
199
|
monkeypatch.setattr("blissdata_lima2.stream.get_frame", mock_get_frame)
|
|
229
200
|
|
|
230
201
|
# Slicing
|
|
231
|
-
_ =
|
|
202
|
+
_ = lima2_stream[:3]
|
|
232
203
|
assert mock_get_frame.mock_calls[-3:] == [
|
|
233
204
|
call(
|
|
234
|
-
services=
|
|
235
|
-
acq_uuid=
|
|
205
|
+
services=lima2_stream._services,
|
|
206
|
+
acq_uuid=lima2_stream._acq_uuid,
|
|
236
207
|
source="cafe",
|
|
237
208
|
frame_idx=0,
|
|
238
209
|
),
|
|
239
210
|
call(
|
|
240
|
-
services=
|
|
241
|
-
acq_uuid=
|
|
211
|
+
services=lima2_stream._services,
|
|
212
|
+
acq_uuid=lima2_stream._acq_uuid,
|
|
242
213
|
source="cafe",
|
|
243
214
|
frame_idx=1,
|
|
244
215
|
),
|
|
245
216
|
call(
|
|
246
|
-
services=
|
|
247
|
-
acq_uuid=
|
|
217
|
+
services=lima2_stream._services,
|
|
218
|
+
acq_uuid=lima2_stream._acq_uuid,
|
|
248
219
|
source="cafe",
|
|
249
220
|
frame_idx=2,
|
|
250
221
|
),
|
|
251
222
|
]
|
|
252
223
|
|
|
253
224
|
with pytest.raises(IndexNotYetThereError):
|
|
254
|
-
_ =
|
|
225
|
+
_ = lima2_stream[-2:]
|
|
255
226
|
|
|
256
227
|
with pytest.raises(IndexNotYetThereError):
|
|
257
|
-
_ =
|
|
228
|
+
_ = lima2_stream[:-2]
|
|
258
229
|
|
|
259
230
|
with pytest.raises(TypeError):
|
|
260
|
-
_ =
|
|
231
|
+
_ = lima2_stream["hi :)"]
|
|
261
232
|
|
|
262
|
-
|
|
263
|
-
event_stream.join()
|
|
233
|
+
lima2_stream.seal()
|
|
264
234
|
|
|
265
235
|
# Now slicing/indexing from end is ok
|
|
266
|
-
_ =
|
|
236
|
+
_ = lima2_stream[-2:]
|
|
267
237
|
assert mock_get_frame.mock_calls[-2:] == [
|
|
268
238
|
call(
|
|
269
|
-
services=
|
|
270
|
-
acq_uuid=
|
|
239
|
+
services=lima2_stream._services,
|
|
240
|
+
acq_uuid=lima2_stream._acq_uuid,
|
|
271
241
|
source="cafe",
|
|
272
242
|
frame_idx=123 - 2,
|
|
273
243
|
),
|
|
274
244
|
call(
|
|
275
|
-
services=
|
|
276
|
-
acq_uuid=
|
|
245
|
+
services=lima2_stream._services,
|
|
246
|
+
acq_uuid=lima2_stream._acq_uuid,
|
|
277
247
|
source="cafe",
|
|
278
248
|
frame_idx=123 - 1,
|
|
279
249
|
),
|
|
280
250
|
]
|
|
281
251
|
|
|
282
|
-
_ =
|
|
252
|
+
_ = lima2_stream[:]
|
|
283
253
|
assert mock_get_frame.mock_calls[-123:] == [
|
|
284
254
|
call(
|
|
285
|
-
services=
|
|
286
|
-
acq_uuid=
|
|
255
|
+
services=lima2_stream._services,
|
|
256
|
+
acq_uuid=lima2_stream._acq_uuid,
|
|
287
257
|
source="cafe",
|
|
288
258
|
frame_idx=i,
|
|
289
259
|
)
|
|
290
260
|
for i in range(123)
|
|
291
261
|
]
|
|
292
262
|
|
|
293
|
-
_ =
|
|
263
|
+
_ = lima2_stream.get_last_live_image()
|
|
294
264
|
mock_get_frame.assert_called_with(
|
|
295
|
-
services=
|
|
296
|
-
acq_uuid=
|
|
265
|
+
services=lima2_stream._services,
|
|
266
|
+
acq_uuid=lima2_stream._acq_uuid,
|
|
297
267
|
source="cafe",
|
|
298
268
|
frame_idx=-1,
|
|
299
269
|
)
|
|
300
270
|
|
|
301
271
|
|
|
302
272
|
def test_lima2_stream_build_view(lima2_stream, monkeypatch):
|
|
303
|
-
stream_def, event_stream, stream = lima2_stream
|
|
304
|
-
|
|
305
273
|
mock_get_frame = Mock()
|
|
306
274
|
monkeypatch.setattr("blissdata_lima2.stream.get_frame", mock_get_frame)
|
|
307
275
|
|
|
308
|
-
view =
|
|
276
|
+
view = lima2_stream._build_view_from_events(
|
|
309
277
|
index=0,
|
|
310
278
|
events=EventRange(
|
|
311
279
|
index=0,
|
|
@@ -317,7 +285,7 @@ def test_lima2_stream_build_view(lima2_stream, monkeypatch):
|
|
|
317
285
|
)
|
|
318
286
|
assert view._idx_range == range(0, 42)
|
|
319
287
|
|
|
320
|
-
view =
|
|
288
|
+
view = lima2_stream._build_view_from_events(
|
|
321
289
|
index=0,
|
|
322
290
|
events=EventRange(
|
|
323
291
|
index=0,
|
|
@@ -331,7 +299,7 @@ def test_lima2_stream_build_view(lima2_stream, monkeypatch):
|
|
|
331
299
|
|
|
332
300
|
with pytest.raises(EmptyViewException):
|
|
333
301
|
# index >= data[-1]
|
|
334
|
-
view =
|
|
302
|
+
view = lima2_stream._build_view_from_events(
|
|
335
303
|
index=42,
|
|
336
304
|
events=EventRange(
|
|
337
305
|
index=0,
|
|
@@ -344,23 +312,21 @@ def test_lima2_stream_build_view(lima2_stream, monkeypatch):
|
|
|
344
312
|
|
|
345
313
|
|
|
346
314
|
def test_lima2_stream_fetch_frames(lima2_stream, monkeypatch):
|
|
347
|
-
stream_def, event_stream, stream = lima2_stream
|
|
348
|
-
|
|
349
315
|
mock_get_frame = Mock()
|
|
350
316
|
monkeypatch.setattr("blissdata_lima2.stream.get_frame", mock_get_frame)
|
|
351
317
|
|
|
352
318
|
with monkeypatch.context() as mpc:
|
|
353
319
|
# Stream sealed, has master file
|
|
354
320
|
mock_fetch = Mock()
|
|
355
|
-
mpc.setattr(
|
|
356
|
-
mpc.setattr(
|
|
321
|
+
mpc.setattr(lima2_stream, "_fetch_from_disk", mock_fetch)
|
|
322
|
+
mpc.setattr(lima2_stream, "is_sealed", lambda: True)
|
|
357
323
|
mpc.setattr(
|
|
358
|
-
|
|
324
|
+
lima2_stream,
|
|
359
325
|
"_master_file",
|
|
360
326
|
("/path/to/master.h5", "entry/instrument/detector/dataset"),
|
|
361
327
|
)
|
|
362
328
|
|
|
363
|
-
|
|
329
|
+
lima2_stream._fetch_frames(start=0, stop=42, step=3)
|
|
364
330
|
|
|
365
331
|
mock_fetch.assert_called_once_with(
|
|
366
332
|
filepath="/path/to/master.h5",
|
|
@@ -373,11 +339,11 @@ def test_lima2_stream_fetch_frames(lima2_stream, monkeypatch):
|
|
|
373
339
|
with monkeypatch.context() as mpc:
|
|
374
340
|
# Stream sealed, no master file
|
|
375
341
|
mock_fetch = Mock()
|
|
376
|
-
mpc.setattr(
|
|
377
|
-
mpc.setattr(
|
|
378
|
-
mpc.setattr(
|
|
342
|
+
mpc.setattr(lima2_stream, "_fetch_online", mock_fetch)
|
|
343
|
+
mpc.setattr(lima2_stream, "is_sealed", lambda: True)
|
|
344
|
+
mpc.setattr(lima2_stream, "_master_file", None)
|
|
379
345
|
|
|
380
|
-
|
|
346
|
+
lima2_stream._fetch_frames(start=0, stop=42, step=3)
|
|
381
347
|
|
|
382
348
|
mock_fetch.assert_called_once_with(
|
|
383
349
|
start=0,
|
|
@@ -388,10 +354,10 @@ def test_lima2_stream_fetch_frames(lima2_stream, monkeypatch):
|
|
|
388
354
|
with monkeypatch.context() as mpc:
|
|
389
355
|
# Stream not sealed
|
|
390
356
|
mock_fetch = Mock()
|
|
391
|
-
mpc.setattr(
|
|
392
|
-
mpc.setattr(
|
|
357
|
+
mpc.setattr(lima2_stream, "_fetch_online", mock_fetch)
|
|
358
|
+
mpc.setattr(lima2_stream, "is_sealed", lambda: False)
|
|
393
359
|
|
|
394
|
-
|
|
360
|
+
lima2_stream._fetch_frames(start=0, stop=42, step=3)
|
|
395
361
|
|
|
396
362
|
mock_fetch.assert_called_once_with(
|
|
397
363
|
start=0,
|
|
@@ -401,19 +367,17 @@ def test_lima2_stream_fetch_frames(lima2_stream, monkeypatch):
|
|
|
401
367
|
|
|
402
368
|
|
|
403
369
|
def test_lima2_stream_fetch_online(lima2_stream, monkeypatch):
|
|
404
|
-
stream_def, event_stream, stream = lima2_stream
|
|
405
|
-
|
|
406
370
|
mock_get_frame = Mock()
|
|
407
371
|
monkeypatch.setattr("blissdata_lima2.stream.get_frame", mock_get_frame)
|
|
408
372
|
|
|
409
|
-
|
|
373
|
+
lima2_stream._fetch_online(start=0, stop=42, step=3)
|
|
410
374
|
|
|
411
375
|
mock_get_frame.assert_has_calls(
|
|
412
376
|
[
|
|
413
377
|
call(
|
|
414
|
-
services=
|
|
415
|
-
acq_uuid=
|
|
416
|
-
source=
|
|
378
|
+
services=lima2_stream._services,
|
|
379
|
+
acq_uuid=lima2_stream._acq_uuid,
|
|
380
|
+
source=lima2_stream._source,
|
|
417
381
|
frame_idx=idx,
|
|
418
382
|
)
|
|
419
383
|
for idx in range(0, 42, 3)
|
|
@@ -429,7 +393,7 @@ def test_lima2_stream_fetch_online(lima2_stream, monkeypatch):
|
|
|
429
393
|
)
|
|
430
394
|
|
|
431
395
|
with pytest.raises(IndexNoMoreThereError):
|
|
432
|
-
_ =
|
|
396
|
+
_ = lima2_stream._fetch_online(start=0, stop=1, step=1)
|
|
433
397
|
|
|
434
398
|
# ValueError
|
|
435
399
|
def mock_get_frame_value_error(services, acq_uuid, source, frame_idx):
|
|
@@ -438,16 +402,14 @@ def test_lima2_stream_fetch_online(lima2_stream, monkeypatch):
|
|
|
438
402
|
monkeypatch.setattr("blissdata_lima2.stream.get_frame", mock_get_frame_value_error)
|
|
439
403
|
|
|
440
404
|
with pytest.raises(IndexNoMoreThereError):
|
|
441
|
-
_ =
|
|
405
|
+
_ = lima2_stream._fetch_online(start=0, stop=1, step=1)
|
|
442
406
|
|
|
443
407
|
|
|
444
408
|
def test_lima2_stream_fetch_offline(lima2_stream, monkeypatch):
|
|
445
|
-
stream_def, event_stream, stream = lima2_stream
|
|
446
|
-
|
|
447
409
|
mock_dynamic_hdf5 = MagicMock()
|
|
448
410
|
monkeypatch.setattr("blissdata_lima2.stream.dynamic_hdf5", mock_dynamic_hdf5)
|
|
449
411
|
|
|
450
|
-
|
|
412
|
+
lima2_stream._fetch_from_disk(
|
|
451
413
|
filepath="/path/to/master.h5",
|
|
452
414
|
datapath="entry/instrument/detector/dataset",
|
|
453
415
|
start=0,
|
|
@@ -456,3 +418,55 @@ def test_lima2_stream_fetch_offline(lima2_stream, monkeypatch):
|
|
|
456
418
|
)
|
|
457
419
|
|
|
458
420
|
mock_dynamic_hdf5.File.assert_called_once()
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
def test_lima2_stream_reshape(data_store, mock_handshake, monkeypatch):
|
|
424
|
+
"""Verify proper reshaping of the frame on online frame fetch."""
|
|
425
|
+
|
|
426
|
+
stream_def = Lima2Stream.make_definition(
|
|
427
|
+
name="device:cafe",
|
|
428
|
+
source_name="cafe",
|
|
429
|
+
conductor_hostname="www.lima2.org",
|
|
430
|
+
conductor_port=12345,
|
|
431
|
+
acq_uuid=uuid1(),
|
|
432
|
+
master_file=None,
|
|
433
|
+
dtype=np.uint32,
|
|
434
|
+
shape=(13, 37), # note 2D
|
|
435
|
+
)
|
|
436
|
+
lima2_stream = Lima2Stream(
|
|
437
|
+
event_stream=EventStream.create(
|
|
438
|
+
data_store=data_store,
|
|
439
|
+
name=stream_def.name,
|
|
440
|
+
model=data_store._stream_model(
|
|
441
|
+
encoding=stream_def.encoder.info(), info=stream_def.info
|
|
442
|
+
),
|
|
443
|
+
)
|
|
444
|
+
)
|
|
445
|
+
|
|
446
|
+
def mock_get_frame_3d(services, acq_uuid, source, frame_idx):
|
|
447
|
+
return ImageData(array=np.zeros((1, 13, 37)), frame_id=0, acq_tag=None)
|
|
448
|
+
|
|
449
|
+
monkeypatch.setattr("blissdata_lima2.stream.get_frame", mock_get_frame_3d)
|
|
450
|
+
|
|
451
|
+
data = lima2_stream._fetch_online(start=0, stop=4, step=1)
|
|
452
|
+
assert data.shape == (4, 13, 37)
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
def test_lima2_client_lazy_init(data_store, monkeypatch, lima2_stream):
|
|
456
|
+
class InitForbiddenError(Exception):
|
|
457
|
+
pass
|
|
458
|
+
|
|
459
|
+
def mock_client_init(*args, **kwargs):
|
|
460
|
+
raise InitForbiddenError()
|
|
461
|
+
|
|
462
|
+
monkeypatch.setattr("lima2.client.services.init", mock_client_init)
|
|
463
|
+
|
|
464
|
+
lima2_stream.send(np.uint32(42))
|
|
465
|
+
lima2_stream.join()
|
|
466
|
+
view = lima2_stream.cursor().read(block=False)
|
|
467
|
+
|
|
468
|
+
with pytest.raises(InitForbiddenError):
|
|
469
|
+
view.get_data()
|
|
470
|
+
|
|
471
|
+
with pytest.raises(InitForbiddenError):
|
|
472
|
+
lima2_stream[0]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: blissdata-lima2
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.3
|
|
4
4
|
Summary: Lima2 plugin for blissdata
|
|
5
5
|
Maintainer: BCU (ESRF)
|
|
6
6
|
License-Expression: MIT
|
|
@@ -11,7 +11,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
11
11
|
Requires-Python: >=3.10
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
License-File: LICENSE.md
|
|
14
|
-
Requires-Dist: blissdata~=2.
|
|
14
|
+
Requires-Dist: blissdata~=2.4
|
|
15
15
|
Requires-Dist: lima2-client~=4.1
|
|
16
16
|
Provides-Extra: dev
|
|
17
17
|
Requires-Dist: black; extra == "dev"
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
[build-system]
|
|
2
|
-
requires = ["setuptools"]
|
|
3
|
-
build-backend = "setuptools.build_meta"
|
|
4
|
-
|
|
5
|
-
[project]
|
|
6
|
-
name = "blissdata-lima2"
|
|
7
|
-
version = "2.0.2"
|
|
8
|
-
description = "Lima2 plugin for blissdata"
|
|
9
|
-
readme = "README.md"
|
|
10
|
-
license = "MIT"
|
|
11
|
-
license-files = ["LICENSE.md"]
|
|
12
|
-
maintainers = [{ name = "BCU (ESRF)" }]
|
|
13
|
-
classifiers = [
|
|
14
|
-
"Intended Audience :: Science/Research",
|
|
15
|
-
"Programming Language :: Python :: 3",
|
|
16
|
-
]
|
|
17
|
-
keywords = ["blissdata", "lima2"]
|
|
18
|
-
requires-python = ">=3.10"
|
|
19
|
-
dependencies = ["blissdata~=2.3", "lima2-client~=4.1"]
|
|
20
|
-
|
|
21
|
-
[project.urls]
|
|
22
|
-
Repository = "https://gitlab.esrf.fr/bliss/blissdata-lima2"
|
|
23
|
-
|
|
24
|
-
[project.optional-dependencies]
|
|
25
|
-
dev = ["black", "flake8", "mypy", "pytest", "pytest-cov", "pytest-redis"]
|
|
26
|
-
|
|
27
|
-
[project.entry-points.blissdata]
|
|
28
|
-
lima2 = "blissdata_lima2"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{blissdata_lima2-2.0.2 → blissdata_lima2-2.0.3}/src/blissdata_lima2.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{blissdata_lima2-2.0.2 → blissdata_lima2-2.0.3}/src/blissdata_lima2.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|