legend-pydataobj 1.10.1__py3-none-any.whl → 1.11.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.
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: legend_pydataobj
3
- Version: 1.10.1
3
+ Version: 1.11.0
4
4
  Summary: LEGEND Python Data Objects
5
5
  Author: The LEGEND Collaboration
6
6
  Maintainer: The LEGEND Collaboration
7
- License: GNU GENERAL PUBLIC LICENSE
7
+ License: GNU GENERAL PUBLIC LICENSE
8
8
  Version 3, 29 June 2007
9
9
 
10
10
  Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
@@ -697,34 +697,34 @@ Classifier: Topic :: Scientific/Engineering
697
697
  Requires-Python: >=3.9
698
698
  Description-Content-Type: text/markdown
699
699
  License-File: LICENSE
700
- Requires-Dist: awkward >=2
700
+ Requires-Dist: awkward>=2
701
701
  Requires-Dist: awkward-pandas
702
702
  Requires-Dist: colorlog
703
- Requires-Dist: h5py >=3.10
703
+ Requires-Dist: h5py>=3.10
704
704
  Requires-Dist: hdf5plugin
705
705
  Requires-Dist: hist
706
- Requires-Dist: numba !=0.53.*,!=0.54.*
706
+ Requires-Dist: numba!=0.53.*,!=0.54.*
707
707
  Requires-Dist: numexpr
708
- Requires-Dist: numpy >=1.21
709
- Requires-Dist: pandas >=1.4.4
708
+ Requires-Dist: numpy>=1.21
709
+ Requires-Dist: pandas>=1.4.4
710
710
  Requires-Dist: parse
711
- Requires-Dist: pint >0.24
711
+ Requires-Dist: pint>0.24
712
712
  Requires-Dist: pint-pandas
713
713
  Provides-Extra: all
714
- Requires-Dist: legend-pydataobj[docs,test] ; extra == 'all'
714
+ Requires-Dist: legend-pydataobj[docs,test]; extra == "all"
715
715
  Provides-Extra: docs
716
- Requires-Dist: furo ; extra == 'docs'
717
- Requires-Dist: jupyter ; extra == 'docs'
718
- Requires-Dist: myst-parser ; extra == 'docs'
719
- Requires-Dist: nbsphinx ; extra == 'docs'
720
- Requires-Dist: sphinx ; extra == 'docs'
721
- Requires-Dist: sphinx-copybutton ; extra == 'docs'
722
- Requires-Dist: sphinx-inline-tabs ; extra == 'docs'
716
+ Requires-Dist: furo; extra == "docs"
717
+ Requires-Dist: jupyter; extra == "docs"
718
+ Requires-Dist: myst-parser; extra == "docs"
719
+ Requires-Dist: nbsphinx; extra == "docs"
720
+ Requires-Dist: sphinx; extra == "docs"
721
+ Requires-Dist: sphinx-copybutton; extra == "docs"
722
+ Requires-Dist: sphinx-inline-tabs; extra == "docs"
723
723
  Provides-Extra: test
724
- Requires-Dist: pre-commit ; extra == 'test'
725
- Requires-Dist: pylegendtestdata ; extra == 'test'
726
- Requires-Dist: pytest >=6.0 ; extra == 'test'
727
- Requires-Dist: pytest-cov ; extra == 'test'
724
+ Requires-Dist: pre-commit; extra == "test"
725
+ Requires-Dist: pylegendtestdata; extra == "test"
726
+ Requires-Dist: pytest>=6.0; extra == "test"
727
+ Requires-Dist: pytest-cov; extra == "test"
728
728
 
729
729
  # legend-pydataobj
730
730
 
@@ -1,6 +1,6 @@
1
1
  lgdo/__init__.py,sha256=1YUuAFQHNrOOkr3ZfrtEJOpYqgzbHRYA81ssbQZitQE,3196
2
- lgdo/_version.py,sha256=8G9z72uuzZV_GnX2AJUyUhUAHl8bmD6KQXou4HB100U,413
3
- lgdo/cli.py,sha256=vB1Oj6kZ5gWaY9HBPBRRRyiepp72hm3bFvQeUUWeMYg,8214
2
+ lgdo/_version.py,sha256=rZqhcUFwPMyj_mTWUN2A6qcFr8Ptv08CSbXbruC3jR4,413
3
+ lgdo/cli.py,sha256=Qm2EPmoIVxENAR8BeW7oWpTdHT4GbV-owfzM5NkgjvM,9353
4
4
  lgdo/lgdo_utils.py,sha256=6a2YWEwpyEMXlAyTHZMO01aqxy6SxJzPZkGNWKNWuS0,2567
5
5
  lgdo/lh5_store.py,sha256=5BzbJA9sLcqjp8bJDc2olwOiw0VS6rmfg3cfh1kQkRY,8512
