Skip to content

Commit fc6450f

Browse files
authored
Merge pull request #106 from ManuelHu/histogram-fixes
histogram: restrict more error messages to when they are necessary
2 parents cd78184 + da6747d commit fc6450f

File tree

4 files changed

+44
-9
lines changed

4 files changed

+44
-9
lines changed

src/lgdo/lh5/_serializers/write/composite.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,12 @@ def _h5_write_lgdo(
7070

7171
# struct, table, waveform table or histogram.
7272
if isinstance(obj, types.Struct):
73-
if isinstance(obj, types.Histogram) and wo_mode not in ["w", "o", "of"]:
74-
msg = f"can't append-write histogram in wo_mode '{wo_mode}'"
73+
if (
74+
isinstance(obj, types.Histogram)
75+
and wo_mode not in ["w", "o", "of"]
76+
and name in group
77+
):
78+
msg = f"can't append-write to histogram in wo_mode '{wo_mode}'"
7579
raise LH5EncodeError(msg, lh5_file, group, name)
7680
if isinstance(obj, types.Histogram) and write_start != 0:
7781
msg = f"can't write histogram in wo_mode '{wo_mode}' with write_start != 0"

src/lgdo/types/histogram.py

+18-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import logging
34
from collections.abc import Iterable
45
from typing import Any
56

@@ -12,6 +13,8 @@
1213
from .scalar import Scalar
1314
from .struct import Struct
1415

16+
log = logging.getLogger(__name__)
17+
1518

1619
class Histogram(Struct):
1720
class Axis(Struct):
@@ -197,6 +200,7 @@ def __init__(
197200
isdensity: bool = False,
198201
attrs: dict[str, Any] | None = None,
199202
binedge_attrs: dict[str, Any] | None = None,
203+
flow: bool = True,
200204
) -> None:
201205
"""A special struct to contain histogrammed data.
202206
@@ -221,6 +225,16 @@ def __init__(
221225
as binning.
222226
attrs
223227
a set of user attributes to be carried along with this LGDO.
228+
flow
229+
If ``False``, discard counts in over-/underflow bins of the passed
230+
:class:`hist.Hist` instance. If ``True``, this data will also be discarded,
231+
but a warning is emitted.
232+
233+
.. note ::
234+
235+
:class:`Histogram` does not support storing counts in overflow or
236+
underflow bins. This parameter just controls, whether a warning will
237+
be emitted.
224238
"""
225239
if isinstance(weights, hist.Hist):
226240
if binning is not None:
@@ -230,9 +244,10 @@ def __init__(
230244
msg = "not allowed to pass isdensity=True if constructing from hist.Hist instance"
231245
raise ValueError(msg)
232246

233-
if weights.sum(flow=True) != weights.sum(flow=False):
234-
msg = "flow bins of hist.Hist cannot be represented"
235-
raise ValueError(msg)
247+
if weights.sum(flow=True) != weights.sum(flow=False) and flow:
248+
log.warning(
249+
"flow bins of hist.Hist cannot be represented, their counts are discarded"
250+
)
236251
weights_view = weights.view(flow=False)
237252
if type(weights_view) is not np.ndarray:
238253
msg = "only simple numpy-backed storages can be used in a hist.Hist"

tests/lh5/test_lh5_write.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -414,13 +414,23 @@ def test_write_histogram(caplog, tmptestdir):
414414

415415
# Same field name, different values
416416
store = lh5.LH5Store()
417+
# "appending" to a non-existing histogram should work.
417418
store.write(
418419
h1,
419420
"my_histogram",
420421
f"{tmptestdir}/write_histogram_test.lh5",
421422
group="my_group",
422-
wo_mode="write_safe",
423+
wo_mode="append",
423424
)
425+
with pytest.raises(lh5.exceptions.LH5EncodeError):
426+
# appending to an existing histogram should not work.
427+
store.write(
428+
h1,
429+
"my_histogram",
430+
f"{tmptestdir}/write_histogram_test.lh5",
431+
group="my_group",
432+
wo_mode="append",
433+
)
424434
store.write(
425435
h2,
426436
"my_histogram",

tests/types/test_histogram.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from __future__ import annotations
22

3+
import logging
4+
35
import hist
46
import numpy as np
57
import pytest
@@ -8,7 +10,9 @@
810
from lgdo.lh5.exceptions import LH5DecodeError
911

1012

11-
def test_init_hist_regular():
13+
def test_init_hist_regular(caplog):
14+
caplog.set_level(logging.WARNING)
15+
1216
h = hist.Hist(
1317
hist.axis.Regular(bins=10, start=0, stop=1, name="x"),
1418
hist.axis.Regular(bins=10, start=0, stop=1, name="y"),
@@ -34,8 +38,10 @@ def test_init_hist_regular():
3438
Histogram(h, binning=(np.array([0, 1, 2]),))
3539

3640
h.fill([-1, 0.8, 2])
37-
with pytest.raises(ValueError, match="flow bins"):
38-
Histogram(h)
41+
caplog.clear()
42+
Histogram(h)
43+
assert "flow bins" in caplog.text
44+
caplog.clear()
3945

4046
# assert that the hist data is not copied into the LGDO.
4147
h = hist.Hist(hist.axis.Regular(bins=10, start=0, stop=10))

0 commit comments

Comments
 (0)