legend-pydataobj 1.5.0a5__tar.gz → 1.6.0__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.
Files changed (97) hide show
  1. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/PKG-INFO +1 -1
  2. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/pyproject.toml +12 -1
  3. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/legend_pydataobj.egg-info/PKG-INFO +1 -1
  4. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/legend_pydataobj.egg-info/SOURCES.txt +24 -0
  5. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/legend_pydataobj.egg-info/entry_points.txt +1 -0
  6. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/lgdo/__init__.py +7 -4
  7. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/lgdo/_version.py +2 -2
  8. legend_pydataobj-1.6.0/src/lgdo/cli.py +289 -0
  9. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/lgdo/compression/__init__.py +1 -0
  10. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/lgdo/lh5/__init__.py +9 -1
  11. legend_pydataobj-1.6.0/src/lgdo/lh5/_serializers/__init__.py +43 -0
  12. legend_pydataobj-1.6.0/src/lgdo/lh5/_serializers/read/__init__.py +0 -0
  13. legend_pydataobj-1.6.0/src/lgdo/lh5/_serializers/read/array.py +34 -0
  14. legend_pydataobj-1.6.0/src/lgdo/lh5/_serializers/read/composite.py +405 -0
  15. legend_pydataobj-1.6.0/src/lgdo/lh5/_serializers/read/encoded.py +129 -0
  16. legend_pydataobj-1.6.0/src/lgdo/lh5/_serializers/read/ndarray.py +104 -0
  17. legend_pydataobj-1.6.0/src/lgdo/lh5/_serializers/read/scalar.py +34 -0
  18. legend_pydataobj-1.6.0/src/lgdo/lh5/_serializers/read/utils.py +12 -0
  19. legend_pydataobj-1.6.0/src/lgdo/lh5/_serializers/read/vector_of_vectors.py +195 -0
  20. legend_pydataobj-1.6.0/src/lgdo/lh5/_serializers/write/__init__.py +0 -0
  21. legend_pydataobj-1.6.0/src/lgdo/lh5/_serializers/write/array.py +92 -0
  22. legend_pydataobj-1.6.0/src/lgdo/lh5/_serializers/write/composite.py +259 -0
  23. legend_pydataobj-1.6.0/src/lgdo/lh5/_serializers/write/scalar.py +23 -0
  24. legend_pydataobj-1.6.0/src/lgdo/lh5/_serializers/write/vector_of_vectors.py +95 -0
  25. legend_pydataobj-1.6.0/src/lgdo/lh5/core.py +272 -0
  26. legend_pydataobj-1.6.0/src/lgdo/lh5/datatype.py +46 -0
  27. legend_pydataobj-1.6.0/src/lgdo/lh5/exceptions.py +34 -0
  28. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/lgdo/lh5/iterator.py +1 -1
  29. legend_pydataobj-1.6.0/src/lgdo/lh5/store.py +220 -0
  30. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/lgdo/lh5/tools.py +27 -53
  31. legend_pydataobj-1.6.0/src/lgdo/lh5/utils.py +223 -0
  32. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/lgdo/lh5_store.py +59 -2
  33. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/lgdo/logging.py +4 -3
  34. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/lgdo/types/__init__.py +1 -0
  35. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/lgdo/types/array.py +3 -0
  36. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/lgdo/types/arrayofequalsizedarrays.py +1 -0
  37. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/lgdo/types/encoded.py +3 -8
  38. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/lgdo/types/fixedsizearray.py +1 -0
  39. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/lgdo/types/struct.py +1 -0
  40. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/lgdo/types/table.py +69 -26
  41. legend_pydataobj-1.6.0/src/lgdo/types/vectorofvectors.py +669 -0
  42. legend_pydataobj-1.6.0/src/lgdo/types/vovutils.py +320 -0
  43. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/lgdo/types/waveformtable.py +1 -0
  44. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/lgdo/utils.py +1 -32
  45. legend_pydataobj-1.6.0/tests/lh5/conftest.py +130 -0
  46. legend_pydataobj-1.6.0/tests/lh5/test_core.py +37 -0
  47. legend_pydataobj-1.6.0/tests/lh5/test_lh5_datatype.py +51 -0
  48. legend_pydataobj-1.6.0/tests/lh5/test_lh5_store.py +452 -0
  49. legend_pydataobj-1.6.0/tests/lh5/test_lh5_tools.py +85 -0
  50. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/tests/lh5/test_lh5_utils.py +0 -22
  51. legend_pydataobj-1.6.0/tests/lh5/test_lh5_write.py +393 -0
  52. legend_pydataobj-1.6.0/tests/test_cli.py +151 -0
  53. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/tests/types/test_array.py +1 -7
  54. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/tests/types/test_table.py +17 -0
  55. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/tests/types/test_table_eval.py +10 -0
  56. legend_pydataobj-1.6.0/tests/types/test_vectorofvectors.py +416 -0
  57. legend_pydataobj-1.6.0/tests/types/test_vovutils.py +78 -0
  58. legend_pydataobj-1.5.0a5/src/lgdo/cli.py +0 -64
  59. legend_pydataobj-1.5.0a5/src/lgdo/lh5/store.py +0 -1311
  60. legend_pydataobj-1.5.0a5/src/lgdo/lh5/utils.py +0 -120
  61. legend_pydataobj-1.5.0a5/src/lgdo/types/vectorofvectors.py +0 -813
  62. legend_pydataobj-1.5.0a5/tests/lh5/test_lh5_store.py +0 -909
  63. legend_pydataobj-1.5.0a5/tests/test_cli.py +0 -15
  64. legend_pydataobj-1.5.0a5/tests/types/test_vectorofvectors.py +0 -333
  65. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/LICENSE +0 -0
  66. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/README.md +0 -0
  67. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/setup.cfg +0 -0
  68. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/legend_pydataobj.egg-info/dependency_links.txt +0 -0
  69. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/legend_pydataobj.egg-info/not-zip-safe +0 -0
  70. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/legend_pydataobj.egg-info/requires.txt +0 -0
  71. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/legend_pydataobj.egg-info/top_level.txt +0 -0
  72. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/lgdo/compression/base.py +0 -0
  73. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/lgdo/compression/generic.py +0 -0
  74. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/lgdo/compression/radware.py +0 -0
  75. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/lgdo/compression/utils.py +0 -0
  76. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/lgdo/compression/varlen.py +0 -0
  77. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/lgdo/lgdo_utils.py +0 -0
  78. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/lgdo/types/lgdo.py +0 -0
  79. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/lgdo/types/scalar.py +0 -0
  80. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/src/lgdo/units.py +0 -0
  81. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/tests/compression/conftest.py +0 -0
  82. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/tests/compression/sigcompress/LDQTA_r117_20200110T105115Z_cal_geds_raw-0.dat +0 -0
  83. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/tests/compression/sigcompress/special-wf-clipped.dat +0 -0
  84. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/tests/compression/test_compression.py +0 -0
  85. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/tests/compression/test_radware_sigcompress.py +0 -0
  86. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/tests/compression/test_str2wfcodec.py +0 -0
  87. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/tests/compression/test_uleb128_zigzag_diff.py +0 -0
  88. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/tests/conftest.py +0 -0
  89. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/tests/lh5/test_lh5_iterator.py +0 -0
  90. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/tests/test_lgdo_utils.py +0 -0
  91. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/tests/types/test_arrayofequalsizedarrays.py +0 -0
  92. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/tests/types/test_encoded.py +0 -0
  93. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/tests/types/test_fixedsizearray.py +0 -0
  94. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/tests/types/test_representations.py +0 -0
  95. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/tests/types/test_scalar.py +0 -0
  96. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/tests/types/test_struct.py +0 -0
  97. {legend_pydataobj-1.5.0a5 → legend_pydataobj-1.6.0}/tests/types/test_waveformtable.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: legend_pydataobj