6
6
  lgdo/logging.py,sha256=82wIOj7l7xr3WYyeHdpSXbbjzHJsy-uRyKYUYx2vMfQ,1003
@@ -13,7 +13,7 @@ lgdo/compression/radware.py,sha256=GcNTtjuyL7VBBqziUBmSqNXuhqy1bJJgvcyvyumPtrc,2
13
13
  lgdo/compression/utils.py,sha256=W2RkBrxPpXlat84dnU9Ad7d_tTws0irtGl7O1dNWjnk,1140
14
14
  lgdo/compression/varlen.py,sha256=6ZZUItyoOfygDdE0DyoISeFZfqdbH6xl7T0eclfarzg,15127
15
15
  lgdo/lh5/__init__.py,sha256=KzWF6HI-6N1NqQUm8LAxMmDbg0rgRY4DAaJ2s7w2tLM,811
16
- lgdo/lh5/core.py,sha256=YVtkTaU3SISDoLqR9UE_BDzsPApEW6_h_ac2NwSZ9zg,13868
16
+ lgdo/lh5/core.py,sha256=__-A6Abctzfwfo4-xJi68xs2e4vfzONEQTJVrUCOw-I,13922
17
17
  lgdo/lh5/datatype.py,sha256=O_7BqOlX8PFMyG0ppkfUT5aps5HEqX0bpuKcJO3jhu0,1691
18
18
  lgdo/lh5/exceptions.py,sha256=43fQ8MnAsylY4aG6GF6hsRclagYaMkUv8957c1uTjWE,962
19
19
  lgdo/lh5/iterator.py,sha256=ZaBBnmuNIjinwO0JUY55wLxX8Om9rVRRzXBC5uHmSKM,19772
@@ -23,12 +23,12 @@ lgdo/lh5/utils.py,sha256=ioz8DlyXZsejwnU2qYdIccdHcF12H62jgLkZsiDOLSM,6243
23
23
  lgdo/lh5/_serializers/__init__.py,sha256=NSH8uOVY3r_Wn3t0nQHhEHhkHT7-GJYlxuS3YTDJa5Y,1263
24
24
  lgdo/lh5/_serializers/read/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
25
  lgdo/lh5/_serializers/read/array.py,sha256=uWfMCihfAmW2DE2ewip2qCK_kvQC_mb2zvOv26uzijc,1000
26
- lgdo/lh5/_serializers/read/composite.py,sha256=vQGh6nUQdSuHl0NTF2FeU7QC9UAA-E7XvNvrRJi4uw8,12384
26
+ lgdo/lh5/_serializers/read/composite.py,sha256=yTm5dfTgkIL7eG9iZXxhdiRhG04cQLd_hybP4wmxCJE,11809
27
27
  lgdo/lh5/_serializers/read/encoded.py,sha256=Q98c08d8LkZq2AlY4rThYECVaEqwbv4T2Urn7TGnsyE,4130
28
28
  lgdo/lh5/_serializers/read/ndarray.py,sha256=lFCXD6bSzmMOH7cVmvRYXakkfMCI8EoqTPNONRJ1F0s,3690
29
29
  lgdo/lh5/_serializers/read/scalar.py,sha256=kwhWm1T91pXf86CqtUUD8_qheSR92gXZrQVtssV5YCg,922
30
- lgdo/lh5/_serializers/read/utils.py,sha256=0kYUFKiaQ3JUbjhP7tuKas_s80Kou6DhPlVXc40NHRE,5945
31
- lgdo/lh5/_serializers/read/vector_of_vectors.py,sha256=aCWTMbym7dF2yrhEfQs_GotcDqOKALRxgdJm4CA-bYs,7189
30
+ lgdo/lh5/_serializers/read/utils.py,sha256=USacxDA0eY-u9lDOZDuJHcScoSVMNeAYljmRvW0T1Jk,7587
31
+ lgdo/lh5/_serializers/read/vector_of_vectors.py,sha256=98P_XoXE8QWLQeSyBm9QHBF_5WGHKrfpNppLhj3QrbE,7169
32
32
  lgdo/lh5/_serializers/write/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
33
  lgdo/lh5/_serializers/write/array.py,sha256=eyVPwwddVOR9TNNyliCNYlS-XYXsdTEA8QoTnnOYJbw,2943
34
34
  lgdo/lh5/_serializers/write/composite.py,sha256=I6lH0nWFIpAfZyG4-0rLxzg3mfazZ_FEhQVp1FZ0aA4,9254
@@ -44,12 +44,12 @@ lgdo/types/lgdo.py,sha256=UnJDi1emQYVgH_H29Vipfs4LelPopxG5pgZUu1eKOlw,2761
44
44
  lgdo/types/scalar.py,sha256=c5Es2vyDqyWTPV6mujzfIzMpC1jNWkEIcvYyWQUxH3Q,1933
