ewoksdata 2.1.0__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.
Files changed (34) hide show
  1. ewoksdata/__init__.py +0 -0
  2. ewoksdata/data/__init__.py +0 -0
  3. ewoksdata/data/bliss.py +341 -0
  4. ewoksdata/data/blissdata/__init__.py +31 -0
  5. ewoksdata/data/blissdata/blissdatav0.py +119 -0
  6. ewoksdata/data/blissdata/blissdatav1.py +279 -0
  7. ewoksdata/data/blissdata/blissdatav2.py +342 -0
  8. ewoksdata/data/contextiterator.py +43 -0
  9. ewoksdata/data/hdf5/__init__.py +23 -0
  10. ewoksdata/data/hdf5/config.py +186 -0
  11. ewoksdata/data/hdf5/dataset_writer/__init__.py +4 -0
  12. ewoksdata/data/hdf5/dataset_writer/_base.py +55 -0
  13. ewoksdata/data/hdf5/dataset_writer/_non_sequential.py +139 -0
  14. ewoksdata/data/hdf5/dataset_writer/_non_sequential_stack.py +158 -0
  15. ewoksdata/data/hdf5/dataset_writer/_sequential.py +143 -0
  16. ewoksdata/data/hdf5/dataset_writer/_sequential_stack.py +195 -0
  17. ewoksdata/data/hdf5/types.py +14 -0
  18. ewoksdata/data/nexus.py +187 -0
  19. ewoksdata/data/url.py +30 -0
  20. ewoksdata/data/utils.py +53 -0
  21. ewoksdata/tests/__init__.py +0 -0
  22. ewoksdata/tests/conftest.py +30 -0
  23. ewoksdata/tests/data/__init__.py +1 -0
  24. ewoksdata/tests/data/bliss_scans.py +137 -0
  25. ewoksdata/tests/test_contextiterator.py +61 -0
  26. ewoksdata/tests/test_data_bliss.py +98 -0
  27. ewoksdata/tests/test_data_hdf5.py +14 -0
  28. ewoksdata/tests/test_data_nexus.py +80 -0
  29. ewoksdata/tests/test_dataset_writer.py +275 -0
  30. ewoksdata-2.1.0.dist-info/METADATA +70 -0
  31. ewoksdata-2.1.0.dist-info/RECORD +34 -0
  32. ewoksdata-2.1.0.dist-info/WHEEL +5 -0
  33. ewoksdata-2.1.0.dist-info/licenses/LICENSE.md +20 -0
  34. ewoksdata-2.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,61 @@
