legend-pydataobj 1.5.1__py3-none-any.whl → 1.6.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 (46) hide show
  1. {legend_pydataobj-1.5.1.dist-info → legend_pydataobj-1.6.0.dist-info}/METADATA +1 -1
  2. legend_pydataobj-1.6.0.dist-info/RECORD +54 -0
  3. {legend_pydataobj-1.5.1.dist-info → legend_pydataobj-1.6.0.dist-info}/WHEEL +1 -1
  4. {legend_pydataobj-1.5.1.dist-info → legend_pydataobj-1.6.0.dist-info}/entry_points.txt +1 -0
  5. lgdo/__init__.py +7 -4
  6. lgdo/_version.py +2 -2
  7. lgdo/cli.py +237 -12
  8. lgdo/compression/__init__.py +1 -0
  9. lgdo/lh5/__init__.py +9 -1
  10. lgdo/lh5/_serializers/__init__.py +43 -0
  11. lgdo/lh5/_serializers/read/__init__.py +0 -0
  12. lgdo/lh5/_serializers/read/array.py +34 -0
  13. lgdo/lh5/_serializers/read/composite.py +405 -0
  14. lgdo/lh5/_serializers/read/encoded.py +129 -0
  15. lgdo/lh5/_serializers/read/ndarray.py +104 -0
  16. lgdo/lh5/_serializers/read/scalar.py +34 -0
  17. lgdo/lh5/_serializers/read/utils.py +12 -0
  18. lgdo/lh5/_serializers/read/vector_of_vectors.py +195 -0
  19. lgdo/lh5/_serializers/write/__init__.py +0 -0
  20. lgdo/lh5/_serializers/write/array.py +92 -0
  21. lgdo/lh5/_serializers/write/composite.py +259 -0
  22. lgdo/lh5/_serializers/write/scalar.py +23 -0
  23. lgdo/lh5/_serializers/write/vector_of_vectors.py +95 -0
  24. lgdo/lh5/core.py +272 -0
  25. lgdo/lh5/datatype.py +46 -0
  26. lgdo/lh5/exceptions.py +34 -0
  27. lgdo/lh5/iterator.py +1 -1
  28. lgdo/lh5/store.py +69 -1160
  29. lgdo/lh5/tools.py +27 -53
  30. lgdo/lh5/utils.py +130 -27
  31. lgdo/lh5_store.py +11 -2
  32. lgdo/logging.py +1 -0
  33. lgdo/types/__init__.py +1 -0
  34. lgdo/types/array.py +1 -0
  35. lgdo/types/arrayofequalsizedarrays.py +1 -0
  36. lgdo/types/encoded.py +3 -8
  37. lgdo/types/fixedsizearray.py +1 -0
  38. lgdo/types/struct.py +1 -0
  39. lgdo/types/table.py +37 -5
  40. lgdo/types/vectorofvectors.py +314 -458
  41. lgdo/types/vovutils.py +320 -0
  42. lgdo/types/waveformtable.py +1 -0
  43. lgdo/utils.py +1 -32
  44. legend_pydataobj-1.5.1.dist-info/RECORD +0 -36
  45. {legend_pydataobj-1.5.1.dist-info → legend_pydataobj-1.6.0.dist-info}/LICENSE +0 -0
  46. {legend_pydataobj-1.5.1.dist-info → legend_pydataobj-1.6.0.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: legend_pydataobj
3
- Version: 1.5.1
3
+ Version: 1.6.0
4
4
  Summary: LEGEND Python Data Objects
5
5
  Author: The LEGEND Collaboration
6
6
  Maintainer: The LEGEND Collaboration
@@ -0,0 +1,54 @@
1
+ lgdo/__init__.py,sha256=nv9kORuX2FCA6rQLbH959E0fuGMfZvHb0H5uyrLr2WI,3046
2
+ lgdo/_version.py,sha256=Ry70pc5l-IBhT9gahlkNwZPp4g0CzVEWqsat9H-UASY,411
3
+ lgdo/cli.py,sha256=hHc0Cz4ZXEOwo55oIukHAhHUkw09ePr4m3sO7eUbWHA,8018
4
+ lgdo/lgdo_utils.py,sha256=6a2YWEwpyEMXlAyTHZMO01aqxy6SxJzPZkGNWKNWuS0,2567
5
+ lgdo/lh5_store.py,sha256=xHwzbKNueEtFwScxrgfvCo2_bWKS6j7ojrpeF9kQflc,8483
6
+ lgdo/logging.py,sha256=82wIOj7l7xr3WYyeHdpSXbbjzHJsy-uRyKYUYx2vMfQ,1003
7
+ lgdo/units.py,sha256=nbJ0JTNqlhHUXiBXT3k6qhRpSfMk5_9yW7EeC0dhMuQ,151
8
+ lgdo/utils.py,sha256=9t_GYdB8aQhZ4Vz6ujmASzwCgTuP7ZdINtPTVPyIR6E,3661
9
+ lgdo/compression/__init__.py,sha256=gqbdx4NnpCcW-C7kUXV-hVUZFiNlbCwIbs3uzFe4AFE,1127
10
+ lgdo/compression/base.py,sha256=82cQJujfvoAOKBFx761dEcx_xM02TBCBBuBo6i78tuI,838
11
+ lgdo/compression/generic.py,sha256=tF3UhLJbUDcovLxpIzgQRxFSjZ5Fz3uDRy9kI4mFntQ,2515
12
+ lgdo/compression/radware.py,sha256=VbKAvi18h48Fz-ZxMEg64yD1ezaw1NkMZazxurdyMmc,24015
13
+ lgdo/compression/utils.py,sha256=W2RkBrxPpXlat84dnU9Ad7d_tTws0irtGl7O1dNWjnk,1140
14
+ lgdo/compression/varlen.py,sha256=6ZZUItyoOfygDdE0DyoISeFZfqdbH6xl7T0eclfarzg,15127
15
+ lgdo/lh5/__init__.py,sha256=KzWF6HI-6N1NqQUm8LAxMmDbg0rgRY4DAaJ2s7w2tLM,811
16
+ lgdo/lh5/core.py,sha256=ap7K6GrbjdF4n-hvPPVeXOk76OF0S4uBclbP3mNHk04,10780
17
+ lgdo/lh5/datatype.py,sha256=6OfLmoqrfPxZLSmGXIF9xFIwyY6u0yoXT_lr1k_5NcM,1619
18
+ lgdo/lh5/exceptions.py,sha256=QWStQD27Qrm4oYs5Z3UAIoq4y7X-f_Z6QWCBCH0DXwE,1006
19
+ lgdo/lh5/iterator.py,sha256=eqH9a_ZjEhgqJUZbMj36jXK_1Xbx86450DVw7LHNB3Y,12369
20
+ lgdo/lh5/store.py,sha256=sYX1harVGRyP0oq1LGq2qrFhorutkev9MOovwhzEWZ4,6670
21
+ lgdo/lh5/tools.py,sha256=AH0RuaUEJ7Tfzb964KnuVdxCKrGqwNP8XDt2iq4829g,8386
22
+ lgdo/lh5/utils.py,sha256=xSTv0obtsUxO38JpkPKd2FbzENlhuTvYR0aexFU1ZQc,6640
23
+ lgdo/lh5/_serializers/__init__.py,sha256=7zvTmBdp-pqS0ium6cKKjEvcqIND-kBC7319G5wMq5Y,1213
24
+ lgdo/lh5/_serializers/read/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
+ lgdo/lh5/_serializers/read/array.py,sha256=DLguBkiVNXZuUk7LdalixA8uISx_SETVPXWk-26HYmk,933
26
+ lgdo/lh5/_serializers/read/composite.py,sha256=M3RR4SEyFGtb4qsscJOtB-P4HhdMQw0_JDIWKkUOsKA,12066
27
+ lgdo/lh5/_serializers/read/encoded.py,sha256=LTdSqEH5tJOdqcSCrMLWutYiQ4FwBFIPF7FDZ-iallw,3744
28
+ lgdo/lh5/_serializers/read/ndarray.py,sha256=4vdgHwj_yIon1KvSiOkDSHq7CJhYtFcjjSHijsvp1aU,3481
29
+ lgdo/lh5/_serializers/read/scalar.py,sha256=YwvA6kyNUh6H0kh2L7bzfgLkA8Et2dQFjp2nFnRmeGI,755
30
+ lgdo/lh5/_serializers/read/utils.py,sha256=K_HDQ_H-vtbs_gEif1MTtFki4qh6lw-5HE7b-7_s-9Q,417
31
+ lgdo/lh5/_serializers/read/vector_of_vectors.py,sha256=nlaoOuDPDQvZWslGm3YxyRkcFodfSBEXRKwY046VDvM,6318
32
+ lgdo/lh5/_serializers/write/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
+ lgdo/lh5/_serializers/write/array.py,sha256=Gosg8rOCH_2dRMj_oNSWyXuoYXDjy0OK--GCYWswR4U,2803
34
+ lgdo/lh5/_serializers/write/composite.py,sha256=f3b4YeOoUr8y1wA7zsKEFT5mIwX8SD0MYQ40unMRyQc,8460
35
+ lgdo/lh5/_serializers/write/scalar.py,sha256=gkcF2WVBR3aQYl0EynbVUocx4y3r8tvPfQYQJjkPvP4,643
36
+ lgdo/lh5/_serializers/write/vector_of_vectors.py,sha256=mZuC7NIb-IkmJ9wgn37TTvFTLLAFR71iivrY4yiSJZM,2912
37
+ lgdo/types/__init__.py,sha256=_cHZEpsh7OGsA243WBK2a2UmCp3NSA0MjXYf95y728k,771
38
+ lgdo/types/array.py,sha256=sUxh1CNCaefrnybt5qdjmmMpVQa_RqFxUv1tJ_pyBbc,6537
39
+ lgdo/types/arrayofequalsizedarrays.py,sha256=DOGJiTmc1QCdm7vLbE6uIRXoMPtt8uuCfmwQawgWf5s,4949
40
+ lgdo/types/encoded.py,sha256=JW4U5ow7KLMzhKnmhdnxbC3SZJAs4bOEDZWKG4KY1uU,15293
41
+ lgdo/types/fixedsizearray.py,sha256=7Fj4QS9ubaeEf2tM3HwjSs6AuG8hKSYaT6Hy7Y_VHdQ,1525
42
+ lgdo/types/lgdo.py,sha256=UnJDi1emQYVgH_H29Vipfs4LelPopxG5pgZUu1eKOlw,2761
43
+ lgdo/types/scalar.py,sha256=c5Es2vyDqyWTPV6mujzfIzMpC1jNWkEIcvYyWQUxH3Q,1933
44
+ lgdo/types/struct.py,sha256=rLtyPthut2wjwiOqwntPrYjjt3uRQbTLWWjiewfKm20,3979
45
+ lgdo/types/table.py,sha256=YL_71PalmGnh4YvaDlK0oY4aeypYRAETwJEkRHVOUu8,16887
46
+ lgdo/types/vectorofvectors.py,sha256=9pKtPfvh0vQ-nmg68LUM8cMttoxTl0BG3QH5awQtSxo,24503
47
+ lgdo/types/vovutils.py,sha256=7BWPP0BSj-92ifbCIUBcfqxG5-TS8uxujTyJJuDFI04,10302
48
+ lgdo/types/waveformtable.py,sha256=f2tS4f1OEoYaTM5ldCX9zmw8iSISCT3t3wS1SrPdu_o,9901
49
+ legend_pydataobj-1.6.0.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
50
+ legend_pydataobj-1.6.0.dist-info/METADATA,sha256=WuFjFye6W_q3YdhE5tHCQlcKNaOCml-TK7ItWAM_f34,44353
51
+ legend_pydataobj-1.6.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
52
+ legend_pydataobj-1.6.0.dist-info/entry_points.txt,sha256=Uu5MTlppBZxB4QGlLv-oX8FqACWjAZDNii__TBDJwLQ,72
53
+ legend_pydataobj-1.6.0.dist-info/top_level.txt,sha256=KyR-EUloqiXcQ62IWnzBmtInDtvsHl4q2ZJAZgTcLXE,5
54
+ legend_pydataobj-1.6.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.42.0)
2
+ Generator: bdist_wheel (0.43.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,2 +1,3 @@
1
1
  [console_scripts]
2
+ lh5concat = lgdo.cli:lh5concat
2
3
  lh5ls = lgdo.cli:lh5ls
lgdo/__init__.py CHANGED
@@ -15,10 +15,12 @@ basic data object classes are:
15
15
  :attr:`nda` attribute.
16
16
  * :class:`.ArrayOfEqualSizedArrays`: multi-dimensional :class:`numpy.ndarray`.
17
17
  Access data via the :attr:`nda` attribute.
18
- * :class:`.VectorOfVectors`: a variable length array of variable length arrays.
19
- Implemented as a pair of :class:`.Array`: :attr:`flattened_data` holding the
20
- raw data, and :attr:`cumulative_length` whose ith element is the sum of the
21
- lengths of the vectors with ``index <= i``
18
+ * :class:`.VectorOfVectors`: an n-dimensional variable length array of variable
19
+ length arrays. Implemented as a pair of datasets: :attr:`flattened_data`
20
+ holding the raw data (:class:`.Array` or :class:`.VectorOfVectors`, if the
21
+ vector dimension is greater than 2), and :attr:`cumulative_length` (always an
22
+ :class:`.Array`) whose i-th element is the sum of the lengths of the vectors
23
+ with ``index <= i``
22
24
  * :class:`.VectorOfEncodedVectors`: an array of variable length *encoded*
23
25
  arrays. Implemented as a :class:`.VectorOfVectors` :attr:`encoded_data`
24
26
  holding the encoded vectors and an :class:`.Array` :attr:`decoded_size`
@@ -37,6 +39,7 @@ is done via the class :class:`.lh5_store.LH5Store`. LH5 files can also be
37
39
  browsed easily in python like any `HDF5 <https://www.hdfgroup.org>`_ file using
38
40
  `h5py <https://www.h5py.org>`_.
39
41
  """
42
+
40
43
  from __future__ import annotations
41
44
 
42
45
  from ._version import version as __version__
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.5.1'
16
- __version_tuple__ = version_tuple = (1, 5, 1)
15
+ __version__ = version = '1.6.0'
16
+ __version_tuple__ = version_tuple = (1, 6, 0)
lgdo/cli.py CHANGED
@@ -1,16 +1,19 @@
1
1
  """legend-pydataobj's command line interface utilities."""
2
+
2
3
  from __future__ import annotations
3
4
 
4
5
  import argparse
6
+ import fnmatch
5
7
  import logging
6
8
  import sys
7
9
 
8
- import lgdo
9
- import lgdo.logging
10
- from lgdo.lh5 import show
10
+ from . import Array, Table, VectorOfVectors, __version__, lh5
11
+ from . import logging as lgdogging # eheheh
12
+
13
+ log = logging.getLogger(__name__)
11
14
 
12
15
 
13
- def lh5ls():
16
+ def lh5ls(args=None):
14
17
  """:func:`.lh5.show` command line interface."""
15
18
  parser = argparse.ArgumentParser(
16
19
  prog="lh5ls", description="Inspect LEGEND HDF5 (LH5) file contents"
@@ -18,7 +21,9 @@ def lh5ls():
18
21
 
19
22
  # global options
20
23
  parser.add_argument(
21
- "--version", action="store_true", help="""Print lgdo version and exit"""
24
+ "--version",
25
+ action="store_true",
26
+ help="""Print legend-pydataobj version and exit""",
22
27
  )
23
28
  parser.add_argument(
24
29
  "--verbose",
@@ -34,7 +39,7 @@ def lh5ls():
34
39
 
35
40
  parser.add_argument(
36
41
  "lh5_file",
37
- help="""Input LH5 file.""",
42
+ help="""Input LH5 file""",
38
43
  )
39
44
  parser.add_argument("lh5_group", nargs="?", help="""LH5 group.""", default="/")
40
45
  parser.add_argument(
@@ -48,17 +53,237 @@ def lh5ls():
48
53
  help="""Maximum tree depth of groups to print""",
49
54
  )
50
55
 
51
- args = parser.parse_args()
56
+ args = parser.parse_args(args)
52
57
 
53
58
  if args.verbose:
54
- lgdo.logging.setup(logging.DEBUG)
59
+ lgdogging.setup(logging.DEBUG)
55
60
  elif args.debug:
56
- lgdo.logging.setup(logging.DEBUG, logging.root)
61
+ lgdogging.setup(logging.DEBUG, logging.root)
57
62
  else:
58
- lgdo.logging.setup()
63
+ lgdogging.setup()
59
64
 
60
65
  if args.version:
61
- print(lgdo.__version__) # noqa: T201
66
+ print(__version__) # noqa: T201
62
67
  sys.exit()
63
68
 
64
- show(args.lh5_file, args.lh5_group, attrs=args.attributes, depth=args.depth)
69
+ lh5.show(args.lh5_file, args.lh5_group, attrs=args.attributes, depth=args.depth)
70
+
71
+
72
+ def lh5concat(args=None):
73
+ """Command line interface for concatenating array-like LGDOs in LH5 files."""
74
+ parser = argparse.ArgumentParser(
75
+ prog="lh5concat",
76
+ description="""
77
+ Concatenate LGDO Arrays, VectorOfVectors and Tables in LH5 files.
78
+
79
+ Examples
80
+ --------
81
+
82
+ Concatenate all eligible objects in file{1,2}.lh5 into concat.lh5:
83
+
84
+ $ lh5concat -o concat.lh5 file1.lh5 file2.lh5
85
+
86
+ Include only the /data/table1 Table:
87
+
88
+ $ lh5concat -o concat.lh5 -i /data/table1/* file1.lh5 file2.lh5
89
+
90
+ Exclude the /data/table1/col1 Table column:
91
+
92
+ $ lh5concat -o concat.lh5 -e /data/table1/col1 file1.lh5 file2.lh5
93
+ """,
94
+ formatter_class=argparse.RawTextHelpFormatter,
95
+ )
96
+
97
+ # global options
98
+ parser.add_argument(
99
+ "--version",
100
+ action="store_true",
101
+ help="""Print legend-pydataobj version and exit""",
102
+ )
103
+ parser.add_argument(
104
+ "--verbose",
105
+ "-v",
106
+ action="store_true",
107
+ help="""Increase the program verbosity""",
108
+ )
109
+ parser.add_argument(
110
+ "--debug",
111
+ action="store_true",
112
+ help="""Increase the program verbosity to maximum""",
113
+ )
114
+
115
+ parser.add_argument(
116
+ "lh5_file",
117
+ nargs="+",
118
+ help="""Input LH5 files""",
119
+ )
120
+ parser.add_argument(
121
+ "--output",
122
+ "-o",
123
+ help="""Output file""",
124
+ default="lh5concat-output.lh5",
125
+ )
126
+ parser.add_argument(
127
+ "--overwrite",
128
+ "-w",
129
+ action="store_true",
130
+ help="""Overwrite output file""",
131
+ )
132
+ parser.add_argument(
133
+ "--include",
134
+ "-i",
135
+ help="""Regular expression (fnmatch style) for object names that should
136
+ be concatenated. To include full tables, you need to explicitly include
137
+ all its columns with e.g. '/path/to/table/*'. The option can be passed
138
+ multiple times to provide a list of patterns.
139
+ """,
140
+ action="append",
141
+ default=None,
142
+ )
143
+ parser.add_argument(
144
+ "--exclude",
145
+ "-e",
146
+ help="""List of object names that should be excluded. Takes priority
147
+ over --include. See --include help for more details.
148
+ """,
149
+ action="append",
150
+ default=None,
151
+ )
152
+
153
+ args = parser.parse_args(args)
154
+
155
+ if args.verbose:
156
+ lgdogging.setup(logging.INFO, log)
157
+ elif args.debug:
158
+ lgdogging.setup(logging.DEBUG, logging.root)
159
+ else:
160
+ lgdogging.setup()
161
+
162
+ if args.version:
163
+ print(__version__) # noqa: T201
164
+ sys.exit()
165
+
166
+ if len(args.lh5_file) < 2:
167
+ msg = "you must provide at least two input files"
168
+ raise RuntimeError(msg)
169
+
170
+ # determine list of objects by recursively ls'ing first file
171
+ file0 = args.lh5_file[0]
172
+ obj_list_full = set(lh5.ls(file0, recursive=True))
173
+
174
+ # let's remove objects with nested LGDOs inside
175
+ to_remove = set()
176
+ for name in obj_list_full:
177
+ if len(fnmatch.filter(obj_list_full, f"{name}/*")) > 1:
178
+ to_remove.add(name)
179
+ obj_list_full -= to_remove
180
+
181
+ obj_list = set()
182
+ # now first remove excluded stuff
183
+ if args.exclude is not None:
184
+ for exc in args.exclude:
185
+ obj_list_full -= set(fnmatch.filter(obj_list_full, exc.strip("/")))
186
+
187
+ # then make list of included, based on latest list
188
+ if args.include is not None:
189
+ for inc in args.include:
190
+ obj_list |= set(fnmatch.filter(obj_list_full, inc.strip("/")))
191
+ else:
192
+ obj_list = obj_list_full
193
+
194
+ # sort
195
+ obj_list = sorted(obj_list)
196
+
197
+ msg = f"objects matching include patterns {args.include} in {file0}: {obj_list}"
198
+ log.debug(msg)
199
+
200
+ # 1. read first valid lgdo from left to right
201
+ store = lh5.LH5Store()
202
+ h5f0 = store.gimme_file(file0)
203
+ lgdos = {}
204
+ # loop over object list in the first file
205
+ for name in obj_list:
206
+ # now loop over groups starting from root
207
+ current = ""
208
+ for item in name.split("/"):
209
+ current = f"{current}/{item}".strip("/")
210
+
211
+ if current in lgdos:
212
+ break
213
+
214
+ # not even an LGDO!
215
+ if "datatype" not in h5f0[current].attrs:
216
+ continue
217
+
218
+ # read as little as possible
219
+ obj, _ = store.read(current, h5f0, n_rows=1)
220
+ if isinstance(obj, (Table, Array, VectorOfVectors)):
221
+ # read all!
222
+ obj, _ = store.read(current, h5f0)
223
+ lgdos[current] = obj
224
+
225
+ break
226
+
227
+ msg = f"first-level, array-like objects: {lgdos.keys()}"
228
+ log.debug(msg)
229
+
230
+ h5f0.close()
231
+
232
+ # 2. remove (nested) table fields based on obj_list
233
+
234
+ def _inplace_table_filter(name, table, obj_list):
235
+ # filter objects nested in this LGDO
236
+ skm = fnmatch.filter(obj_list, f"{name}/*")
237
+ kept = {it.removeprefix(name).strip("/").split("/")[0] for it in skm}
238
+
239
+ # now remove fields
240
+ for k in list(table.keys()):
241
+ if k not in kept:
242
+ table.remove_column(k)
243
+
244
+ msg = f"fields left in table '{name}': {table.keys()}"
245
+ log.debug(msg)
246
+
247
+ # recurse!
248
+ for k2, v2 in table.items():
249
+ if not isinstance(v2, Table):
250
+ continue
251
+
252
+ _inplace_table_filter(f"{name}/{k2}", v2, obj_list)
253
+
254
+ for key, val in lgdos.items():
255
+ if not isinstance(val, Table):
256
+ continue
257
+
258
+ _inplace_table_filter(key, val, obj_list)
259
+
260
+ # 3. write to output file
261
+ msg = f"creating output file {args.output}"
262
+ log.info(msg)
263
+
264
+ first_done = False
265
+ for name, obj in lgdos.items():
266
+ store.write(
267
+ obj,
268
+ name,
269
+ args.output,
270
+ wo_mode="overwrite_file"
271
+ if (args.overwrite and not first_done)
272
+ else "write_safe",
273
+ )
274
+
275
+ first_done = True
276
+
277
+ # 4. loop over rest of files/names and write-append
278
+
279
+ for file in args.lh5_file[1:]:
280
+ msg = f"appending file {file} to {args.output}"
281
+ log.info(msg)
282
+
283
+ for name in lgdos:
284
+ obj, _ = store.read(name, file)
285
+ # need to remove nested LGDOs from obj too before appending
286
+ if isinstance(obj, Table):
287
+ _inplace_table_filter(name, obj, obj_list)
288
+
289
+ store.write(obj, name, args.output, wo_mode="append")
@@ -21,6 +21,7 @@ interface for encoding/decoding :class:`~.lgdo.LGDO`\ s.
21
21
  >>> enc_wft = compression.encode(wftable, RadwareSigcompress(codec_shift=-23768)
22
22
  >>> compression.decode(enc_wft) # == wftbl
23
23
  """
24
+
24
25
  from __future__ import annotations
25
26
 
26
27
  from .base import WaveformCodec
lgdo/lh5/__init__.py CHANGED
@@ -4,18 +4,26 @@ is done via the class :class:`.store.LH5Store`. LH5 files can also be
4
4
  browsed easily in python like any `HDF5 <https://www.hdfgroup.org>`_ file using
5
5
  `h5py <https://www.h5py.org>`_.
6
6
  """
7
+
7
8
  from __future__ import annotations
8
9
 
10
+ from ._serializers.write.array import DEFAULT_HDF5_SETTINGS
11
+ from .core import read, read_as, write
9
12
  from .iterator import LH5Iterator
10
13
  from .store import LH5Store
11
- from .tools import load_dfs, load_nda, ls, read_as, show
14
+ from .tools import load_dfs, load_nda, ls, show
15
+ from .utils import read_n_rows
12
16
 
13
17
  __all__ = [
18
+ "DEFAULT_HDF5_SETTINGS",
14
19
  "LH5Iterator",
15
20
  "LH5Store",
16
21
  "load_dfs",
17
22
  "load_nda",
23
+ "read",
24
+ "write",
18
25
  "read_as",
19
26
  "ls",
27
+ "read_n_rows",
20
28
  "show",
21
29
  ]
@@ -0,0 +1,43 @@
1
+ from __future__ import annotations
2
+
3
+ from .read.array import (
4
+ _h5_read_array,
5
+ _h5_read_array_of_equalsized_arrays,
6
+ _h5_read_fixedsize_array,
7
+ _h5_read_ndarray,
8
+ )
9
+ from .read.composite import (
10
+ _h5_read_lgdo,
11
+ _h5_read_struct,
12
+ _h5_read_table,
13
+ )
14
+ from .read.encoded import (
15
+ _h5_read_array_of_encoded_equalsized_arrays,
16
+ _h5_read_vector_of_encoded_vectors,
17
+ )
18
+ from .read.scalar import _h5_read_scalar
19
+ from .read.vector_of_vectors import _h5_read_vector_of_vectors
20
+ from .write.array import _h5_write_array
21
+ from .write.composite import _h5_write_lgdo, _h5_write_struct
22
+ from .write.scalar import _h5_write_scalar
23
+ from .write.vector_of_vectors import _h5_write_vector_of_vectors
24
+
25
+ __all__ = [
26
+ "_h5_read_lgdo",
27
+ "_h5_read_vector_of_vectors",
28
+ "_h5_read_ndarray",
29
+ "_h5_read_array",
30
+ "_h5_read_encoded_array",
31
+ "_h5_read_fixedsize_array",
32
+ "_h5_read_array_of_equalsized_arrays",
33
+ "_h5_read_struct",
34
+ "_h5_read_table",
35
+ "_h5_read_scalar",
36
+ "_h5_read_array_of_encoded_equalsized_arrays",
37
+ "_h5_read_vector_of_encoded_vectors",
38
+ "_h5_write_scalar",
39
+ "_h5_write_array",
40
+ "_h5_write_vector_of_vectors",
41
+ "_h5_write_struct",
42
+ "_h5_write_lgdo",
43
+ ]
File without changes
@@ -0,0 +1,34 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+
5
+ from ....types import Array, ArrayOfEqualSizedArrays, FixedSizeArray
6
+ from . import utils
7
+ from .ndarray import _h5_read_ndarray
8
+
9
+ log = logging.getLogger(__name__)
10
+
11
+
12
+ def _h5_read_array_generic(type_, name, h5f, **kwargs):
13
+ nda, attrs, n_rows_to_read = _h5_read_ndarray(name, h5f, **kwargs)
14
+
15
+ obj_buf = kwargs["obj_buf"]
16
+
17
+ if obj_buf is None:
18
+ return type_(nda=nda, attrs=attrs), n_rows_to_read
19
+
20
+ utils.check_obj_buf_attrs(obj_buf.attrs, attrs, h5f, name)
21
+
22
+ return obj_buf, n_rows_to_read
23
+
24
+
25
+ def _h5_read_array(name, h5f, **kwargs):
26
+ return _h5_read_array_generic(Array, name, h5f, **kwargs)
27
+
28
+
29
+ def _h5_read_fixedsize_array(name, h5f, **kwargs):
30
+ return _h5_read_array_generic(FixedSizeArray, name, h5f, **kwargs)
31
+
32
+
33
+ def _h5_read_array_of_equalsized_arrays(name, h5f, **kwargs):
34
+ return _h5_read_array_generic(ArrayOfEqualSizedArrays, name, h5f, **kwargs)