45
45
  lgdo/types/struct.py,sha256=Q0OWLVd4B0ciLb8t6VsxU3MPbmGLZ7WfQNno1lSQS0Q,4918
46
46
  lgdo/types/table.py,sha256=lB_jj6C0C5w8jbo17Lp0P8_uY8jy7opkTJc1OrbCGEI,17956
47
- lgdo/types/vectorofvectors.py,sha256=fBLI8P0HDe12Ib95eFUJObLa--gxz6wfAmOs_mDsokg,24390
47
+ lgdo/types/vectorofvectors.py,sha256=cic9PsZ5EptQ6RMsykYeVHA8T7fh_KBZCcqeTP4i1wU,24395
48
48
  lgdo/types/vovutils.py,sha256=7BWPP0BSj-92ifbCIUBcfqxG5-TS8uxujTyJJuDFI04,10302
49
49
  lgdo/types/waveformtable.py,sha256=f2tS4f1OEoYaTM5ldCX9zmw8iSISCT3t3wS1SrPdu_o,9901
50
- legend_pydataobj-1.10.1.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
51
- legend_pydataobj-1.10.1.dist-info/METADATA,sha256=gY35ifo00rptHQjVQ3BqkGeInupz20DGh1VIjeNEGlY,44381
52
- legend_pydataobj-1.10.1.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
53
- legend_pydataobj-1.10.1.dist-info/entry_points.txt,sha256=Uu5MTlppBZxB4QGlLv-oX8FqACWjAZDNii__TBDJwLQ,72
54
- legend_pydataobj-1.10.1.dist-info/top_level.txt,sha256=KyR-EUloqiXcQ62IWnzBmtInDtvsHl4q2ZJAZgTcLXE,5
55
- legend_pydataobj-1.10.1.dist-info/RECORD,,
50
+ legend_pydataobj-1.11.0.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
51
+ legend_pydataobj-1.11.0.dist-info/METADATA,sha256=d4lBYc7gKmmSdW59x4tUxcfUSlETmAknC1f2TchfgNc,44382
52
+ legend_pydataobj-1.11.0.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
53
+ legend_pydataobj-1.11.0.dist-info/entry_points.txt,sha256=Uu5MTlppBZxB4QGlLv-oX8FqACWjAZDNii__TBDJwLQ,72
54
+ legend_pydataobj-1.11.0.dist-info/top_level.txt,sha256=KyR-EUloqiXcQ62IWnzBmtInDtvsHl4q2ZJAZgTcLXE,5
55
+ legend_pydataobj-1.11.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.3.0)
2
+ Generator: setuptools (75.6.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
lgdo/_version.py CHANGED
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '1.10.1'
16
- __version_tuple__ = version_tuple = (1, 10, 1)
15
+ __version__ = version = '1.11.0'
16
+ __version_tuple__ = version_tuple = (1, 11, 0)
lgdo/cli.py CHANGED
@@ -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()
@@ -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
- # check field_mask and make it a default dict
76
- if field_mask is None:
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"] = "struct{" + ",".join(selected_fields) + "}"
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 (types.Table, types.WaveformTable):
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
- if not field_mask:
141
- field_mask = datatype.get_struct_fields(type_attr)
142
- for field in field_mask:
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.nda.resize(fdb_size, refcheck=False)
159
+ fd_buf.resize(fdb_size)
160
160
 
161
161
  # now read
162
162
  h5o = h5py.h5o.open(h5g, b"flattened_data")
lgdo/lh5/core.py CHANGED
@@ -120,6 +120,7 @@ def read(
120
120
  lh5_obj = lh5_file[name]
121
121
  else:
122
122
  lh5_files = list(lh5_file)
123
+
123
124
  n_rows_read = 0
124
125
  obj_buf_is_new = False
125
126
 
@@ -353,5 +354,8 @@ def read_as(
353
354
  # NOTE: providing a buffer does not make much sense
354
355
  obj = read(name, lh5_file, **kwargs1)
355
356
 
357
+ if isinstance(obj, tuple):
358
+ obj = obj[0]
359
+
356
360
  # and finally return a view
357
361
  return obj.view_as(library, **kwargs2)
@@ -503,7 +503,7 @@ class VectorOfVectors(LGDO):
503
503
  def __str__(self) -> str:
504
504
  string = self.view_as("ak").show(stream=None)
505
505
 
506
- string = string.strip().removesuffix("]")
506
+ string = str(string).strip().removesuffix("]")
507
507
  string += "\n]"
508
508
 
509
509
  tmp_attrs = self.attrs.copy()