1
+ from ..data import contextiterator
2
+
3
+
4
+ def test_context_iterator():
5
+
6
+ exited = False
7
+
8
+ @contextiterator.contextiterator
9
+ def iterator():
10
+ nonlocal exited
11
+ exited = False
12
+ try:
13
+ yield from [1, 2, 3]
14
+ finally:
15
+ exited = True
16
+
17
+ # Use like a normal iterator
18
+ it = iterator()
19
+ assert next(it) == 1
20
+ assert not exited
21
+
22
+ # Use like a context iterator
23
+ with iterator() as it:
24
+ assert next(it) == 1
25
+ assert not exited
26
+ assert exited
27
+
28
+
29
+ def test_context_generator():
30
+
31
+ @contextiterator.contextiterator
32
+ def generator():
33
+ nonlocal exited
34
+ exited = False
35
+ try:
36
+ while True:
37
+ x = yield
38
+ yield x * 2
39
+ finally:
40
+ exited = True
41
+
42
+ # Use like a normal generator
43
+ exited = False
44
+ gen = generator()
45
+ assert next(gen) is None # run up to first yield
46
+ assert not exited
47
+ assert gen.send(10) == 20
48
+ assert next(gen) is None
49
+ assert gen.send(15) == 30
50
+ assert not exited
51
+
52
+ # Use like a context iterator
53
+ exited = False
54
+ with generator() as gen:
55
+ assert next(gen) is None
56
+ assert not exited
57
+ assert gen.send(10) == 20
58
+ assert next(gen) is None
59
+ assert gen.send(15) == 30
60
+ assert not exited
61
+ assert exited
@@ -0,0 +1,98 @@
1
+ import h5py
2
+ import numpy
3
+ import pytest
4
+ from fabio.edfimage import edfimage
5
+
6
+ from ..data import bliss
7
+
8
+
9
+ def test_get_data_edf(tmpdir):
10
+ filename = str(tmpdir / "data.edf")
11
+ img1 = numpy.random.uniform(((10, 12)))
12
+ edf = edfimage(data=img1)
13
+ edf.write(filename)
14
+ img2 = bliss.get_data(filename)
15
+ numpy.testing.assert_array_equal(img1, img2)
16
+
17
+
18
+ def test_get_data_hdf5(tmpdir):
19
+ filename = str(tmpdir / "data.h5")
20
+ img1 = numpy.random.uniform(((10, 12)))
21
+ with h5py.File(filename, "w") as f:
22
+ f["img"] = img1
23
+
24
+ img2 = bliss.get_data(f"{filename}::/img")
25
+ numpy.testing.assert_array_equal(img1, img2)
26
+
27
+ img3 = bliss.get_data(f"{filename}?path=/img")
28
+ numpy.testing.assert_array_equal(img1, img3)
29
+
30
+ filename_non_existing = str(tmpdir / "data_non_existing.h5")
31
+ with pytest.raises(TimeoutError):
32
+ _ = bliss.get_data(f"{filename_non_existing}?path=/img", retry_timeout=0)
33
+
34
+ filename_non_existing = str(tmpdir / "data_non_existing.edf")
35
+ with pytest.raises(TimeoutError):
36
+ _ = bliss.get_data(filename_non_existing, retry_timeout=0)
37
+
38
+
39
+ @pytest.mark.parametrize("lima_names", [(), ("p3",), ("p3", "p4")])
40
+ @pytest.mark.parametrize("counter_names", [(), ("diode1",), ("diode1", "diode2")])
41
+ def test_iter_bliss_data(lima_names, counter_names, bliss_scan):
42
+ nexpected = len(lima_names) + len(counter_names)
43
+ index = None
44
+ filename, npoints, scan_nb = bliss_scan
45
+ with bliss.iter_bliss_data(
46
+ filename, scan_nb, lima_names=lima_names, counter_names=counter_names
47
+ ) as bliss_data_iterator:
48
+ for index, data in bliss_data_iterator:
49
+ assert len(data) == nexpected
50
+ if "diode1" in counter_names:
51
+ assert data["diode1"] == index
52
+ if "diode2" in counter_names:
53
+ assert data["diode2"] == index
54
+ if "p3" in lima_names:
55
+ assert (data["p3"] == index).all()
56
+ if "p4" in lima_names:
57
+ assert (data["p4"] == index).all()
58
+
59
+ if nexpected:
60
+ assert index == npoints - 1
61
+ else:
62
+ assert index is None
63
+
64
+
65
+ @pytest.mark.parametrize(
66
+ "lima_names,counter_names",
67
+ [
68
+ ([""], []),
69
+ ([" "], []),
70
+ ([], [""]),
71
+ ([], [" "]),
72
+ ],
73
+ )
74
+ def test_iter_bliss_data_invalid_names(bliss_scan, lima_names, counter_names):
75
+ filename, _, scan_nb = bliss_scan
76
+ with bliss.iter_bliss_data(
77
+ filename, scan_nb, lima_names=lima_names, counter_names=counter_names
78
+ ) as bliss_data_iterator:
79
+ with pytest.raises(ValueError) as exc_info:
80
+ next(bliss_data_iterator)
81
+ assert "Invalid LIMA name" in str(exc_info.value) or "Invalid Counter name" in str(
82
+ exc_info.value
83
+ )
84
+
85
+
86
+ def test_closure_of_iter_bliss_data(bliss_scan):
87
+ filename, npoints, scan_nb = bliss_scan
88
+
89
+ # This opens filename with `locking=False`
90
+ with bliss.iter_bliss_data(
91
+ filename, scan_nb, counter_names=[], lima_names=("p3",)
92
+ ) as lima_iterator:
93
+ for i in range(npoints):
94
+ next(lima_iterator)
95
+
96
+ # Make sure that the file is closed and can be reopened with a different locking flag
97
+ with h5py.File(filename, "r", locking=True):
98
+ pass
@@ -0,0 +1,14 @@
1
+ from ..data import hdf5
2
+
3
+
4
+ def test_bliss_data(bliss_scan):
5
+ filename, nb_points, scan_nb = bliss_scan
6
+ with hdf5.h5context(filename) as f:
7
+ values = f[f"/{scan_nb}.1/measurement/diode1"][()]
8
+ assert values.tolist() == list(range(nb_points))
9
+ values = f[f"/{scan_nb}.1/measurement/diode2"][()]
10
+ assert values.tolist() == list(range(nb_points))
11
+ values = f[f"/{scan_nb}.1/measurement/p3"][:, 0, 0]
12
+ assert values.tolist() == list(range(nb_points))
13
+ values = f[f"/{scan_nb}.1/measurement/p3"][:, -1, -1]
14
+ assert values.tolist() == list(range(nb_points))
@@ -0,0 +1,80 @@
1
+ import time
2
+
3
+ import pytest
4
+ from silx.io import h5py_utils
5
+ from silx.io.url import DataUrl
6
+
7
+ from ..data import nexus
8
+ from ..data import url
9
+
10
+
11
+ def test_create_nexus_group(tmp_path):
12
+ with nexus.create_nexus_group(str(tmp_path / "file.h5")) as (
13
+ h5item,
14
+ already_existed,
15
+ ):
16
+ assert not already_existed
17
+ assert h5item.name == "/results"
18
+ with nexus.create_nexus_group(str(tmp_path / "file.h5")) as (
19
+ h5item,
20
+ already_existed,
21
+ ):
22
+ assert already_existed
23
+ assert h5item.name == "/results"
24
+
25
+ with nexus.create_nexus_group(
26
+ str(tmp_path / "file.h5::/c"), default_levels=("a", "b")
27
+ ) as (h5item, already_existed):
28
+ assert not already_existed
29
+ assert h5item.name == "/c/b"
30
+ with nexus.create_nexus_group(
31
+ str(tmp_path / "file.h5::/c"), default_levels=("a", "b")
32
+ ) as (h5item, already_existed):
33
+ assert already_existed
34
+ assert h5item.name == "/c/b"
35
+ with nexus.create_nexus_group(str(tmp_path / "file.h5::/c/b")) as (
36
+ h5item,
37
+ already_existed,
38
+ ):
39
+ assert already_existed
40
+ assert h5item.name == "/c/b"
41
+
42
+
43
+ @pytest.mark.parametrize("as_string", [True, False])
44
+ @pytest.mark.parametrize("data_path", ["", "::/1.1/measurement/integrated"])
45
+ def test_create_url(tmp_path, data_path, as_string):
46
+ tmp_url = DataUrl(f"{tmp_path / 'file.h5'}{data_path}")
47
+
48
+ if data_path:
49
+ expected_url = url.as_dataurl(tmp_url.path())
50
+ else:
51
+ expected_url = url.as_dataurl(f"{tmp_url.path()}::/results")
52
+
53
+ if as_string:
54
+ input_url = tmp_url.path()
55
+ else:
56
+ input_url = tmp_url
57
+
58
+ created_url = nexus.create_url(input_url)
59
+ assert created_url == expected_url
60
+
61
+ with h5py_utils.open_item(
62
+ created_url.file_path(), created_url.data_path(), mode="a"
63
+ ) as item:
64
+ # Add unique id to identify the item
65
+ item_id = f"CREATED AT {time.time()}"
66
+ item.attrs["id"] = item_id
67
+
68
+ created_url = nexus.create_url(input_url, overwrite=False)
69
+ with h5py_utils.open_item(
70
+ created_url.file_path(), created_url.data_path()
71
+ ) as new_item:
72
+ # It is the same item
73
+ assert new_item.attrs["id"] == item_id
74
+
75
+ created_url = nexus.create_url(input_url, overwrite=True)
76
+ with h5py_utils.open_item(
77
+ created_url.file_path(), created_url.data_path()
78
+ ) as new_item:
79
+ # It is a different item
80
+ assert "id" not in new_item.attrs
@@ -0,0 +1,275 @@
1
+ import itertools
2
+ import multiprocessing
3
+ import time
4
+
5
+ import h5py
6
+ import numpy
7
+ import pytest
8
+ from silx.io import h5py_utils
9
+
10
+ from ..data.hdf5 import dataset_writer
11
+
12
+
13
+ @pytest.mark.parametrize("npoints", (1, 3, 1000))
14
+ @pytest.mark.parametrize("flush_period", (None, 0.1))
15
+ @pytest.mark.parametrize("known_npoints", (True, False))
16
+ def test_dataset_writer(tmp_path, npoints, flush_period, known_npoints):
17
+ expected = list()
18
+ filename = str(tmp_path / "test.h5")
19
+ if flush_period is None:
20
+ sleep_time = None
21
+ else:
22
+ sleep_time = flush_period + 0.1
23
+ isleep = npoints // 3
24
+
25
+ kwargs = {"flush_period": flush_period}
26
+ if known_npoints:
27
+ kwargs["npoints"] = npoints
28
+
29
+ with h5py.File(filename, mode="w") as f:
30
+ with dataset_writer.DatasetWriter(f, "data", **kwargs) as writer:
31
+ for ipoint in range(npoints):
32
+ data = numpy.random.random((10, 20))
33
+ writer.add_point(data)
34
+ expected.append(data)
35
+ if sleep_time and ipoint == isleep:
36
+ time.sleep(sleep_time)
37
+
38
+ with h5py.File(filename, mode="r") as f:
39
+ data = f["data"][()]
40
+ numpy.testing.assert_allclose(data, expected)
41
+
42
+
43
+ @pytest.mark.parametrize("nstack", (1, 4))
44
+ @pytest.mark.parametrize("npoints", (1, 3, 1000))
45
+ @pytest.mark.parametrize("flush_period", (None, 0.1))
46
+ @pytest.mark.parametrize("known_npoints", (True, False))
47
+ @pytest.mark.parametrize("known_nstack", (True, False))
48
+ @pytest.mark.parametrize("append_stacks_in_parallel", (True, False))
49
+ def test_stack_dataset_writer(
50
+ tmp_path,
51
+ nstack,
52
+ npoints,
53
+ flush_period,
54
+ known_npoints,
55
+ known_nstack,
56
+ append_stacks_in_parallel,
57
+ ):
58
+ expected = [list() for _ in range(nstack)]
59
+ filename = str(tmp_path / "test.h5")
60
+ if flush_period is None:
61
+ sleep_time = None
62
+ else:
63
+ sleep_time = flush_period + 0.1
64
+ isleep = (nstack * npoints) // 3
65
+
66
+ kwargs = {"flush_period": flush_period}
67
+ if known_npoints:
68
+ kwargs["npoints"] = npoints
69
+ if known_nstack:
70
+ kwargs["nstack"] = nstack
71
+
72
+ if append_stacks_in_parallel:
73
+ itpoints = itertools.product(range(npoints), range(nstack))
74
+ else:
75
+ itpoints = itertools.product(range(nstack), range(npoints))
76
+
77
+ with h5py.File(filename, mode="w") as f:
78
+ with dataset_writer.StackDatasetWriter(f, "data", **kwargs) as writer:
79
+ for tpl in itpoints:
80
+ if append_stacks_in_parallel:
81
+ ipoint, istack = tpl
82
+ else:
83
+ istack, ipoint = tpl
84
+ data = numpy.random.random((10, 20))
85
+ writer.add_point(data, istack)
86
+ expected[istack].append(data)
87
+ if sleep_time and (ipoint * nstack + istack) == isleep:
88
+ time.sleep(sleep_time)
89
+
90
+ with h5py.File(filename, mode="r") as f:
91
+ data = f["data"][()]
92
+ numpy.testing.assert_allclose(data, expected)
93
+
94
+
95
+ @pytest.mark.parametrize("npoints", (1, 3, 1000))
96
+ @pytest.mark.parametrize("flush_period", (None, 0.1))
97
+ @pytest.mark.parametrize("known_npoints", (True, False))
98
+ def test_indexed_dataset_writer(tmp_path, npoints, flush_period, known_npoints):
99
+ filename = str(tmp_path / "test.h5")
100
+
101
+ if flush_period is None:
102
+ sleep_time = None
103
+ else:
104
+ sleep_time = flush_period + 0.1
105
+
106
+ isleep = npoints // 3
107
+
108
+ kwargs = {"flush_period": flush_period}
109
+ if known_npoints:
110
+ kwargs["npoints"] = npoints
111
+
112
+ # Generate data and shuffled indices
113
+ indices = numpy.arange(npoints)
114
+ numpy.random.shuffle(indices)
115
+
116
+ expected = [None] * npoints
117
+ data_points = [numpy.random.random((10, 20)) for _ in range(npoints)]
118
+ for idx, data in zip(indices, data_points):
119
+ expected[idx] = data
120
+
121
+ with h5py.File(filename, mode="w") as f:
122
+ with dataset_writer.IndexedDatasetWriter(f, "data", **kwargs) as writer:
123
+ for i, (idx, data) in enumerate(zip(indices, data_points)):
124
+ writer.add_point(data, idx)
125
+ if sleep_time and i == isleep:
126
+ time.sleep(sleep_time)
127
+
128
+ with h5py.File(filename, mode="r") as f:
129
+ data = f["data"][()]
130
+
131
+ numpy.testing.assert_allclose(data, expected)
132
+
133
+
134
+ @pytest.mark.parametrize("nstack", (1, 4))
135
+ @pytest.mark.parametrize("npoints", (1, 3, 100))
136
+ @pytest.mark.parametrize("flush_period", (None, 0.1))
137
+ @pytest.mark.parametrize("known_npoints", (True, False))
138
+ @pytest.mark.parametrize("known_nstack", (True, False))
139
+ def test_indexed_stack_dataset_writer(
140
+ tmp_path,
141
+ nstack,
142
+ npoints,
143
+ flush_period,
144
+ known_npoints,
145
+ known_nstack,
146
+ ):
147
+ filename = str(tmp_path / "test.h5")
148
+
149
+ if flush_period is None:
150
+ sleep_time = None
151
+ else:
152
+ sleep_time = flush_period + 0.1
153
+
154
+ isleep = (nstack * npoints) // 3
155
+
156
+ kwargs = {"flush_period": flush_period}
157
+ if known_npoints:
158
+ kwargs["npoints"] = npoints
159
+ if known_nstack:
160
+ kwargs["nstack"] = nstack
161
+
162
+ # Generate data and shuffled indices
163
+ indices = list(itertools.product(range(nstack), range(npoints)))
164
+ numpy.random.shuffle(indices)
165
+
166
+ expected = [[None for _ in range(npoints)] for _ in range(nstack)]
167
+ values = [numpy.random.random((10, 20)) for _ in indices]
168
+
169
+ for (istack, ipoint), value in zip(indices, values):
170
+ expected[istack][ipoint] = value
171
+
172
+ with h5py.File(filename, mode="w") as f:
173
+ with dataset_writer.IndexedStackDatasetWriter(f, "data", **kwargs) as writer:
174
+ for i, ((istack, ipoint), value) in enumerate(zip(indices, values)):
175
+ writer.add_point(value, istack, ipoint)
176
+ if sleep_time and i == isleep:
177
+ time.sleep(sleep_time)
178
+
179
+ with h5py.File(filename, mode="r") as f:
180
+ data = f["data"][()]
181
+
182
+ numpy.testing.assert_allclose(data, expected)
183
+
184
+
185
+ def test_concurrent_reader(tmp_path):
186
+ npoints = 50
187
+ hdf5_filename = str(tmp_path / "test.h5")
188
+ read_timestamps = str(tmp_path / "read_timestamps.log")
189
+ write_timestamps = str(tmp_path / "write_timestamps.log")
190
+ dataset_name = "data"
191
+
192
+ # Run read loop in a sub-process
193
+ start_event = multiprocessing.Event()
194
+ reader_process = multiprocessing.Process(
195
+ target=_read_hdf5_file,
196
+ args=(hdf5_filename, dataset_name, npoints, read_timestamps, start_event),
197
+ )
198
+ reader_process.start()
199
+
200
+ assert start_event.wait(timeout=10)
201
+
202
+ # Run write loop
203
+ try:
204
+ _write_hdf5_file(hdf5_filename, dataset_name, npoints, write_timestamps)
205
+ except Exception:
206
+ reader_process.terminate()
207
+ raise
208
+
209
+ # Wait for read loop to finish
210
+ try:
211
+ reader_process.join(timeout=10)
212
+ if reader_process.exitcode is None:
213
+ raise TimeoutError("Reader process did not terminate within the timeout.")
214
+ elif reader_process.exitcode != 0:
215
+ raise RuntimeError(
216
+ f"Reader process terminated with exit code {reader_process.exitcode}."
217
+ )
218
+ except Exception:
219
+ reader_process.terminate()
220
+ raise
221
+
222
+ # Check that reading and writing happened concurrently
223
+ with open(read_timestamps, "r") as eventfile:
224
+ read_events = [int(line.strip()) for line in eventfile.readlines()]
225
+ with open(write_timestamps, "r") as eventfile:
226
+ write_events = [int(line.strip()) for line in eventfile.readlines()]
227
+
228
+ assert len(read_events) == npoints
229
+ assert len(write_events) == npoints
230
+
231
+ all_events = sorted(read_events + write_events)
232
+ assert (
233
+ read_events != all_events[: len(read_events)]
234
+ ), "reads and writes are not interleaved"
235
+
236
+
237
+ class _DatasetWriter(dataset_writer.DatasetWriter):
238
+ """Testing concurrent reading and writing always ends up
239
+ being flaky. So we introduce a sleep after flushing
240
+ to give the reader plenty of time to fetch new data.
241
+ """
242
+
243
+ def _flush_hdf5(self) -> None:
244
+ print("flush")
245
+ super()._flush_hdf5()
246
+ time.sleep(0.2)
247
+
248
+
249
+ def _write_hdf5_file(hdf5_filename, dataset_name, npoints, event_filename):
250
+ data = numpy.zeros((500, 500), dtype=numpy.int64)
251
+ with open(event_filename, "a") as eventfile:
252
+ with h5py.File(hdf5_filename, mode="w") as h5file:
253
+ with _DatasetWriter(h5file, dataset_name) as writer:
254
+ for i in range(npoints):
255
+ writer.add_point(data)
256
+ eventfile.write(f"{time.perf_counter_ns()}\n")
257
+ print(f"write {i}")
258
+
259
+
260
+ def _read_hdf5_file(hdf5_filename, dataset_name, npoints, event_filename, start_event):
261
+ i = 0
262
+ with open(event_filename, "a") as eventfile:
263
+ start_event.set()
264
+ while i < npoints:
265
+ for _ in _iter_data(hdf5_filename, dataset_name):
266
+ eventfile.write(f"{time.perf_counter_ns()}\n")
267
+ print(f"read {i}")
268
+ i += 1
269
+
270
+
271
+ @h5py_utils.retry()
272
+ def _iter_data(hdf5_filename, dataset_name, start_index=0):
273
+ with h5py_utils.File(hdf5_filename) as h5file:
274
+ for _ in h5file[dataset_name][start_index:], start_index:
275
+ yield None
@@ -0,0 +1,70 @@
1
+ Metadata-Version: 2.4
2
+ Name: ewoksdata
3
+ Version: 2.1.0
4
+ Summary: Ewoks tasks for data access
5
+ Author-email: ESRF <dau-pydev@esrf.fr>
6
+ License: # MIT License
7
+
8
+ **Copyright (c) 2021 European Synchrotron Radiation Facility**
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
11
+ this software and associated documentation files (the "Software"), to deal in
12
+ the Software without restriction, including without limitation the rights to
13
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
14
+ the Software, and to permit persons to whom the Software is furnished to do so,
15
+ subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
22
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
23
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
24
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
+
27
+ Project-URL: Homepage, https://gitlab.esrf.fr/workflow/ewoksapps/ewoksdata/
28
+ Project-URL: Documentation, https://ewoksdata.readthedocs.io
29
+ Project-URL: Repository, https://gitlab.esrf.fr/workflow/ewoksapps/ewoksdata/
30
+ Project-URL: Issues, https://gitlab.esrf.fr/workflow/ewoksapps/ewoksdata/issues
31
+ Project-URL: Changelog, https://gitlab.esrf.fr/workflow/ewoksapps/ewoksdata/-/blob/main/CHANGELOG.md
32
+ Classifier: Intended Audience :: Science/Research
33
+ Classifier: License :: OSI Approved :: MIT License
34
+ Classifier: Programming Language :: Python :: 3
35
+ Requires-Python: >=3.8
36
+ Description-Content-Type: text/markdown
37
+ License-File: LICENSE.md
38
+ Requires-Dist: packaging
39
+ Requires-Dist: h5py>=2.8
40
+ Requires-Dist: silx>=1.1.0
41
+ Requires-Dist: hdf5plugin
42
+ Requires-Dist: blissdata>=0.3.4
43
+ Requires-Dist: redis
44
+ Requires-Dist: redis!=5.3.0b1,!=5.3.0b3
45
+ Requires-Dist: redis-om!=1.0.0b0; python_version < "3.9"
46
+ Requires-Dist: redis-om!=1.0.3b0; python_version < "3.9"
47
+ Provides-Extra: online
48
+ Requires-Dist: blissdata[tango]; extra == "online"
49
+ Provides-Extra: test
50
+ Requires-Dist: ewoksdata[online]; extra == "test"
51
+ Requires-Dist: pytest>=7; extra == "test"
52
+ Provides-Extra: dev
53
+ Requires-Dist: ewoksdata[test]; extra == "dev"
54
+ Requires-Dist: black>=25; extra == "dev"
55
+ Requires-Dist: flake8>=4; extra == "dev"
56
+ Requires-Dist: isort; extra == "dev"
57
+ Provides-Extra: doc
58
+ Requires-Dist: ewoksdata[test]; extra == "doc"
59
+ Requires-Dist: sphinx>=4.5; extra == "doc"
60
+ Requires-Dist: sphinx-autodoc-typehints>=1.16; extra == "doc"
61
+ Requires-Dist: pydata-sphinx-theme<0.15; extra == "doc"
62
+ Dynamic: license-file
63
+
64
+ # ewoksdata
65
+
66
+ Data access utilities for [ewoks](https://ewoks.readthedocs.io/) workflows.
67
+
68
+ ## Documentation
69
+
70
+ https://ewoksdata.readthedocs.io
@@ -0,0 +1,34 @@
1
+ ewoksdata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ ewoksdata/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ ewoksdata/data/bliss.py,sha256=yJ2ic00tilevtMpwObconChQoizv47Cr4RlzIP6XwNc,12791
4
+ ewoksdata/data/contextiterator.py,sha256=LSle5CwfHfemfu_7eOY8wHv_kDqARTXaPvkKTJ35xm8,1078
5
+ ewoksdata/data/nexus.py,sha256=V1AC6H-tXwuXoZUl4QQTuoKmEDOIoDJ5T6R5f-1DlZ0,6358
6
+ ewoksdata/data/url.py,sha256=3Fd_8tTXfM2B44EfDKzyo0QL4KSh6QIVfBwj_bPcyPY,762
7
+ ewoksdata/data/utils.py,sha256=zt6Y93xNKqoeWnPPlwg86yGz-s2vEFy1EBkTXrlRHjU,1410
8
+ ewoksdata/data/blissdata/__init__.py,sha256=jbuhm0oFxkf87mlaENmWOlv-ExFuqWSH8IdnYsmc9A8,1162
9
+ ewoksdata/data/blissdata/blissdatav0.py,sha256=v8DPi2bqGtZkT93sLkrxOUyx93dFzT9O3PfMP2MhGRk,4164
10
+ ewoksdata/data/blissdata/blissdatav1.py,sha256=_LfAaLcsbPdOjhE-53kUt7HXdnCf5WRSEBgVc4P388Q,10611
11
+ ewoksdata/data/blissdata/blissdatav2.py,sha256=MBnqao7_auKrYIILB2nvBGaIir843_86vVPoq2N-zD4,12188
12
+ ewoksdata/data/hdf5/__init__.py,sha256=LggGhbjxpR5XF6nDB-eAHPZ-YCWWeuotLEQvTrWEexs,622
13
+ ewoksdata/data/hdf5/config.py,sha256=TwaZXgAoV3vJZTYSr3Oj_AtS3lePUUBj_vdE1FxU81M,6121
14
+ ewoksdata/data/hdf5/types.py,sha256=LKNRsGcBYt6FLRt2oGsUQQsiDaIvZv-X6OSnl0q_BNI,510
15
+ ewoksdata/data/hdf5/dataset_writer/__init__.py,sha256=D-IWijYU3osAPtOvcYmx8VNyHIxMfFHHfEyP3Ps7sFE,252
16
+ ewoksdata/data/hdf5/dataset_writer/_base.py,sha256=DrdC66xK_Px5mT6SRWBbdepwfLSSI4CrugV_-ng48Zw,1470
17
+ ewoksdata/data/hdf5/dataset_writer/_non_sequential.py,sha256=NMzsp7dbeQU6JWEHcelc3Oa5cZgP_qkoqQeYkyNgg34,4188
18
+ ewoksdata/data/hdf5/dataset_writer/_non_sequential_stack.py,sha256=CjhpyDD3jeN5x_oKpR7a7CWTHSPk5Ms6XgEBI1qdMbk,5164
19
+ ewoksdata/data/hdf5/dataset_writer/_sequential.py,sha256=qyzPhG3sGm0rEBrg4jJbm1SOhBeW7hm7kq6oW_vPUcE,4440
20
+ ewoksdata/data/hdf5/dataset_writer/_sequential_stack.py,sha256=ymwU09yNUWQP5YCMuQ8eQPMugPYAUoco2p2W3NuwsiM,7508
21
+ ewoksdata/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ ewoksdata/tests/conftest.py,sha256=DNN1bt0VIavqQBfCneKh3WXtK2ytLb5rjjQBVz8XnVQ,666
23
+ ewoksdata/tests/test_contextiterator.py,sha256=a-Elm4SLdvjxaNdTb4WyKCmb33idteQJ6aMbg0X81Cw,1338
24
+ ewoksdata/tests/test_data_bliss.py,sha256=6E3YdjopOF7-Ulns5VzSzlsqiLhqtj8BuwUiXl5AgUw,3202
25
+ ewoksdata/tests/test_data_hdf5.py,sha256=eAvCRvzUWw77q5NGyiDv_rKOEkJXAErDOQtJDlNcPjI,613
26
+ ewoksdata/tests/test_data_nexus.py,sha256=3jON9hBqZ8tJE4jlstmh3ia6GPRMTY3bipM3xnTgrXI,2465
27
+ ewoksdata/tests/test_dataset_writer.py,sha256=YIYDv_84fq7Wc7RBjMrlnHIKiJK_Q1danrh3YTcnpWE,9064
28
+ ewoksdata/tests/data/__init__.py,sha256=Zux5qxSbtT37x4yjtSbU0QZzAKG2t5QPTfAr00R0y-A,40
29
+ ewoksdata/tests/data/bliss_scans.py,sha256=-OcVto9C0cOdHIHQ5YVHBJp7EZG5YC7b12pVzj5cvLQ,4712
30
+ ewoksdata-2.1.0.dist-info/licenses/LICENSE.md,sha256=NJLjvGCcDcGPof6QvVOo_T8F-eu_iF6PBf5m3PlzAbI,1102
31
+ ewoksdata-2.1.0.dist-info/METADATA,sha256=VOrh0mNs0-QEcKMhvmSYAE2fMRz8VqZqBuCnTbsu6dE,3109
32
+ ewoksdata-2.1.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
33
+ ewoksdata-2.1.0.dist-info/top_level.txt,sha256=g3W5d3Rdd2kTJ7HJLmXEPJg1OB-Ad7FpNi_rqg_C4J4,10
34
+ ewoksdata-2.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.10.2)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,20 @@
1
+ # MIT License
2
+
3
+ **Copyright (c) 2021 European Synchrotron Radiation Facility**
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1 @@
1
+ ewoksdata