blissdata-lima2 2.0.1__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.1 → blissdata_lima2-2.0.3}/PKG-INFO +3 -3
- blissdata_lima2-2.0.3/pyproject.toml +70 -0
- {blissdata_lima2-2.0.1 → blissdata_lima2-2.0.3}/src/blissdata_lima2/stream.py +20 -42
- {blissdata_lima2-2.0.1 → blissdata_lima2-2.0.3}/src/blissdata_lima2/tests/test_lima2_stream.py +145 -121
- {blissdata_lima2-2.0.1 → blissdata_lima2-2.0.3}/src/blissdata_lima2.egg-info/PKG-INFO +3 -3
- {blissdata_lima2-2.0.1 → blissdata_lima2-2.0.3}/src/blissdata_lima2.egg-info/requires.txt +2 -2
- blissdata_lima2-2.0.1/pyproject.toml +0 -28
- {blissdata_lima2-2.0.1 → blissdata_lima2-2.0.3}/LICENSE.md +0 -0
- {blissdata_lima2-2.0.1 → blissdata_lima2-2.0.3}/README.md +0 -0
- {blissdata_lima2-2.0.1 → blissdata_lima2-2.0.3}/setup.cfg +0 -0
- {blissdata_lima2-2.0.1 → blissdata_lima2-2.0.3}/src/blissdata_lima2/__init__.py +0 -0
- {blissdata_lima2-2.0.1 → blissdata_lima2-2.0.3}/src/blissdata_lima2/tests/__init__.py +0 -0
- {blissdata_lima2-2.0.1 → blissdata_lima2-2.0.3}/src/blissdata_lima2/tests/conftest.py +0 -0
- {blissdata_lima2-2.0.1 → blissdata_lima2-2.0.3}/src/blissdata_lima2.egg-info/SOURCES.txt +0 -0
- {blissdata_lima2-2.0.1 → blissdata_lima2-2.0.3}/src/blissdata_lima2.egg-info/dependency_links.txt +0 -0
- {blissdata_lima2-2.0.1 → blissdata_lima2-2.0.3}/src/blissdata_lima2.egg-info/entry_points.txt +0 -0
- {blissdata_lima2-2.0.1 → 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,8 +11,8 @@ 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.
|
|
15
|
-
Requires-Dist: lima2-client~=4.
|
|
14
|
+
Requires-Dist: blissdata~=2.4
|
|
15
|
+
Requires-Dist: lima2-client~=4.1
|
|
16
16
|
Provides-Extra: dev
|
|
17
17
|
Requires-Dist: black; extra == "dev"
|
|
18
18
|
Requires-Dist: flake8; 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,12 +106,6 @@ 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
|
|
|
@@ -145,6 +115,16 @@ class Lima2Stream(BaseStream, LimaDirectAccess):
|
|
|
145
115
|
# BaseStream
|
|
146
116
|
####################################################################################
|
|
147
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
|
+
|
|
148
128
|
@property
|
|
149
129
|
def kind(self) -> str:
|
|
150
130
|
return "array"
|
|
@@ -260,9 +240,7 @@ class Lima2Stream(BaseStream, LimaDirectAccess):
|
|
|
260
240
|
raise EmptyViewException
|
|
261
241
|
|
|
262
242
|
return Lima2View(
|
|
263
|
-
|
|
264
|
-
acq_uuid=self._acq_uuid,
|
|
265
|
-
source=self._source,
|
|
243
|
+
stream=self,
|
|
266
244
|
start=stop_idx - 1 if last_only else index,
|
|
267
245
|
stop=stop_idx,
|
|
268
246
|
)
|
|
@@ -335,7 +313,7 @@ class Lima2Stream(BaseStream, LimaDirectAccess):
|
|
|
335
313
|
f"Can't fetch {self._source}: no associated live data"
|
|
336
314
|
) from e
|
|
337
315
|
|
|
338
|
-
return np.asarray(frames)
|
|
316
|
+
return np.asarray(frames).reshape(-1, *self.shape)
|
|
339
317
|
|
|
340
318
|
def _fetch_from_disk(
|
|
341
319
|
self, filepath: str, datapath: str, start: int, stop: int, step: int
|
{blissdata_lima2-2.0.1 → blissdata_lima2-2.0.3}/src/blissdata_lima2/tests/test_lima2_stream.py
RENAMED
|
@@ -27,6 +27,16 @@ from blissdata_lima2 import Lima2Stream, Lima2View
|
|
|
27
27
|
from blissdata_lima2.stream import get_frame
|
|
28
28
|
|
|
29
29
|
|
|
30
|
+
@pytest.fixture
|
|
31
|
+
def mock_handshake(monkeypatch):
|
|
32
|
+
def mock_handshake(self):
|
|
33
|
+
pass
|
|
34
|
+
|
|
35
|
+
monkeypatch.setattr(
|
|
36
|
+
"lima2.client.services.ConductorServices.handshake", mock_handshake
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
|
|
30
40
|
def test_lima2_get_frame():
|
|
31
41
|
services = Mock()
|
|
32
42
|
uuid = str(uuid1())
|
|
@@ -56,45 +66,23 @@ def test_lima2_get_sparse_frame():
|
|
|
56
66
|
|
|
57
67
|
|
|
58
68
|
def test_lima2_view(monkeypatch):
|
|
59
|
-
|
|
60
|
-
uuid = str(uuid1())
|
|
69
|
+
stream = Mock()
|
|
61
70
|
view = Lima2View(
|
|
62
|
-
|
|
63
|
-
acq_uuid=uuid,
|
|
64
|
-
source="cafe",
|
|
71
|
+
stream=stream,
|
|
65
72
|
start=0,
|
|
66
73
|
stop=42,
|
|
67
74
|
)
|
|
68
75
|
assert len(view) == 42
|
|
69
76
|
assert view.index == 0
|
|
70
77
|
|
|
71
|
-
|
|
72
|
-
assert len(frames) == len(view)
|
|
73
|
-
|
|
74
|
-
services.pipeline.get_frame.assert_has_calls(
|
|
75
|
-
[call(uuid=uuid, source="cafe", frame_idx=i) for i in range(42)]
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
# RuntimeError
|
|
79
|
-
def mock_get_frame_runtime_error(services, acq_uuid, source, frame_idx):
|
|
80
|
-
raise RuntimeError("frame has left the buffer")
|
|
78
|
+
_ = view.get_data()
|
|
81
79
|
|
|
82
|
-
|
|
83
|
-
|
|
80
|
+
stream._fetch_online.assert_has_calls(
|
|
81
|
+
[
|
|
82
|
+
call(0, 42, 1),
|
|
83
|
+
]
|
|
84
84
|
)
|
|
85
85
|
|
|
86
|
-
with pytest.raises(IndexNoMoreThereError):
|
|
87
|
-
frames = view.get_data()
|
|
88
|
-
|
|
89
|
-
# ValueError
|
|
90
|
-
def mock_get_frame_value_error(services, acq_uuid, source, frame_idx):
|
|
91
|
-
raise ValueError("no such frame buffer")
|
|
92
|
-
|
|
93
|
-
monkeypatch.setattr("blissdata_lima2.stream.get_frame", mock_get_frame_value_error)
|
|
94
|
-
|
|
95
|
-
with pytest.raises(IndexNoMoreThereError):
|
|
96
|
-
frames = view.get_data()
|
|
97
|
-
|
|
98
86
|
|
|
99
87
|
def test_lima2_protocol(data_store):
|
|
100
88
|
uuid = str(uuid1())
|
|
@@ -120,7 +108,7 @@ def test_lima2_protocol(data_store):
|
|
|
120
108
|
|
|
121
109
|
|
|
122
110
|
@pytest.fixture
|
|
123
|
-
def lima2_stream(data_store):
|
|
111
|
+
def lima2_stream(data_store, mock_handshake):
|
|
124
112
|
uuid = str(uuid1())
|
|
125
113
|
|
|
126
114
|
stream_def = Lima2Stream.make_definition(
|
|
@@ -131,7 +119,7 @@ def lima2_stream(data_store):
|
|
|
131
119
|
acq_uuid=uuid,
|
|
132
120
|
master_file=None,
|
|
133
121
|
dtype=np.float128, # fat pixels >:)
|
|
134
|
-
shape=(
|
|
122
|
+
shape=(),
|
|
135
123
|
)
|
|
136
124
|
model = data_store._stream_model(
|
|
137
125
|
encoding=stream_def.encoder.info(), info=stream_def.info
|
|
@@ -140,162 +128,152 @@ def lima2_stream(data_store):
|
|
|
140
128
|
event_stream = EventStream.create(data_store, stream_def.name, model)
|
|
141
129
|
stream = Lima2Stream(event_stream=event_stream)
|
|
142
130
|
|
|
143
|
-
return
|
|
131
|
+
return stream
|
|
144
132
|
|
|
145
133
|
|
|
146
134
|
def test_lima2_stream_attributes(lima2_stream):
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
assert
|
|
150
|
-
assert
|
|
151
|
-
assert
|
|
152
|
-
assert
|
|
153
|
-
assert stream._need_last_only(last_only=True)
|
|
154
|
-
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)
|
|
155
141
|
|
|
156
142
|
|
|
157
143
|
def test_lima2_stream_indexing(lima2_stream, monkeypatch):
|
|
158
|
-
stream_def, event_stream, stream = lima2_stream
|
|
159
|
-
|
|
160
144
|
# Feed the event stream
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
assert len(
|
|
145
|
+
lima2_stream.send(np.uint32(42))
|
|
146
|
+
lima2_stream.join()
|
|
147
|
+
assert len(lima2_stream) == 42
|
|
164
148
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
assert len(
|
|
149
|
+
lima2_stream.send(np.uint32(123))
|
|
150
|
+
lima2_stream.join()
|
|
151
|
+
assert len(lima2_stream) == 123
|
|
168
152
|
|
|
169
153
|
mock_get_frame = Mock()
|
|
170
154
|
monkeypatch.setattr("blissdata_lima2.stream.get_frame", mock_get_frame)
|
|
171
155
|
|
|
172
156
|
# Indexing
|
|
173
|
-
_ =
|
|
157
|
+
_ = lima2_stream[0]
|
|
174
158
|
mock_get_frame.assert_called_with(
|
|
175
|
-
services=
|
|
176
|
-
acq_uuid=
|
|
159
|
+
services=lima2_stream._services,
|
|
160
|
+
acq_uuid=lima2_stream._acq_uuid,
|
|
177
161
|
source="cafe",
|
|
178
162
|
frame_idx=0,
|
|
179
163
|
)
|
|
180
164
|
|
|
181
165
|
with pytest.raises(IndexNotYetThereError):
|
|
182
|
-
_ =
|
|
166
|
+
_ = lima2_stream[-1]
|
|
183
167
|
|
|
184
168
|
with pytest.raises(IndexNotYetThereError):
|
|
185
|
-
_ =
|
|
169
|
+
_ = lima2_stream[123123] # wayyy out of bounds, but we're not sealed yet
|
|
186
170
|
|
|
187
171
|
with monkeypatch.context() as mpc:
|
|
188
|
-
mpc.setattr(
|
|
172
|
+
mpc.setattr(lima2_stream, "is_sealed", lambda: True)
|
|
189
173
|
|
|
190
174
|
with pytest.raises(IndexWontBeThereError):
|
|
191
|
-
_ =
|
|
175
|
+
_ = lima2_stream[123123] # wayyy out of bounds and we're sealed
|
|
192
176
|
|
|
193
|
-
|
|
194
|
-
event_stream.join()
|
|
177
|
+
lima2_stream.seal()
|
|
195
178
|
|
|
196
|
-
_ =
|
|
179
|
+
_ = lima2_stream[-3]
|
|
197
180
|
assert mock_get_frame.mock_calls[-1] == call(
|
|
198
|
-
services=
|
|
199
|
-
acq_uuid=
|
|
181
|
+
services=lima2_stream._services,
|
|
182
|
+
acq_uuid=lima2_stream._acq_uuid,
|
|
200
183
|
source="cafe",
|
|
201
184
|
frame_idx=123 - 3,
|
|
202
185
|
)
|
|
203
186
|
|
|
204
187
|
|
|
205
188
|
def test_lima2_stream_slicing(lima2_stream, monkeypatch):
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
event_stream.join()
|
|
211
|
-
assert len(stream) == 42
|
|
189
|
+
# Feed the stream
|
|
190
|
+
lima2_stream.send(np.uint32(42))
|
|
191
|
+
lima2_stream.join()
|
|
192
|
+
assert len(lima2_stream) == 42
|
|
212
193
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
assert len(
|
|
194
|
+
lima2_stream.send(np.uint32(123))
|
|
195
|
+
lima2_stream.join()
|
|
196
|
+
assert len(lima2_stream) == 123
|
|
216
197
|
|
|
217
198
|
mock_get_frame = Mock()
|
|
218
199
|
monkeypatch.setattr("blissdata_lima2.stream.get_frame", mock_get_frame)
|
|
219
200
|
|
|
220
201
|
# Slicing
|
|
221
|
-
_ =
|
|
202
|
+
_ = lima2_stream[:3]
|
|
222
203
|
assert mock_get_frame.mock_calls[-3:] == [
|
|
223
204
|
call(
|
|
224
|
-
services=
|
|
225
|
-
acq_uuid=
|
|
205
|
+
services=lima2_stream._services,
|
|
206
|
+
acq_uuid=lima2_stream._acq_uuid,
|
|
226
207
|
source="cafe",
|
|
227
208
|
frame_idx=0,
|
|
228
209
|
),
|
|
229
210
|
call(
|
|
230
|
-
services=
|
|
231
|
-
acq_uuid=
|
|
211
|
+
services=lima2_stream._services,
|
|
212
|
+
acq_uuid=lima2_stream._acq_uuid,
|
|
232
213
|
source="cafe",
|
|
233
214
|
frame_idx=1,
|
|
234
215
|
),
|
|
235
216
|
call(
|
|
236
|
-
services=
|
|
237
|
-
acq_uuid=
|
|
217
|
+
services=lima2_stream._services,
|
|
218
|
+
acq_uuid=lima2_stream._acq_uuid,
|
|
238
219
|
source="cafe",
|
|
239
220
|
frame_idx=2,
|
|
240
221
|
),
|
|
241
222
|
]
|
|
242
223
|
|
|
243
224
|
with pytest.raises(IndexNotYetThereError):
|
|
244
|
-
_ =
|
|
225
|
+
_ = lima2_stream[-2:]
|
|
245
226
|
|
|
246
227
|
with pytest.raises(IndexNotYetThereError):
|
|
247
|
-
_ =
|
|
228
|
+
_ = lima2_stream[:-2]
|
|
248
229
|
|
|
249
230
|
with pytest.raises(TypeError):
|
|
250
|
-
_ =
|
|
231
|
+
_ = lima2_stream["hi :)"]
|
|
251
232
|
|
|
252
|
-
|
|
253
|
-
event_stream.join()
|
|
233
|
+
lima2_stream.seal()
|
|
254
234
|
|
|
255
235
|
# Now slicing/indexing from end is ok
|
|
256
|
-
_ =
|
|
236
|
+
_ = lima2_stream[-2:]
|
|
257
237
|
assert mock_get_frame.mock_calls[-2:] == [
|
|
258
238
|
call(
|
|
259
|
-
services=
|
|
260
|
-
acq_uuid=
|
|
239
|
+
services=lima2_stream._services,
|
|
240
|
+
acq_uuid=lima2_stream._acq_uuid,
|
|
261
241
|
source="cafe",
|
|
262
242
|
frame_idx=123 - 2,
|
|
263
243
|
),
|
|
264
244
|
call(
|
|
265
|
-
services=
|
|
266
|
-
acq_uuid=
|
|
245
|
+
services=lima2_stream._services,
|
|
246
|
+
acq_uuid=lima2_stream._acq_uuid,
|
|
267
247
|
source="cafe",
|
|
268
248
|
frame_idx=123 - 1,
|
|
269
249
|
),
|
|
270
250
|
]
|
|
271
251
|
|
|
272
|
-
_ =
|
|
252
|
+
_ = lima2_stream[:]
|
|
273
253
|
assert mock_get_frame.mock_calls[-123:] == [
|
|
274
254
|
call(
|
|
275
|
-
services=
|
|
276
|
-
acq_uuid=
|
|
255
|
+
services=lima2_stream._services,
|
|
256
|
+
acq_uuid=lima2_stream._acq_uuid,
|
|
277
257
|
source="cafe",
|
|
278
258
|
frame_idx=i,
|
|
279
259
|
)
|
|
280
260
|
for i in range(123)
|
|
281
261
|
]
|
|
282
262
|
|
|
283
|
-
_ =
|
|
263
|
+
_ = lima2_stream.get_last_live_image()
|
|
284
264
|
mock_get_frame.assert_called_with(
|
|
285
|
-
services=
|
|
286
|
-
acq_uuid=
|
|
265
|
+
services=lima2_stream._services,
|
|
266
|
+
acq_uuid=lima2_stream._acq_uuid,
|
|
287
267
|
source="cafe",
|
|
288
268
|
frame_idx=-1,
|
|
289
269
|
)
|
|
290
270
|
|
|
291
271
|
|
|
292
272
|
def test_lima2_stream_build_view(lima2_stream, monkeypatch):
|
|
293
|
-
stream_def, event_stream, stream = lima2_stream
|
|
294
|
-
|
|
295
273
|
mock_get_frame = Mock()
|
|
296
274
|
monkeypatch.setattr("blissdata_lima2.stream.get_frame", mock_get_frame)
|
|
297
275
|
|
|
298
|
-
view =
|
|
276
|
+
view = lima2_stream._build_view_from_events(
|
|
299
277
|
index=0,
|
|
300
278
|
events=EventRange(
|
|
301
279
|
index=0,
|
|
@@ -307,7 +285,7 @@ def test_lima2_stream_build_view(lima2_stream, monkeypatch):
|
|
|
307
285
|
)
|
|
308
286
|
assert view._idx_range == range(0, 42)
|
|
309
287
|
|
|
310
|
-
view =
|
|
288
|
+
view = lima2_stream._build_view_from_events(
|
|
311
289
|
index=0,
|
|
312
290
|
events=EventRange(
|
|
313
291
|
index=0,
|
|
@@ -321,7 +299,7 @@ def test_lima2_stream_build_view(lima2_stream, monkeypatch):
|
|
|
321
299
|
|
|
322
300
|
with pytest.raises(EmptyViewException):
|
|
323
301
|
# index >= data[-1]
|
|
324
|
-
view =
|
|
302
|
+
view = lima2_stream._build_view_from_events(
|
|
325
303
|
index=42,
|
|
326
304
|
events=EventRange(
|
|
327
305
|
index=0,
|
|
@@ -334,23 +312,21 @@ def test_lima2_stream_build_view(lima2_stream, monkeypatch):
|
|
|
334
312
|
|
|
335
313
|
|
|
336
314
|
def test_lima2_stream_fetch_frames(lima2_stream, monkeypatch):
|
|
337
|
-
stream_def, event_stream, stream = lima2_stream
|
|
338
|
-
|
|
339
315
|
mock_get_frame = Mock()
|
|
340
316
|
monkeypatch.setattr("blissdata_lima2.stream.get_frame", mock_get_frame)
|
|
341
317
|
|
|
342
318
|
with monkeypatch.context() as mpc:
|
|
343
319
|
# Stream sealed, has master file
|
|
344
320
|
mock_fetch = Mock()
|
|
345
|
-
mpc.setattr(
|
|
346
|
-
mpc.setattr(
|
|
321
|
+
mpc.setattr(lima2_stream, "_fetch_from_disk", mock_fetch)
|
|
322
|
+
mpc.setattr(lima2_stream, "is_sealed", lambda: True)
|
|
347
323
|
mpc.setattr(
|
|
348
|
-
|
|
324
|
+
lima2_stream,
|
|
349
325
|
"_master_file",
|
|
350
326
|
("/path/to/master.h5", "entry/instrument/detector/dataset"),
|
|
351
327
|
)
|
|
352
328
|
|
|
353
|
-
|
|
329
|
+
lima2_stream._fetch_frames(start=0, stop=42, step=3)
|
|
354
330
|
|
|
355
331
|
mock_fetch.assert_called_once_with(
|
|
356
332
|
filepath="/path/to/master.h5",
|
|
@@ -363,11 +339,11 @@ def test_lima2_stream_fetch_frames(lima2_stream, monkeypatch):
|
|
|
363
339
|
with monkeypatch.context() as mpc:
|
|
364
340
|
# Stream sealed, no master file
|
|
365
341
|
mock_fetch = Mock()
|
|
366
|
-
mpc.setattr(
|
|
367
|
-
mpc.setattr(
|
|
368
|
-
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)
|
|
369
345
|
|
|
370
|
-
|
|
346
|
+
lima2_stream._fetch_frames(start=0, stop=42, step=3)
|
|
371
347
|
|
|
372
348
|
mock_fetch.assert_called_once_with(
|
|
373
349
|
start=0,
|
|
@@ -378,10 +354,10 @@ def test_lima2_stream_fetch_frames(lima2_stream, monkeypatch):
|
|
|
378
354
|
with monkeypatch.context() as mpc:
|
|
379
355
|
# Stream not sealed
|
|
380
356
|
mock_fetch = Mock()
|
|
381
|
-
mpc.setattr(
|
|
382
|
-
mpc.setattr(
|
|
357
|
+
mpc.setattr(lima2_stream, "_fetch_online", mock_fetch)
|
|
358
|
+
mpc.setattr(lima2_stream, "is_sealed", lambda: False)
|
|
383
359
|
|
|
384
|
-
|
|
360
|
+
lima2_stream._fetch_frames(start=0, stop=42, step=3)
|
|
385
361
|
|
|
386
362
|
mock_fetch.assert_called_once_with(
|
|
387
363
|
start=0,
|
|
@@ -391,19 +367,17 @@ def test_lima2_stream_fetch_frames(lima2_stream, monkeypatch):
|
|
|
391
367
|
|
|
392
368
|
|
|
393
369
|
def test_lima2_stream_fetch_online(lima2_stream, monkeypatch):
|
|
394
|
-
stream_def, event_stream, stream = lima2_stream
|
|
395
|
-
|
|
396
370
|
mock_get_frame = Mock()
|
|
397
371
|
monkeypatch.setattr("blissdata_lima2.stream.get_frame", mock_get_frame)
|
|
398
372
|
|
|
399
|
-
|
|
373
|
+
lima2_stream._fetch_online(start=0, stop=42, step=3)
|
|
400
374
|
|
|
401
375
|
mock_get_frame.assert_has_calls(
|
|
402
376
|
[
|
|
403
377
|
call(
|
|
404
|
-
services=
|
|
405
|
-
acq_uuid=
|
|
406
|
-
source=
|
|
378
|
+
services=lima2_stream._services,
|
|
379
|
+
acq_uuid=lima2_stream._acq_uuid,
|
|
380
|
+
source=lima2_stream._source,
|
|
407
381
|
frame_idx=idx,
|
|
408
382
|
)
|
|
409
383
|
for idx in range(0, 42, 3)
|
|
@@ -419,7 +393,7 @@ def test_lima2_stream_fetch_online(lima2_stream, monkeypatch):
|
|
|
419
393
|
)
|
|
420
394
|
|
|
421
395
|
with pytest.raises(IndexNoMoreThereError):
|
|
422
|
-
_ =
|
|
396
|
+
_ = lima2_stream._fetch_online(start=0, stop=1, step=1)
|
|
423
397
|
|
|
424
398
|
# ValueError
|
|
425
399
|
def mock_get_frame_value_error(services, acq_uuid, source, frame_idx):
|
|
@@ -428,16 +402,14 @@ def test_lima2_stream_fetch_online(lima2_stream, monkeypatch):
|
|
|
428
402
|
monkeypatch.setattr("blissdata_lima2.stream.get_frame", mock_get_frame_value_error)
|
|
429
403
|
|
|
430
404
|
with pytest.raises(IndexNoMoreThereError):
|
|
431
|
-
_ =
|
|
405
|
+
_ = lima2_stream._fetch_online(start=0, stop=1, step=1)
|
|
432
406
|
|
|
433
407
|
|
|
434
408
|
def test_lima2_stream_fetch_offline(lima2_stream, monkeypatch):
|
|
435
|
-
stream_def, event_stream, stream = lima2_stream
|
|
436
|
-
|
|
437
409
|
mock_dynamic_hdf5 = MagicMock()
|
|
438
410
|
monkeypatch.setattr("blissdata_lima2.stream.dynamic_hdf5", mock_dynamic_hdf5)
|
|
439
411
|
|
|
440
|
-
|
|
412
|
+
lima2_stream._fetch_from_disk(
|
|
441
413
|
filepath="/path/to/master.h5",
|
|
442
414
|
datapath="entry/instrument/detector/dataset",
|
|
443
415
|
start=0,
|
|
@@ -446,3 +418,55 @@ def test_lima2_stream_fetch_offline(lima2_stream, monkeypatch):
|
|
|
446
418
|
)
|
|
447
419
|
|
|
448
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,8 +11,8 @@ 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.
|
|
15
|
-
Requires-Dist: lima2-client~=4.
|
|
14
|
+
Requires-Dist: blissdata~=2.4
|
|
15
|
+
Requires-Dist: lima2-client~=4.1
|
|
16
16
|
Provides-Extra: dev
|
|
17
17
|
Requires-Dist: black; extra == "dev"
|
|
18
18
|
Requires-Dist: flake8; 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.1"
|
|
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.0"]
|
|
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.1 → blissdata_lima2-2.0.3}/src/blissdata_lima2.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{blissdata_lima2-2.0.1 → blissdata_lima2-2.0.3}/src/blissdata_lima2.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|