Skip to content

Commit 989700a

Browse files
committed
refactor: streamline histogram processing and enhance readability in backend and test files
1 parent 8f2afb9 commit 989700a

3 files changed

Lines changed: 25 additions & 61 deletions

File tree

src/khisto/core/backend.py

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -176,32 +176,18 @@ def _process_histogram_files(temp_dir: str, base_name: str) -> list[HistogramRes
176176
khisto_output: _KhistoOutput = _KhistoOutput.from_dict(json.load(f))
177177

178178
histogram_series = khisto_output.histogramSeries
179-
n = len(histogram_series.histograms)
180179
best_idx = histogram_series.interpretableHistogramNumber - 1
181-
granularities = (
182-
histogram_series.granularities
183-
if len(histogram_series.granularities) == n
184-
else list(range(n))
185-
)
186-
187-
def _get(lst: list, i: int):
188-
if i < len(lst):
189-
return lst[i]
190-
else:
191-
raise ValueError(
192-
f"Expected at least {i + 1} values in list, got {len(lst)}"
193-
)
194180

195181
return [
196182
_to_result(
197183
h,
198184
is_best=(i == best_idx),
199-
granularity=granularities[i],
200-
level=_get(histogram_series.levels, i),
201-
information_rate=_get(histogram_series.informationRates, i),
202-
peak_interval_number=_get(histogram_series.peakIntervalNumbers, i),
203-
spike_interval_number=_get(histogram_series.spikeIntervalNumbers, i),
204-
empty_interval_number=_get(histogram_series.emptyIntervalNumbers, i),
185+
granularity=histogram_series.granularities[i],
186+
level=histogram_series.levels[i],
187+
information_rate=histogram_series.informationRates[i],
188+
peak_interval_number=histogram_series.peakIntervalNumbers[i],
189+
spike_interval_number=histogram_series.spikeIntervalNumbers[i],
190+
empty_interval_number=histogram_series.emptyIntervalNumbers[i],
205191
)
206192
for i, h in enumerate(histogram_series.histograms)
207193
]

src/khisto/matplotlib/hist.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,9 @@
1414
from matplotlib.axes import Axes
1515

1616
from khisto.array import histogram as khisto_histogram
17-
from khisto.array.histogram.api import _apply_cumulative
1817

1918
if TYPE_CHECKING:
20-
from numpy.typing import ArrayLike
19+
from numpy.typing import ArrayLike, NDArray
2120

2221

2322
def _normalize_cumulative(cumulative: bool | float) -> int:
@@ -33,6 +32,24 @@ def _normalize_cumulative(cumulative: bool | float) -> int:
3332
raise TypeError("cumulative must be a boolean or a number")
3433

3534

35+
def _apply_cumulative(
36+
hist_values: NDArray[np.float64],
37+
bin_edges: NDArray[np.float64],
38+
*,
39+
density: bool,
40+
reverse: bool = False,
41+
) -> NDArray[np.float64]:
42+
"""Accumulate histogram values using matplotlib-compatible semantics."""
43+
if density:
44+
source_values = hist_values * np.diff(bin_edges)
45+
else:
46+
source_values = hist_values
47+
48+
if reverse:
49+
return np.cumsum(source_values[::-1])[::-1]
50+
return np.cumsum(source_values)
51+
52+
3653
def hist(
3754
x: ArrayLike,
3855
range: Optional[tuple[float, float]] = None,

tests/core/test_backend.py

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -274,42 +274,3 @@ def test_series_keeps_finest_histogram_when_all_interpretable(self, tmp_path):
274274

275275
assert len(results) == 2
276276
assert [result.is_best for result in results] == [False, True]
277-
278-
def test_best_histogram_is_fallback_without_series(self, tmp_path):
279-
"""Test that bestHistogram remains the fallback when the series is absent."""
280-
payload = {
281-
"tool": "Khiops Histogram",
282-
"version": "1.1",
283-
"bestHistogram": _histogram_payload([0.0, 1.0], [1.0, 3.0], [1, 2]),
284-
}
285-
self._write_json(tmp_path / "histogram.series.json", payload)
286-
287-
results = _process_histogram_files(str(tmp_path), "histogram.series")
288-
289-
assert len(results) == 1
290-
assert results[0].is_best is True
291-
assert results[0].granularity == 0
292-
293-
def test_best_histogram_is_fallback_when_series_best_index_is_missing(
294-
self, tmp_path
295-
):
296-
"""Test that bestHistogram matching is used when series metadata is incomplete."""
297-
payload = {
298-
"tool": "Khiops Histogram",
299-
"version": "1.1",
300-
"bestHistogram": _histogram_payload([0.0, 1.0], [1.0, 3.0], [1, 2]),
301-
"histogramSeries": {
302-
"histogramNumber": 2,
303-
"granularities": [0, 2],
304-
"histograms": [
305-
_histogram_payload([0.0], [3.0], [3]),
306-
_histogram_payload([0.0, 1.0], [1.0, 3.0], [1, 2]),
307-
],
308-
},
309-
}
310-
self._write_json(tmp_path / "histogram.series.json", payload)
311-
312-
results = _process_histogram_files(str(tmp_path), "histogram.series")
313-
314-
assert len(results) == 2
315-
assert [result.is_best for result in results] == [False, True]

0 commit comments

Comments
 (0)