3
- Version: 1.5.0a5
3
+ Version: 1.6.0
4
4
  Summary: LEGEND Python Data Objects
5
5
  Author: The LEGEND Collaboration
6
6
  Maintainer: The LEGEND Collaboration
@@ -79,6 +79,7 @@ test = [
79
79
 
80
80
  [project.scripts]
81
81
  lh5ls = "lgdo.cli:lh5ls"
82
+ lh5concat = "lgdo.cli:lh5concat"
82
83
 
83
84
  [tool.setuptools]
84
85
  include-package-data = true
@@ -144,7 +145,6 @@ isort.required-imports = ["from __future__ import annotations"]
144
145
  "tests/**" = ["T20"]
145
146
  "noxfile.py" = ["T20"]
146
147
 
147
-
148
148
  [tool.pylint]
149
149
  py-version = "3.8"
150
150
  ignore-paths = [".*/_version.py"]
@@ -157,3 +157,14 @@ messages_control.disable = [
157
157
  "missing-module-docstring",
158
158
  "wrong-import-position",
159
159
  ]
160
+
161
+ [tool.pytest.ini_options]
162
+ minversion = "6.0"
163
+ addopts = ["-ra", "--showlocals", "--strict-markers", "--strict-config"]
164
+ xfail_strict = true
165
+ filterwarnings = ["error", 'ignore:\nPyarrow:DeprecationWarning']
166
+ log_cli_level = "info"
167
+ testpaths = "tests"
168
+
169
+ [tool.codespell]
170
+ ignore-words-list = "nd, unparseable, compiletime, crate"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: legend_pydataobj
3
- Version: 1.5.0a5
3
+ Version: 1.6.0
4
4
  Summary: LEGEND Python Data Objects
5
5
  Author: The LEGEND Collaboration
6
6
  Maintainer: The LEGEND Collaboration
@@ -23,10 +23,27 @@ src/lgdo/compression/radware.py
23
23
  src/lgdo/compression/utils.py
24
24
  src/lgdo/compression/varlen.py
25
25
  src/lgdo/lh5/__init__.py
26
+ src/lgdo/lh5/core.py
27
+ src/lgdo/lh5/datatype.py
28
+ src/lgdo/lh5/exceptions.py
26
29
  src/lgdo/lh5/iterator.py
27
30
  src/lgdo/lh5/store.py
28
31
  src/lgdo/lh5/tools.py
29
32
  src/lgdo/lh5/utils.py
33
+ src/lgdo/lh5/_serializers/__init__.py
34
+ src/lgdo/lh5/_serializers/read/__init__.py
35
+ src/lgdo/lh5/_serializers/read/array.py
36
+ src/lgdo/lh5/_serializers/read/composite.py
37
+ src/lgdo/lh5/_serializers/read/encoded.py
38
+ src/lgdo/lh5/_serializers/read/ndarray.py
39
+ src/lgdo/lh5/_serializers/read/scalar.py
40
+ src/lgdo/lh5/_serializers/read/utils.py
41
+ src/lgdo/lh5/_serializers/read/vector_of_vectors.py
42
+ src/lgdo/lh5/_serializers/write/__init__.py
43
+ src/lgdo/lh5/_serializers/write/array.py
44
+ src/lgdo/lh5/_serializers/write/composite.py
45
+ src/lgdo/lh5/_serializers/write/scalar.py
46
+ src/lgdo/lh5/_serializers/write/vector_of_vectors.py
30
47
  src/lgdo/types/__init__.py
31
48
  src/lgdo/types/array.py
32
49
  src/lgdo/types/arrayofequalsizedarrays.py
@@ -37,6 +54,7 @@ src/lgdo/types/scalar.py
37
54
  src/lgdo/types/struct.py
38
55
  src/lgdo/types/table.py
39
56
  src/lgdo/types/vectorofvectors.py
57
+ src/lgdo/types/vovutils.py
40
58
  src/lgdo/types/waveformtable.py
41
59
  tests/conftest.py
42
60
  tests/test_cli.py
@@ -48,9 +66,14 @@ tests/compression/test_str2wfcodec.py
48
66
  tests/compression/test_uleb128_zigzag_diff.py
49
67
  tests/compression/sigcompress/LDQTA_r117_20200110T105115Z_cal_geds_raw-0.dat
50
68
  tests/compression/sigcompress/special-wf-clipped.dat
69
+ tests/lh5/conftest.py
70
+ tests/lh5/test_core.py
71
+ tests/lh5/test_lh5_datatype.py
51
72
  tests/lh5/test_lh5_iterator.py
52
73
  tests/lh5/test_lh5_store.py
74
+ tests/lh5/test_lh5_tools.py
53
75
  tests/lh5/test_lh5_utils.py
76
+ tests/lh5/test_lh5_write.py
54
77
  tests/types/test_array.py
55
78
  tests/types/test_arrayofequalsizedarrays.py
56
79
  tests/types/test_encoded.py
@@ -61,4 +84,5 @@ tests/types/test_struct.py
61
84
  tests/types/test_table.py
62
85
  tests/types/test_table_eval.py
63
86
  tests/types/test_vectorofvectors.py
87
+ tests/types/test_vovutils.py
64
88
  tests/types/test_waveformtable.py
@@ -1,2 +1,3 @@
1
1
  [console_scripts]
2
+ lh5concat = lgdo.cli:lh5concat
2
3
  lh5ls = lgdo.cli:lh5ls
@@ -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__
@@ -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.0a5'
16
- __version_tuple__ = version_tuple = (1, 5, 0)
15
+ __version__ = version = '1.6.0'
16
+ __version_tuple__ = version_tuple = (1, 6, 0)
@@ -0,0 +1,289 @@
1
+ """legend-pydataobj's command line interface utilities."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import fnmatch
7
+ import logging
8
+ import sys
9
+
10
+ from . import Array, Table, VectorOfVectors, __version__, lh5
11
+ from . import logging as lgdogging # eheheh
12
+
13
+ log = logging.getLogger(__name__)
14
+
15
+
16
+ def lh5ls(args=None):
17
+ """:func:`.lh5.show` command line interface."""
18
+ parser = argparse.ArgumentParser(
19
+ prog="lh5ls", description="Inspect LEGEND HDF5 (LH5) file contents"
20
+ )
21
+
22
+ # global options
23
+ parser.add_argument(
24
+ "--version",
25
+ action="store_true",
26
+ help="""Print legend-pydataobj version and exit""",
27
+ )
28
+ parser.add_argument(
29
+ "--verbose",
30
+ "-v",
31
+ action="store_true",
32
+ help="""Increase the program verbosity""",
33
+ )
34
+ parser.add_argument(
35
+ "--debug",
36
+ action="store_true",
37
+ help="""Increase the program verbosity to maximum""",
38
+ )
39
+
40
+ parser.add_argument(
41
+ "lh5_file",
42
+ help="""Input LH5 file""",
43
+ )
44
+ parser.add_argument("lh5_group", nargs="?", help="""LH5 group.""", default="/")
45
+ parser.add_argument(
46
+ "--attributes", "-a", action="store_true", help="""Print HDF5 attributes too"""
47
+ )
48
+ parser.add_argument(
49
+ "--depth",
50
+ "-d",
51
+ type=int,
52
+ default=None,
53
+ help="""Maximum tree depth of groups to print""",
54
+ )
55
+
56
+ args = parser.parse_args(args)
57
+
58
+ if args.verbose:
59
+ lgdogging.setup(logging.DEBUG)
60
+ elif args.debug:
61
+ lgdogging.setup(logging.DEBUG, logging.root)
62
+ else:
63
+ lgdogging.setup()
64
+
65
+ if args.version:
66
+ print(__version__) # noqa: T201
67
+ sys.exit()
68
+
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
@@ -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
+ ]
@@ -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)