legend-pydataobj 1.5.0a1__py3-none-any.whl → 1.5.0a3__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.
- {legend_pydataobj-1.5.0a1.dist-info → legend_pydataobj-1.5.0a3.dist-info}/METADATA +1 -1
- {legend_pydataobj-1.5.0a1.dist-info → legend_pydataobj-1.5.0a3.dist-info}/RECORD +14 -14
- lgdo/_version.py +1 -1
- lgdo/cli.py +9 -3
- lgdo/lh5/store.py +25 -3
- lgdo/lh5_store.py +31 -0
- lgdo/types/arrayofequalsizedarrays.py +2 -0
- lgdo/types/struct.py +7 -1
- lgdo/types/table.py +98 -88
- lgdo/types/vectorofvectors.py +35 -21
- {legend_pydataobj-1.5.0a1.dist-info → legend_pydataobj-1.5.0a3.dist-info}/LICENSE +0 -0
- {legend_pydataobj-1.5.0a1.dist-info → legend_pydataobj-1.5.0a3.dist-info}/WHEEL +0 -0
- {legend_pydataobj-1.5.0a1.dist-info → legend_pydataobj-1.5.0a3.dist-info}/entry_points.txt +0 -0
- {legend_pydataobj-1.5.0a1.dist-info → legend_pydataobj-1.5.0a3.dist-info}/top_level.txt +0 -0
@@ -1,8 +1,8 @@
|
|
1
1
|
lgdo/__init__.py,sha256=NVIX9H7OvWq42cyDze1knd5Nzn4JnVsC4jrue9KDJDs,2878
|
2
|
-
lgdo/_version.py,sha256=
|
3
|
-
lgdo/cli.py,sha256=
|
2
|
+
lgdo/_version.py,sha256=Mog3Qr6q816oNESNv10fVvx3UitVasxa7LWRlekJWhs,413
|
3
|
+
lgdo/cli.py,sha256=SW82mGdx9oY-xtD9Dr6yBVSQoTLrUq29nQmgjcCiqBM,1602
|
4
4
|
lgdo/lgdo_utils.py,sha256=lO9ePOxAlSUNAslQLxptje18LhzDl55r9qRG69q1j8w,2546
|
5
|
-
lgdo/lh5_store.py,sha256=
|
5
|
+
lgdo/lh5_store.py,sha256=v5p0oG17Y7CKsD7ruTkFwr-M4L6-8GGHVIuLwMYn74o,7320
|
6
6
|
lgdo/logging.py,sha256=Nu3wgIoWN7cyUxuzPom5rMwFvTlBu8p8d9uONHDquRg,965
|
7
7
|
lgdo/units.py,sha256=nbJ0JTNqlhHUXiBXT3k6qhRpSfMk5_9yW7EeC0dhMuQ,151
|
8
8
|
lgdo/utils.py,sha256=MG594KOHhoTA0qAa7WkBrb3zjQHIlmkcpLosi5K6Fiw,4507
|
@@ -14,22 +14,22 @@ lgdo/compression/utils.py,sha256=YhxfJ_zvDu9I1BnjOsALR7SYbNohZNdm8HZ8IqTjd6w,106
|
|
14
14
|
lgdo/compression/varlen.py,sha256=PL6xRZL0oq5ViE5993_RKoKuOPz8mvjwCRV2LuIQ_HA,15089
|
15
15
|
lgdo/lh5/__init__.py,sha256=maNSqfdGQ5-kEUt2X2yVHqcSjPcQn-lSq3xnUhDAVJg,539
|
16
16
|
lgdo/lh5/iterator.py,sha256=ncLbMzfrLihfX9Xqi-CdSHbYofEgGwdc36rfwA0r2oc,12245
|
17
|
-
lgdo/lh5/store.py,sha256=
|
17
|
+
lgdo/lh5/store.py,sha256=jFid8PU3uTL-4QATACvCv8yr4msSWm6K61sVqF9Ku_E,62994
|
18
18
|
lgdo/lh5/utils.py,sha256=2fE85GFxZVlO7ypWFPrTZSzDTSiSiyTJqZIu_rrqtBI,3638
|
19
19
|
lgdo/types/__init__.py,sha256=1aqmN87_tu-NsSn-wbiKTauL2omSCcxUVC-BOlRpSUU,735
|
20
20
|
lgdo/types/array.py,sha256=PY3TL1FRQZho_87A2S78kxtDchO8e8sm7Ny1uwLeOYY,6618
|
21
|
-
lgdo/types/arrayofequalsizedarrays.py,sha256=
|
21
|
+
lgdo/types/arrayofequalsizedarrays.py,sha256=PJx-_OH9gHrRDWNA8_olB62UQQq2EAVjirh2JxnDRRw,4936
|
22
22
|
lgdo/types/encoded.py,sha256=M3XKv9ubbJO3X4A7UglYDLw0cjDOvRC1Tln7x_bwkYQ,15500
|
23
23
|
lgdo/types/fixedsizearray.py,sha256=0f9nFjMGpQFU9U1_DKKlXXeApc4xzQQV-KZ14C2zEow,1510
|
24
24
|
lgdo/types/lgdo.py,sha256=BTNbL2VrW-SBYdYRbWJ3-0XmIrvKJ2Rk1oJmhajW8Wc,2776
|
25
25
|
lgdo/types/scalar.py,sha256=TtzJIPlqflMoOj0uzyxu3Ucf3ugKf7IDwUE4jLQ8_IE,1872
|
26
|
-
lgdo/types/struct.py,sha256=
|
27
|
-
lgdo/types/table.py,sha256=
|
28
|
-
lgdo/types/vectorofvectors.py,sha256=
|
26
|
+
lgdo/types/struct.py,sha256=7UStGTR3JHlh6lTvAv3LG5HHMLqTxbkW8VrxmYs1PCA,4058
|
27
|
+
lgdo/types/table.py,sha256=itp_PLzT__wUCv9oy92xdHH5CjQGlZ9vUvrJmlrYUWY,15351
|
28
|
+
lgdo/types/vectorofvectors.py,sha256=SH5SobtpNrom9ZfWX0UEWtkheDxjY8XBUhJOOdxAn9o,28078
|
29
29
|
lgdo/types/waveformtable.py,sha256=d6ozsMkaLp9G6EqiDVC7NIFKpLOlzAn6REWuYnVeLyQ,9851
|
30
|
-
legend_pydataobj-1.5.
|
31
|
-
legend_pydataobj-1.5.
|
32
|
-
legend_pydataobj-1.5.
|
33
|
-
legend_pydataobj-1.5.
|
34
|
-
legend_pydataobj-1.5.
|
35
|
-
legend_pydataobj-1.5.
|
30
|
+
legend_pydataobj-1.5.0a3.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
31
|
+
legend_pydataobj-1.5.0a3.dist-info/METADATA,sha256=jg4hFoeTGa11AgsYdapjm6zi36Sh6xb5Y0tRuAp8BYQ,3663
|
32
|
+
legend_pydataobj-1.5.0a3.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
33
|
+
legend_pydataobj-1.5.0a3.dist-info/entry_points.txt,sha256=j22HoS-1cVhTtKJkDnKB49uNH0nEVER2Tpw-lVh1aws,41
|
34
|
+
legend_pydataobj-1.5.0a3.dist-info/top_level.txt,sha256=KyR-EUloqiXcQ62IWnzBmtInDtvsHl4q2ZJAZgTcLXE,5
|
35
|
+
legend_pydataobj-1.5.0a3.dist-info/RECORD,,
|
lgdo/_version.py
CHANGED
lgdo/cli.py
CHANGED
@@ -5,7 +5,7 @@ import sys
|
|
5
5
|
|
6
6
|
import lgdo
|
7
7
|
import lgdo.logging
|
8
|
-
from lgdo import show
|
8
|
+
from lgdo.lh5 import show
|
9
9
|
|
10
10
|
|
11
11
|
def lh5ls():
|
@@ -26,7 +26,6 @@ def lh5ls():
|
|
26
26
|
)
|
27
27
|
parser.add_argument(
|
28
28
|
"--debug",
|
29
|
-
"-d",
|
30
29
|
action="store_true",
|
31
30
|
help="""Increase the program verbosity to maximum""",
|
32
31
|
)
|
@@ -39,6 +38,13 @@ def lh5ls():
|
|
39
38
|
parser.add_argument(
|
40
39
|
"--attributes", "-a", action="store_true", help="""Print HDF5 attributes too"""
|
41
40
|
)
|
41
|
+
parser.add_argument(
|
42
|
+
"--depth",
|
43
|
+
"-d",
|
44
|
+
type=int,
|
45
|
+
default=None,
|
46
|
+
help="""Maximum tree depth of groups to print""",
|
47
|
+
)
|
42
48
|
|
43
49
|
args = parser.parse_args()
|
44
50
|
|
@@ -53,4 +59,4 @@ def lh5ls():
|
|
53
59
|
print(lgdo.__version__) # noqa: T201
|
54
60
|
sys.exit()
|
55
61
|
|
56
|
-
show(args.lh5_file, args.lh5_group, attrs=args.attributes)
|
62
|
+
show(args.lh5_file, args.lh5_group, attrs=args.attributes, depth=args.depth)
|
lgdo/lh5/store.py
CHANGED
@@ -12,6 +12,7 @@ import sys
|
|
12
12
|
from bisect import bisect_left
|
13
13
|
from collections import defaultdict
|
14
14
|
from typing import Any, Union
|
15
|
+
from warnings import warn
|
15
16
|
|
16
17
|
import h5py
|
17
18
|
import numba as nb
|
@@ -347,9 +348,7 @@ class LH5Store:
|
|
347
348
|
default = not field_mask[list(field_mask.keys())[0]]
|
348
349
|
field_mask = defaultdict(lambda: default, field_mask)
|
349
350
|
elif isinstance(field_mask, (list, tuple)):
|
350
|
-
field_mask = defaultdict(
|
351
|
-
lambda: False, {field: True for field in field_mask}
|
352
|
-
)
|
351
|
+
field_mask = defaultdict(bool, {field: True for field in field_mask})
|
353
352
|
elif not isinstance(field_mask, defaultdict):
|
354
353
|
raise RuntimeError("bad field_mask of type", type(field_mask).__name__)
|
355
354
|
elif field_mask is not None:
|
@@ -1337,6 +1336,7 @@ def show(
|
|
1337
1336
|
attrs: bool = False,
|
1338
1337
|
indent: str = "",
|
1339
1338
|
header: bool = True,
|
1339
|
+
depth: int | None = None,
|
1340
1340
|
) -> None:
|
1341
1341
|
"""Print a tree of LH5 file contents with LGDO datatype.
|
1342
1342
|
|
@@ -1352,6 +1352,8 @@ def show(
|
|
1352
1352
|
indent the diagram with this string.
|
1353
1353
|
header
|
1354
1354
|
print `lh5_group` at the top of the diagram.
|
1355
|
+
depth
|
1356
|
+
maximum tree depth of groups to print
|
1355
1357
|
|
1356
1358
|
Examples
|
1357
1359
|
--------
|
@@ -1367,6 +1369,10 @@ def show(
|
|
1367
1369
|
│ └── values · array_of_equalsized_arrays<1,1>{real}
|
1368
1370
|
└── wf_std · array<1>{real}
|
1369
1371
|
"""
|
1372
|
+
# check tree depth if we are using it
|
1373
|
+
if depth is not None and depth <= 0:
|
1374
|
+
return
|
1375
|
+
|
1370
1376
|
# open file
|
1371
1377
|
if isinstance(lh5_file, str):
|
1372
1378
|
lh5_file = h5py.File(expand_path(lh5_file), "r")
|
@@ -1422,6 +1428,7 @@ def show(
|
|
1422
1428
|
indent=indent + (" " if killme else "│ "),
|
1423
1429
|
header=False,
|
1424
1430
|
attrs=attrs,
|
1431
|
+
depth=depth - 1 if depth else None,
|
1425
1432
|
)
|
1426
1433
|
|
1427
1434
|
# break or move to next key
|
@@ -1461,6 +1468,14 @@ def load_nda(
|
|
1461
1468
|
Each entry contains the data for the specified parameter concatenated
|
1462
1469
|
over all files in `f_list`.
|
1463
1470
|
"""
|
1471
|
+
warn(
|
1472
|
+
"load_nda() is deprecated. "
|
1473
|
+
"Please replace it with LH5Store.read(...).view_as('np'). "
|
1474
|
+
"load_nda() will be removed in a future release.",
|
1475
|
+
DeprecationWarning,
|
1476
|
+
stacklevel=2,
|
1477
|
+
)
|
1478
|
+
|
1464
1479
|
if isinstance(f_list, str):
|
1465
1480
|
f_list = [f_list]
|
1466
1481
|
if idx_list is not None:
|
@@ -1515,6 +1530,13 @@ def load_dfs(
|
|
1515
1530
|
all data for the associated parameters concatenated over all files in
|
1516
1531
|
`f_list`.
|
1517
1532
|
"""
|
1533
|
+
warn(
|
1534
|
+
"load_dfs() is deprecated. "
|
1535
|
+
"Please replace it with LH5Store.read(...).view_as('pd'). "
|
1536
|
+
"load_dfs() will be removed in a future release.",
|
1537
|
+
DeprecationWarning,
|
1538
|
+
stacklevel=2,
|
1539
|
+
)
|
1518
1540
|
return pd.DataFrame(
|
1519
1541
|
load_nda(f_list, par_list, lh5_group=lh5_group, idx_list=idx_list)
|
1520
1542
|
)
|
lgdo/lh5_store.py
CHANGED
@@ -131,6 +131,37 @@ class LH5Store(lh5.LH5Store):
|
|
131
131
|
)
|
132
132
|
super().__init__(base_path, keep_open)
|
133
133
|
|
134
|
+
def read_object(
|
135
|
+
self,
|
136
|
+
name: str,
|
137
|
+
lh5_file: str | h5py.File | list[str | h5py.File],
|
138
|
+
**kwargs,
|
139
|
+
) -> tuple[LGDO, int]:
|
140
|
+
warn(
|
141
|
+
"LH5Store.read_object() has been renamed to LH5Store.read(), "
|
142
|
+
"Please update your code."
|
143
|
+
"LH5Store.read_object() will be removed in a future release.",
|
144
|
+
DeprecationWarning,
|
145
|
+
stacklevel=2,
|
146
|
+
)
|
147
|
+
return super().read(self, name, lh5_file, **kwargs)
|
148
|
+
|
149
|
+
def write_object(
|
150
|
+
self,
|
151
|
+
obj: LGDO,
|
152
|
+
name: str,
|
153
|
+
lh5_file: str | h5py.File,
|
154
|
+
**kwargs,
|
155
|
+
) -> tuple[LGDO, int]:
|
156
|
+
warn(
|
157
|
+
"LH5Store.write_object() has been renamed to LH5Store.write(), "
|
158
|
+
"Please update your code."
|
159
|
+
"LH5Store.write_object() will be removed in a future release.",
|
160
|
+
DeprecationWarning,
|
161
|
+
stacklevel=2,
|
162
|
+
)
|
163
|
+
return super().read(self, obj, name, lh5_file, **kwargs)
|
164
|
+
|
134
165
|
|
135
166
|
def load_dfs(
|
136
167
|
f_list: str | list[str],
|
lgdo/types/struct.py
CHANGED
@@ -60,7 +60,13 @@ class Struct(LGDO, dict):
|
|
60
60
|
return self.add_field(name, obj)
|
61
61
|
|
62
62
|
def __getattr__(self, name: str) -> LGDO:
|
63
|
-
|
63
|
+
if hasattr(super(), name):
|
64
|
+
return super().__getattr__(name)
|
65
|
+
|
66
|
+
if name in self.keys():
|
67
|
+
return super().__getitem__(name)
|
68
|
+
|
69
|
+
raise AttributeError(name)
|
64
70
|
|
65
71
|
def remove_field(self, name: str | int, delete: bool = False) -> None:
|
66
72
|
"""Remove a field from the table.
|
lgdo/types/table.py
CHANGED
@@ -5,8 +5,7 @@ equal length and corresponding utilities.
|
|
5
5
|
from __future__ import annotations
|
6
6
|
|
7
7
|
import logging
|
8
|
-
import
|
9
|
-
from typing import Any
|
8
|
+
from typing import Any, Mapping
|
10
9
|
from warnings import warn
|
11
10
|
|
12
11
|
import awkward as ak
|
@@ -18,6 +17,7 @@ from pandas.io.formats import format as fmt
|
|
18
17
|
from .array import Array
|
19
18
|
from .arrayofequalsizedarrays import ArrayOfEqualSizedArrays
|
20
19
|
from .lgdo import LGDO
|
20
|
+
from .scalar import Scalar
|
21
21
|
from .struct import Struct
|
22
22
|
from .vectorofvectors import VectorOfVectors
|
23
23
|
|
@@ -38,8 +38,6 @@ class Table(Struct):
|
|
38
38
|
:meth:`__len__` to access valid data, which returns the ``size`` attribute.
|
39
39
|
"""
|
40
40
|
|
41
|
-
# TODO: overload getattr to allow access to fields as object attributes?
|
42
|
-
|
43
41
|
def __init__(
|
44
42
|
self,
|
45
43
|
size: int = None,
|
@@ -217,102 +215,114 @@ class Table(Struct):
|
|
217
215
|
)
|
218
216
|
return self.view_as(library="pd", cols=cols, prefix=prefix)
|
219
217
|
|
220
|
-
def eval(
|
221
|
-
|
222
|
-
|
218
|
+
def eval(
|
219
|
+
self,
|
220
|
+
expr: str,
|
221
|
+
parameters: Mapping[str, str] = None,
|
222
|
+
) -> LGDO:
|
223
|
+
"""Apply column operations to the table and return a new LGDO.
|
223
224
|
|
224
|
-
|
225
|
-
|
225
|
+
Internally uses :func:`numexpr.evaluate` if dealing with columns
|
226
|
+
representable as NumPy arrays or :func:`eval` if
|
227
|
+
:class:`.VectorOfVectors` are involved. In the latter case, the VoV
|
228
|
+
columns are viewed as :class:`ak.Array` and the respective routines are
|
229
|
+
therefore available.
|
226
230
|
|
227
231
|
Parameters
|
228
232
|
----------
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
-------
|
262
|
-
Blocks in `expr_config` must be ordered according to mutual dependency.
|
233
|
+
expr
|
234
|
+
if the expression only involves non-:class:`.VectorOfVectors`
|
235
|
+
columns, the syntax is the one supported by
|
236
|
+
:func:`numexpr.evaluate` (see `here
|
237
|
+
<https://numexpr.readthedocs.io/projects/NumExpr3/en/latest/index.html>`_
|
238
|
+
for documentation). Note: because of internal limitations,
|
239
|
+
reduction operations must appear the last in the stack. If at least
|
240
|
+
one considered column is a :class:`.VectorOfVectors`, plain
|
241
|
+
:func:`eval` is used and :class:`ak.Array` transforms can be used
|
242
|
+
through the ``ak.`` prefix. (NumPy functions are analogously
|
243
|
+
accessible through ``np.``). See also examples below.
|
244
|
+
parameters
|
245
|
+
a dictionary of function parameters. Passed to
|
246
|
+
:func:`numexpr.evaluate`` as `local_dict` argument or to
|
247
|
+
:func:`eval` as `locals` argument.
|
248
|
+
|
249
|
+
Examples
|
250
|
+
--------
|
251
|
+
>>> import lgdo
|
252
|
+
>>> tbl = lgdo.Table(
|
253
|
+
... col_dict={
|
254
|
+
... "a": lgdo.Array([1, 2, 3]),
|
255
|
+
... "b": lgdo.VectorOfVectors([[5], [6, 7], [8, 9, 0]]),
|
256
|
+
... }
|
257
|
+
... )
|
258
|
+
>>> print(tbl.eval("a + b"))
|
259
|
+
[[6],
|
260
|
+
[8 9],
|
261
|
+
[11 12 3],
|
262
|
+
]
|
263
|
+
>>> print(tbl.eval("np.sum(a) + ak.sum(b)"))
|
264
|
+
41
|
263
265
|
"""
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
266
|
+
if parameters is None:
|
267
|
+
parameters = {}
|
268
|
+
|
269
|
+
# get the valid python variable names in the expression
|
270
|
+
c = compile(expr, "0vbb is real!", "eval")
|
271
|
+
|
272
|
+
# make a dictionary of low-level objects (numpy or awkward)
|
273
|
+
# for later computation
|
274
|
+
self_unwrap = {}
|
275
|
+
has_ak = False
|
276
|
+
for obj in c.co_names:
|
277
|
+
if obj in self.keys():
|
278
|
+
if isinstance(self[obj], VectorOfVectors):
|
279
|
+
self_unwrap[obj] = self[obj].view_as("ak", with_units=False)
|
280
|
+
has_ak = True
|
277
281
|
else:
|
278
|
-
|
279
|
-
# get the nda if it is an Array instance
|
280
|
-
if isinstance(in_vars[elem], Array):
|
281
|
-
in_vars[elem] = in_vars[elem].nda
|
282
|
-
# No vector of vectors support yet
|
283
|
-
elif isinstance(in_vars[elem], VectorOfVectors):
|
284
|
-
raise TypeError("Data of type VectorOfVectors not supported (yet)")
|
282
|
+
self_unwrap[obj] = self[obj].view_as("np", with_units=False)
|
285
283
|
|
284
|
+
# use numexpr if we are only dealing with numpy data types
|
285
|
+
if not has_ak:
|
286
286
|
out_data = ne.evaluate(
|
287
|
-
|
288
|
-
local_dict=
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
# out_data has scalar in each row
|
300
|
-
elif len(np.shape(out_data)) == 1:
|
301
|
-
out_data = Array(nda=out_data)
|
302
|
-
|
303
|
-
# out_data is like
|
304
|
-
elif len(np.shape(out_data)) == 2:
|
305
|
-
out_data = ArrayOfEqualSizedArrays(nda=out_data)
|
306
|
-
|
307
|
-
# higher order data (eg matrix product of ArrayOfEqualSizedArrays) not supported yet
|
287
|
+
expr,
|
288
|
+
local_dict=(self_unwrap | parameters),
|
289
|
+
)
|
290
|
+
|
291
|
+
# need to convert back to LGDO
|
292
|
+
# np.evaluate should always return a numpy thing?
|
293
|
+
if out_data.ndim == 0:
|
294
|
+
return Scalar(out_data.item())
|
295
|
+
elif out_data.ndim == 1:
|
296
|
+
return Array(out_data)
|
297
|
+
elif out_data.ndim == 2:
|
298
|
+
return ArrayOfEqualSizedArrays(nda=out_data)
|
308
299
|
else:
|
309
|
-
|
310
|
-
f"
|
300
|
+
msg = (
|
301
|
+
f"evaluation resulted in {out_data.ndim}-dimensional data, "
|
302
|
+
"I don't know which LGDO this corresponds to"
|
311
303
|
)
|
304
|
+
raise RuntimeError(msg)
|
312
305
|
|
313
|
-
|
306
|
+
else:
|
307
|
+
# resort to good ol' eval()
|
308
|
+
globs = {"ak": ak, "np": np}
|
309
|
+
out_data = eval(expr, globs, (self_unwrap | parameters))
|
310
|
+
|
311
|
+
# need to convert back to LGDO
|
312
|
+
if isinstance(out_data, ak.Array):
|
313
|
+
if out_data.ndim == 1:
|
314
|
+
return Array(out_data.to_numpy())
|
315
|
+
else:
|
316
|
+
return VectorOfVectors(out_data)
|
314
317
|
|
315
|
-
|
318
|
+
if np.isscalar(out_data):
|
319
|
+
return Scalar(out_data)
|
320
|
+
else:
|
321
|
+
msg = (
|
322
|
+
f"evaluation resulted in a {type(out_data)} object, "
|
323
|
+
"I don't know which LGDO this corresponds to"
|
324
|
+
)
|
325
|
+
raise RuntimeError(msg)
|
316
326
|
|
317
327
|
def __str__(self):
|
318
328
|
opts = fmt.get_dataframe_repr_params()
|
lgdo/types/vectorofvectors.py
CHANGED
@@ -35,7 +35,7 @@ class VectorOfVectors(LGDO):
|
|
35
35
|
|
36
36
|
def __init__(
|
37
37
|
self,
|
38
|
-
|
38
|
+
array: ak.Array | list[list[int | float]] = None,
|
39
39
|
flattened_data: Array | NDArray = None,
|
40
40
|
cumulative_length: Array | NDArray = None,
|
41
41
|
shape_guess: tuple[int, int] = None,
|
@@ -46,9 +46,10 @@ class VectorOfVectors(LGDO):
|
|
46
46
|
"""
|
47
47
|
Parameters
|
48
48
|
----------
|
49
|
-
|
50
|
-
create a VectorOfVectors out of a Python list of lists
|
51
|
-
priority over `flattened_data` and
|
49
|
+
array
|
50
|
+
create a ``VectorOfVectors`` out of a Python list of lists or an
|
51
|
+
:class:`ak.Array`. Takes priority over `flattened_data` and
|
52
|
+
`cumulative_length`.
|
52
53
|
flattened_data
|
53
54
|
if not ``None``, used as the internal array for
|
54
55
|
`self.flattened_data`. Otherwise, an internal `flattened_data` is
|
@@ -67,30 +68,43 @@ class VectorOfVectors(LGDO):
|
|
67
68
|
of `flattened_data` if it was not supplied.
|
68
69
|
dtype
|
69
70
|
sets the type of data stored in `flattened_data`. Required if
|
70
|
-
`flattened_data` and `
|
71
|
+
`flattened_data` and `array` are ``None``.
|
71
72
|
fill_val
|
72
73
|
fill all of `self.flattened_data` with this value.
|
73
74
|
attrs
|
74
75
|
a set of user attributes to be carried along with this LGDO.
|
75
76
|
"""
|
76
|
-
if
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
# Find it efficiently, allowing for zero-length lists as some of the entries
|
84
|
-
first_element = next(itertools.chain.from_iterable(listoflists))
|
85
|
-
dtype = type(first_element)
|
77
|
+
if array is not None:
|
78
|
+
if isinstance(array, ak.Array):
|
79
|
+
if array.ndim != 2:
|
80
|
+
raise ValueError(
|
81
|
+
"cannot initialize a VectorOfVectors with "
|
82
|
+
f"{array.ndim}-dimensional data"
|
83
|
+
)
|
86
84
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
85
|
+
form, length, container = ak.to_buffers(array)
|
86
|
+
|
87
|
+
return self.__init__(
|
88
|
+
flattened_data=container["node1-data"],
|
89
|
+
cumulative_length=container["node0-offsets"][1:],
|
90
|
+
)
|
91
|
+
|
92
|
+
else:
|
93
|
+
cl_nda = np.cumsum([len(ll) for ll in array])
|
94
|
+
if dtype is None:
|
95
|
+
if len(cl_nda) == 0 or cl_nda[-1] == 0:
|
96
|
+
raise ValueError("array can't be empty with dtype=None!")
|
97
|
+
else:
|
98
|
+
# Set dtype from the first element in the list
|
99
|
+
# Find it efficiently, allowing for zero-length lists as some of the entries
|
100
|
+
first_element = next(itertools.chain.from_iterable(array))
|
101
|
+
dtype = type(first_element)
|
102
|
+
|
103
|
+
self.dtype = np.dtype(dtype)
|
104
|
+
self.cumulative_length = Array(cl_nda)
|
105
|
+
self.flattened_data = Array(
|
106
|
+
np.fromiter(itertools.chain.from_iterable(array), dtype=self.dtype)
|
92
107
|
)
|
93
|
-
)
|
94
108
|
|
95
109
|
else:
|
96
110
|
if cumulative_length is None:
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|