legend-pydataobj 1.10.2__tar.gz → 1.11.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.
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/PKG-INFO +1 -1
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/legend_pydataobj.egg-info/PKG-INFO +1 -1
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/_version.py +2 -2
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/cli.py +30 -2
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/_serializers/read/composite.py +12 -28
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/_serializers/read/utils.py +64 -14
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/_serializers/read/vector_of_vectors.py +1 -1
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/utils.py +8 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/test_cli.py +18 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/test_lgdo_utils.py +5 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/LICENSE +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/README.md +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/pyproject.toml +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/setup.cfg +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/legend_pydataobj.egg-info/SOURCES.txt +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/legend_pydataobj.egg-info/dependency_links.txt +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/legend_pydataobj.egg-info/entry_points.txt +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/legend_pydataobj.egg-info/not-zip-safe +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/legend_pydataobj.egg-info/requires.txt +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/legend_pydataobj.egg-info/top_level.txt +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/__init__.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/compression/__init__.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/compression/base.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/compression/generic.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/compression/radware.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/compression/utils.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/compression/varlen.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lgdo_utils.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/__init__.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/_serializers/__init__.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/_serializers/read/__init__.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/_serializers/read/array.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/_serializers/read/encoded.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/_serializers/read/ndarray.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/_serializers/read/scalar.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/_serializers/write/__init__.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/_serializers/write/array.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/_serializers/write/composite.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/_serializers/write/scalar.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/_serializers/write/vector_of_vectors.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/core.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/datatype.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/exceptions.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/iterator.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/store.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/tools.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/utils.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5_store.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/logging.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/types/__init__.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/types/array.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/types/arrayofequalsizedarrays.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/types/encoded.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/types/fixedsizearray.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/types/histogram.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/types/lgdo.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/types/scalar.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/types/struct.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/types/table.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/types/vectorofvectors.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/types/vovutils.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/types/waveformtable.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/units.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/compression/conftest.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/compression/sigcompress/LDQTA_r117_20200110T105115Z_cal_geds_raw-0.dat +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/compression/sigcompress/special-wf-clipped.dat +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/compression/test_compression.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/compression/test_radware_sigcompress.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/compression/test_str2wfcodec.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/compression/test_uleb128_zigzag_diff.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/conftest.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/lh5/conftest.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/lh5/test_core.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/lh5/test_lh5_datatype.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/lh5/test_lh5_iterator.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/lh5/test_lh5_store.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/lh5/test_lh5_tools.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/lh5/test_lh5_utils.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/lh5/test_lh5_write.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/types/test_array.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/types/test_arrayofequalsizedarrays.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/types/test_encoded.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/types/test_fixedsizearray.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/types/test_histogram.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/types/test_representations.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/types/test_scalar.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/types/test_struct.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/types/test_table.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/types/test_table_eval.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/types/test_vectorofvectors.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/types/test_vovutils.py +0 -0
- {legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/types/test_waveformtable.py +0 -0
@@ -7,7 +7,7 @@ import fnmatch
|
|
7
7
|
import logging
|
8
8
|
import sys
|
9
9
|
|
10
|
-
from . import Array, Table, VectorOfVectors, __version__, lh5
|
10
|
+
from . import Array, Scalar, Struct, Table, VectorOfVectors, __version__, lh5
|
11
11
|
from . import logging as lgdogging # eheheh
|
12
12
|
|
13
13
|
log = logging.getLogger(__name__)
|
@@ -212,6 +212,7 @@ Exclude the /data/table1/col1 Table column:
|
|
212
212
|
store = lh5.LH5Store()
|
213
213
|
h5f0 = store.gimme_file(file0)
|
214
214
|
lgdos = {}
|
215
|
+
lgdo_structs = {}
|
215
216
|
# loop over object list in the first file
|
216
217
|
for name in obj_list:
|
217
218
|
# now loop over groups starting from root
|
@@ -222,7 +223,7 @@ Exclude the /data/table1/col1 Table column:
|
|
222
223
|
if current in lgdos:
|
223
224
|
break
|
224
225
|
|
225
|
-
# not even an LGDO!
|
226
|
+
# not even an LGDO (i.e. a plain HDF5 group)!
|
226
227
|
if "datatype" not in h5f0[current].attrs:
|
227
228
|
continue
|
228
229
|
|
@@ -232,14 +233,30 @@ Exclude the /data/table1/col1 Table column:
|
|
232
233
|
# read all!
|
233
234
|
obj, _ = store.read(current, h5f0)
|
234
235
|
lgdos[current] = obj
|
236
|
+
elif isinstance(obj, Struct):
|
237
|
+
# structs might be used in a "group-like" fashion (i.e. they might only
|
238
|
+
# contain array-like objects).
|
239
|
+
# note: handle after handling tables, as tables also satisfy this check.
|
240
|
+
lgdo_structs[current] = obj.attrs["datatype"]
|
241
|
+
continue
|
242
|
+
elif isinstance(obj, Scalar):
|
243
|
+
msg = f"cannot concat scalar field {current}"
|
244
|
+
log.warning(msg)
|
235
245
|
|
236
246
|
break
|
237
247
|
|
238
248
|
msg = f"first-level, array-like objects: {lgdos.keys()}"
|
239
249
|
log.debug(msg)
|
250
|
+
msg = f"nested structs: {lgdo_structs.keys()}"
|
251
|
+
log.debug(msg)
|
240
252
|
|
241
253
|
h5f0.close()
|
242
254
|
|
255
|
+
if lgdos == {}:
|
256
|
+
msg = "did not find any field to concatenate, exit"
|
257
|
+
log.error(msg)
|
258
|
+
return
|
259
|
+
|
243
260
|
# 2. remove (nested) table fields based on obj_list
|
244
261
|
|
245
262
|
def _inplace_table_filter(name, table, obj_list):
|
@@ -298,3 +315,14 @@ Exclude the /data/table1/col1 Table column:
|
|
298
315
|
_inplace_table_filter(name, obj, obj_list)
|
299
316
|
|
300
317
|
store.write(obj, name, args.output, wo_mode="append")
|
318
|
+
|
319
|
+
# 5. reset datatypes of the "group-like" structs
|
320
|
+
|
321
|
+
if lgdo_structs != {}:
|
322
|
+
output_file = store.gimme_file(args.output, mode="a")
|
323
|
+
for struct, struct_dtype in lgdo_structs.items():
|
324
|
+
msg = f"reset datatype of struct {struct} to {struct_dtype}"
|
325
|
+
log.debug(msg)
|
326
|
+
|
327
|
+
output_file[struct].attrs["datatype"] = struct_dtype
|
328
|
+
output_file.close()
|
{legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/_serializers/read/composite.py
RENAMED
@@ -3,7 +3,6 @@ from __future__ import annotations
|
|
3
3
|
import bisect
|
4
4
|
import logging
|
5
5
|
import sys
|
6
|
-
from collections import defaultdict
|
7
6
|
|
8
7
|
import h5py
|
9
8
|
import numpy as np
|
@@ -72,19 +71,8 @@ def _h5_read_lgdo(
|
|
72
71
|
obj_buf=obj_buf,
|
73
72
|
)
|
74
73
|
|
75
|
-
#
|
76
|
-
|
77
|
-
field_mask = defaultdict(lambda: True)
|
78
|
-
elif isinstance(field_mask, dict):
|
79
|
-
default = True
|
80
|
-
if len(field_mask) > 0:
|
81
|
-
default = not field_mask[next(iter(field_mask.keys()))]
|
82
|
-
field_mask = defaultdict(lambda: default, field_mask)
|
83
|
-
elif isinstance(field_mask, (list, tuple, set)):
|
84
|
-
field_mask = defaultdict(bool, {field: True for field in field_mask})
|
85
|
-
elif not isinstance(field_mask, defaultdict):
|
86
|
-
msg = "bad field_mask type"
|
87
|
-
raise ValueError(msg, type(field_mask).__name__)
|
74
|
+
# Convert whatever we input into a defaultdict
|
75
|
+
field_mask = utils.build_field_mask(field_mask)
|
88
76
|
|
89
77
|
if lgdotype is Struct:
|
90
78
|
return _h5_read_struct(
|
@@ -246,18 +234,16 @@ def _h5_read_struct(
|
|
246
234
|
|
247
235
|
# determine fields to be read out
|
248
236
|
all_fields = dtypeutils.get_struct_fields(attrs["datatype"])
|
249
|
-
selected_fields = (
|
250
|
-
[field for field in all_fields if field_mask[field]]
|
251
|
-
if field_mask is not None
|
252
|
-
else all_fields
|
253
|
-
)
|
237
|
+
selected_fields = utils.eval_field_mask(field_mask, all_fields)
|
254
238
|
|
255
239
|
# modify datatype in attrs if a field_mask was used
|
256
|
-
attrs["datatype"] =
|
240
|
+
attrs["datatype"] = (
|
241
|
+
"struct{" + ",".join(field for field, _ in selected_fields) + "}"
|
242
|
+
)
|
257
243
|
|
258
244
|
# loop over fields and read
|
259
245
|
obj_dict = {}
|
260
|
-
for field in selected_fields:
|
246
|
+
for field, submask in selected_fields:
|
261
247
|
# support for integer keys
|
262
248
|
field_key = int(field) if attrs.get("int_keys") else str(field)
|
263
249
|
h5o = h5py.h5o.open(h5g, field.encode("utf-8"))
|
@@ -269,6 +255,7 @@ def _h5_read_struct(
|
|
269
255
|
n_rows=n_rows,
|
270
256
|
idx=idx,
|
271
257
|
use_h5idx=use_h5idx,
|
258
|
+
field_mask=submask,
|
272
259
|
decompress=decompress,
|
273
260
|
)
|
274
261
|
h5o.close()
|
@@ -297,19 +284,15 @@ def _h5_read_table(
|
|
297
284
|
|
298
285
|
# determine fields to be read out
|
299
286
|
all_fields = dtypeutils.get_struct_fields(attrs["datatype"])
|
300
|
-
selected_fields = (
|
301
|
-
[field for field in all_fields if field_mask[field]]
|
302
|
-
if field_mask is not None
|
303
|
-
else all_fields
|
304
|
-
)
|
287
|
+
selected_fields = utils.eval_field_mask(field_mask, all_fields)
|
305
288
|
|
306
289
|
# modify datatype in attrs if a field_mask was used
|
307
|
-
attrs["datatype"] = "table{" + ",".join(selected_fields) + "}"
|
290
|
+
attrs["datatype"] = "table{" + ",".join(field for field, _ in selected_fields) + "}"
|
308
291
|
|
309
292
|
# read out each of the fields
|
310
293
|
col_dict = {}
|
311
294
|
rows_read = []
|
312
|
-
for field in selected_fields:
|
295
|
+
for field, submask in selected_fields:
|
313
296
|
fld_buf = None
|
314
297
|
if obj_buf is not None:
|
315
298
|
if not isinstance(obj_buf, Table) or field not in obj_buf:
|
@@ -329,6 +312,7 @@ def _h5_read_table(
|
|
329
312
|
use_h5idx=use_h5idx,
|
330
313
|
obj_buf=fld_buf,
|
331
314
|
obj_buf_start=obj_buf_start,
|
315
|
+
field_mask=submask,
|
332
316
|
decompress=decompress,
|
333
317
|
)
|
334
318
|
h5o.close()
|
@@ -1,6 +1,8 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import logging
|
4
|
+
from collections import defaultdict
|
5
|
+
from collections.abc import Collection, Mapping
|
4
6
|
|
5
7
|
import h5py
|
6
8
|
import numpy as np
|
@@ -22,6 +24,56 @@ def check_obj_buf_attrs(attrs, new_attrs, fname, oname):
|
|
22
24
|
raise LH5DecodeError(msg, fname, oname)
|
23
25
|
|
24
26
|
|
27
|
+
def build_field_mask(field_mask: Mapping[str, bool] | Collection[str]) -> defaultdict:
|
28
|
+
# check field_mask and make it a default dict
|
29
|
+
if field_mask is None:
|
30
|
+
return defaultdict(lambda: True)
|
31
|
+
if isinstance(field_mask, dict):
|
32
|
+
default = True
|
33
|
+
if len(field_mask) > 0:
|
34
|
+
default = not field_mask[next(iter(field_mask.keys()))]
|
35
|
+
return defaultdict(lambda: default, field_mask)
|
36
|
+
if isinstance(field_mask, (list, tuple, set)):
|
37
|
+
return defaultdict(bool, {field: True for field in field_mask})
|
38
|
+
if isinstance(field_mask, defaultdict):
|
39
|
+
return field_mask
|
40
|
+
msg = "bad field_mask type"
|
41
|
+
raise ValueError(msg, type(field_mask).__name__)
|
42
|
+
|
43
|
+
|
44
|
+
def eval_field_mask(
|
45
|
+
field_mask: defaultdict, all_fields: list[str]
|
46
|
+
) -> list[tuple(str, defaultdict)]:
|
47
|
+
"""Get list of fields that need to be loaded along with a sub-field-mask
|
48
|
+
in case we have a nested Table"""
|
49
|
+
|
50
|
+
if field_mask is None:
|
51
|
+
return all_fields
|
52
|
+
|
53
|
+
this_field_mask = defaultdict(field_mask.default_factory)
|
54
|
+
sub_field_masks = {}
|
55
|
+
|
56
|
+
for key, val in field_mask.items():
|
57
|
+
field = key.strip("/")
|
58
|
+
pos = field.find("/")
|
59
|
+
if pos < 0:
|
60
|
+
this_field_mask[field] = val
|
61
|
+
else:
|
62
|
+
sub_field = field[pos + 1 :]
|
63
|
+
field = field[:pos]
|
64
|
+
this_field_mask[field] = True
|
65
|
+
sub_mask = sub_field_masks.setdefault(
|
66
|
+
field, defaultdict(field_mask.default_factory)
|
67
|
+
)
|
68
|
+
sub_mask[sub_field] = val
|
69
|
+
|
70
|
+
return [
|
71
|
+
(field, sub_field_masks.get(field))
|
72
|
+
for field in all_fields
|
73
|
+
if this_field_mask[field]
|
74
|
+
]
|
75
|
+
|
76
|
+
|
25
77
|
def read_attrs(h5o, fname, oname):
|
26
78
|
"""Read all attributes for an hdf5 dataset or group using low level API
|
27
79
|
and return them as a dict. Assume all are strings or scalar types."""
|
@@ -114,6 +166,7 @@ def read_size_in_bytes(h5o, fname, oname, field_mask=None):
|
|
114
166
|
h5a.read(type_attr)
|
115
167
|
type_attr = type_attr.item().decode()
|
116
168
|
lgdotype = datatype.datatype(type_attr)
|
169
|
+
field_mask = build_field_mask(field_mask)
|
117
170
|
|
118
171
|
# scalars are dim-0 datasets
|
119
172
|
if lgdotype in (
|
@@ -124,24 +177,21 @@ def read_size_in_bytes(h5o, fname, oname, field_mask=None):
|
|
124
177
|
):
|
125
178
|
return int(np.prod(h5o.shape) * h5o.dtype.itemsize)
|
126
179
|
|
127
|
-
# structs don't have rows
|
128
|
-
if lgdotype in (types.Struct, types.Histogram, types.Histogram.Axis):
|
129
|
-
size = 0
|
130
|
-
for key in h5o:
|
131
|
-
obj = h5py.h5o.open(h5o, key)
|
132
|
-
size += read_size_in_bytes(obj, fname, oname, field_mask)
|
133
|
-
obj.close()
|
134
|
-
return size
|
135
|
-
|
136
180
|
# tables should have elements with all the same length
|
137
|
-
if lgdotype in (
|
181
|
+
if lgdotype in (
|
182
|
+
types.Struct,
|
183
|
+
types.Histogram,
|
184
|
+
types.Histogram.Axis,
|
185
|
+
types.Table,
|
186
|
+
types.WaveformTable,
|
187
|
+
):
|
138
188
|
# read out each of the fields
|
139
189
|
size = 0
|
140
|
-
|
141
|
-
|
142
|
-
for field in
|
190
|
+
all_fields = datatype.get_struct_fields(type_attr)
|
191
|
+
selected_fields = eval_field_mask(field_mask, all_fields)
|
192
|
+
for field, submask in selected_fields:
|
143
193
|
obj = h5py.h5o.open(h5o, field.encode())
|
144
|
-
size += read_size_in_bytes(obj, fname, field)
|
194
|
+
size += read_size_in_bytes(obj, fname, field, submask)
|
145
195
|
obj.close()
|
146
196
|
return size
|
147
197
|
|
@@ -156,7 +156,7 @@ def _h5_read_vector_of_vectors(
|
|
156
156
|
# grow fd_buf if necessary to hold the data
|
157
157
|
fdb_size = fd_buf_start + fd_n_rows
|
158
158
|
if len(fd_buf) < fdb_size:
|
159
|
-
fd_buf.
|
159
|
+
fd_buf.resize(fdb_size)
|
160
160
|
|
161
161
|
# now read
|
162
162
|
h5o = h5py.h5o.open(h5g, b"flattened_data")
|
@@ -49,6 +49,14 @@ def get_element_type(obj: object) -> str:
|
|
49
49
|
return "complex"
|
50
50
|
if kind in ["S", "U"]:
|
51
51
|
return "string"
|
52
|
+
if (
|
53
|
+
kind == "O"
|
54
|
+
and dt.metadata is not None
|
55
|
+
and dt.metadata.get("vlen", None) in (str, bytes)
|
56
|
+
):
|
57
|
+
# variable length strings in HDF5 are read as numpy object arrays in h5py.
|
58
|
+
# see also h5py.check_vlen_dtype.
|
59
|
+
return "string"
|
52
60
|
|
53
61
|
# couldn't figure it out
|
54
62
|
msg = "cannot determine lgdo element_type for object of type"
|
@@ -149,3 +149,21 @@ def test_lh5concat(lgnd_test_data, tmptestdir):
|
|
149
149
|
assert tbl.packet_id[i] == tbl2.packet_id[i - 10]
|
150
150
|
assert np.array_equal(tbl.tracelist[i], tbl2.tracelist[i - 10])
|
151
151
|
assert np.array_equal(tbl.waveform.values[i], tbl2.waveform.values[i - 10])
|
152
|
+
|
153
|
+
# test concatenating arrays in structs.
|
154
|
+
infile1 = f"{tmptestdir}/concat_test_struct_0.lh5"
|
155
|
+
tb1 = types.Table(col_dict={"col": types.Array(np.zeros(4))})
|
156
|
+
struct1 = types.Struct({"x": tb1})
|
157
|
+
store.write(struct1, "stp", infile1, wo_mode="overwrite_file")
|
158
|
+
|
159
|
+
infile2 = f"{tmptestdir}/concat_test_struct_1.lh5"
|
160
|
+
tb2 = types.Table(col_dict={"col": types.Array(np.ones(7))})
|
161
|
+
struct2 = types.Struct({"x": tb2})
|
162
|
+
store.write(struct2, "stp", infile2, wo_mode="overwrite_file")
|
163
|
+
|
164
|
+
outfile = f"{tmptestdir}/concat_test_struct_out.lh5"
|
165
|
+
cli.lh5concat(["--output", outfile, "--", infile1, infile2])
|
166
|
+
|
167
|
+
out_stp = store.read("stp", outfile)[0]
|
168
|
+
assert out_stp.attrs["datatype"] == "struct{x}"
|
169
|
+
assert np.all(out_stp.x["col"].nda == np.array([0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1]))
|
@@ -1,11 +1,15 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
+
import h5py
|
3
4
|
import numpy as np
|
4
5
|
|
5
6
|
from lgdo import utils
|
6
7
|
|
7
8
|
|
8
9
|
def test_get_element_type():
|
10
|
+
# variable length HD5 string datatype.
|
11
|
+
h5py_str_dtype = h5py.string_dtype(encoding="ascii", length=None)
|
12
|
+
|
9
13
|
objs = [
|
10
14
|
("hi", "string"),
|
11
15
|
(True, "bool"),
|
@@ -16,6 +20,7 @@ def test_get_element_type():
|
|
16
20
|
(1 + 1j, "complex"),
|
17
21
|
(b"hi", "string"),
|
18
22
|
(np.array(["hi"]), "string"),
|
23
|
+
(np.array([b"hi"], h5py_str_dtype), "string"),
|
19
24
|
]
|
20
25
|
|
21
26
|
for obj, name in objs:
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/legend_pydataobj.egg-info/SOURCES.txt
RENAMED
File without changes
|
File without changes
|
{legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/legend_pydataobj.egg-info/entry_points.txt
RENAMED
File without changes
|
{legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/legend_pydataobj.egg-info/not-zip-safe
RENAMED
File without changes
|
{legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/legend_pydataobj.egg-info/requires.txt
RENAMED
File without changes
|
{legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/legend_pydataobj.egg-info/top_level.txt
RENAMED
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
|
{legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/_serializers/read/__init__.py
RENAMED
File without changes
|
File without changes
|
{legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/_serializers/read/encoded.py
RENAMED
File without changes
|
{legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/_serializers/read/ndarray.py
RENAMED
File without changes
|
{legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/_serializers/read/scalar.py
RENAMED
File without changes
|
{legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/_serializers/write/__init__.py
RENAMED
File without changes
|
{legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/_serializers/write/array.py
RENAMED
File without changes
|
{legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/_serializers/write/composite.py
RENAMED
File without changes
|
{legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/lh5/_serializers/write/scalar.py
RENAMED
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
|
{legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/src/lgdo/types/arrayofequalsizedarrays.py
RENAMED
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
|
{legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/compression/test_radware_sigcompress.py
RENAMED
File without changes
|
File without changes
|
{legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/compression/test_uleb128_zigzag_diff.py
RENAMED
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
|
{legend_pydataobj-1.10.2 → legend_pydataobj-1.11.1}/tests/types/test_arrayofequalsizedarrays.py
RENAMED
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
|