def test_taulnunu_exp(self): # compare to the experimental values # cf. eq. (95) of 1705.00929 self.assertAlmostEqual(flavio.sm_prediction('BR(tau->mununu)') / 0.1739, 1 / 1.0060, delta=0.0003) self.assertAlmostEqual(flavio.sm_prediction('BR(tau->enunu)') / 0.1782, 1 / 1.0022, delta=0.0003)
def test_bksnunu(self): # just check that the SM prediction of BR(B->K*nunu) is OK self.assertAlmostEqual( flavio.sm_prediction('BR(B0->K*nunu)')/9.48e-6, 1, delta=0.2) # just check the other stuff doesn't raise errors flavio.sm_prediction('dBR/dq2(B+->K*nunu)', 11) flavio.sm_prediction('<dBR/dq2>(B+->K*nunu)', 11, 13)
def test_bxgamma(self): # compare SM predictions to arXiv:1503.01789 self.assertAlmostEqual(1e4*flavio.sm_prediction('BR(B->Xsgamma)'), 3.36, delta=0.2) self.assertAlmostEqual(1e5*flavio.sm_prediction('BR(B->Xdgamma)'), 1.73, delta=0.2)
def test_bxll_lratio(self): # compare to arXiv:1503.04849 self.assertAlmostEqual(flavio.sm_prediction('<Rmue>(B->Xsll)', 1, 3.5), 0.96, delta=0.01) self.assertAlmostEqual(flavio.sm_prediction('<Rmue>(B->Xsll)', 14.4, 25), 1.15, delta=0.01) # for tau, just check this doesn't raise an error flavio.sm_prediction('<Rtaumu>(B->Xsll)', 14.4, 25)
def test_bsll_lfv(self): # test for errors self.assertEqual(flavio.sm_prediction('BR(B0->emu)'), 0) self.assertEqual(flavio.sm_prediction('BR(Bs->taumu)'), 0) self.assertEqual(flavio.sm_prediction('BR(B0->emu,mue)'), 0) self.assertEqual(flavio.sm_prediction('BR(Bs->mutau,taumu)'), 0) wc = flavio.WilsonCoefficients() wc.set_initial({'C10_bdemu': 1, 'C10_bdmue': 2}, scale=4.8) self.assertAlmostEqual(flavio.np_prediction('BR(B0->mue)', wc) /flavio.np_prediction('BR(B0->emu)', wc), 4) self.assertAlmostEqual(flavio.np_prediction('BR(B0->emu,mue)', wc) /flavio.np_prediction('BR(B0->emu)', wc), 5)
def test_taulnunu_np3(self): CLSM = -4 * par['GF'] / sqrt(2) w = Wilson({'CVLL_numunueemu': CLSM}, 80, 'WET', 'flavio') BRSM = flavio.sm_prediction('BR(tau->enunu)') BRNP = flavio.np_prediction('BR(tau->enunu)', w) self.assertEqual(BRNP / BRSM, 0.25) w = Wilson({'CVLL_numunueemu': -0.5 * CLSM}, 80, 'WET', 'flavio') BRSM = flavio.sm_prediction('BR(tau->enunu)') BRNP = flavio.np_prediction('BR(tau->enunu)', w) self.assertEqual(BRNP / BRSM, 4)
def test_bpll_lfv(self): # test for errors self.assertEqual(flavio.sm_prediction('BR(B0->Kemu)'), 0) self.assertEqual(flavio.sm_prediction('BR(B+->Ktaumu)'), 0) self.assertEqual(flavio.sm_prediction('BR(B+->pitaumu)'), 0) self.assertEqual(flavio.sm_prediction('BR(B0->pitaumu)'), 0) obs_1 = flavio.classes.Observable["BR(B0->Kemu)"] obs_2 = flavio.classes.Observable["BR(B0->Kmue)"] self.assertEqual(obs_1.prediction_central(flavio.default_parameters, wc_sm), 0) # BR(B->Kemu) should be 4 times larger as Wilson coeff is 2x the mue one self.assertAlmostEqual( obs_1.prediction_central(flavio.default_parameters, wc_lfv) /obs_2.prediction_central(flavio.default_parameters, wc_lfv), 4., places=10)
def testkpinunu(self): self.assertAlmostEqual( flavio.sm_prediction('BR(K+->pinunu)')/1e-10, 1, delta=0.2) self.assertAlmostEqual( flavio.sm_prediction('BR(KL->pinunu)')/3e-11, 1, delta=0.2) obs = flavio.classes.Observable['BR(K+->pinunu)'] wc_sm = flavio.WilsonCoefficients() # confirm that deltaPcu leads to an enhancement of the K+->pinunu BR # by 6% as stated in the abstract of hep-ph/0503107 self.assertAlmostEqual( obs.prediction_central(constraints, wc_sm)/obs.prediction_central(constraints_no_deltaPcu, wc_sm), 1.06, delta=0.01)
def q2_plot_th_diff(obs_name, q2min, q2max, wc=None, q2steps=100, **kwargs): r"""Plot the central theory prediction of a $q^2$-dependent observable as a function of $q^2$. Parameters: - `q2min`, `q2max`: minimum and maximum $q^2$ values in GeV^2 - `wc` (optional): `WilsonCoefficient` instance to define beyond-the-SM Wilson coefficients - `q2steps` (optional): number of $q^2$ steps. Defaults to 100. Less is faster but less precise. Additional keyword arguments are passed to the matplotlib plot function, e.g. 'c' for colour. """ obs = flavio.classes.Observable.get_instance(obs_name) if obs.arguments != ['q2']: raise ValueError(r"Only observables that depend on $q^2$ (and nothing else) are allowed") q2_arr = np.arange(q2min, q2max, (q2max-q2min)/(q2steps-1)) if wc is None: wc = flavio.WilsonCoefficients() # SM Wilson coefficients obs_arr = [flavio.sm_prediction(obs_name, q2) for q2 in q2_arr] else: obs_arr = [flavio.np_prediction(obs_name, wc, q2) for q2 in q2_arr] ax = plt.gca() if 'c' not in kwargs and 'color' not in kwargs: kwargs['c'] = 'k' ax.plot(q2_arr, obs_arr, **kwargs)
def test_bpll_lfv(self): # rough numerical test for branching ratio at high q^2 to old code self.assertAlmostEqual(bpll_dbrdq2(15., wc_obj, par, 'B+', 'K+', 'mu', 'mu')/2.1824401629030333e-8, 1, delta=0.1) # test for errors self.assertEqual(flavio.sm_prediction('BR(B0->Kemu)'), 0) self.assertEqual(flavio.sm_prediction('BR(B+->Ktaumu)'), 0) self.assertEqual(flavio.sm_prediction('BR(B+->pitaumu)'), 0) self.assertEqual(flavio.sm_prediction('BR(B0->pitaumu)'), 0) obs_1 = flavio.classes.Observable.get_instance("BR(B0->Kemu)") obs_2 = flavio.classes.Observable.get_instance("BR(B0->Kmue)") self.assertEqual(obs_1.prediction_central(flavio.default_parameters, wc_sm), 0) # BR(B->Kemu) should be 4 times larger as Wilson coeff is 2x the mue one self.assertAlmostEqual( obs_1.prediction_central(flavio.default_parameters, wc_lfv) /obs_2.prediction_central(flavio.default_parameters, wc_lfv), 4., places=10)
def q2_plot_th_bin(obs_name, bin_list, wc=None, divide_binwidth=False, N=50, **kwargs): r"""Plot the binned theory prediction with uncertainties of a $q^2$-dependent observable as a function of $q^2$ (in the form of coloured boxes).""" obs = flavio.classes.Observable.get_instance(obs_name) if obs.arguments != ['q2min', 'q2max']: raise ValueError(r"Only observables that depend on q2min and q2max (and nothing else) are allowed") if wc is None: wc = flavio.WilsonCoefficients() # SM Wilson coefficients obs_dict = {bin_: flavio.sm_prediction(obs_name, *bin_) for bin_ in bin_list} obs_err_dict = {bin_: flavio.sm_uncertainty(obs_name, *bin_, N=N) for bin_ in bin_list} else: wc = flavio.WilsonCoefficients() # SM Wilson coefficients obs_dict = {bin_:flavio.np_prediction(obs_name, wc, *bin_) for bin_ in bin_list} ax = plt.gca() for bin_, central_ in obs_dict.items(): q2min, q2max = bin_ err = obs_err_dict[bin_] if divide_binwidth: err = err/(q2max-q2min) central = central_/(q2max-q2min) else: central = central_ if 'fc' not in kwargs and 'facecolor' not in kwargs: kwargs['fc'] = flavio.plots.colors.pastel[3] if 'linewidth' not in kwargs and 'lw' not in kwargs: kwargs['lw'] = 0 ax.add_patch(patches.Rectangle((q2min, central-err), q2max-q2min, 2*err,**kwargs))
def q2_plot_th_diff(obs_name, q2min, q2max, wc=None, q2steps=100, **kwargs): r"""Plot the central theory prediction of a $q^2$-dependent observable as a function of $q^2$. Parameters: - `q2min`, `q2max`: minimum and maximum $q^2$ values in GeV^2 - `wc` (optional): `WilsonCoefficient` instance to define beyond-the-SM Wilson coefficients - `q2steps` (optional): number of $q^2$ steps. Defaults to 100. Less is faster but less precise. Additional keyword arguments are passed to the matplotlib plot function, e.g. 'c' for colour. """ obs = flavio.classes.Observable[obs_name] if obs.arguments != ['q2']: raise ValueError(r"Only observables that depend on $q^2$ (and nothing else) are allowed") q2_arr = np.arange(q2min, q2max, (q2max-q2min)/(q2steps-1)) if wc is None: wc = flavio.physics.eft._wc_sm # SM Wilson coefficients obs_arr = [flavio.sm_prediction(obs_name, q2) for q2 in q2_arr] else: obs_arr = [flavio.np_prediction(obs_name, wc, q2) for q2 in q2_arr] ax = plt.gca() if 'c' not in kwargs and 'color' not in kwargs: kwargs['c'] = 'k' ax.plot(q2_arr, obs_arr, **kwargs)
def test_bpll_lfv(self): # test for errors self.assertEqual(flavio.sm_prediction('BR(B0->Kemu)'), 0) self.assertEqual(flavio.sm_prediction('BR(B+->Ktaumu)'), 0) self.assertEqual(flavio.sm_prediction('BR(B+->pitaumu)'), 0) self.assertEqual(flavio.sm_prediction('BR(B0->pitaumu)'), 0) obs_1 = flavio.classes.Observable["BR(B0->Kemu)"] obs_2 = flavio.classes.Observable["BR(B0->Kmue)"] self.assertEqual( obs_1.prediction_central(flavio.default_parameters, wc_sm), 0) # BR(B->Kemu) should be 4 times larger as Wilson coeff is 2x the mue one self.assertAlmostEqual( obs_1.prediction_central(flavio.default_parameters, wc_lfv) / obs_2.prediction_central(flavio.default_parameters, wc_lfv), 4., places=10)
def diff_plot_th(obs_name, x_min, x_max, wc=None, steps=100, **kwargs): r"""Plot the central theory prediction of an observable dependending on a continuous parameter, e.g. $q^2$. Parameters: - `x_min`, `x_max`: minimum and maximum values of the parameter - `wc` (optional): `WilsonCoefficient` instance to define beyond-the-SM Wilson coefficients - `steps` (optional): number of steps in x. Defaults to 100. Less is faster but less precise. Additional keyword arguments are passed to the matplotlib plot function, e.g. 'c' for colour. """ obs = flavio.classes.Observable[obs_name] if not obs.arguments or len(obs.arguments) != 1: raise ValueError(r"Only observables that depend on a single parameter are allowed") x_arr = np.arange(x_min, x_max, (x_max-x_min)/(steps-1)) if wc is None: wc = flavio.physics.eft._wc_sm # SM Wilson coefficients obs_arr = [flavio.sm_prediction(obs_name, x) for x in x_arr] else: obs_arr = [flavio.np_prediction(obs_name, wc, x) for x in x_arr] ax = plt.gca() if 'c' not in kwargs and 'color' not in kwargs: kwargs['c'] = 'k' ax.plot(x_arr, obs_arr, **kwargs)
def diff_plot_th(obs_name, x_min, x_max, wc=None, steps=100, **kwargs): r"""Plot the central theory prediction of an observable dependending on a continuous parameter, e.g. $q^2$. Parameters: - `x_min`, `x_max`: minimum and maximum values of the parameter - `wc` (optional): `WilsonCoefficient` instance to define beyond-the-SM Wilson coefficients - `steps` (optional): number of steps in x. Defaults to 100. Less is faster but less precise. Additional keyword arguments are passed to the matplotlib plot function, e.g. 'c' for colour. """ obs = flavio.classes.Observable[obs_name] if not obs.arguments or len(obs.arguments) != 1: raise ValueError( r"Only observables that depend on a single parameter are allowed") x_arr = np.arange(x_min, x_max, (x_max - x_min) / (steps - 1)) if wc is None: wc = flavio.physics.eft._wc_sm # SM Wilson coefficients obs_arr = [flavio.sm_prediction(obs_name, x) for x in x_arr] else: obs_arr = [flavio.np_prediction(obs_name, wc, x) for x in x_arr] ax = plt.gca() if 'c' not in kwargs and 'color' not in kwargs: kwargs['c'] = 'k' ax.plot(x_arr, obs_arr, **kwargs)
def test_bdsenu(self): Vcb = flavio.default_parameters.get_central('Vcb') # assert that total BR is in the ballpark of the experimental number self.assertAlmostEqual(flavio.sm_prediction('BR(B+->D*lnu)') / 5.41e-2 * 0.04**2 / Vcb**2, 1, delta=0.1)
def test_sm(self): self.assertAlmostEqual(flavio.sm_prediction('BR(W->enu)'), 10.83e-2, delta=0.02e-2) self.assertAlmostEqual(flavio.sm_prediction('BR(W->munu)'), 10.83e-2, delta=0.02e-2) self.assertAlmostEqual(flavio.sm_prediction('BR(W->taunu)'), 10.83e-2, delta=0.02e-2) self.assertAlmostEqual(flavio.sm_prediction('Rmue(W->lnu)'), 1, delta=1e-16) self.assertAlmostEqual(flavio.sm_prediction('Rtaue(W->lnu)'), 1, delta=1e-16) self.assertAlmostEqual(flavio.sm_prediction('Rtaumu(W->lnu)'), 1, delta=1e-16) self.assertAlmostEqual(flavio.sm_prediction('R(W->cX)'), 0.5, delta=1e-16) self.assertAlmostEqual(flavio.sm_prediction('GammaW'), 2.091, delta=0.001)
def test_kpilnu(self): # test for errors q2 = 0.05 flavio.physics.kdecays.kpilnu.get_ff(q2, par, 'KL') flavio.physics.kdecays.kpilnu.get_ff(q2, par, 'K+') flavio.physics.kdecays.kpilnu.get_angularcoeff(q2, wc_obj, par, 'KL', 'pi+', 'e') flavio.physics.kdecays.kpilnu.get_angularcoeff(q2, wc_obj, par, 'KL', 'pi+', 'mu') flavio.physics.kdecays.kpilnu.get_angularcoeff(q2, wc_obj, par, 'K+', 'pi0', 'e') flavio.physics.kdecays.kpilnu.get_angularcoeff(q2, wc_obj, par, 'K+', 'pi0', 'mu') # unphysical q2 self.assertEqual( flavio.physics.kdecays.kpilnu.dBRdq2(0, wc_obj, par, 'KL', 'pi+', 'e'), 0) self.assertEqual( flavio.physics.kdecays.kpilnu.dBRdq2(0.01, wc_obj, par, 'K+', 'pi0', 'mu'), 0) self.assertEqual( flavio.physics.kdecays.kpilnu.dBRdq2(2, wc_obj, par, 'K+', 'pi0', 'e'), 0) self.assertEqual( flavio.physics.kdecays.kpilnu.dBRdq2(1.5, wc_obj, par, 'KL', 'pi+', 'mu'), 0) self.assertEqual( flavio.physics.kdecays.kpilnu.dBRdq2(0.1, wc_obj, par, 'KL', 'pi+', 'tau'), 0) # compare central predictions to PDG values self.assertAlmostEqual(flavio.sm_prediction('BR(KL->pienu)') * 1e2 / 40.55, 1, delta=0.04) self.assertAlmostEqual(flavio.sm_prediction('BR(K+->pienu)') * 1e2 / 5.07, 1, delta=0.04) self.assertAlmostEqual(flavio.sm_prediction('BR(KL->pimunu)') * 1e2 / 27.04, 1, delta=0.02) self.assertAlmostEqual(flavio.sm_prediction('BR(K+->pimunu)') * 1e2 / 3.352, 1, delta=0.03)
def test_taulnunu_np4(self): CLSM = -4 * par['GF'] / sqrt(2) w = Wilson({'CVLL_numunueemu': -0.5 * CLSM, 'CVLL_nutaunueetau': CLSM}, 80, 'WET', 'flavio') BR1 = flavio.sm_prediction('BR(tau->enunu)') BR2 = flavio.np_prediction('BR(tau->enunu)', w) self.assertEqual(BR2 / BR1, 9)
def test_afbz_sm(self): for l in ['e', 'mu', 'tau']: self.assertAlmostEqual(flavio.sm_prediction('A(Z->{}{})'.format( l, l)), 0.1472, delta=0.0002, msg="Failed for {}".format(l)) self.assertAlmostEqual(flavio.sm_prediction('AFB(Z->{}{})'.format( l, l)), 0.0163, delta=0.0002, msg="Failed for {}".format(l)) self.assertAlmostEqual(flavio.sm_prediction('A(Z->bb)'), 0.935, delta=0.001) self.assertAlmostEqual(flavio.sm_prediction('A(Z->cc)'), 0.668, delta=0.001) self.assertAlmostEqual(flavio.sm_prediction('A(Z->ss)'), 0.935, delta=0.001) self.assertAlmostEqual(flavio.sm_prediction('AFB(Z->bb)'), 0.1032, delta=0.0002) self.assertAlmostEqual(flavio.sm_prediction('AFB(Z->cc)'), 0.0738, delta=0.0002)
def test_bs_timedep(self): q2 = 3 wc_obj = flavio.WilsonCoefficients() par = flavio.default_parameters.get_central_all() B = 'Bs' V = 'phi' l = 'mu' # a set of parameters with y_s=0! par_y0 = par.copy() par_y0['DeltaGamma/Gamma_Bs']=0 # compare without lifetime effect: must be equal! self.assertEqual( observables.bvll_obs( observables.dGdq2_ave, q2, wc_obj, par_y0, B, V, l), observables_bs.bsvll_obs( observables_bs.dGdq2_ave_Bs, q2, wc_obj, par_y0, B, V, l)) self.assertEqual( observables.bvll_obs( observables.FL, q2, wc_obj, par_y0, B, V, l), observables_bs.bsvll_obs( observables_bs.FL_Bs, q2, wc_obj, par_y0, B, V, l)) for i in [3, 4, 7]: # S3,4,7 self.assertEqual( observables.bvll_obs( lambda J, J_bar: observables.S_experiment(J, J_bar, i), q2, wc_obj, par_y0, B, V, l), observables_bs.bsvll_obs( lambda y, J, J_bar, J_h: observables_bs.S_experiment_Bs(y, J, J_bar, J_h, i), q2, wc_obj, par_y0, B, V, l)) # check that the phase phi has the right convention q_over_p = flavio.physics.mesonmixing.observables.q_over_p(wc_obj, par, B) phi = cmath.phase(-q_over_p) # the phase of q/p self.assertAlmostEqual(phi, 0.04, delta=0.01) # compare WITH lifetime effect: angular observables must be similar delta = 0.01 self.assertAlmostEqual( observables.bvll_obs( observables.FL, q2, wc_obj, par, B, V, l)/ observables_bs.bsvll_obs( observables_bs.FL_Bs, q2, wc_obj, par, B, V, l), 1, delta=delta) for i in [4, 7]: # S4,7 self.assertAlmostEqual( observables.bvll_obs( lambda J, J_bar: observables.S_experiment(J, J_bar, i), q2, wc_obj, par, B, V, l)/ observables_bs.bsvll_obs( lambda y, J, J_bar, J_h: observables_bs.S_experiment_Bs(y, J, J_bar, J_h, i), q2, wc_obj, par, B, V, l), 1, delta=delta) for i in [3]: # S3: look at differnece only self.assertAlmostEqual( observables.bvll_obs( lambda J, J_bar: observables.S_experiment(J, J_bar, i), q2, wc_obj, par, B, V, l) - observables_bs.bsvll_obs( lambda y, J, J_bar, J_h: observables_bs.S_experiment_Bs(y, J, J_bar, J_h, i), q2, wc_obj, par, B, V, l), 0, delta=0.01) # compare WITH lifetime effect: BR suppressed by ~6%! self.assertAlmostEqual( observables.bvll_obs( observables.dGdq2_ave, q2, wc_obj, par, B, V, l)/ observables_bs.bsvll_obs( observables_bs.dGdq2_ave_Bs, q2, wc_obj, par, B, V, l), 1.06, delta=0.02) # and now just check a few observables to see if any errors are raised flavio.sm_prediction("FL(Bs->phimumu)", q2=1) flavio.sm_prediction("S3(Bs->phimumu)", q2=1) flavio.sm_prediction("S4(Bs->phimumu)", q2=1) flavio.sm_prediction("S7(Bs->phimumu)", q2=1)
def test_taulnunu_np4(self): CLSM = -4 * par['GF'] / sqrt(2) w = Wilson({ 'CVLL_numunueemu': -0.5 * CLSM, 'CVLL_nutaunueetau': CLSM }, 80, 'WET', 'flavio') BR1 = flavio.sm_prediction('BR(tau->enunu)') BR2 = flavio.np_prediction('BR(tau->enunu)', w) self.assertEqual(BR2 / BR1, 9)
def test_blnu(self): Vub = flavio.physics.ckm.get_ckm(par)[0,2] # compare to literature value self.assertAlmostEqual( flavio.Observable["BR(B+->taunu)"].prediction_central(constraints, wc_obj), 1.1e-4 * (abs(Vub)/3.95e-3)**2 * (par['f_B+']/0.2)**2, delta=2e-6) # check that B->enu BR is smaller than B->munu # (ratio given by mass ratio squared) self.assertAlmostEqual( ( flavio.Observable["BR(B+->enu)"].prediction_central(constraints, wc_obj)/ flavio.Observable["BR(B+->munu)"].prediction_central(constraints, wc_obj) )/(par['m_e']**2/par['m_mu']**2), 1, delta=0.001) # there are corrections of order mmu**2/mB**2 # check that Bc->taunu works without errors flavio.sm_prediction('BR(Bc->taunu)')
def test_ae_SM(self): self.assertAlmostEqual(flavio.sm_prediction('a_e') / ae_SM, 1) pd = flavio.combine_measurements('a_e') ae_exp = pd.central_value ae_err_exp = pd.error_left np.random.seed(17) ae_err_sm = flavio.sm_uncertainty('a_e') # check that there is a -2.3 sigma tension, see 1804.07409 p. 13 self.assertAlmostEqual((ae_exp - ae_SM) / sqrt(ae_err_sm**2 + ae_err_exp**2), -2.3, delta=0.5)
def test_lfratios(self): self.assertAlmostEqual( flavio.sm_prediction('<Rmue>(B->Dlnu)', 0.5, 5), 1, delta=0.01) self.assertAlmostEqual( flavio.sm_prediction('<Rmue>(B->pilnu)', 0.5, 5), 1, delta=0.01) self.assertAlmostEqual( flavio.sm_prediction('Rmue(B->Dlnu)'), 1, delta=0.01) self.assertAlmostEqual( flavio.sm_prediction('Rmue(B->pilnu)'), 1, delta=0.01) # for the taus, just make sure no error is raised flavio.sm_prediction('Rtaumu(B->pilnu)') flavio.sm_prediction('<Rtaumu>(B->Dlnu)', 15, 16)
def test_np(self): wc = flavio.WilsonCoefficients() for l in ['e', 'mu', 'tau']: wc.set_initial({'CSL_bc' + l + 'nu' + l: 1}, 4.8) self.assertTrue(par['tau_Bc_SM'] / flavio.np_prediction('tau_Bc', wc) > 1.1) self.assertAlmostEqual(par['tau_Bc_SM'] / flavio.np_prediction('tau_Bc', wc), 1 + flavio.np_prediction('BR(Bc->' + l + 'nu)', wc) - flavio.sm_prediction('BR(Bc->' + l + 'nu)'), delta=0.05, msg="Failed for {}".format(l))
def test_fl(self): # compare to 1409.4557 table 2 self.assertAlmostEqual(flavio.sm_prediction('<FL>(B0->K*nunu)', 0, 27), 0.47, delta=2 * 0.03) self.assertAlmostEqual(flavio.sm_prediction('<FL>(B0->K*nunu)', 0, 4), 0.79, delta=2 * 0.03) self.assertAlmostEqual(flavio.sm_prediction('<FL>(B0->K*nunu)', 16, 19.25), 0.32, delta=2 * 0.03) # ... and the differential ones self.assertAlmostEqual(flavio.sm_prediction('FL(B0->K*nunu)', 2), 0.79, delta=3 * 0.03) self.assertAlmostEqual(flavio.sm_prediction('FL(B0->K*nunu)', 17.5), 0.32, delta=3 * 0.03)
def test_ft(self): # compare to exp values in table 4 of 1803.08732 wc_obj = flavio.WilsonCoefficients() Ft = flavio.physics.betadecays.ft.Ft_superallowed(par, wc_obj, '10C') self.assertAlmostEqual(Ft / s, 3078, delta=2 * 5) Ft = flavio.physics.betadecays.ft.Ft_superallowed(par, wc_obj, '26mAl') self.assertAlmostEqual(Ft / s, 3072.9, delta=3 * 1) Ft = flavio.physics.betadecays.ft.Ft_superallowed(par, wc_obj, '46V') self.assertAlmostEqual(Ft / s, 3074.1, delta=2 * 2) Ft = flavio.sm_prediction('Ft(38Ca)') self.assertAlmostEqual(Ft / s, 3076.4, delta=2 * 7.2)
def test_kpilnu(self): # test for errors q2=0.05 flavio.physics.kdecays.kpilnu.get_ff(q2, par, 'KL') flavio.physics.kdecays.kpilnu.get_ff(q2, par, 'K+') flavio.physics.kdecays.kpilnu.get_angularcoeff(q2, wc_obj, par, 'KL', 'pi+', 'e') flavio.physics.kdecays.kpilnu.get_angularcoeff(q2, wc_obj, par, 'KL', 'pi+', 'mu') flavio.physics.kdecays.kpilnu.get_angularcoeff(q2, wc_obj, par, 'K+', 'pi0', 'e') flavio.physics.kdecays.kpilnu.get_angularcoeff(q2, wc_obj, par, 'K+', 'pi0', 'mu') # unphysical q2 self.assertEqual(flavio.physics.kdecays.kpilnu.dBRdq2(0, wc_obj, par, 'KL', 'pi+', 'e'), 0) self.assertEqual(flavio.physics.kdecays.kpilnu.dBRdq2(0.01, wc_obj, par, 'K+', 'pi0', 'mu'), 0) self.assertEqual(flavio.physics.kdecays.kpilnu.dBRdq2(2, wc_obj, par, 'K+', 'pi0', 'e'), 0) self.assertEqual(flavio.physics.kdecays.kpilnu.dBRdq2(1.5, wc_obj, par, 'KL', 'pi+', 'mu'), 0) self.assertEqual(flavio.physics.kdecays.kpilnu.dBRdq2(0.1, wc_obj, par, 'KL', 'pi+', 'tau'), 0) # compare central predictions to PDG values self.assertAlmostEqual(flavio.sm_prediction('BR(KL->pienu)')*1e2/40.55, 1, delta=0.04) self.assertAlmostEqual(flavio.sm_prediction('BR(K+->pienu)')*1e2/5.07, 1, delta=0.04) self.assertAlmostEqual(flavio.sm_prediction('BR(KL->pimunu)')*1e2/27.04, 1, delta=0.02) self.assertAlmostEqual(flavio.sm_prediction('BR(K+->pimunu)')*1e2/3.352, 1, delta=0.03)
def test_ae_SM(self): self.assertAlmostEqual(flavio.sm_prediction('a_e') / ae_SM, 1) pd = flavio.combine_measurements('a_e') ae_exp = pd.central_value ae_err_exp = pd.error_left np.random.seed(17) ae_err_sm = flavio.sm_uncertainty('a_e') # check that there is a -2.3 sigma tension, see 1804.07409 p. 13 self.assertAlmostEqual( (ae_exp - ae_SM) / sqrt(ae_err_sm**2 + ae_err_exp**2), -2.3, delta=0.5)
def chi2_budget(wc=None): chi = [] for i in range(0, nobs): if isinstance(obslist[i]['obs'], tuple): if wc is None: th = flavio.sm_prediction(obslist[i]['obs'][0], q2min=obslist[i]['obs'][1], q2max=obslist[i]['obs'][2]) else: th = flavio.np_prediction(obslist[i]['obs'][0], wc_obj=wc, q2min=obslist[i]['obs'][1], q2max=obslist[i]['obs'][2]) else: if wc is None: th = flavio.sm_prediction(obslist[i]['obs']) else: th = flavio.np_prediction(obslist[i]['obs'], wc_obj=wc) chi.append((th - obslist[i]['central'])**2 / obslist[i]['error']**2) return chi
def test_bxclnu(self): # check that the NLO and NNLO functions reproduce the correct numbers self.assertAlmostEqual( flavio.physics.bdecays.bxlnu.pc1(r=(0.986/4.6)**2, mb=4.6), -1.65019, delta=0.001) self.assertAlmostEqual( flavio.physics.bdecays.bxlnu.pc2(r=(0.986/4.6)**2, mb=4.6), -1.91556 -0.4519 * 9 , delta=0.001) # check that the total BR roughly agrees with the experimental value self.assertAlmostEqual( flavio.sm_prediction('BR(B->Xcenu)'), 0.1065, delta = 0.0005) self.assertAlmostEqual( flavio.sm_prediction('BR(B->Xcmunu)'), 0.1065, delta = 0.0005) self.assertAlmostEqual( flavio.sm_prediction('BR(B->Xclnu)'), 0.1065, delta = 0.0005)
def test_lfv(self): obs_1 = flavio.classes.Observable.get_instance("BR(B0->K*emu)") obs_2 = flavio.classes.Observable.get_instance("BR(B0->K*mue)") self.assertEqual(obs_1.prediction_central(flavio.default_parameters, wc_sm), 0) # BR(B->K*emu) should be 4 times larger as Wilson coeff is 2x the mue one self.assertAlmostEqual( obs_1.prediction_central(flavio.default_parameters, wc_np) /obs_2.prediction_central(flavio.default_parameters, wc_np), 4., places=10) # test for errors flavio.sm_prediction("BR(B+->K*mue)") flavio.sm_prediction("BR(B0->rhotaue)") flavio.sm_prediction("BR(B+->rhotaumu)") flavio.sm_prediction("BR(Bs->phimutau)")
def test_bxll(self): # check whether QED corrections have the right behaviour wc_obj = flavio.WilsonCoefficients() par = flavio.default_parameters.get_central_all() br_1_noqedpc = _bxll_dbrdq2(1, wc_obj, par, 's', 'mu', include_qed=False, include_pc=False) br_1_qed = _bxll_dbrdq2(1, wc_obj, par, 's', 'mu', include_qed=True, include_pc=False) br_6_noqedpc = _bxll_dbrdq2(6, wc_obj, par, 's', 'mu', include_qed=False, include_pc=False) br_6_qed = _bxll_dbrdq2(6, wc_obj, par, 's', 'mu', include_qed=True, include_pc=False) br_15_noqedpc = _bxll_dbrdq2(15, wc_obj, par, 's', 'mu', include_qed=False, include_pc=False) br_15_qed = _bxll_dbrdq2(15, wc_obj, par, 's', 'mu', include_qed=True, include_pc=False) br_21_noqedpc = _bxll_dbrdq2(21, wc_obj, par, 's', 'mu', include_qed=False, include_pc=False) br_21_qed = _bxll_dbrdq2(21, wc_obj, par, 's', 'mu', include_qed=True, include_pc=False) self.assertAlmostEqual((br_1_qed+br_6_qed)/(br_1_noqedpc+br_6_noqedpc), 1.02, delta=0.01) # should lead to a 2% enhancement self.assertAlmostEqual((br_15_qed+br_21_qed)/(br_15_noqedpc+br_21_noqedpc), 0.92, delta=0.03) # should lead to a 8% suppression # compare SM predictions to arXiv:1503.04849 # to convert to the parameters used there xi_t = flavio.physics.ckm.xi('t','bs')(par) Vcb = flavio.physics.ckm.get_ckm(par)[1,2] r = abs(xi_t)**2/Vcb**2/0.9621*0.574/par['C_BXlnu']*par['BR(B->Xcenu)_exp']/0.1051 self.assertAlmostEqual(1e6*flavio.sm_prediction('<BR>(B->Xsmumu)', 1, 3.5)/r, 0.888, delta=0.02) self.assertAlmostEqual(1e6*flavio.sm_prediction('<BR>(B->Xsmumu)', 3.5, 6)/r, 0.731, delta=0.01) self.assertAlmostEqual(1e7*flavio.sm_prediction('<BR>(B->Xsmumu)', 14.4, 25)/r, 2.53, delta=0.7) # larger difference due to Krüger-Sehgal self.assertAlmostEqual(1e6*flavio.sm_prediction('<BR>(B->Xsee)', 1, 3.5)/r, 0.926, delta=0.04) self.assertAlmostEqual(1e6*flavio.sm_prediction('<BR>(B->Xsee)', 3.5, 6)/r, 0.744, delta=0.015) self.assertAlmostEqual(1e7*flavio.sm_prediction('<BR>(B->Xsee)', 14.4, 25)/r, 2.20, delta=0.6) # larger difference due to Krüger-Sehgal
def test_bxll(self): # check whether QED corrections have the right behaviour wc_obj = flavio.WilsonCoefficients() par = flavio.default_parameters.get_central_all() br_1_noqedpc = _bxll_dbrdq2(1, wc_obj, par, 's', 'mu', include_qed=False, include_pc=False) br_1_qed = _bxll_dbrdq2(1, wc_obj, par, 's', 'mu', include_qed=True, include_pc=False) br_6_noqedpc = _bxll_dbrdq2(6, wc_obj, par, 's', 'mu', include_qed=False, include_pc=False) br_6_qed = _bxll_dbrdq2(6, wc_obj, par, 's', 'mu', include_qed=True, include_pc=False) br_15_noqedpc = _bxll_dbrdq2(15, wc_obj, par, 's', 'mu', include_qed=False, include_pc=False) br_15_qed = _bxll_dbrdq2(15, wc_obj, par, 's', 'mu', include_qed=True, include_pc=False) br_21_noqedpc = _bxll_dbrdq2(21, wc_obj, par, 's', 'mu', include_qed=False, include_pc=False) br_21_qed = _bxll_dbrdq2(21, wc_obj, par, 's', 'mu', include_qed=True, include_pc=False) self.assertAlmostEqual((br_1_qed+br_6_qed)/(br_1_noqedpc+br_6_noqedpc), 1.02, delta=0.01) # should lead to a 2% enhancement self.assertAlmostEqual((br_15_qed+br_21_qed)/(br_15_noqedpc+br_21_noqedpc), 0.92, delta=0.03) # should lead to a 8% suppression # compare SM predictions to arXiv:1503.04849 # to convert to the parameters used there xi_t = flavio.physics.ckm.xi('t','bs')(par) Vcb = flavio.physics.ckm.get_ckm(par)[1,2] r = abs(xi_t)**2/Vcb**2/0.9621*0.574/par['C_BXlnu']*par['BR(B->Xcenu)_exp']/0.1051 self.assertAlmostEqual(1e6*flavio.sm_prediction('<BR>(B->Xsmumu)', 1, 3.5)/r, 0.888, delta=0.02) self.assertAlmostEqual(1e6*flavio.sm_prediction('<BR>(B->Xsmumu)', 3.5, 6)/r, 0.731, delta=0.01) self.assertAlmostEqual(1e7*flavio.sm_prediction('<BR>(B->Xsmumu)', 14.4, 25)/r, 2.53, delta=0.6) # larger difference due to Krüger-Sehgal self.assertAlmostEqual(1e6*flavio.sm_prediction('<BR>(B->Xsee)', 1, 3.5)/r, 0.926, delta=0.04) self.assertAlmostEqual(1e6*flavio.sm_prediction('<BR>(B->Xsee)', 3.5, 6)/r, 0.744, delta=0.015) self.assertAlmostEqual(1e7*flavio.sm_prediction('<BR>(B->Xsee)', 14.4, 25)/r, 2.20, delta=0.6) # larger difference due to Krüger-Sehgal
def test_bkll(self): # rough numerical test for branching ratio at high q^2 to old code self.assertAlmostEqual(bpll_dbrdq2(15., wc_obj, par, 'B+', 'K+', 'mu', 'mu')/2.1824401629030333e-8, 1, delta=0.1) # test for errors flavio.sm_prediction('dBR/dq2(B0->Kmumu)', q2=3) flavio.sm_prediction('AFB(B0->Kmumu)', q2=15) flavio.sm_prediction('FH(B+->Kmumu)', q2=21)
def test_lfv(self): obs_1 = flavio.classes.Observable["BR(B0->K*emu)"] obs_2 = flavio.classes.Observable["BR(B0->K*mue)"] self.assertEqual(obs_1.prediction_central(flavio.default_parameters, wc_sm), 0) # BR(B->K*emu) should be 4 times larger as Wilson coeff is 2x the mue one self.assertAlmostEqual( obs_1.prediction_central(flavio.default_parameters, wc_np) /obs_2.prediction_central(flavio.default_parameters, wc_np), 4., places=10) # test for errors flavio.sm_prediction("BR(B+->K*mue)") flavio.sm_prediction("BR(B0->rhotaue)") flavio.sm_prediction("BR(B+->rhotaumu)") flavio.sm_prediction("BR(Bs->phimutau)")
def test_tau3l_sm(self): self.assertEqual(flavio.sm_prediction('BR(tau->muee)'), 0) self.assertEqual(flavio.sm_prediction('BR(tau->mumumu)'), 0) self.assertEqual(flavio.sm_prediction('BR(tau->emumu)'), 0) self.assertEqual(flavio.sm_prediction('BR(tau->eee)'), 0) self.assertEqual(flavio.sm_prediction('BR(tau->emue)'), 0) self.assertEqual(flavio.sm_prediction('BR(tau->muemu)'), 0)
def test_bpll_lfv(self): # rough numerical test for branching ratio at high q^2 to old code self.assertAlmostEqual( bpll_dbrdq2(15., wc_obj, par, 'B+', 'K+', 'mu', 'mu') / 2.1824401629030333e-8, 1, delta=0.1) # test for errors self.assertEqual(flavio.sm_prediction('BR(B0->Kemu)'), 0) self.assertEqual(flavio.sm_prediction('BR(B+->Ktaumu)'), 0) self.assertEqual(flavio.sm_prediction('BR(B+->pitaumu)'), 0) self.assertEqual(flavio.sm_prediction('BR(B0->pitaumu)'), 0) obs_1 = flavio.classes.Observable["BR(B0->Kemu)"] obs_2 = flavio.classes.Observable["BR(B0->Kmue)"] self.assertEqual( obs_1.prediction_central(flavio.default_parameters, wc_sm), 0) # BR(B->Kemu) should be 4 times larger as Wilson coeff is 2x the mue one self.assertAlmostEqual( obs_1.prediction_central(flavio.default_parameters, wc_lfv) / obs_2.prediction_central(flavio.default_parameters, wc_lfv), 4., places=10)
def q2_plot_th_bin(obs_name, bin_list, wc=None, divide_binwidth=False, N=50, **kwargs): r"""Plot the binned theory prediction with uncertainties of a $q^2$-dependent observable as a function of $q^2$ (in the form of coloured boxes). Parameters: - `bin_list`: a list of tuples containing bin boundaries - `wc` (optional): `WilsonCoefficient` instance to define beyond-the-SM Wilson coefficients - `divide_binwidth` (optional): this should be set to True when comparing integrated branching ratios from experiments with different bin widths or to theory predictions for a differential branching ratio. It will divide all values and uncertainties by the bin width (i.e. dimensionless integrated BRs will be converted to integrated differential BRs with dimensions of GeV$^{-2}$). Defaults to False. - `N` (optional): number of random draws to determine the uncertainty. Defaults to 50. Larger is slower but more precise. The relative error of the theory uncertainty scales as $1/\sqrt{2N}$. Additional keyword arguments are passed to the matplotlib add_patch function, e.g. 'fc' for face colour. """ obs = flavio.classes.Observable[obs_name] if obs.arguments != ['q2min', 'q2max']: raise ValueError(r"Only observables that depend on q2min and q2max (and nothing else) are allowed") if wc is None: wc = flavio.physics.eft._wc_sm # SM Wilson coefficients obs_dict = {bin_: flavio.sm_prediction(obs_name, *bin_) for bin_ in bin_list} obs_err_dict = {bin_: flavio.sm_uncertainty(obs_name, *bin_, N=N) for bin_ in bin_list} else: obs_dict = {bin_:flavio.np_prediction(obs_name, wc, *bin_) for bin_ in bin_list} obs_err_dict = {bin_: flavio.np_uncertainty(obs_name, wc, *bin_, N=N) for bin_ in bin_list} ax = plt.gca() for _i, (bin_, central_) in enumerate(obs_dict.items()): q2min, q2max = bin_ err = obs_err_dict[bin_] if divide_binwidth: err = err/(q2max-q2min) central = central_/(q2max-q2min) else: central = central_ if 'fc' not in kwargs and 'facecolor' not in kwargs: kwargs['fc'] = flavio.plots.colors.pastel[3] if 'linewidth' not in kwargs and 'lw' not in kwargs: kwargs['lw'] = 0 if _i > 0: # the label should only be set for one (i.e. the first) # of the boxes, otherwise it will appear multiply in the legend kwargs.pop('label', None) ax.add_patch(patches.Rectangle((q2min, central-err), q2max-q2min, 2*err,**kwargs))
def bin_plot_th(obs_name, bin_list, wc=None, divide_binwidth=False, N=50, threads=1, **kwargs): r"""Plot the binned theory prediction with uncertainties of an observable dependending on a continuous parameter, e.g. $q^2$ (in the form of coloured boxes). Parameters: - `bin_list`: a list of tuples containing bin boundaries - `wc` (optional): `WilsonCoefficient` instance to define beyond-the-SM Wilson coefficients - `divide_binwidth` (optional): this should be set to True when comparing integrated branching ratios from experiments with different bin widths or to theory predictions for a differential branching ratio. It will divide all values and uncertainties by the bin width (i.e. dimensionless integrated BRs will be converted to $q^2$-integrated differential BRs with dimensions of GeV$^{-2}$). Defaults to False. - `N` (optional): number of random draws to determine the uncertainty. Defaults to 50. Larger is slower but more precise. The relative error of the theory uncertainty scales as $1/\sqrt{2N}$. Additional keyword arguments are passed to the matplotlib add_patch function, e.g. 'fc' for face colour. """ obs = flavio.classes.Observable[obs_name] if not obs.arguments or len(obs.arguments) != 2: raise ValueError(r"Only observables that depend on the two bin boundaries (and nothing else) are allowed") if wc is None: wc = flavio.physics.eft._wc_sm # SM Wilson coefficients obs_dict = {bin_: flavio.sm_prediction(obs_name, *bin_) for bin_ in bin_list} obs_err_dict = {bin_: flavio.sm_uncertainty(obs_name, *bin_, N=N, threads=threads) for bin_ in bin_list} else: obs_dict = {bin_:flavio.np_prediction(obs_name, wc, *bin_) for bin_ in bin_list} obs_err_dict = {bin_: flavio.np_uncertainty(obs_name, wc, *bin_, N=N, threads=threads) for bin_ in bin_list} ax = plt.gca() for _i, (bin_, central_) in enumerate(obs_dict.items()): xmin, xmax = bin_ err = obs_err_dict[bin_] if divide_binwidth: err = err/(xmax-xmin) central = central_/(xmax-xmin) else: central = central_ if 'fc' not in kwargs and 'facecolor' not in kwargs: kwargs['fc'] = flavio.plots.colors.pastel[3] if 'linewidth' not in kwargs and 'lw' not in kwargs: kwargs['lw'] = 0 if _i > 0: # the label should only be set for one (i.e. the first) # of the boxes, otherwise it will appear multiply in the legend kwargs.pop('label', None) ax.add_patch(patches.Rectangle((xmin, central-err), xmax-xmin, 2*err,**kwargs))
def test_fl(self): # compare to 1409.4557 table 2 self.assertAlmostEqual( flavio.sm_prediction('<FL>(B0->K*nunu)', 0, 27), 0.47, delta=2*0.03) self.assertAlmostEqual( flavio.sm_prediction('<FL>(B0->K*nunu)', 0, 4), 0.79, delta=2*0.03) self.assertAlmostEqual( flavio.sm_prediction('<FL>(B0->K*nunu)', 16, 19.25), 0.32, delta=2*0.03) # ... and the differential ones self.assertAlmostEqual( flavio.sm_prediction('FL(B0->K*nunu)', 2), 0.79, delta=3*0.03) self.assertAlmostEqual( flavio.sm_prediction('FL(B0->K*nunu)', 17.5), 0.32, delta=3*0.03)
def test_functions(self): o = Observable('test_obs') o.arguments = ['x'] def f(wc_obj, par_dict, x): return x pr = Prediction('test_obs', f ) wc_obj = None self.assertEqual(flavio.sm_prediction('test_obs', 7), 7) self.assertEqual(flavio.np_prediction('test_obs', x=7, wc_obj=wc_obj), 7) self.assertEqual(flavio.sm_uncertainty('test_obs', 7), 0) self.assertEqual(flavio.np_uncertainty('test_obs', x=7, wc_obj=wc_obj), 0) self.assertEqual(flavio.sm_uncertainty('test_obs', 7, threads=2), 0) self.assertEqual(flavio.np_uncertainty('test_obs', x=7, wc_obj=wc_obj, threads=2), 0) # delete dummy instance Observable.del_instance('test_obs')
def test_acp(self): # check that the SM central values for the individual B->Xsgamma # and B->Xdgamma (ignoring long distance contributions) roughly # agree with the values quoted in hep-ph/0312260 wc_sm_s = flavio.physics.bdecays.wilsoncoefficients.wctot_dict(wc_obj, 'bsee', scale=2, par=par_dict, nf_out=5) wc_sm_d = flavio.physics.bdecays.wilsoncoefficients.wctot_dict(wc_obj, 'bdee', scale=2, par=par_dict, nf_out=5) p_ave_s = flavio.physics.bdecays.bxgamma.PE0_BR_BXgamma(wc_sm_s, par_dict, 's', 1.6) p_asy_s = flavio.physics.bdecays.bxgamma.PE0_ACP_BXgamma(wc_sm_s, par_dict, 's', 1.6) acp_s = p_asy_s/p_ave_s self.assertAlmostEqual(100*acp_s, 0.44, delta=0.5) p_ave_d = flavio.physics.bdecays.bxgamma.PE0_BR_BXgamma(wc_sm_d, par_dict, 'd', 1.6) p_asy_d = flavio.physics.bdecays.bxgamma.PE0_ACP_BXgamma(wc_sm_d, par_dict, 'd', 1.6) acp_d = p_asy_d/p_ave_d # check that the s+d CP asymmetry vanishes self.assertAlmostEqual(flavio.sm_prediction('ACP(B->Xgamma)'), 0, delta=1e-9)
def q2_plot_th_diff(obs_name, q2min, q2max, wc=None, q2steps=100, **kwargs): r"""Plot the central theory prediction of a $q^2$-dependent observable as a function of $q^2$.""" obs = flavio.classes.Observable.get_instance(obs_name) if obs.arguments != ['q2']: raise ValueError(r"Only observables that depend on $q^2$ (and nothing else) are allowed") q2_arr = np.arange(q2min, q2max, (q2max-q2min)/(q2steps-1)) if wc is None: wc = flavio.WilsonCoefficients() # SM Wilson coefficients obs_arr = [flavio.sm_prediction(obs_name, q2) for q2 in q2_arr] else: obs_arr = [flavio.np_prediction(obs_name, wc, q2) for q2 in q2_arr] ax = plt.gca() if 'c' not in kwargs and 'color' not in kwargs: kwargs['c'] = 'k' ax.plot(q2_arr, obs_arr, **kwargs)
def test_unphysical(self): # check BR calculation yields zero outside kinematical limits self.assertEqual(flavio.sm_prediction("dBR/dq2(B0->K*mumu)", q2=0.01), 0) self.assertEqual(flavio.sm_prediction("dBR/dq2(B0->K*mumu)", q2=25), 0) # and also *at* kinemetical limits par = flavio.default_parameters.get_central_all() q2min = 4*par['m_mu']**2 q2max = (par['m_B0']-par['m_K*0'])**2 self.assertAlmostEqual(flavio.sm_prediction("dBR/dq2(B0->K*mumu)", q2=q2min), 0, delta=1e-10) self.assertAlmostEqual(flavio.sm_prediction("dBR/dq2(B0->K*mumu)", q2=q2max), 0, delta=1e-10) # same for angular observables (make sure no division by 0) self.assertEqual(flavio.sm_prediction("S5(B0->K*mumu)", q2=0.01), 0) self.assertEqual(flavio.sm_prediction("S5(B0->K*mumu)", q2=25), 0)
def test_bsll(self): # just some trivial tests to see if calling the functions raises an error self.assertGreater(br_lifetime_corr(0.08, -1), 0) self.assertEqual(len(amplitudes(par, wc, 'Bs', 'mu', 'mu')), 2) # ADeltaGamma should be +1.0 in the SM self.assertEqual(ADeltaGamma(par, wc, 'Bs', 'mu'), 1.0) self.assertEqual(flavio.sm_prediction('ADeltaGamma(Bs->mumu)'), 1.0) # BR should be around 3.5e-9 self.assertAlmostEqual(br_inst(par, wc, 'Bs', 'mu', 'mu')*1e9, 3.5, places=0) # correction factor should enhance the BR by roughly 7% self.assertAlmostEqual(br_timeint(par, wc, 'Bs', 'mu', 'mu')/br_inst(par, wc, 'Bs', 'mu', 'mu'), 1.07, places=2) # ratio of Bs->mumu and Bs->ee BRs should be roughly given by ratio of squared masses self.assertAlmostEqual( br_timeint(par, wc_e, 'Bs', 'e', 'e')/br_timeint(par, wc, 'Bs', 'mu', 'mu')/par['m_e']**2*par['m_mu']**2, 1., places=2) # comparison to 1311.0903 self.assertAlmostEqual(abs(ckm.xi('t','bs')(par))/par['Vcb'], 0.980, places=3) self.assertAlmostEqual(br_timeint(par, wc, 'Bs', 'mu', 'mu')/3.65e-9, 1, places=1) self.assertAlmostEqual(br_timeint(par, wc_e, 'Bs', 'e', 'e')/8.54e-14, 1, places=1) self.assertAlmostEqual(br_timeint(par, wc_tau, 'Bs', 'tau', 'tau')/7.73e-7, 1, places=1)
def test_diff_ee_ww_NP(self): coeffs = ['phiWB', 'phiD', 'phil3_11', 'phil3_22', 'll_1221', 'phil1_11', 'phie_11'] for coeff in coeffs: for E in [182.66, 189.09, 198.38, 205.92]: _E = Es.flat[np.abs(Es - E).argmin()] dsigma = [] dsigma_sm = [] for i in range(10): args = (E, np.round(i * 0.2 - 1, 1), np.round((i + 1) * 0.2 - 1, 1)) w = wilson.Wilson({coeff: 0.1 / 246.22**2}, 91.1876, 'SMEFT', 'Warsaw') dsigma.append(np_prediction('<dR/dtheta>(ee->WW)', w, *args)) dsigma_sm.append(sm_prediction('<dR/dtheta>(ee->WW)', *args)) r_tot = np_prediction('R(ee->WW)', w, _E) sigma_tot_sm = sum(dsigma_sm) sigma_tot = sum(dsigma) self.assertAlmostEqual(sigma_tot / sigma_tot_sm, r_tot, delta=0.25, msg="Failed for E={}, C_{}".format(E, coeff))
def test_corrn(self): # compare to exp values in table 5 of 1803.08732 self.assertAlmostEqual(flavio.sm_prediction('a_n'), -0.1034, delta=2 * 0.0037) self.assertAlmostEqual(flavio.sm_prediction('atilde_n', me_E=0.695), -0.1090, delta=0.01) self.assertAlmostEqual(flavio.sm_prediction('Atilde_n', me_E=0.569), -0.11869, delta=0.01) self.assertAlmostEqual(flavio.sm_prediction('Btilde_n', me_E=0.591), 0.9805, delta=3 * 0.003) self.assertAlmostEqual(flavio.sm_prediction('lambdaAB_n', me_E=0.581), -1.2686, delta=0.04) self.assertEqual(flavio.sm_prediction('D_n'), 0) self.assertEqual(flavio.sm_prediction('R_n'), 0)
def test_acp(self): # check that the SM central values for the individual B->Xsgamma # and B->Xdgamma (ignoring long distance contributions) roughly # agree with the values quoted in hep-ph/0312260 wc_sm_s = flavio.physics.bdecays.wilsoncoefficients.wctot_dict( wc_obj, 'bsee', scale=2, par=par_dict, nf_out=5) wc_sm_d = flavio.physics.bdecays.wilsoncoefficients.wctot_dict( wc_obj, 'bdee', scale=2, par=par_dict, nf_out=5) p_ave_s = flavio.physics.bdecays.bxgamma.PE0_BR_BXgamma( wc_sm_s, par_dict, 's', 1.6) p_asy_s = flavio.physics.bdecays.bxgamma.PE0_ACP_BXgamma( wc_sm_s, par_dict, 's', 1.6) acp_s = p_asy_s / p_ave_s self.assertAlmostEqual(100 * acp_s, 0.44, delta=0.5) p_ave_d = flavio.physics.bdecays.bxgamma.PE0_BR_BXgamma( wc_sm_d, par_dict, 'd', 1.6) p_asy_d = flavio.physics.bdecays.bxgamma.PE0_ACP_BXgamma( wc_sm_d, par_dict, 'd', 1.6) acp_d = p_asy_d / p_ave_d # check that the s+d CP asymmetry vanishes self.assertAlmostEqual(flavio.sm_prediction('ACP(B->Xgamma)'), 0, delta=1e-9)
def test_bxll_afb(self): # check calling outside of kinematical regions yields 0 self.assertAlmostEqual(flavio.sm_prediction('AFB(B->Xsmumu)', 0), 0) self.assertAlmostEqual(flavio.sm_prediction('AFB(B->Xsll)', 30), 0) # just check differential AFB doesn't raise errors flavio.sm_prediction('AFB(B->Xsee)', 1) flavio.sm_prediction('AFB(B->Xsmumu)', 6) flavio.sm_prediction('AFB(B->Xsll)', 14.4) # check whether QED corrections have the right behaviour # (table 2 of arXiv:1503.04849) wc_obj = flavio.WilsonCoefficients() par = flavio.default_parameters.get_central_all() afb_num_low1_noqed = bxll_afb_num_int(1, 3.5, wc_obj, par, 's', 'e', include_qed=False) afb_num_low1_qed = bxll_afb_num_int(1, 3.5, wc_obj, par, 's', 'e', include_qed=True) afb_num_low2_noqed = bxll_afb_num_int(3.5, 6, wc_obj, par, 's', 'e', include_qed=False) afb_num_low2_qed = bxll_afb_num_int(3.5, 6, wc_obj, par, 's', 'e', include_qed=True) afb_den_low1_noqed = bxll_afb_den_int(1, 3.5, wc_obj, par, 's', 'e', include_qed=False) afb_den_low1_qed = bxll_afb_den_int(1, 3.5, wc_obj, par, 's', 'e', include_qed=True) afb_den_low2_noqed = bxll_afb_den_int(3.5, 6, wc_obj, par, 's', 'e', include_qed=False) afb_den_low2_qed = bxll_afb_den_int(3.5, 6, wc_obj, par, 's', 'e', include_qed=True) self.assertAlmostEqual((afb_num_low1_qed-afb_num_low1_noqed)/afb_num_low1_qed, -0.107, delta=0.050) # should lead to a -10.7% suppression self.assertAlmostEqual((afb_num_low2_qed-afb_num_low2_noqed)/afb_num_low2_qed, +0.162, delta=0.025) # should lead to a 16.2% enhancement self.assertAlmostEqual((afb_den_low1_qed-afb_den_low1_noqed)/afb_den_low1_qed, 0.068, delta=0.005) # should lead to a 6.8% enhancement self.assertAlmostEqual((afb_den_low2_qed-afb_den_low2_noqed)/afb_den_low2_qed, 0.031, delta=0.010) # should lead to a 3.1% enhancement # compare SM predictions to arXiv:1503.04849 self.assertAlmostEqual( flavio.sm_prediction('<AFB>(B->Xsee)', 1, 3.5)/(3/4.*(-1.03e-7)/((2.91e-7)+(6.35e-7))), 1, delta=0.15) self.assertAlmostEqual( flavio.sm_prediction('<AFB>(B->Xsee)', 3.5, 6)/(3/4.*(0.73e-7)/((2.43e-7)+(4.97e-7))), 1, delta=0.1) self.assertAlmostEqual( flavio.sm_prediction('<AFB>(B->Xsmumu)', 1, 3.5)/(3/4.*(-1.10e-7)/((2.09e-7)+(6.79e-7))), 1, delta=0.1) self.assertAlmostEqual( flavio.sm_prediction('<AFB>(B->Xsmumu)', 3.5, 6)/(3/4.*(0.67e-7)/((1.94e-7)+(5.34e-7))), 1, delta=0.15)