def xtalball(x, *p): if len(p) == 5: mu, sigma, A, beta, m = p else: print( "Incorrect usage of crystal ball function! params: mu, sigma, area, beta, m. You input: {}" .format(p)) exit(0) return A * crystalball.pdf(x, beta, m, loc=mu, scale=sigma)
def xtalball(x, mu, sigma, A, beta, m): """ power-law tail plus gaussian https://en.wikipedia.org/wiki/Crystal_Ball_function """ return A * crystalball.pdf(x, beta, m, loc=mu, scale=sigma)
import numpy as np from scipy.stats import moyal, crystalball import matplotlib.pyplot as plt fig, ax = plt.subplots(1, 1) # plot moyal pdf loc, scale = 0, 0.625 x = np.linspace(moyal.ppf(0.01, loc, scale), moyal.ppf(0.99, loc, scale), 100) ax.plot(x, moyal.pdf(x, loc, scale), 'r-', alpha=0.6, label='moyal pdf') # plot crystal ball pdf beta, m = 2, 3 x = np.linspace(crystalball.ppf(0.01, beta, m), crystalball.ppf(0.99, beta, m), 100) ax.plot(x, crystalball.pdf(x, beta, m), 'b-', alpha=0.6, label='crystalball pdf') plt.legend() plt.show()
def density_function(x): return crystalball.pdf(x, beta=abs(alpha), m=n, loc=-mu, scale=sigma)
def density_function(x): return crystalball.pdf(x, 1.11, 1.37, -85.6, 55.37)
def density_function(x): return crystalball.pdf(x, 0.99, 1.6, -60.5, 16.3)
def test_cb_dcb(): obs = zfit.Space('x', limits=bounds) mu_ = zfit.Parameter('mu_cb5', mu) sigma_ = zfit.Parameter('sigma_cb5', sigma) alphal_ = zfit.Parameter('alphal_cb5', alphal) nl_ = zfit.Parameter('nl_cb5', nl) alphar_ = zfit.Parameter('alphar_cb5', alphar) nr_ = zfit.Parameter('nr_cb5', nr) cbl = CrystalBall(obs=obs, mu=mu_, sigma=sigma_, alpha=alphal_, n=nl_) cbr = CrystalBall(obs=obs, mu=mu_, sigma=sigma_, alpha=-alphar_, n=nr_) dcb = DoubleCB(obs=obs, mu=mu_, sigma=sigma_, alphal=alphal_, nl=nl_, alphar=alphar_, nr=nr_) sample_testing(cbl) sample_testing(cbr) sample_testing(dcb) x = np.random.normal(mu, sigma, size=10000) probsl = eval_testing(cbl, x) probsr = eval_testing(cbr, x) assert not any(np.isnan(probsl)) assert not any(np.isnan(probsr)) probsl_scipy = crystalball.pdf(x, beta=alphal, m=nl, loc=mu, scale=sigma) probsr_scipy = crystalball.pdf(-x, beta=alphar, m=nr, loc=mu, scale=sigma) ratio_l = probsl_scipy / probsl ratio_r = probsr_scipy / probsr assert np.allclose(ratio_l, ratio_l[0]) assert np.allclose(ratio_r, ratio_r[0]) kwargs = dict(limits=(-5.0, mu), norm_range=lbounds) intl = cbl.integrate(**kwargs) - dcb.integrate(**kwargs) assert pytest.approx(intl.numpy()) == 0. intl = cbr.integrate(**kwargs) - dcb.integrate(**kwargs) assert pytest.approx(intl.numpy()) != 0 kwargs = dict(limits=(mu, 2.0), norm_range=rbounds) intr = cbr.integrate(**kwargs) - dcb.integrate(**kwargs) assert pytest.approx(intr.numpy()) == 0. intr = cbl.integrate(**kwargs) - dcb.integrate(**kwargs) assert pytest.approx(intr.numpy()) != 0. xl = x[x <= mu] xr = x[x > mu] probs_dcb_l = eval_testing(dcb, xl) probs_dcb_r = eval_testing(dcb, xr) probsl_scipy = crystalball.pdf(xl, beta=alphal, m=nl, loc=mu, scale=sigma) probsr_scipy = crystalball.pdf(-xr, beta=alphar, m=nr, loc=mu, scale=sigma) ratio_l = probsl_scipy / probs_dcb_l ratio_r = probsr_scipy / probs_dcb_r assert np.allclose(ratio_l, ratio_l[0]) assert np.allclose(ratio_r, ratio_r[0])
def test_cb_dcb(): obs = zfit.Space("x", limits=bounds) mu_ = zfit.Parameter("mu_cb5", mu) sigma_ = zfit.Parameter("sigma_cb5", sigma) alphal_ = zfit.Parameter("alphal_cb5", alphal) nl_ = zfit.Parameter("nl_cb5", nl) alphar_ = zfit.Parameter("alphar_cb5", alphar) nr_ = zfit.Parameter("nr_cb5", nr) cbl = CrystalBall(obs=obs, mu=mu_, sigma=sigma_, alpha=alphal_, n=nl_) cbr = CrystalBall(obs=obs, mu=mu_, sigma=sigma_, alpha=-alphar_, n=nr_) dcb = DoubleCB(obs=obs, mu=mu_, sigma=sigma_, alphal=alphal_, nl=nl_, alphar=alphar_, nr=nr_) sample_testing(cbl) sample_testing(cbr) sample_testing(dcb) x = np.random.normal(mu, sigma, size=10000) probsl = eval_testing(cbl, x) probsr = eval_testing(cbr, x) assert not any(np.isnan(probsl)) assert not any(np.isnan(probsr)) probsl_scipy = crystalball.pdf(x, beta=alphal, m=nl, loc=mu, scale=sigma) probsr_scipy = crystalball.pdf(-x + 2 * mu, beta=alphar, m=nr, loc=mu, scale=sigma) # We take the ration as the normalization is not fixed ratio_l = probsl_scipy / probsl ratio_r = probsr_scipy / probsr assert np.allclose(ratio_l, ratio_l[0]) assert np.allclose(ratio_r, ratio_r[0]) kwargs = dict(limits=(-5.0, mu), norm_range=lbounds) intl = cbl.integrate(**kwargs) - dcb.integrate(**kwargs) assert pytest.approx(intl.numpy(), abs=1e-3) == 0.0 intl = cbr.integrate(**kwargs) - dcb.integrate(**kwargs) assert pytest.approx(intl.numpy(), abs=1e-3) != 0 # TODO: update test to fixed DCB integral kwargs = dict(limits=(mu, 2.0), norm_range=rbounds) dcb_integr1 = dcb.integrate(**kwargs) intr = cbr.integrate(**kwargs) - dcb_integr1 assert pytest.approx(intr.numpy(), abs=1e-3) == 0.0 intr = cbl.integrate(**kwargs) - dcb.integrate(**kwargs) assert pytest.approx(intr.numpy(), abs=1e-3) != 0.0 xl = x[x <= mu] xr = x[x > mu] probs_dcb_l = eval_testing(dcb, xl) probs_dcb_r = eval_testing(dcb, xr) probsl_scipy = crystalball.pdf(xl, beta=alphal, m=nl, loc=mu, scale=sigma) probsr_scipy = crystalball.pdf(-xr + 2 * mu, beta=alphar, m=nr, loc=mu, scale=sigma) ratio_l = probsl_scipy / probs_dcb_l ratio_r = probsr_scipy / probs_dcb_r assert np.allclose(ratio_l, ratio_l[0]) assert np.allclose(ratio_r, ratio_r[0]) rnd_limits = sorted(np.random.uniform(*bounds, 130)) integrals = [] for low, up in zip(rnd_limits[:-1], rnd_limits[1:]): integrals.append(dcb.integrate((low, up), norm=False)) integral = np.sum(integrals) integral_full = zfit.run(dcb.integrate((bounds[0], up), norm=False)) assert pytest.approx(integral_full, integral)
from scipy.stats import crystalball import matplotlib.pyplot as plt fig, ax = plt.subplots(1, 1) # Calculate a few first moments: beta, m = 2, 3 mean, var, skew, kurt = crystalball.stats(beta, m, moments='mvsk') # Display the probability density function (``pdf``): x = np.linspace(crystalball.ppf(0.01, beta, m), crystalball.ppf(0.99, beta, m), 100) ax.plot(x, crystalball.pdf(x, beta, m), 'r-', lw=5, alpha=0.6, label='crystalball pdf') # Alternatively, the distribution object can be called (as a function) # to fix the shape, location and scale parameters. This returns a "frozen" # RV object holding the given parameters fixed. # Freeze the distribution and display the frozen ``pdf``: rv = crystalball(beta, m) ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf') # Check accuracy of ``cdf`` and ``ppf``: vals = crystalball.ppf([0.001, 0.5, 0.999], beta, m) np.allclose([0.001, 0.5, 0.999], crystalball.cdf(vals, beta, m)) # True