def test_named_axestuple(): """ Test named axes tuple -- whether NamedHist axes tuple work properly. """ h = NamedHist( axis.Regular(20, 0, 12, name="A"), axis.Regular(10, 1, 3, name="B", label="Beta"), axis.Regular(15, 3, 5, name="C"), axis.Regular(5, 3, 2, name="D", label="Axis 3"), ) assert h.axes.name == ("A", "B", "C", "D") assert h.axes.label == ("A", "Beta", "C", "Axis 3") assert h.axes[0].size == 20 assert h.axes["A"].size == 20 assert h.axes[1].size == 10 assert h.axes["B"].size == 10 assert h.axes[2].size == 15 assert h.axes[:2].size == (20, 10) assert h.axes["A":"B"].size == (20,) assert h.axes[:"B"].size == (20,) assert h.axes["B":].size == (10, 15, 5)
def test_image_plot_ratio_hist(): """ Test plot_pull by comparing against a reference image generated via `pytest --mpl-generate-path=tests/baseline` """ np.random.seed(42) hist_1 = Hist( axis.Regular(50, -5, 5, name="X", label="x [units]", underflow=False, overflow=False)).fill(np.random.normal(size=1000)) hist_2 = Hist( axis.Regular(50, -5, 5, name="X", label="x [units]", underflow=False, overflow=False)).fill(np.random.normal(size=1700)) fig = plt.figure() assert hist_1.plot_ratio(hist_2, rp_num_label="numerator", rp_denom_label="denominator") return fig
def test_general_axestuple(): """ Test general axes tuple -- whether Hist axes tuple work properly. """ h = Hist( axis.Regular(20, 0, 12, name="A", label="alpha"), axis.Regular(10, 1, 3, name="B"), axis.Regular(15, 3, 5, label="other"), axis.Regular(5, 3, 2), ) assert h.axes.name == ("A", "B", "", "") assert h.axes.label == ("alpha", "B", "other", "Axis 3") assert h.axes[0].size == 20 assert h.axes["A"].size == 20 assert h.axes[1].size == 10 assert h.axes["B"].size == 10 assert h.axes[2].size == 15 assert h.axes[:2].size == (20, 10) assert h.axes["A":"B"].size == (20, ) assert h.axes[:"B"].size == (20, ) assert h.axes["B":].size == (10, 15, 5)
def test_named_access(): """ Test named access -- whether NamedHist bins can be accessed. """ h = NamedHist(axis.Regular(10, -5, 5, name="X", label="x [units]")).fill( X=np.random.normal(size=1000) ) assert h[6] == h[bh.loc(1)] == h[1j] == h[0j + 1] == h[-3j + 4] == h[bh.loc(1, 0)] h[6] = h[bh.loc(1)] = h[1j] = h[0j + 1] = h[-3j + 4] = h[bh.loc(1, 0)] = 0 h = NamedHist( axis.Regular(50, -5, 5, name="Norm", label="normal distribution"), axis.Regular(50, -5, 5, name="Unif", label="uniform distribution"), axis.StrCategory(["hi", "hello"], name="Greet"), axis.Boolean(name="Yes"), axis.Integer(0, 1000, name="Int"), ).fill( Norm=np.random.normal(size=1000), Unif=np.random.uniform(size=1000), Greet=["hi"] * 800 + ["hello"] * 200, Yes=[True] * 600 + [False] * 400, Int=np.ones(1000), ) assert h[0j, -0j + 2, "hi", True, 1] # mismatch dimension with pytest.raises(Exception): h[0j, -0j + 2, "hi", True]
def test_weighted_mean(self): h = ( Hist.new.Reg(10, 0, 1, name="x") .WeightedMean() .fill([0.5, 0.5], weight=[1, 1], sample=[1, 1]) ) assert h[0.5j].sum_of_weights == 2 assert h[0.5j].sum_of_weights_squared == 2 assert h[0.5j].value == 1 assert h[0.5j].variance == 0 # add storage to existing storage with pytest.raises(Exception): h.WeightedMean() assert ( Hist(axis.Regular(10, 0, 1, name="x"), "WeighTEDMEAn")._storage_type == storage.WeightedMean ) assert ( Hist(axis.Regular(10, 0, 1, name="x"), storage="weightedMean")._storage_type == storage.WeightedMean ) assert ( Hist(axis.Regular(10, 0, 1, name="x"), storage.WeightedMean())._storage_type == storage.WeightedMean )
def test_mean(self): h = ( Hist.new.Reg(10, 0, 1, name="x") .Mean() .fill([0.5, 0.5], weight=[1, 1], sample=[1, 1]) ) assert h[0.5j].count == 2 assert h[0.5j].value == 1 assert h[0.5j].variance == 0 # add storage to existing storage with pytest.raises(Exception): h.Mean() assert ( Hist(axis.Regular(10, 0, 1, name="x"), "MEAn")._storage_type == storage.Mean ) assert ( Hist(axis.Regular(10, 0, 1, name="x"), storage="mean")._storage_type == storage.Mean ) assert ( Hist(axis.Regular(10, 0, 1, name="x"), storage.Mean())._storage_type == storage.Mean )
def test_double(self): h = ( Hist.new.Reg(10, 0, 1, name="x") .Reg(10, 0, 1, name="y") .Double() .fill(x=[0.5, 0.5], y=[0.2, 0.6]) ) assert h[0.5j, 0.2j] == 1 assert h[bh.loc(0.5), bh.loc(0.6)] == 1 assert isinstance(h[0.5j, 0.5j], float) # add storage to existing storage with pytest.raises(Exception): h.Double() assert ( Hist(axis.Regular(10, 0, 1, name="x"), "double")._storage_type == storage.Double ) assert ( Hist(axis.Regular(10, 0, 1, name="x"), storage="DouBle")._storage_type == storage.Double ) assert ( Hist(axis.Regular(10, 0, 1, name="x"), storage.Double())._storage_type == storage.Double )
def test_basic_usage(): ''' Test basic usage -- whether Hist are properly derived from\ boost-histogram. ''' # Test normal Hist h = Hist(axis.Regular(10, 0, 1, name='x')) h.fill([0.35, 0.35, 0.45]) assert h[2] == 0 assert h[3] == 2 assert h[4] == 1 assert h[5] == 0 assert h[{0:2}] == 0 assert h[{0:3}] == 2 assert h[{0:4}] == 1 assert h[{0:5}] == 0 # Test multi-axis Hist h = Hist( axis.Regular(10, 0, 1, name="x"), axis.Regular(10, 0, 1, name="y"), axis.Integer(0, 2, name="z") ) h.fill([0.35, 0.35, 0.35, 0.45, 0.55, 0.55, 0.55], [0.35, 0.35, 0.45, 0.45, 0.45, 0.45, 0.45], [0, 0, 1, 1, 1, 1, 1])
def test_duplicated_names_init(named_hist): with pytest.raises(Exception): named_hist(axis.Regular(50, -3, 3, name="x"), axis.Regular(50, -3, 3, name="x")) with pytest.raises(Exception): named_hist(axis.Boolean(name="y"), axis.Boolean(name="y")) with pytest.raises(Exception): named_hist(axis.Variable(range(-3, 3), name="x"), axis.Variable(range(-3, 3), name="x")) with pytest.raises(Exception): named_hist(axis.Integer(-3, 3, name="x"), axis.Integer(-3, 3, name="x")) with pytest.raises(Exception): named_hist( axis.IntCategory(range(-3, 3), name="x"), axis.IntCategory(range(-3, 3), name="x"), ) with pytest.raises(Exception): named_hist(axis.StrCategory("TF", name="y"), axis.StrCategory(["T", "F"], name="y"))
def test_named_project(): """ Test named project -- whether NamedHist can be projected properly. """ h = NamedHist( axis.Regular( 50, -5, 5, name="A", label="a [units]", underflow=False, overflow=False ), axis.Boolean(name="B", label="b [units]"), axis.Variable(range(11), name="C", label="c [units]"), axis.Integer(0, 10, name="D", label="d [units]"), axis.IntCategory(range(10), name="E", label="e [units]"), axis.StrCategory("FT", name="F", label="f [units]"), ) # via names assert h.project() assert h.project("A", "B") assert h.project("A", "B", "C", "D", "E", "F") h = NamedHist( axis.Regular( 50, -5, 5, name="A", label="a [units]", underflow=False, overflow=False ), axis.Boolean(name="B", label="b [units]"), axis.Variable(range(11), name="C", label="c [units]"), axis.Integer(0, 10, name="D", label="d [units]"), axis.IntCategory(range(10), name="E", label="e [units]"), axis.StrCategory("FT", name="F", label="f [units]"), ) # via indices with pytest.raises(Exception): h.project(0, 1) with pytest.raises(Exception): h.project(0, 1, 2, 3, 4, 5) # duplicated with pytest.raises(Exception): h.project(0, 0) with pytest.raises(Exception): h.project("A", "A") # wrong/mixed types with pytest.raises(Exception): h.project(2, "A") with pytest.raises(Exception): h.project(True, "A") # cannot found with pytest.raises(Exception): h.project(-1, 9) with pytest.raises(Exception): h.project("G", "H")
def test_named_plot2d(): """ Test named plot2d -- whether 2d-NamedHist can be plotted properly. """ h = NamedHist( axis.Regular(50, -5, 5, name="A", label="a [units]", underflow=False, overflow=False), axis.Regular(50, -4, 4, name="B", label="b [units]", underflow=False, overflow=False), ).fill(B=np.random.normal(size=10), A=np.random.normal(size=10)) assert h.plot2d(cmap="cividis") plt.close("all") # dimension error h = NamedHist( axis.Regular(50, -5, 5, name="A", label="a [units]", underflow=False, overflow=False), axis.Regular(50, -4, 4, name="B", label="b [units]", underflow=False, overflow=False), ).fill(B=np.random.normal(size=10), A=np.random.normal(size=10)) with pytest.raises(Exception): h.project("A").plot2d() # wrong kwargs names with pytest.raises(Exception): h.plot2d(abc="red") # wrong kwargs type with pytest.raises(Exception): h.plot2d(cmap=0.1) plt.close("all")
def test_init_and_fill(unnamed_hist): """ Test general init -- whether Hist can be properly initialized. Also tests filling. """ np.random.seed(42) # basic h = unnamed_hist(axis.Regular(10, 0, 1, name="x"), axis.Regular(10, 0, 1, name="y")).fill([0.35, 0.35, 0.45], [0.35, 0.35, 0.45]) for idx in range(10): if idx == 3: assert h[idx, idx] == 2 assert h[{0: idx, 1: idx}] == 2 assert h[{"x": idx, "y": idx}] == 2 elif idx == 4: assert h[idx, idx] == 1 assert h[{0: idx, 1: idx}] == 1 assert h[{"x": idx, "y": idx}] == 1 else: assert h[idx, idx] == 0 assert h[{0: idx, 1: idx}] == 0 assert h[{"x": idx, "y": idx}] == 0 assert unnamed_hist(axis.Regular(50, -3, 3, name="x"), axis.Regular(50, -3, 3, name="y")).fill(np.random.randn(10), np.random.randn(10)) assert unnamed_hist(axis.Boolean(name="x"), axis.Boolean(name="y")).fill([True, False, True], [True, False, True]) assert unnamed_hist(axis.Variable(range(-3, 3), name="x"), axis.Variable(range(-3, 3), name="y")).fill(np.random.randn(10), np.random.randn(10)) assert unnamed_hist(axis.Integer(-3, 3, name="x"), axis.Integer(-3, 3, name="y")).fill(np.random.randn(10), np.random.randn(10)) assert unnamed_hist( axis.IntCategory(range(-3, 3), name="x"), axis.IntCategory(range(-3, 3), name="y"), ).fill(np.random.randn(10), np.random.randn(10)) assert unnamed_hist(axis.StrCategory(["F", "T"], name="x"), axis.StrCategory("FT", name="y")).fill(["T", "F", "T"], ["T", "F", "T"])
def test_general_index_access(): """ Test general index access -- whether Hist can be accessed by index. """ h = Hist( axis.Regular(10, -5, 5, name="Ones"), axis.Regular(10, -5, 5, name="Twos"), axis.StrCategory(["hi", "hello"], name="Greet"), axis.Boolean(name="Yes"), axis.Integer(0, 10, name="Int"), ).fill( np.ones(10), np.ones(10) * 2, ["hi"] * 8 + ["hello"] * 2, [True] * 6 + [False] * 4, np.ones(10), ) assert h[1j, 2j, "hi", True, 1] == 6 assert h[{0: 6, 1: 7, 2: bh.loc("hi"), 3: bh.loc(True), 4: bh.loc(1)}] == 6 assert h[0j + 1, -2j + 4, "hi", True, 1] == 6 assert (h[{ "Greet": "hi", "Ones": bh.loc(1, 0), 1: bh.loc(3, -1), 3: True, "Int": 1 }] == 6) assert h[0:10:2j, 0:5:5j, "hello", False, 5] assert len(h[::2j, 0:5, :, :, :].axes[1]) == 5 assert len(h[:, 0:5, :, :, :].axes[1]) == 5 # wrong loc shortcut with pytest.raises(Exception): h[0.5, 1 / 2, "hi", True, 1] with pytest.raises(Exception): h[0.5 + 1j, 1 / 2 + 1j, "hi", True, 1] # wrong rebin shortcut with pytest.raises(Exception): h[0:10:0.2j, 0:5:0.5j, "hello", False, 5] with pytest.raises(Exception): h[0:10:1 + 2j, 0:5:1 + 5j, "hello", False, 5] with pytest.raises(Exception): h[0:10:20j, 0:5:10j, "hello", False, 5]
def test_unlimited(self): h = Hist.new.Reg(10, 0, 1, name="x").Unlimited().fill([0.5, 0.5]) assert h[0.5j] == 2 # add storage to existing storage with pytest.raises(Exception): h.Unlimited() assert (Hist(axis.Regular(10, 0, 1, name="x"), "unlimited")._storage_type == storage.Unlimited) assert (Hist(axis.Regular(10, 0, 1, name="x"), storage="UNLImited")._storage_type == storage.Unlimited) assert (Hist(axis.Regular(10, 0, 1, name="x"), storage.Unlimited())._storage_type == storage.Unlimited)
def test_named_plot2d_full(): """ Test named plot2d_full -- whether 2d-NamedHist can be fully plotted properly. """ h = NamedHist( axis.Regular( 50, -5, 5, name="A", label="a [units]", underflow=False, overflow=False ), axis.Regular( 50, -4, 4, name="B", label="b [units]", underflow=False, overflow=False ), ).fill(B=np.random.normal(size=10), A=np.random.normal(size=10)) assert h.plot2d_full( main_cmap="cividis", top_ls="--", top_color="orange", top_lw=2, side_ls="-.", side_lw=1, side_color="steelblue", ) plt.close("all") # dimension error h = NamedHist( axis.Regular( 50, -5, 5, name="A", label="a [units]", underflow=False, overflow=False ), axis.Regular( 50, -4, 4, name="B", label="b [units]", underflow=False, overflow=False ), ).fill(B=np.random.normal(size=10), A=np.random.normal(size=10)) with pytest.raises(Exception): h.project("A").plot2d_full() # wrong kwargs names with pytest.raises(Exception): h.plot2d_full(abc="red") with pytest.raises(Exception): h.plot2d_full(color="red") # wrong kwargs type with pytest.raises(Exception): h.plot2d_full(main_cmap=0.1, side_lw="autumn") plt.close("all")
def test_int64(self): h = Hist.new.Reg(10, 0, 1, name="x").Int64().fill([0.5, 0.5]) assert h[0.5j] == 2 assert isinstance(h[0.5j], int) # add storage to existing storage with pytest.raises(Exception): h.Int64() assert (Hist(axis.Regular(10, 0, 1, name="x"), "int64")._storage_type == storage.Int64) assert (Hist(axis.Regular(10, 0, 1, name="x"), storage="INT64")._storage_type == storage.Int64) assert (Hist(axis.Regular(10, 0, 1, name="x"), storage.Int64())._storage_type == storage.Int64)
def test_weight(self): h = Hist.new.Reg(10, 0, 1, name="x").Weight().fill([0.5, 0.5]) assert h[0.5j].variance == 2 assert h[0.5j].value == 2 # add storage to existing storage with pytest.raises(Exception): h.Weight() assert (Hist(axis.Regular(10, 0, 1, name="x"), "WeighT")._storage_type == storage.Weight) assert (Hist(axis.Regular(10, 0, 1, name="x"), storage="weight")._storage_type == storage.Weight) assert (Hist(axis.Regular(10, 0, 1, name="x"), storage.Weight())._storage_type == storage.Weight)
def test_image_plot_pull(): """ Test plot_pull by comparing against a reference image generated via `pytest --mpl-generate-path=tests/baseline` """ np.random.seed(42) h = Hist( axis.Regular(50, -4, 4, name="S", label="s [units]", underflow=False, overflow=False)).fill(np.random.normal(size=100)) def pdf(x, a=1 / np.sqrt(2 * np.pi), x0=0, sigma=1, offset=0): return a * np.exp(-((x - x0)**2) / (2 * sigma**2)) + offset fig = plt.figure() assert h.plot_pull( pdf, eb_color="black", fp_color="blue", ub_color="lightblue", fit_fmt=r"{name} = {value:.3g} $\pm$ {error:.3g}", ) return fig
def test_no_named_init(unnamed_hist): # with no-named axes assert unnamed_hist(axis.Regular(50, -3, 3), axis.Regular(50, -3, 3)) assert unnamed_hist(axis.Boolean(), axis.Boolean()) assert unnamed_hist(axis.Variable(range(-3, 3)), axis.Variable(range(-3, 3))) assert unnamed_hist(axis.Integer(-3, 3), axis.Integer(-3, 3)) assert unnamed_hist( axis.IntCategory(range(-3, 3)), axis.IntCategory(range(-3, 3)), ) assert unnamed_hist(axis.StrCategory("TF"), axis.StrCategory(["T", "F"]))
def test_image_plot_ratio_callable(): """ Test plot_pull by comparing against a reference image generated via `pytest --mpl-generate-path=tests/baseline` """ np.random.seed(42) hist_1 = Hist( axis.Regular(50, -5, 5, name="X", label="x [units]", underflow=False, overflow=False)).fill(np.random.normal(size=1000)) def model(x, a=1 / np.sqrt(2 * np.pi), x0=0, sigma=1, offset=0): return a * np.exp(-((x - x0)**2) / (2 * sigma**2)) + offset fig = plt.figure() assert hist_1.plot_ratio(model, eb_color="black", fp_color="blue", ub_color="lightblue") return fig
def test_general_plot1d(): """ Test general plot1d -- whether 1d-Hist can be plotted properly. """ h = Hist( axis.Regular(50, -5, 5, name="A", label="a [units]", underflow=False, overflow=False), ).fill(np.random.normal(size=10)) assert h.plot1d(color="green", ls="--", lw=3) plt.close("all") # dimension error h = Hist( axis.Regular(50, -5, 5, name="A", label="a [units]", underflow=False, overflow=False), axis.Regular(50, -4, 4, name="B", label="b [units]", underflow=False, overflow=False), ).fill(np.random.normal(size=10), np.random.normal(size=10)) with pytest.raises(Exception): h.plot1d() # wrong kwargs names with pytest.raises(Exception): h.project("A").plot1d(abc="red") # wrong kwargs type with pytest.raises(Exception): h.project("B").plot1d(ls="red") plt.close("all")
def test_basic_usage(): # Check hist with only one axis h = Hist(axis.Regular(10, 0, 1)) h.fill([0.35, 0.35, 0.45]) assert h[2] == 0 assert h[3] == 2 assert h[4] == 1 assert h[5] == 0 # Check hist with two axes h = Hist(axis.Regular(10, 0, 1), axis.Regular(10, 0, 1)) h.fill([0.35, 0.35, 0.45], [0.65, 0.65, 0.85]) assert h[3, 6] == 2 assert h[4, 8] == 1 assert h[3, 5] == 0 # Checking hist with axis type bool h = Hist(axis.bool()) h.fill([0, 1, 1]) assert h[0] == 1 assert h[1] == 2 # check if there are exactly two bins (accessing h[2] raises IndexError) with pytest.raises(IndexError): assert h[2] == 0 # check if flow is disabled (if view() with or without flow gives the same output) assert (h.view() == h.view(flow=True)).all() h = Hist(axis.Regular(10, 0, 1), axis.Regular(10, 0, 1)) h.fill([0.35, 0.35, 0.45], [0.65, 0.65, 0.85]) # Check indexing using dict and bh.loc() h2 = h[loc(0.35), :] # Broken in 0.6.2, fixed now h3 = h[{0: loc(0.35)}] assert (h2.view() == h3.view()).all()
def test_basic_usage(): ''' Test basic usage -- whether NamedHist are properly derived from\ boost-histogram and whether it can be filled by names. ''' # Test normal NamedHist h = NamedHist(axis.Regular(10, 0, 1, name="x")) h.fill(x=[0.35, 0.35, 0.45]) assert h[2] == 0 assert h[3] == 2 assert h[4] == 1 assert h[5] == 0 assert h[{0: 2}] == 0 assert h[{0: 3}] == 2 assert h[{0: 4}] == 1 assert h[{0: 5}] == 0 assert h[{'x': 2}] == 0 assert h[{'x': 3}] == 2 assert h[{'x': 4}] == 1 assert h[{'x': 5}] == 0 # Test multi-axis NamedHist h = NamedHist(axis.Regular(10, 0, 1, name="x"), axis.Regular(10, 0, 1, name="y"), axis.Integer(0, 2, name="z")) h.fill(x=[0.35, 0.35, 0.35, 0.45, 0.55, 0.55, 0.55], y=[0.35, 0.35, 0.45, 0.45, 0.45, 0.45, 0.45], z=[0, 0, 1, 1, 1, 1, 1]) z_one_only = h[{'z': bh.loc(1)}] assert z_one_only[{'x': 3, 'y': 4}] == 1 assert z_one_only[{'x': 4, 'y': 4}] == 1 assert z_one_only[{'x': 5, 'y': 4}] == 3 assert z_one_only[{'x': 5, 'y': 5}] == 0 assert z_one_only[{'x': 6, 'y': 5}] == 0 assert z_one_only[3, 4] == 1 assert z_one_only[4, 4] == 1 assert z_one_only[5, 4] == 3 assert z_one_only[5, 5] == 0 assert z_one_only[6, 5] == 0
def test_named_density(): """ Test named density -- whether NamedHist density work properly. """ for data in range(10, 20, 10): h = NamedHist(axis.Regular(10, -3, 3, name="x")).fill(x=np.random.randn(data)) assert pytest.approx(sum(h.density()), 2) == pytest.approx(10 / 6, 2)
def test_basic_usage(): h = Hist(axis.Regular(10, 0, 1)) h.fill([0.35, 0.35, 0.45]) assert h[2] == 0 assert h[3] == 2 assert h[4] == 1 assert h[5] == 0
def test_sum_empty_axis_hist(): h = Hist( axis.StrCategory("", growth=True), axis.Regular(10, 0, 1), storage=storage.Weight(), ) assert h.sum().value == 0 assert "Str" in repr(h) h._repr_html_()
def test_stack_repr(named_hist): a1 = axis.Regular(50, -5, 5, name="A", label="a [unit]", underflow=False, overflow=False) a2 = axis.Regular(50, -5, 5, name="A", label="a [unit]", underflow=False, overflow=False) assert "name='A'" in repr(Stack(Hist(a1), Hist(a2))) assert "label='a [unit]'" in repr(Stack(Hist(a1), Hist(a2)))
def test_axis_names(): """ Test axis names -- whether axis names work. """ assert axis.Regular(50, -3, 3, name="x0") assert axis.Boolean(name="x_") assert axis.Variable(range(-3, 3), name="xx") assert axis.Integer(-3, 3, name="x_x") assert axis.IntCategory(range(-3, 3), name="X__X") assert axis.StrCategory("FT", name="X00") assert axis.Regular(50, -3, 3, name="") assert axis.Boolean(name="") assert axis.Variable(range(-3, 3)) assert axis.Integer(-3, 3, name="") assert axis.IntCategory(range(-3, 3), name="") assert axis.StrCategory("FT")
def hist_fixture(): np.random.seed(42) hist_1 = Hist( axis.Regular(10, -3, 3, name="X", label="x [units]", underflow=False, overflow=False)).fill(np.random.normal(size=1000)) hist_2 = Hist( axis.Regular(10, -3, 3, name="X", label="x [units]", underflow=False, overflow=False)).fill(np.random.normal(size=1700)) return hist_1, hist_2
def test_basic_usage(): h = NamedHist(axis.Regular( 10, 0, 1, name="x")) # NamedHist should require axis.Regular to have a name set h.fill([0.35, 0.35, 0.45]) # Fill should be keyword only, with the names # Optional if you want these to fail assert h[2] == 0 assert h[3] == 2 assert h[4] == 1 assert h[5] == 0