def test_unbinned_data(): n = 751 gauss, gauss_binned, obs, obs_binned = create_gauss_binned(n, 70) x = znp.linspace(-5, 10, 200) centers = obs_binned.binning.centers[0] y_binned = gauss_binned.pdf(x) y_true = gauss.pdf(x) max_error = np.max(y_true) / 10 np.testing.assert_allclose(y_true, y_binned, atol=max_error) ycenter_binned = gauss_binned.pdf(centers) ycenter_true = gauss.pdf(centers) np.testing.assert_allclose(ycenter_binned, ycenter_true, atol=max_error / 10) x_outside = znp.array([-7.0, 3.0, 12]) y_outside = gauss_binned.pdf(x_outside) assert y_outside[0] == 0 assert y_outside[1] > 0 assert y_outside[2] == 0 plt.figure() plt.title("Binned Gauss evaluated on unbinned edges") plt.plot(centers, ycenter_true, label="unbinned pdf") plt.plot(centers, ycenter_binned, "--", label="binned pdf") plt.legend() pytest.zfit_savefig() # plt.show() plt.figure() plt.title("Binned Gauss evaluated on unbinned data") plt.plot(x, y_true, label="unbinned pdf") plt.plot(x, y_binned, "--", label="binned pdf") plt.legend() pytest.zfit_savefig()
def test_unbinned_from_binned_from_unbinned(): n = 1004 gauss, gauss_binned, obs, obs_binned = create_gauss_binned(n) x = znp.linspace(-5, 10, n // 5) # values = gauss_binned.rel_counts(obs_binned) sample = gauss_binned.sample(n, limits=obs_binned) title = "Comparison of binned gaussian and sample" plt.figure() plt.title(title) mplhep.histplot(sample.to_hist(), label="sampled binned") plt.plot( obs_binned.binning.centers[0], gauss_binned.counts(obs_binned), label="counts binned", ) plt.legend() pytest.zfit_savefig() unbinned = zfit.pdf.UnbinnedFromBinnedPDF(gauss_binned, obs=obs) y = unbinned.ext_pdf(x) y_true = gauss.ext_pdf(x) plt.figure() plt.title("Comparison of unbinned gauss to binned to unbinned again") plt.plot( obs_binned.binning.centers[0], gauss_binned.ext_pdf(obs_binned), "x", label="binned", ) plt.plot(x, y_true, label="original") plt.plot(x, y, ".", label="unbinned") plt.legend() pytest.zfit_savefig() np.testing.assert_allclose(y, y_true, atol=50) nsample = 500000 sample_binned = unbinned.sample(nsample).to_binned(obs_binned) sample_binned_hist = sample_binned.to_hist() sample_gauss = gauss.sample(nsample).to_binned(obs_binned) sample_gauss_hist = sample_gauss.to_hist() title = "Comparison of unbinned gaussian and unbinned from binned sampled" plt.figure() plt.title(title) mplhep.histplot(sample_binned_hist, label="unbinned from binned") mplhep.histplot(sample_gauss_hist, label="original") plt.legend() pytest.zfit_savefig() diff = (sample_binned_hist.values() - sample_gauss_hist.values()) / ( sample_gauss_hist.variances() + 1 ) ** 0.5 np.testing.assert_allclose(diff, 0, atol=7) # 7 sigma away
def test_sum_histogram_pdf(): bins1 = 5 bins2 = 7 counts = znp.random.uniform(high=1, size=(bins1, bins2)) # generate counts counts2 = np.random.normal(loc=5, size=(bins1, bins2)) counts3 = (znp.linspace(0, 10, num=bins1)[:, None] * znp.linspace(0, 5, num=bins2)[None, :]) binnings = [ zfit.binned.RegularBinning(bins1, 0, 10, name="obs1"), zfit.binned.RegularBinning(7, -10, bins2, name="obs2"), ] binning = binnings obs = zfit.Space(obs=["obs1", "obs2"], binning=binning) data = BinnedData.from_tensor(space=obs, values=counts, variances=znp.ones_like(counts) * 1.3) data2 = BinnedData.from_tensor(obs, counts2) data3 = BinnedData.from_tensor(obs, counts3) pdf = zfit.pdf.HistogramPDF(data=data, extended=znp.sum(counts)) pdf2 = zfit.pdf.HistogramPDF(data=data2, extended=znp.sum(counts2)) pdf3 = zfit.pdf.HistogramPDF(data=data3, extended=znp.sum(counts3)) assert len(pdf.ext_pdf(data)) > 0 pdf_sum = zfit.pdf.BinnedSumPDF(pdfs=[pdf, pdf2, pdf3], obs=obs) probs = pdf_sum.counts(data) true_sum_counts = counts + counts2 + counts3 np.testing.assert_allclose(true_sum_counts, probs) nsamples = 100_000_000 sample = pdf_sum.sample(n=nsamples) np.testing.assert_allclose(true_sum_counts, sample.values() / nsamples * pdf_sum.get_yield(), rtol=0.03) # integrate true_integral = znp.sum(true_sum_counts) integral = pdf_sum.ext_integrate(limits=obs) assert pytest.approx(float(true_integral)) == float(integral)
def test_spline_from_binned_from_unbinned(): n = 1004 gauss, gauss_binned, obs, obs_binned = create_gauss_binned(n) x = znp.linspace(-5, 10, n // 5) # values = gauss_binned.rel_counts(obs_binned) sample = gauss_binned.sample(n, limits=obs_binned) title = "Comparison of binned gaussian and sample" plt.figure() plt.title(title) mplhep.histplot(sample.to_hist(), label="sampled binned") plt.plot( obs_binned.binning.centers[0], gauss_binned.counts(obs_binned), label="counts binned", ) plt.legend() pytest.zfit_savefig() spline_gauss = SplinePDF(gauss_binned, obs=obs) # spline_gauss.set_yield(n) # HACK y = spline_gauss.ext_pdf(x) y_true = gauss.ext_pdf(x) plt.figure() plt.title("Comparison of unbinned gauss to binned to interpolated") plt.plot( obs_binned.binning.centers[0], gauss_binned.ext_pdf(obs_binned), "x", label="binned", ) plt.plot(x, y_true, label="original") plt.plot(x, y, ".", label="interpolated") plt.legend() pytest.zfit_savefig() np.testing.assert_allclose(y, y_true, atol=50)
def _run(kdetype, full, upper=None, legacy=True, padding=False): from zfit.z import numpy as znp kde, pdf, data = create_kde(*kdetype, full=full, upper=upper, legacy=legacy, padding=padding) integral = kde.integrate( limits=kde.space, norm=(-3, 2), ) expected_integral = kde.integrate( limits=kde.space, norm=(-3, 2), ) rel_tol = 0.04 sample = kde.sample(1).value() sample2 = kde.sample(1500).value() x = znp.linspace(*kde.space.limit1d, 30000) prob = kde.pdf(x) prob_true = pdf.pdf(x) return ( expected_integral, integral, kde.name, prob, prob_true, rel_tol, sample, sample2, x, kde.name, data, )
def test_morphing_templates(alphas): bins1 = 15 irregular_str = "irregular templates" if alphas is not None else "" counts1 = np.random.uniform(70, high=100, size=bins1) # generate counts counts = [ counts1 - np.random.uniform(high=20, size=bins1), counts1, counts1 + np.random.uniform(high=20, size=bins1), ] if alphas is not None: counts.append(counts1 + np.random.uniform(high=5, size=bins1)) binning = zfit.binned.RegularBinning(bins1, 0, 10, name="obs1") obs = zfit.Space(obs="obs1", binning=binning) histos = [BinnedData.from_tensor(obs, count) for count in counts] pdfs = [zfit.pdf.HistogramPDF(h) for h in histos] if alphas is not None: pdfs = {a: p for a, p in zip(alphas, pdfs)} alpha = zfit.Parameter("alpha", 0, -5, 5) morph = SplineMorphingPDF(alpha=alpha, hists=pdfs) if alphas is None: alphas = [-1, 0, 1] for i, a in enumerate(alphas): alpha.set_value(a) np.testing.assert_allclose(morph.counts(), counts[i]) if len(alphas) > i + 1: alpha.set_value((a + alphas[i + 1]) / 2) max_dist = (counts[i] - counts[i + 1])**2 + 5 # tolerance max_dist *= 1.1 # not strict, it can be a bit higher numpy.testing.assert_array_less((morph.counts() - counts[i])**2, max_dist) numpy.testing.assert_array_less( (morph.counts() - counts[i + 1])**2, max_dist) import matplotlib.cm as cm amin, amax = -2, 2 n = 5 template_alphas = np.array(list(alphas)) for do_3d in [True, False]: plt.figure() if do_3d: ax = plt.gcf().add_subplot(111, projection="3d") else: ax = plt.gca() plotstyle = "3d plot" if do_3d else "hist plot" plt.title(f"Morphing with splines {irregular_str} {plotstyle}") for a in list(znp.linspace(amin, amax, n * 2)) + list(template_alphas): normed_a = (a - amin) / (amax - amin) / 1.3 # 3 is a scaling factor color = cm.get_cmap("winter")(normed_a) alpha.set_value(a) histo = morph.ext_pdf(None) histo = BinnedData.from_tensor(obs, histo) histo = histo.to_hist() values = histo.values() x = histo.axes.edges[0][:-1] y = np.broadcast_to(a, values.shape) z = values label = None if do_3d: ax.step(x, y, z, color=color, where="pre", label=label) else: if np.min((a - template_alphas)**2) < 0.0001: label = f"alpha={a}" mplhep.histplot(histo, label=label, color=color) ax.set_xlabel("observable") ax.set_ylabel("alpha") if do_3d: ax.set_zlabel("ext_pdf") plt.legend() pytest.zfit_savefig()