From e929fe26d361eaea88acb77125a30fa28c2173b5 Mon Sep 17 00:00:00 2001 From: Jay Gohil Date: Thu, 23 Jun 2022 19:04:49 -0400 Subject: [PATCH 01/12] Update BoostHistogramHandsOn.ipynb --- notebooks/BoostHistogramHandsOn.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notebooks/BoostHistogramHandsOn.ipynb b/notebooks/BoostHistogramHandsOn.ipynb index 62c9ebe0..fd83aa96 100644 --- a/notebooks/BoostHistogramHandsOn.ipynb +++ b/notebooks/BoostHistogramHandsOn.ipynb @@ -452,7 +452,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "This is transposed because [`pcolormesh` expects it](https://matplotlib.org/3.2.2/api/_as_gen/matplotlib.pyplot.pcolormesh.html#axes-pcolormesh-grid-orientation)." + "This is transposed because `pcolormesh` [expects it](https://matplotlib.org/3.2.2/api/_as_gen/matplotlib.pyplot.pcolormesh.html#axes-pcolormesh-grid-orientation)." ] }, { From 7d8252a6eb2eba7e47891635a8db47f7ea8b0e21 Mon Sep 17 00:00:00 2001 From: Jay Gohil Date: Mon, 27 Jun 2022 17:52:54 -0400 Subject: [PATCH 02/12] Updated all numpy.testing asserts to pytest.approx --- tests/test_pickle.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/tests/test_pickle.py b/tests/test_pickle.py index a898d0e4..c79b2afa 100644 --- a/tests/test_pickle.py +++ b/tests/test_pickle.py @@ -2,12 +2,10 @@ import ctypes import math import platform +from pytest import approx from pickle import dumps, loads - import numpy as np import pytest -from numpy.testing import assert_almost_equal, assert_array_equal - import boost_histogram as bh ftype = ctypes.CFUNCTYPE(ctypes.c_double, ctypes.c_double) @@ -86,7 +84,7 @@ def test_axes(axis, args, opts, copy_fn): orig = axis(*args, **opts) new = copy_fn(orig) assert new == orig - np.testing.assert_array_equal(new.centers, orig.centers) + assert new.centers == approx(orig.centers) @pytest.mark.parametrize("axis,args,opts", axes_creations) @@ -97,7 +95,7 @@ def test_metadata_str(axis, args, opts, copy_fn): assert new.metadata == orig.metadata new.metadata = orig.metadata assert new == orig - np.testing.assert_array_equal(new.centers, orig.centers) + assert new.centers == approx(orig.centers) # Special test: Deepcopy should change metadata id, copy should not @@ -162,7 +160,7 @@ def test_storage(benchmark, copy_fn, storage, extra): hist.fill(x, weight=np.arange(2 * n + 4) + 1, sample=np.arange(2 * n + 4) + 1) new = benchmark(copy_fn, hist) - assert_array_equal(hist.view(True), new.view(True)) + assert hist.view(True) == approx(new.view(True)) assert new == hist @@ -213,8 +211,8 @@ def test_pickle_transforms(mod, copy_fn): ax3 = bh.axis.Regular(100, 1, 100, transform=bh.axis.transform.log) assert ax1 == ax2 - assert_array_equal(ax1.centers, ax2.centers) - assert_almost_equal(ax2.centers, ax3.centers, decimal=10) + assert ax1.centers == approx(ax2.centers) + assert ax2.centers == approx(ax3.centers) def test_hist_axes_reference(copy_fn): From a063d371c10f7d2584b2d018023831bdc47a8fe1 Mon Sep 17 00:00:00 2001 From: Jay Gohil Date: Mon, 27 Jun 2022 17:54:06 -0400 Subject: [PATCH 03/12] Updated all numpy.testing asserts to pytest.approx --- tests/test_numpy_interface.py | 58 +++++++++++++++++------------------ 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/tests/test_numpy_interface.py b/tests/test_numpy_interface.py index da0a6eea..a4b5958f 100644 --- a/tests/test_numpy_interface.py +++ b/tests/test_numpy_interface.py @@ -1,9 +1,7 @@ import copy - import numpy as np import pytest from pytest import approx - import boost_histogram as bh np113 = tuple(int(x) for x in np.__version__.split(".")[:2]) >= (1, 13) @@ -46,8 +44,8 @@ def test_histogram1d(a, opt): h1, e1 = np.histogram(v, **opt) h2, e2 = bh.numpy.histogram(v, **opt) - np.testing.assert_array_almost_equal(e1, e2) - np.testing.assert_array_equal(h1, h2) + assert e1 == approx(e2) + assert h1 == approx(h2) opt = copy.deepcopy(opt) opt["density"] = True @@ -55,8 +53,8 @@ def test_histogram1d(a, opt): h1, e1 = np.histogram(v, **opt) h2, e2 = bh.numpy.histogram(v, **opt) - np.testing.assert_array_almost_equal(e1, e2) - np.testing.assert_array_almost_equal(h1, h2) + assert e1 == approx(e2) + assert h1 == approx(h2) @pytest.mark.parametrize("a", inputs_1d) @@ -71,11 +69,11 @@ def test_histogram1d_object(a, opt): bh_h2 = bh.numpy.histogram(v, **bh_opt) h2, e2 = bh_h2.to_numpy() - np.testing.assert_array_almost_equal(e1, e2) - np.testing.assert_array_equal(h1, h2) + assert e1 == approx(e2) + assert h1 == approx(h2) # Ensure reducible - assert bh_h2[:5].values() == pytest.approx(h1[:5]) + assert bh_h2[:5].values() == approx(h1[:5]) opt = copy.deepcopy(opt) opt["density"] = True @@ -94,16 +92,16 @@ def test_histogram2d(): h1, e1x, e1y = np.histogram2d(x, y) h2, e2x, e2y = bh.numpy.histogram2d(x, y) - np.testing.assert_array_almost_equal(e1x, e2x) - np.testing.assert_array_almost_equal(e1y, e2y) - np.testing.assert_array_equal(h1, h2) + assert e1x == approx(e2x) + assert e1y == approx(e2y) + assert h1 == approx(h2) h1, e1x, e1y = np.histogram2d(x, y, density=True) h2, e2x, e2y = bh.numpy.histogram2d(x, y, density=True) - np.testing.assert_array_almost_equal(e1x, e2x) - np.testing.assert_array_almost_equal(e1y, e2y) - np.testing.assert_array_almost_equal(h1, h2) + assert e1x == approx(e2x) + assert e1y == approx(e2y) + assert h1 == approx(h2) def test_histogram2d_object(): @@ -114,9 +112,9 @@ def test_histogram2d_object(): bh_h2 = bh.numpy.histogram2d(x, y, histogram=bh.Histogram) h2, e2x, e2y = bh_h2.to_numpy() - np.testing.assert_array_almost_equal(e1x, e2x) - np.testing.assert_array_almost_equal(e1y, e2y) - np.testing.assert_array_equal(h1, h2) + assert e1x == approx(e2x) + assert e1y == approx(e2y) + assert h1 == approx(h2) with pytest.raises(KeyError): bh.numpy.histogram2d(x, y, density=True, histogram=bh.Histogram) @@ -130,18 +128,18 @@ def test_histogramdd(): h1, (e1x, e1y, e1z) = np.histogramdd([x, y, z]) h2, (e2x, e2y, e2z) = bh.numpy.histogramdd([x, y, z]) - np.testing.assert_array_almost_equal(e1x, e2x) - np.testing.assert_array_almost_equal(e1y, e2y) - np.testing.assert_array_almost_equal(e1z, e2z) - np.testing.assert_array_equal(h1, h2) + assert e1x == approx(e2x) + assert e1y == approx(e2y) + assert e1z == approx(e2z) + assert h1 == approx(h2) h1, (e1x, e1y, e1z) = np.histogramdd([x, y, z], density=True) h2, (e2x, e2y, e2z) = bh.numpy.histogramdd([x, y, z], density=True) - np.testing.assert_array_almost_equal(e1x, e2x) - np.testing.assert_array_almost_equal(e1y, e2y) - np.testing.assert_array_almost_equal(e1z, e2z) - np.testing.assert_array_almost_equal(h1, h2) + assert e1x == approx(e2x) + assert e1y == approx(e2y) + assert e1z == approx(e2z) + assert h1 == approx(h2) def test_histogramdd_object(): @@ -153,10 +151,10 @@ def test_histogramdd_object(): bh_h2 = bh.numpy.histogramdd([x, y, z], histogram=bh.Histogram) h2, (e2x, e2y, e2z) = bh_h2.to_numpy(dd=True) - np.testing.assert_array_almost_equal(e1x, e2x) - np.testing.assert_array_almost_equal(e1y, e2y) - np.testing.assert_array_almost_equal(e1z, e2z) - np.testing.assert_array_equal(h1, h2) + assert e1x == approx(e2x) + assert e1y == approx(e2y) + assert e1z == approx(e2z) + assert h1 == approx(h2) with pytest.raises(KeyError): bh.numpy.histogramdd([x, y, z], density=True, histogram=bh.Histogram) From 65f0a1c226e96500d820cdb5dffe25c215710f96 Mon Sep 17 00:00:00 2001 From: Jay Gohil Date: Mon, 27 Jun 2022 17:54:56 -0400 Subject: [PATCH 04/12] Updated all numpy.testing asserts to pytest.approx --- tests/test_axes_object.py | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/tests/test_axes_object.py b/tests/test_axes_object.py index e67a94d0..84770ff4 100644 --- a/tests/test_axes_object.py +++ b/tests/test_axes_object.py @@ -1,9 +1,8 @@ import numpy as np import pytest - +from pytest import approx import boost_histogram as bh - @pytest.fixture def h(): return bh.Histogram( @@ -39,12 +38,11 @@ def test_axes_centers(h): full_answers = np.mgrid[0.5:10, 0.5:5, 0.5:2] for i in range(3): - np.testing.assert_allclose(centers.broadcast()[i], full_answers[i]) - np.testing.assert_allclose(centers[i], answers[i]) - np.testing.assert_allclose(centers.T[i], answers[i].T) - np.testing.assert_allclose(centers.flatten()[i], answers[i].flatten()) - np.testing.assert_allclose(h.axes[i].centers, answers[i].ravel()) - + assert centers.broadcast()[i] == approx(full_answers[i]) + assert centers[i] == approx(answers[i]) + assert centers.T[i] == approx(answers[i].T) + assert centers.flatten()[i] == approx(answers[i].flatten()) + assert h.axes[i].centers == approx(answers[i].ravel()) def test_axes_edges(h): edges = h.axes.edges @@ -52,12 +50,11 @@ def test_axes_edges(h): full_answers = np.mgrid[0:11, 0:6, 0:3] for i in range(3): - np.testing.assert_allclose(edges.broadcast()[i], full_answers[i]) - np.testing.assert_allclose(edges[i], answers[i]) - np.testing.assert_allclose(edges.T[i], answers[i].T) - np.testing.assert_allclose(edges.ravel()[i], answers[i].ravel()) - np.testing.assert_allclose(h.axes[i].edges, answers[i].ravel()) - + assert edges.broadcast()[i] == approx(full_answers[i]) + assert edges[i] == approx(answers[i]) + assert edges.T[i] == approx(answers[i].T) + assert edges.ravel()[i] == approx(answers[i].ravel()) + assert h.axes[i].edges == approx(answers[i].ravel()) def test_axes_widths(h): widths = h.axes.widths @@ -65,12 +62,11 @@ def test_axes_widths(h): full_answers = np.mgrid[1:1:10j, 1:1:5j, 1:1:2j] for i in range(3): - np.testing.assert_allclose(widths.broadcast()[i], full_answers[i]) - np.testing.assert_allclose(widths[i], answers[i]) - np.testing.assert_allclose(widths.T[i], answers[i].T) - np.testing.assert_allclose(widths.ravel()[i], answers[i].ravel()) - np.testing.assert_allclose(h.axes[i].widths, answers[i].ravel()) - + assert widths.broadcast()[i] == approx(full_answers[i]) + assert widths[i] == approx(answers[i]) + assert widths.T[i] == approx(answers[i].T) + assert widths.ravel()[i] == approx(answers[i].ravel()) + assert h.axes[i].widths == approx(answers[i].ravel()) def test_axis_misconstuct(): inp = [bh.axis.Regular(12, 0, 1)] From b877ee56e69aeaa6ddae2fc64739de6d5c2529e5 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 29 Jun 2022 18:28:54 +0000 Subject: [PATCH 05/12] style: pre-commit fixes --- tests/test_axes_object.py | 5 +++++ tests/test_numpy_interface.py | 2 ++ tests/test_pickle.py | 6 ++++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/test_axes_object.py b/tests/test_axes_object.py index 84770ff4..4e652729 100644 --- a/tests/test_axes_object.py +++ b/tests/test_axes_object.py @@ -1,8 +1,10 @@ import numpy as np import pytest from pytest import approx + import boost_histogram as bh + @pytest.fixture def h(): return bh.Histogram( @@ -44,6 +46,7 @@ def test_axes_centers(h): assert centers.flatten()[i] == approx(answers[i].flatten()) assert h.axes[i].centers == approx(answers[i].ravel()) + def test_axes_edges(h): edges = h.axes.edges answers = np.ogrid[0:11, 0:6, 0:3] @@ -56,6 +59,7 @@ def test_axes_edges(h): assert edges.ravel()[i] == approx(answers[i].ravel()) assert h.axes[i].edges == approx(answers[i].ravel()) + def test_axes_widths(h): widths = h.axes.widths answers = np.ogrid[1:1:10j, 1:1:5j, 1:1:2j] @@ -68,6 +72,7 @@ def test_axes_widths(h): assert widths.ravel()[i] == approx(answers[i].ravel()) assert h.axes[i].widths == approx(answers[i].ravel()) + def test_axis_misconstuct(): inp = [bh.axis.Regular(12, 0, 1)] ok = bh.axis.AxesTuple(inp) diff --git a/tests/test_numpy_interface.py b/tests/test_numpy_interface.py index a4b5958f..4989557f 100644 --- a/tests/test_numpy_interface.py +++ b/tests/test_numpy_interface.py @@ -1,7 +1,9 @@ import copy + import numpy as np import pytest from pytest import approx + import boost_histogram as bh np113 = tuple(int(x) for x in np.__version__.split(".")[:2]) >= (1, 13) diff --git a/tests/test_pickle.py b/tests/test_pickle.py index c79b2afa..2c27c4f3 100644 --- a/tests/test_pickle.py +++ b/tests/test_pickle.py @@ -2,10 +2,12 @@ import ctypes import math import platform -from pytest import approx from pickle import dumps, loads + import numpy as np import pytest +from pytest import approx + import boost_histogram as bh ftype = ctypes.CFUNCTYPE(ctypes.c_double, ctypes.c_double) @@ -160,7 +162,7 @@ def test_storage(benchmark, copy_fn, storage, extra): hist.fill(x, weight=np.arange(2 * n + 4) + 1, sample=np.arange(2 * n + 4) + 1) new = benchmark(copy_fn, hist) - assert hist.view(True) == approx(new.view(True)) + assert hist.view(True) == approx(new.view(True)) assert new == hist From 190e6cef752d3b0090dea50aefa3d7ececa00cf6 Mon Sep 17 00:00:00 2001 From: Jay Gohil Date: Wed, 29 Jun 2022 23:58:40 -0400 Subject: [PATCH 06/12] Wrapping this assert to remove test failing --- tests/test_pickle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_pickle.py b/tests/test_pickle.py index 2c27c4f3..0a90e079 100644 --- a/tests/test_pickle.py +++ b/tests/test_pickle.py @@ -162,7 +162,7 @@ def test_storage(benchmark, copy_fn, storage, extra): hist.fill(x, weight=np.arange(2 * n + 4) + 1, sample=np.arange(2 * n + 4) + 1) new = benchmark(copy_fn, hist) - assert hist.view(True) == approx(new.view(True)) + assert np.asarray(hist.view(True)) == approx(np.asarray(new.view(True))) assert new == hist From b6b0003b16726d8c175efd6c0b9a56deda2af9b0 Mon Sep 17 00:00:00 2001 From: Jay Gohil Date: Thu, 30 Jun 2022 21:40:58 -0400 Subject: [PATCH 07/12] Added histograms comparison function --- src/boost_histogram/_internal/hist.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/boost_histogram/_internal/hist.py b/src/boost_histogram/_internal/hist.py index 80d27c4b..ef90cb95 100644 --- a/src/boost_histogram/_internal/hist.py +++ b/src/boost_histogram/_internal/hist.py @@ -1,3 +1,4 @@ +import re import collections.abc import copy import logging @@ -337,6 +338,24 @@ def ndim(self) -> int: """ return self._hist.rank() + def compare(self, hist2): + if (np.allclose(self.view().shape, hist2.view().shape)): + if (np.allclose(self.view(), hist2.view())): + if (np.allclose(self.variances(), hist2.variances())): + if (re.search("(?<=storage=).*", str(self.view))[0].split('(')[0] == re.search("(?<=storage=).*", str(hist2.view))[0].split('(')[0]): + if (list(map(str, [i for i in self.axes]))==list(map(str, [i for i in hist2.axes]))): + return True + else: + return False + else: + return False + else: + return False + else: + return False + else: + return False + def view( self, flow: bool = False ) -> Union["np.typing.NDArray[Any]", WeightedSumView, WeightedMeanView, MeanView]: From ebe0cff05f10170dbcf374dbbe7e138de0cca768 Mon Sep 17 00:00:00 2001 From: Jay Gohil Date: Thu, 30 Jun 2022 21:42:14 -0400 Subject: [PATCH 08/12] Added 'compare' operation --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1d344293..90565539 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,7 @@ histograms can be plotted via any compatible library, such as [mplhep][]. * `.kind`: Either `bh.Kind.COUNT` or `bh.Kind.MEAN`, depending on storage * `.sum(flow=False)`: The total count of all bins * `.project(ax1, ax2, ...)`: Project down to listed axis (numbers). Can also reorder axes. + * `.compare(second_hist)`: Compare the histogram with another histogram * `.to_numpy(flow=False, view=False)`: Convert to a NumPy style tuple (with or without under/overflow bins) * `.view(flow=False)`: Get a view on the bin contents (with or without under/overflow bins) * `.values(flow=False)`: Get a view on the values (counts or means, depending on storage) From 772104cac239c2186123115088fa00fed2597bd2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 1 Jul 2022 01:46:27 +0000 Subject: [PATCH 09/12] style: pre-commit fixes --- src/boost_histogram/_internal/hist.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/boost_histogram/_internal/hist.py b/src/boost_histogram/_internal/hist.py index ef90cb95..35a0a91b 100644 --- a/src/boost_histogram/_internal/hist.py +++ b/src/boost_histogram/_internal/hist.py @@ -1,7 +1,7 @@ -import re import collections.abc import copy import logging +import re import threading import typing import warnings @@ -339,11 +339,18 @@ def ndim(self) -> int: return self._hist.rank() def compare(self, hist2): - if (np.allclose(self.view().shape, hist2.view().shape)): - if (np.allclose(self.view(), hist2.view())): - if (np.allclose(self.variances(), hist2.variances())): - if (re.search("(?<=storage=).*", str(self.view))[0].split('(')[0] == re.search("(?<=storage=).*", str(hist2.view))[0].split('(')[0]): - if (list(map(str, [i for i in self.axes]))==list(map(str, [i for i in hist2.axes]))): + if np.allclose(self.view().shape, hist2.view().shape): + if np.allclose(self.view(), hist2.view()): + if np.allclose(self.variances(), hist2.variances()): + if ( + re.search("(?<=storage=).*", str(self.view))[0].split("(")[0] + == re.search("(?<=storage=).*", str(hist2.view))[0].split("(")[ + 0 + ] + ): + if list(map(str, [i for i in self.axes])) == list( + map(str, [i for i in hist2.axes]) + ): return True else: return False From 220c1ca1de35477847179b2a661fdc19de18e45d Mon Sep 17 00:00:00 2001 From: Jay Gohil Date: Thu, 30 Jun 2022 22:21:07 -0400 Subject: [PATCH 10/12] Tweaked the comparison function --- src/boost_histogram/_internal/hist.py | 28 ++++++--------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/src/boost_histogram/_internal/hist.py b/src/boost_histogram/_internal/hist.py index 35a0a91b..c5d08258 100644 --- a/src/boost_histogram/_internal/hist.py +++ b/src/boost_histogram/_internal/hist.py @@ -339,29 +339,13 @@ def ndim(self) -> int: return self._hist.rank() def compare(self, hist2): - if np.allclose(self.view().shape, hist2.view().shape): - if np.allclose(self.view(), hist2.view()): - if np.allclose(self.variances(), hist2.variances()): - if ( - re.search("(?<=storage=).*", str(self.view))[0].split("(")[0] - == re.search("(?<=storage=).*", str(hist2.view))[0].split("(")[ - 0 - ] - ): - if list(map(str, [i for i in self.axes])) == list( - map(str, [i for i in hist2.axes]) - ): + if (np.allclose(self.view().shape, hist2.view().shape)): + if (np.allclose(self.view(), hist2.view())): + if (np.allclose(self.variances(), hist2.variances())): + if (re.search("(?<=storage=).*", str(self.view))[0].split('(')[0] == re.search("(?<=storage=).*", str(hist2.view))[0].split('(')[0]): + if (list(self.axes)==list(hist2.axes)): return True - else: - return False - else: - return False - else: - return False - else: - return False - else: - return False + return False def view( self, flow: bool = False From 246cc2f675f6416a9b8f9cffe173a9467769d063 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 1 Jul 2022 02:21:32 +0000 Subject: [PATCH 11/12] style: pre-commit fixes --- src/boost_histogram/_internal/hist.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/boost_histogram/_internal/hist.py b/src/boost_histogram/_internal/hist.py index c5d08258..01cd3768 100644 --- a/src/boost_histogram/_internal/hist.py +++ b/src/boost_histogram/_internal/hist.py @@ -339,11 +339,16 @@ def ndim(self) -> int: return self._hist.rank() def compare(self, hist2): - if (np.allclose(self.view().shape, hist2.view().shape)): - if (np.allclose(self.view(), hist2.view())): - if (np.allclose(self.variances(), hist2.variances())): - if (re.search("(?<=storage=).*", str(self.view))[0].split('(')[0] == re.search("(?<=storage=).*", str(hist2.view))[0].split('(')[0]): - if (list(self.axes)==list(hist2.axes)): + if np.allclose(self.view().shape, hist2.view().shape): + if np.allclose(self.view(), hist2.view()): + if np.allclose(self.variances(), hist2.variances()): + if ( + re.search("(?<=storage=).*", str(self.view))[0].split("(")[0] + == re.search("(?<=storage=).*", str(hist2.view))[0].split("(")[ + 0 + ] + ): + if list(self.axes) == list(hist2.axes): return True return False From 8a6102385b21f09ffdc96a25c79ff81b0217622b Mon Sep 17 00:00:00 2001 From: Jay Gohil Date: Thu, 30 Jun 2022 22:55:20 -0400 Subject: [PATCH 12/12] Added type annotation --- src/boost_histogram/_internal/hist.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/boost_histogram/_internal/hist.py b/src/boost_histogram/_internal/hist.py index 01cd3768..80106516 100644 --- a/src/boost_histogram/_internal/hist.py +++ b/src/boost_histogram/_internal/hist.py @@ -338,7 +338,7 @@ def ndim(self) -> int: """ return self._hist.rank() - def compare(self, hist2): + def compare(self, hist2) -> bool: if np.allclose(self.view().shape, hist2.view().shape): if np.allclose(self.view(), hist2.view()): if np.allclose(self.variances(), hist2.variances()):