def test_profiler(self): # defining some dummy parameters and observables Parameter('tmp a') Parameter('tmp b') Parameter('tmp c') Parameter('tmp d') p = ParameterConstraints() p.set_constraint('tmp b', '2+-0.3') p.set_constraint('tmp c', '0.2+-0.1') p.set_constraint('tmp d', '1+-0.5') def prediction(wc_obj, par): return par['tmp a']**2 + par['tmp b'] + par['tmp c'] + par[ 'tmp d']**2 flavio.Observable('tmp obs') Prediction('tmp obs', prediction) m = Measurement('tmp measurement') m.add_constraint(['tmp obs'], flavio.statistics.probability.NormalDistribution( 1, 0.2)) # test 1D profiler fit_1d = FrequentistFit('test profiler 1d', p, ['tmp a'], ['tmp b', 'tmp c', 'tmp d'], ['tmp obs']) profiler_1d = profiler.Profiler1D(fit_1d, -10, 10) x, z, n = profiler_1d.run(steps=4) self.assertEqual(x.shape, (4, )) self.assertEqual(z.shape, (4, )) self.assertEqual(n.shape, (3, 4)) npt.assert_array_equal(x, profiler_1d.x) npt.assert_array_equal(z, profiler_1d.log_profile_likelihood) npt.assert_array_equal(n, profiler_1d.profile_nuisance) pdat = profiler_1d.pvalue_prob_plotdata() npt.assert_array_equal(pdat['x'], x) # test 2D profiler p.remove_constraint('d') fit_2d = FrequentistFit('test profiler 2d', p, ['tmp a', 'tmp d'], ['tmp b', 'tmp c'], ['tmp obs']) profiler_2d = profiler.Profiler2D(fit_2d, -10, 10, -10, 10) x, y, z, n = profiler_2d.run(steps=(3, 4)) self.assertEqual(x.shape, (3, )) self.assertEqual(y.shape, (4, )) self.assertEqual(z.shape, (3, 4)) self.assertEqual(n.shape, (2, 3, 4)) npt.assert_array_equal(x, profiler_2d.x) npt.assert_array_equal(y, profiler_2d.y) npt.assert_array_equal(z, profiler_2d.log_profile_likelihood) npt.assert_array_equal(n, profiler_2d.profile_nuisance) pdat = profiler_2d.contour_plotdata() npt.assert_array_almost_equal(pdat['z'], -2 * (z - np.max(z))) # delete dummy instances for p in ['tmp a', 'tmp b', 'tmp c', 'tmp d']: Parameter.del_instance(p) FrequentistFit.del_instance('test profiler 1d') Observable.del_instance('tmp obs') Measurement.del_instance('tmp measurement')
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_exp_combo(self): o = Observable('test_obs') o.arguments = ['x'] m = Measurement('test_obs measurement 1') m.add_constraint([('test_obs', 1)], MultivariateNormalDistribution([1, 2], np.eye(2))) # error: no measurement with self.assertRaises(ValueError): flavio.combine_measurements('test_obs', x=1, include_measurements=['bla']) m.add_constraint([('test_obs', 1)], NormalDistribution(2, 3)) combo = flavio.combine_measurements('test_obs', x=1) self.assertEqual(combo.central_value, 2) self.assertEqual(combo.standard_deviation, 3) m2 = Measurement('test_obs measurement 2') m2.add_constraint([('test_obs', 1)], NormalDistribution(3, 3)) combo = flavio.combine_measurements('test_obs', x=1) self.assertAlmostEqual(combo.central_value, 2.5) self.assertAlmostEqual(combo.standard_deviation, sqrt(9 / 2)) Observable.del_instance('test_obs')
def make_obs_neutron_corr(coeff, me_E=False): _process_tex = r"n\to p^+ e^-\bar\nu_e" _process_taxonomy = r'Process :: Nucleon decays :: Beta decays :: Neutron decay :: $' + _process_tex + r"$" _obs_name = coeff + "_n" if me_E: _obs = Observable(_obs_name, arguments=['me_E']) else: _obs = Observable(_obs_name) _obs.set_description(r"Correlation coefficient $" + tex + r"$ in neutron beta decay") _obs.tex = r"$" + tex + r"$" _obs.add_taxonomy(_process_taxonomy) if me_E: func = lambda wc_obj, par, me_E: Neutron_corr(wc_obj, par, me_E, coeff)() else: func = lambda wc_obj, par: Neutron_corr(wc_obj, par, None, coeff)() Prediction(_obs_name, func)
def _define_obs_B_Mll(M, ll): _process_tex = _hadr_lfv[M]['tex']+' '+_tex_lfv[''.join(ll)] _process_taxonomy = r'Process :: $b$ hadron decays :: FCNC decays :: $B\to P\ell^+\ell^-$ :: $' + _process_tex + r"$" _obs_name = "BR("+M+''.join(ll)+")" _obs = Observable(_obs_name) _obs.set_description(r"Total branching ratio of $"+_process_tex+r"$") _obs.tex = r"$\text{BR}(" + _process_tex+r")$" _obs.add_taxonomy(_process_taxonomy) return _obs_name
def make_metadata_binned(M, l, obs, obsdict): _process_tex = _hadr[M]['tex'] +_tex[l]+r"^+"+_tex[l]+r"^-" _process_taxonomy = r'Process :: $b$ hadron decays :: FCNC decays :: $B\to V\ell^+\ell^-$ :: $' + _process_tex + r"$" B = _hadr[M]['B'] V = _hadr[M]['V'] _obs_name = "<" + obs + ">("+M+l+l+")" _obs = Observable(name=_obs_name, arguments=['q2min', 'q2max']) _obs.set_description('Binned ' + obsdict['desc'] + r" in $" + _process_tex + r"$") _obs.tex = r"$\langle " + obsdict['tex'] + r"\rangle(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy) return _obs
def make_metadata_differential(M, l, obs, obsdict): _process_tex = _hadr[M]['tex'] +_tex[l]+r"^+"+_tex[l]+r"^-" _process_taxonomy = r'Process :: $b$ hadron decays :: FCNC decays :: $B\to V\ell^+\ell^-$ :: $' + _process_tex + r"$" B = _hadr[M]['B'] V = _hadr[M]['V'] _obs_name = obs + "("+M+l+l+")" _obs = Observable(name=_obs_name, arguments=['q2']) _obs.set_description(obsdict['desc'][0].capitalize() + obsdict['desc'][1:] + r" in $" + _process_tex + r"$") _obs.tex = r"$" + obsdict['tex'] + r"(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy) return _obs
def test_sm_covariance(self): o1 = Observable( 'test_obs 1' ) o2 = Observable( 'test_obs 2' ) def f1(wc_obj, par_dict): return par_dict['m_b'] def f2(wc_obj, par_dict): return par_dict['m_c'] Prediction('test_obs 1', f1) Prediction('test_obs 2', f2) cov_par = np.array([[0.1**2, 0.1*0.2*0.3], [0.1*0.2*0.3, 0.2**2]]) d = flavio.statistics.probability.MultivariateNormalDistribution([4.2, 1.2], covariance=cov_par) par = copy.deepcopy(flavio.parameters.default_parameters) par.add_constraint(['m_b', 'm_c'], d) # test serial np.random.seed(135) cov = flavio.sm_covariance(['test_obs 1', 'test_obs 2'], N=1000, par_vary='all', par_obj=par) npt.assert_array_almost_equal(cov, cov_par, decimal=2) # test parallel np.random.seed(135) cov_parallel = flavio.sm_covariance(['test_obs 1', 'test_obs 2'], N=1000, par_vary='all', par_obj=par, threads=4) npt.assert_array_almost_equal(cov, cov_parallel, decimal=6) np.random.seed(135) cov_1 = flavio.sm_covariance(['test_obs 1'], N=1000, par_vary='all', par_obj=par) # test with single observable npt.assert_array_almost_equal(cov_1, cov[0, 0]) # test with fixed parameter cov_f = flavio.sm_covariance(['test_obs 1', 'test_obs 2'], N=1000, par_vary=['m_b'], par_obj=par) npt.assert_array_almost_equal(cov_f, [[cov_par[0, 0], 0], [0, 0]], decimal=3) # delete dummy instances Observable.del_instance('test_obs 1') Observable.del_instance('test_obs 2')
def test_sm_covariance(self): o1 = Observable('test_obs 1') o2 = Observable('test_obs 2') def f1(wc_obj, par_dict): return par_dict['m_b'] def f2(wc_obj, par_dict): return par_dict['m_c'] Prediction('test_obs 1', f1) Prediction('test_obs 2', f2) cov_par = np.array([[0.1**2, 0.1 * 0.2 * 0.3], [0.1 * 0.2 * 0.3, 0.2**2]]) d = flavio.statistics.probability.MultivariateNormalDistribution( [4.2, 1.2], covariance=cov_par) par = copy.deepcopy(flavio.parameters.default_parameters) par.add_constraint(['m_b', 'm_c'], d) # test serial np.random.seed(135) cov = flavio.sm_covariance(['test_obs 1', 'test_obs 2'], N=1000, par_vary='all', par_obj=par) npt.assert_array_almost_equal(cov, cov_par, decimal=2) # test parallel np.random.seed(135) cov_parallel = flavio.sm_covariance(['test_obs 1', 'test_obs 2'], N=1000, par_vary='all', par_obj=par, threads=4) npt.assert_array_almost_equal(cov, cov_parallel, decimal=6) np.random.seed(135) cov_1 = flavio.sm_covariance(['test_obs 1'], N=1000, par_vary='all', par_obj=par) # test with single observable npt.assert_array_almost_equal(cov_1, cov[0, 0]) # test with fixed parameter cov_f = flavio.sm_covariance(['test_obs 1', 'test_obs 2'], N=1000, par_vary=['m_b'], par_obj=par) npt.assert_array_almost_equal(cov_f, [[cov_par[0, 0], 0], [0, 0]], decimal=3) # delete dummy instances Observable.del_instance('test_obs 1') Observable.del_instance('test_obs 2')
def BVgamma_function(function, B, V): return lambda wc_obj, par: function(wc_obj, par, B, V) # Observable and Prediction instances _func = {"BR": BR, "ACP": ACP} _tex = {"BR": r"\text{BR}", "ACP": r"A_{CP}"} _desc = {"BR": "Branching ratio", "ACP": "Direct CP asymmetry"} _process_taxonomy = r"Process :: $b$ hadron decays :: FCNC decays :: $B\to V\gamma$ :: $" for key in _func.keys(): _obs_name = key + "(B+->K*gamma)" _obs = Observable(_obs_name) _process_tex = r"B^+\to K^{*+}\gamma" _obs.set_description(_desc[key] + r" of $" + _process_tex + r"$") _obs.tex = r"$" + _tex[key] + r"(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy + _process_tex + r"$") Prediction(_obs_name, BVgamma_function(_func[key], "B+", "K*+")) _obs_name = key + "(B0->K*gamma)" _obs = Observable(_obs_name) _process_tex = r"B^0\to K^{*0}\gamma" _obs.set_description(_desc[key] + r" of $" + _process_tex + r"$") _obs.tex = r"$" + _tex[key] + r"(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy + _process_tex + r"$") Prediction(_obs_name, BVgamma_function(_func[key], "B0", "K*0")) _obs_name = "ACP(Bs->phigamma)"
wc = wctot_dict(wc_obj, label, scale, par) else: wc = wc_obj.get_wc(label, scale, par) return function(par, wc, B, l1, l2) def bqll_obs_function(function, B, l1, l2): return lambda wc_obj, par: bqll_obs(function, wc_obj, par, B, l1, l2) # Observable and Prediction instances _tex = {'e': 'e', 'mu': '\mu', 'tau': r'\tau'} for l in ['e', 'mu', 'tau']: # For the B^0 decay, we take the time-integrated branching ratio _obs_name = "BR(Bs->"+l+l+")" _obs = Observable(_obs_name) _obs.set_description(r"Time-integrated branching ratio of $B_s\to "+_tex[l]+"^+"+_tex[l]+"^-$.") _obs.tex = r"$\overline{\text{BR}}(B_s\to "+_tex[l]+"^+"+_tex[l]+"^-)$." Prediction(_obs_name, bqll_obs_function(br_timeint, 'Bs', l, l)) # For the B^0 decay, we take the prompt branching ratio since DeltaGamma is negligible _obs_name = "BR(Bd->"+l+l+")" _obs = Observable(_obs_name) _obs.set_description(r"Branching ratio of $B^0\to "+_tex[l]+"^+"+_tex[l]+"^-$.") _obs.tex = r"$\text{BR}(B^0\to "+_tex[l]+"^+"+_tex[l]+"^-)$." Prediction(_obs_name, bqll_obs_function(br_inst, 'B0', l, l)) _tex_B = {'B0': r'\bar B^0', 'Bs': r'\bar B_s'} _tex_lfv = {'emu': r'e^+\mu^-', 'mue': r'\mu^+e^-', 'taue': r'\tau^+e^-', 'etau': r'e^+\tau^-', 'taumu': r'\tau^+\mu^-', 'mutau': r'\mu^+\tau^-'}
_tex = {'emu': r'e^+\mu^-', 'mue': r'\mu^+e^-', 'taue': r'\tau^+e^-', 'etau': r'e^+\tau^-', 'taumu': r'\tau^+\mu^-', 'mutau': r'\mu^+\tau^-'} _tex_lsum = {'emu': r'e^\pm\mu^\mp', 'etau': r'e^\pm\tau^\mp', 'mutau': r'\mu^\pm\tau^\mp'} _func = {'BR': BR_tot_function, } _desc = { 'BR': 'Total', } _tex_br = {'BR': r'\text{BR}', } _args = {'BR': None, } _hadr = { 'B0->K*': {'tex': r"\bar B^0\to \bar K^{*0}", 'B': 'B0', 'V': 'K*0', }, 'B+->K*': {'tex': r"B^-\to K^{*-}", 'B': 'B+', 'V': 'K*+', }, 'B+->rho': {'tex': r"B^-\to \rho^{-}", 'B': 'B+', 'V': 'rho+', }, 'B0->rho': {'tex': r"\bar B^0\to \rho^{0}", 'B': 'B0', 'V': 'rho0', }, 'Bs->phi': {'tex': r"\bar B_s\to \phi", 'B': 'Bs', 'V': 'phi', }, } for ll in [('e','mu'), ('mu','e'), ('e','tau'), ('tau','e'), ('mu','tau'), ('tau','mu')]: for M in _hadr.keys(): _process_tex = _hadr[M]['tex']+' '+_tex[''.join(ll)] _process_taxonomy = r'Process :: $b$ hadron decays :: FCNC decays :: $B\to V\ell^+\ell^-$ :: $' + _process_tex + r"$" for br in ['BR',]: _obs_name = br + "("+M+''.join(ll)+")" _obs = Observable(_obs_name) _obs.set_description(_desc[br] + r" branching ratio of $"+_process_tex+r"$") _obs.tex = r'$' + _tex_br[br] + "(" + _process_tex+r")$" _obs.arguments = _args[br] _obs.add_taxonomy(_process_taxonomy) Prediction(_obs_name, _func[br](_hadr[M]['B'], _hadr[M]['V'], ll[0], ll[1]))
'taumu': r'\tau^+\mu^-', 'mutau': r'\mu^+\tau^-', 'emu,mue': r'e^\pm\mu^\mp', 'etau,taue': r'e^\pm\tau^\mp', 'mutau,taumu': r'\mu^\pm\tau^\mp' } for l in ['e', 'mu', 'tau']: for M in _hadr.keys(): _process_tex = _hadr[M]['tex'] + _tex[l] + r"^+" + _tex[l] + r"^-" _process_taxonomy = r'Process :: $b$ hadron decays :: FCNC decays :: $B\to P\ell^+\ell^-$ :: $' + _process_tex + r"$" for obs in sorted(_observables.keys()): _obs_name = "<" + obs + ">(" + M + l + l + ")" _obs = Observable(name=_obs_name, arguments=['q2min', 'q2max']) _obs.set_description('Binned ' + _observables[obs]['desc'] + r" in $" + _process_tex + r"$") _obs.tex = r"$\langle " + _observables[obs][ 'tex'] + r"\rangle(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy) Prediction( _obs_name, bpll_obs_int_ratio_func(_observables[obs]['func_num'], dGdq2_cpaverage, _hadr[M]['B'], _hadr[M]['P'], l)) _obs_name = obs + "(" + M + l + l + ")" _obs = Observable(name=_obs_name, arguments=['q2']) _obs.set_description(_observables[obs]['desc'][0].capitalize() + _observables[obs]['desc'][1:] + r" in $" +
_observables = { 'FL': {'func_num': FL_num_Bs, 'tex': r'\overline{F_L}', 'desc': 'Time-averaged longitudinal polarization fraction'}, 'S3': {'func_num': lambda y, J, J_bar, J_h: S_experiment_num_Bs(y, J, J_bar, J_h, 3), 'tex': r'\overline{S_3}', 'desc': 'Time-averaged, CP-averaged angular observable'}, 'S4': {'func_num': lambda y, J, J_bar, J_h: S_experiment_num_Bs(y, J, J_bar, J_h, 4), 'tex': r'\overline{S_4}', 'desc': 'Time-averaged, CP-averaged angular observable'}, 'S7': {'func_num': lambda y, J, J_bar, J_h: S_experiment_num_Bs(y, J, J_bar, J_h, 7), 'tex': r'\overline{S_7}', 'desc': 'Time-averaged, CP-averaged angular observable'}, } _hadr = { 'Bs->phi': {'tex': r"B_s\to \phi ", 'B': 'Bs', 'V': 'phi', }, } for l in ['e', 'mu', 'tau']: for M in _hadr.keys(): for obs in sorted(_observables.keys()): # binned angular observables _obs_name = "<" + obs + ">("+M+l+l+")" _obs = Observable(name=_obs_name, arguments=['q2min', 'q2max']) _obs.set_description('Binned ' + _observables[obs]['desc'] + r" in $" + _hadr[M]['tex'] +_tex[l]+r"^+"+_tex[l]+"^-$") _obs.tex = r"$\langle " + _observables[obs]['tex'] + r"\rangle(" + _hadr[M]['tex'] +_tex[l]+r"^+"+_tex[l]+"^-)$" Prediction(_obs_name, bsvll_obs_int_ratio_func(_observables[obs]['func_num'], SA_den_Bs, _hadr[M]['B'], _hadr[M]['V'], l)) # differential angular observables _obs_name = obs + "("+M+l+l+")" _obs = Observable(name=_obs_name, arguments=['q2']) _obs.set_description(_observables[obs]['desc'][0].capitalize() + _observables[obs]['desc'][1:] + r" in $" + _hadr[M]['tex'] +_tex[l]+r"^+"+_tex[l]+"^-$") _obs.tex = r"$" + _observables[obs]['tex'] + r"(" + _hadr[M]['tex'] +_tex[l]+r"^+"+_tex[l]+"^-)$" Prediction(_obs_name, bsvll_obs_ratio_func(_observables[obs]['func_num'], SA_den_Bs, _hadr[M]['B'], _hadr[M]['V'], l)) # binned branching ratio _obs_name = "<dBR/dq2>("+M+l+l+")" _obs = Observable(name=_obs_name, arguments=['q2min', 'q2max']) _obs.set_description(r"Binned time-integrated differential branching ratio of $" + _hadr[M]['tex'] +_tex[l]+r"^+"+_tex[l]+"^-$")
# Observable and Prediction instances _tex = {'emu': r'e^+\mu^-', 'mue': r'\mu^+e^-', 'taue': r'\tau^+e^-', 'etau': r'e^+\tau^-', 'taumu': r'\tau^+\mu^-', 'mutau': r'\mu^+\tau^-'} _tex_lsum = {'emu': r'e^\pm\mu^\mp', 'etau': r'e^\pm\tau^\mp', 'mutau': r'\mu^\pm\tau^\mp'} _func = {'BR': BR_tot_function, } _desc = { 'BR': 'Total', } _tex_br = {'BR': r'\text{BR}', } _args = {'BR': None, } _hadr = { 'B0->K*': {'tex': r"\bar B^0\to \bar K^{*0}", 'B': 'B0', 'V': 'K*0', }, 'B+->K*': {'tex': r"B^-\to K^{*-}", 'B': 'B+', 'V': 'K*+', }, 'B+->rho': {'tex': r"B^-\to \rho^{-}", 'B': 'B+', 'V': 'rho+', }, 'B0->rho': {'tex': r"\bar B^0\to \rho^{0}", 'B': 'B0', 'V': 'rho0', }, 'Bs->phi': {'tex': r"\bar B_s\to \phi", 'B': 'Bs', 'V': 'phi', }, } for ll in [('e','mu'), ('mu','e'), ('e','tau'), ('tau','e'), ('mu','tau'), ('tau','mu')]: for M in _hadr.keys(): for br in ['BR',]: _obs_name = br + "("+M+''.join(ll)+")" _obs = Observable(_obs_name) _obs.set_description(_desc[br] + r" branching ratio of $"+_hadr[M]['tex']+' '+_tex[''.join(ll)]+r"$") _obs.tex = r'$' + _tex_br[br] + "(" + _hadr[M]['tex']+' '+_tex[''.join(ll)]+r")$" _obs.arguments = _args[br] Prediction(_obs_name, _func[br](_hadr[M]['B'], _hadr[M]['V'], ll[0], ll[1]))
'Bs->K*': {'tex': r"B_s\to K^{* -} ", 'B': 'Bs', 'V': 'K*+', 'decays': ['Bs->K*'],}, } _process_taxonomy = r'Process :: $b$ hadron decays :: Semi-leptonic tree-level decays :: $B\to V\ell\nu$ :: $' for l in ['e', 'mu', 'tau', 'l']: for br in ['dBR/dq2', 'BR', '<BR>', 'dBR_L/dq2', 'BR_L', '<BR_L>', 'dBR_T/dq2', 'BR_T', '<BR_T>', '<BR>/<cl>', '<BR>/<cV>', '<BR>/<phi>', 'dBR/dcl', 'dBR/dcV', 'dBR/dphi', '<FL>', 'FL', 'FLtot']: for M in _hadr.keys(): _process_tex = _hadr[M]['tex']+_tex[l]+r"^+\nu_"+_tex[l] _obs_name = br + "("+M+l+"nu)" _obs = Observable(_obs_name) _obs.set_description(_desc[br] + r" branching ratio of $" + _process_tex + "$") _obs.tex = r'$' + _tex_br[br] + r"(" +_process_tex + ")$" _obs.arguments = _args[br] _obs.add_taxonomy(_process_taxonomy + _process_tex + r'$') if br in _A: # for dBR/dq2, need to distinguish between total, L, and T Prediction(_obs_name, _func[br](_hadr[M]['B'], _hadr[M]['V'], l, A=_A[br])) else: # for other observables not Prediction(_obs_name, _func[br](_hadr[M]['B'], _hadr[M]['V'], l)) # Lepton flavour ratios for l in [('mu','e'), ('tau','mu'), ('tau', 'l')]: for M in _hadr_l.keys():
('mu', 'e'), ('tau', 'mu'), ]: for M in _hadr.keys(): make_obs_lfur(M, l) # define LFU differences D_P4p,5p def diff(x, y): return x - y for Pp in ['P4p', 'P5p']: tex = _observables_pprime[Pp]['tex'] obs = Observable.from_function( 'Dmue_{}(B0->K*ll)'.format(Pp), ['{}(B0->K*mumu)'.format(Pp), '{}(B0->K*ee)'.format(Pp)], diff) obs.set_description( r"Difference of angular observable ${}$ in $B^0\to K^{{\ast 0}}\mu^+\mu^-$ and $B^0\to K^{{\ast 0}}e^+e^-$" .format(tex)) obs.tex = r"$D_{{{}}}^{{\mu e}}(B^0\to K^{{\ast 0}}\ell^+\ell^-)$".format( tex) obs.add_taxonomy( r"Process :: $b$ hadron decays :: FCNC decays :: $B\to V\ell^+\ell^-$ :: $B^0\to K^{\ast 0}e^+e^-$" ) obs.add_taxonomy( r"Process :: $b$ hadron decays :: FCNC decays :: $B\to V\ell^+\ell^-$ :: $B^0\to K^{\ast 0}\mu^+\mu^-$" ) obs = Observable.from_function( '<Dmue_{}>(B0->K*ll)'.format(Pp),
'func_num': AFBlh_num, 'tex': r'A_\text{FB}^{\ell h}', 'desc': 'lepton-hadron forward-backward asymmetry' }, } for l in [ 'e', 'mu', ]: # tau requires lepton mass dependence! _process_tex = r"\Lambda_b\to\Lambda " + _tex[l] + r"^+" + _tex[l] + r"^-" _process_taxonomy = r'Process :: $b$ hadron decays :: FCNC decays :: $\Lambda_b\to \Lambda\ell^+\ell^-$ :: $' + _process_tex + r"$" # binned branching ratio _obs_name = "<dBR/dq2>(Lambdab->Lambda" + l + l + ")" _obs = Observable(name=_obs_name, arguments=['q2min', 'q2max']) _obs.set_description(r"Binned differential branching ratio of $" + _process_tex + r"$") _obs.tex = r"$\langle \frac{d\text{BR}}{dq^2} \rangle(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy) Prediction(_obs_name, dbrdq2_int_func(l)) # differential branching ratio _obs_name = "dBR/dq2(Lambdab->Lambda" + l + l + ")" _obs = Observable(name=_obs_name, arguments=['q2']) _obs.set_description(r"Differential branching ratio of $" + _process_tex + r"$") _obs.tex = r"$\frac{d\text{BR}}{dq^2}(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy) Prediction(_obs_name, dbrdq2_func(l))
_tex = {'e': 'e', 'mu': '\mu', 'tau': r'\tau'} _tex_B = {'B0': r'\bar B^0', 'Bs': r'\bar B_s'} _process_taxonomy = r'Process :: $b$ hadron decays :: FCNC decays :: $B\to \ell^+\ell^-\gamma$ :: $' for l in ['e', 'mu']: for B in ['Bs', 'B0']: _process_tex = _tex_B[B] + r"\to" + _tex[l] + r"^+" + _tex[ l] + r"^-\gamma" # binned branching ratio _obs_name = "<dBR/dq2>(" + B + "->" + l + l + "gamma)" _obs = Observable(name=_obs_name, arguments=['q2min', 'q2max']) _obs.set_description(r"Binned differential branching ratio of $" + _process_tex + r"$") _obs.tex = r"$\langle \frac{d\text{BR}}{dq^2} \rangle(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy + _process_tex + r"$") Prediction(_obs_name, bllg_dbrdq2_int_func(B, l)) # differential branching ratio _obs_name = "dBR/dq2(" + B + "->" + l + l + "gamma)" _obs = Observable(name=_obs_name, arguments=['q2']) _obs.set_description(r"Differential branching ratio of $" + _process_tex + r"$") _obs.tex = r"$\frac{d\text{BR}}{dq^2}(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy + _process_tex + r"$") Prediction(_obs_name, bllg_dbrdq2_func(B, l))
return _BR_tot(wc_obj, par, B, V, lep) def BR_tot_function(B, V, lep): return lambda wc_obj, par: BR_tot(wc_obj, par, B, V, lep) # Observable and Prediction instances _tex = {'e': 'e', 'mu': '\mu', 'tau': r'\tau', 'l': r'\ell'} _func = {'dBR/dq2': dBRdq2_function, 'BR': BR_tot_function, '<BR>': BR_binned_function} _desc = {'dBR/dq2': 'Differential', 'BR': 'Total', '<BR>': 'Binned'} _tex_br = {'dBR/dq2': r'\frac{d\text{BR}}{dq^2}', 'BR': r'\text{BR}', '<BR>': r'\langle\text{BR}\rangle'} _args = {'dBR/dq2': ['q2'], 'BR': None, '<BR>': ['q2min', 'q2max']} _hadr = { 'B0->D*': {'tex': r"B^0\to D^{\ast -}", 'B': 'B0', 'V': 'D*+', }, 'B+->D*': {'tex': r"B^+\to D^{\ast 0}", 'B': 'B+', 'V': 'D*0', }, 'B0->rho': {'tex': r"B^0\to \rho^-", 'B': 'B0', 'V': 'rho+', }, 'B+->rho': {'tex': r"B^+\to \rho^0", 'B': 'B+', 'V': 'rho0', }, 'B+->omega': {'tex': r"B^+\to \omega ", 'B': 'B+', 'V': 'omega', }, 'Bs->K*': {'tex': r"B_s\to K^{* -} ", 'B': 'Bs', 'V': 'K*+', }, } for l in ['e', 'mu', 'tau', 'l']: for br in ['dBR/dq2', 'BR', '<BR>']: for M in _hadr.keys(): _obs_name = br + "("+M+l+"nu)" _obs = Observable(_obs_name) _obs.set_description(_desc[br] + r" branching ratio of $"+_hadr[M]['tex']+_tex[l]+r"^+\nu_"+_tex[l]+"$") _obs.tex = r'$' + _tex_br[br] + r"("+_hadr[M]['tex']+_tex[l]+r"^+\nu_"+_tex[l]+")$" _obs.arguments = _args[br] Prediction(_obs_name, _func[br](_hadr[M]['B'], _hadr[M]['V'], l))
def make_obs_br(M, l): """Make observable instances for branching ratios""" _process_tex = _hadr[M]['tex'] +_tex[l]+r"^+"+_tex[l]+r"^-" _process_taxonomy = r'Process :: $b$ hadron decays :: FCNC decays :: $B\to V\ell^+\ell^-$ :: $' + _process_tex + r"$" B = _hadr[M]['B'] V = _hadr[M]['V'] # binned branching ratio _obs_name = "<dBR/dq2>("+M+l+l+")" _obs = Observable(name=_obs_name, arguments=['q2min', 'q2max']) _obs.set_description(r"Binned differential branching ratio of $" + _process_tex + r"$") _obs.tex = r"$\langle \frac{d\text{BR}}{dq^2} \rangle(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy) func = lambda wc_obj, par, q2min, q2max: BVll_dBRdq2_int(q2min, q2max, B, V, l, wc_obj, par)() Prediction(_obs_name, func) # differential branching ratio _obs_name = "dBR/dq2("+M+l+l+")" _obs = Observable(name=_obs_name, arguments=['q2']) _obs.set_description(r"Differential branching ratio of $" + _process_tex + r"$") _obs.tex = r"$\frac{d\text{BR}}{dq^2}(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy) func = lambda wc_obj, par, q2: BVll_dBRdq2(q2, B, V, l, wc_obj, par)() Prediction(_obs_name, func)
'V': 'rho+', }, 'B0->rho': { 'tex': r"\bar B^0\to \rho^{0}", 'B': 'B0', 'V': 'rho0', }, 'Bs->phi': { 'tex': r"\bar B_s\to \phi", 'B': 'Bs', 'V': 'phi', }, } for ll in [('e', 'mu'), ('mu', 'e'), ('e', 'tau'), ('tau', 'e'), ('mu', 'tau'), ('tau', 'mu')]: for M in _hadr.keys(): for br in [ 'BR', ]: _obs_name = br + "(" + M + ''.join(ll) + ")" _obs = Observable(_obs_name) _obs.set_description(_desc[br] + r" branching ratio of $" + _hadr[M]['tex'] + ' ' + _tex[''.join(ll)] + r"$") _obs.tex = r'$' + _tex_br[br] + "(" + _hadr[M]['tex'] + ' ' + _tex[ ''.join(ll)] + r")$" _obs.arguments = _args[br] Prediction(_obs_name, _func[br](_hadr[M]['B'], _hadr[M]['V'], ll[0], ll[1]))
return fct # Observable instances _tex = {'e': 'e', 'mu': '\mu', 'tau': r'\tau', 'l': r'\ell'} for l in ['e', 'mu', 'tau', 'l']: for q in ['s', 'd']: _process_tex = r"B\to X_" + q + _tex[l] + r"^+" + _tex[l] + r"^-" _process_taxonomy = r'Process :: $b$ hadron decays :: FCNC decays :: $B\to X\ell^+\ell^-$ :: $' + _process_tex + r"$" # binned branching ratio _obs_name = "<BR>(B->X" + q + l + l + ")" _obs = Observable(name=_obs_name, arguments=['q2min', 'q2max']) _obs.set_description(r"Binned branching ratio of $" + _process_tex + r"$") _obs.tex = r"$\langle \text{BR} \rangle(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy) Prediction(_obs_name, bxll_br_int_func(q, l)) # differential branching ratio _obs_name = "dBR/dq2(B->X" + q + l + l + ")" _obs = Observable(name=_obs_name, arguments=['q2']) _obs.set_description(r"Differential branching ratio of $" + _process_tex + r"$") _obs.tex = r"$\frac{d\text{BR}}{dq^2}(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy) Prediction(_obs_name, bxll_dbrdq2_func(q, l))
den = BR_BXclnu(par, wc_obj, lden) return num / den def BR_tot_leptonflavour_function(lnum, lden): return lambda wc_obj, par: BR_tot_leptonflavour(wc_obj, par, lnum, lden) _process_taxonomy = r'Process :: $b$ hadron decays :: Semi-leptonic tree-level decays :: $B\to X\ell\nu$ :: $' _lep = {'e': 'e', 'mu': r'\mu', 'tau': r'\tau', 'l': r'\ell'} for l in _lep: _obs_name = "BR(B->Xc" + l + "nu)" _process_tex = r"B\to X_c" + _lep[l] + r"^+\nu_" + _lep[l] _obs = Observable(_obs_name) _obs.set_description(r"Total branching ratio of $" + _process_tex + r"$") _obs.tex = r"$\text{BR}(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy + _process_tex + r"$") Prediction(_obs_name, BR_tot_function(l)) # Lepton flavour ratios for l in [('mu', 'e'), ('tau', 'mu'), ('tau', 'l')]: _obs_name = "R" + l[0] + l[1] + "(B->Xclnu)" _obs = Observable(name=_obs_name) _process_1 = r"B\to X_c" + _lep[l[0]] + r"^+\nu_" + _lep[l[0]] _process_2 = r"B\to X_c" + _lep[l[1]] + r"^+\nu_" + _lep[l[1]] _obs.set_description(r"Ratio of total branching ratios of $" + _process_1 + r"$" + " and " + r"$" + _process_2 + r"$") _obs.tex = r"$R_{" + _lep[l[0]] + ' ' + _lep[ l[1]] + r"}(B\to X_c\ell^+\nu)$"
def BR_tot_function(B, V, lep): return lambda wc_obj, par: BR_tot(wc_obj, par, B, V, lep) # Observable and Prediction instances _tex = {'e': 'e', 'mu': '\mu', 'tau': r'\tau', 'l': r'\ell'} _func = {'dBR/dq2': dBRdq2_function, 'BR': BR_tot_function, '<BR>': BR_binned_function} _desc = {'dBR/dq2': 'Differential', 'BR': 'Total', '<BR>': 'Binned'} _tex_br = {'dBR/dq2': r'\frac{d\text{BR}}{dq^2}', 'BR': r'\text{BR}', '<BR>': r'\langle\text{BR}\rangle'} _args = {'dBR/dq2': ['q2'], 'BR': None, '<BR>': ['q2min', 'q2max']} _hadr = { 'B0->D*': {'tex': r"B^0\to D^{\ast -}", 'B': 'B0', 'V': 'D*+', }, 'B+->D*': {'tex': r"B^+\to D^{\ast 0}", 'B': 'B+', 'V': 'D*0', }, 'B0->rho': {'tex': r"B^0\to \rho^-", 'B': 'B0', 'V': 'rho+', }, 'B+->rho': {'tex': r"B^+\to \rho^0", 'B': 'B+', 'V': 'rho0', }, 'B+->omega': {'tex': r"B^+\to \omega ", 'B': 'B+', 'V': 'omega', }, 'Bs->K*': {'tex': r"B_s\to K^{* -} ", 'B': 'Bs', 'V': 'K*+', }, } for l in ['e', 'mu', 'tau', 'l']: for br in ['dBR/dq2', 'BR', '<BR>']: for M in _hadr.keys(): _process_tex = _hadr[M]['tex']+_tex[l]+r"^+\nu_"+_tex[l] _obs_name = br + "("+M+l+"nu)" _obs = Observable(_obs_name) _obs.set_description(_desc[br] + r" branching ratio of $" + _process_tex + "$") _obs.tex = r'$' + _tex_br[br] + r"(" +_process_tex + ")$" _obs.arguments = _args[br] _obs.add_taxonomy(r'Process :: $b$ hadron decays :: Semi-leptonic tree-level decays :: $B\to V\ell\nu$ :: $' + _process_tex + r'$') Prediction(_obs_name, _func[br](_hadr[M]['B'], _hadr[M]['V'], l))
def make_obs_lfur(M, l): """Make observable instances for lepton flavour ratios""" # binned ratio of BRs _obs_name = "<R"+l[0]+l[1]+">("+M+"ll)" _obs = Observable(name=_obs_name, arguments=['q2min', 'q2max']) _obs.set_description(r"Ratio of partial branching ratios of $" + _hadr[M]['tex'] +_tex[l[0]]+r"^+ "+_tex[l[0]]+r"^-$" + " and " + r"$" + _hadr[M]['tex'] +_tex[l[1]]+r"^+ "+_tex[l[1]]+"^-$") _obs.tex = r"$\langle R_{" + _tex[l[0]] + ' ' + _tex[l[1]] + r"} \rangle(" + _hadr[M]['tex'] + r"\ell^+\ell^-)$" for li in l: # add taxonomy for both processes (e.g. B->Vee and B->Vmumu) _obs.add_taxonomy(r'Process :: $b$ hadron decays :: FCNC decays :: $B\to V\ell^+\ell^-$ :: $' + _hadr[M]['tex'] +_tex[li]+r"^+"+_tex[li]+r"^-$") Prediction(_obs_name, bvll_obs_int_ratio_leptonflavour(dGdq2_ave, _hadr[M]['B'], _hadr[M]['V'], *l)) # differential ratio of BRs _obs_name = "R"+l[0]+l[1]+"("+M+"ll)" _obs = Observable(name=_obs_name, arguments=['q2']) _obs.set_description(r"Ratio of differential branching ratios of $" + _hadr[M]['tex'] +_tex[l[0]]+r"^+ "+_tex[l[0]]+r"^-$" + " and " + r"$" + _hadr[M]['tex'] +_tex[l[1]]+r"^+ "+_tex[l[1]]+"^-$") _obs.tex = r"$R_{" + _tex[l[0]] + ' ' + _tex[l[1]] + r"} (" + _hadr[M]['tex'] + r"\ell^+\ell^-)$" for li in l: # add taxonomy for both processes (e.g. B->Vee and B->Vmumu) _obs.add_taxonomy(r'Process :: $b$ hadron decays :: FCNC decays :: $B\to V\ell^+\ell^-$ :: $' + _hadr[M]['tex'] +_tex[li]+r"^+"+_tex[li]+r"^-$") func = lambda wc_obj, par, q2: BVll_dBRdq2(q2, B, V, l, wc_obj, par)() Prediction(_obs_name, bvll_obs_ratio_leptonflavour(dGdq2_ave, _hadr[M]['B'], _hadr[M]['V'], *l))
A_bar = amplitude(conjugate_par(par)) xi = etaCP * qp * A / A_bar return -2 * xi.imag / (1 + abs(xi)**2) def S_BJpsiK(wc_obj, par): return S(wc_obj, par, 'B0', amplitude_BJpsiK, etaCP=-1) def S_Bspsiphi(wc_obj, par): return S(wc_obj, par, 'Bs', amplitude_Bspsiphi, etaCP=+1) # Observable and Prediction instances o = Observable('DeltaM_s') o.set_description(r"Mass difference in the $B_s$-$\bar B_s$ system") o.tex = r"$\Delta M_s$" o.add_taxonomy( r'Process :: Meson-antimeson mixing :: $B_s$-$\bar B_s$ mixing') Prediction('DeltaM_s', lambda wc_obj, par: DeltaM(wc_obj, par, 'Bs')) o = Observable('DeltaM_d') o.set_description(r"Mass difference in the $B^0$-$\bar B^0$ system") o.tex = r"$\Delta M_d$" o.add_taxonomy( r'Process :: Meson-antimeson mixing :: $B^0$-$\bar B^0$ mixing') Prediction('DeltaM_d', lambda wc_obj, par: DeltaM(wc_obj, par, 'B0')) o = Observable('a_fs_s') o.set_description(r"CP asymmetry in flavour-specific $B_s$ decays")
qp = -qp # switch the sign of q/p to keep DeltaM > 0 A = amplitude(par) A_bar = amplitude(conjugate_par(par)) xi = etaCP * qp * A / A_bar return -2*xi.imag / ( 1 + abs(xi)**2 ) def S_BJpsiK(wc_obj, par): return S(wc_obj, par, 'B0', amplitude_BJpsiK, etaCP=-1) def S_Bspsiphi(wc_obj, par): return S(wc_obj, par, 'Bs', amplitude_Bspsiphi, etaCP=+1) # Observable and Prediction instances o = Observable('DeltaM_s') o.set_description(r"Mass difference in the $B_s$-$\bar B_s$ system") o.tex = r"$\Delta M_s$" o.add_taxonomy(r'Process :: Meson-antimeson mixing :: $B_s$-$\bar B_s$ mixing') Prediction('DeltaM_s', lambda wc_obj, par: DeltaM_positive(wc_obj, par, 'Bs')) o = Observable('DeltaM_d') o.set_description(r"Mass difference in the $B^0$-$\bar B^0$ system") o.tex = r"$\Delta M_d$" o.add_taxonomy(r'Process :: Meson-antimeson mixing :: $B^0$-$\bar B^0$ mixing') Prediction('DeltaM_d', lambda wc_obj, par: DeltaM_positive(wc_obj, par, 'B0')) o = Observable('DeltaM_d/DeltaM_s') o.set_description(r"Ratio of Mass differences in the $B^0$-$\bar B^0$ and $B_s$-$\bar B_s$ systems") o.tex = r"$\Delta M_d/\Delta M_s$" o.add_taxonomy(r'Process :: Meson-antimeson mixing :: $B^0$-$\bar B^0$ mixing')
ml = par['m_'+lep] q2max = (mK-mP)**2 q2min = ml**2 return BR_binned(q2min, q2max, wc_obj, par, K, P, lep) def BR_tot_function(K, P, lep): return lambda wc_obj, par: BR_tot(wc_obj, par, K, P, lep) # Observable and Prediction instances _tex = {'e': 'e', 'mu': '\mu', 'l': r'\ell'} _tex_br = {'dBR/dq2': r'\frac{d\text{BR}}{dq^2}', 'BR': r'\text{BR}', '<BR>': r'\langle\text{BR}\rangle'} _args = {'dBR/dq2': ['q2'], 'BR': None, '<BR>': ['q2min', 'q2max']} _hadr = { 'KL->pi': {'tex': r"K_L\to \pi^+", 'K': 'KL', 'P': 'pi+', }, 'K+->pi': {'tex': r"K^+\to \pi^0", 'K': 'K+', 'P': 'pi0', }, } for l in ['e', 'mu', 'l']: for M in _hadr.keys(): _process_tex = _hadr[M]['tex']+_tex[l]+r"^+\nu_"+_tex[l] _process_taxonomy = r'Process :: $s$ hadron decays :: Semi-leptonic tree-level decays :: $K\to P\ell\nu$ :: $' + _process_tex + r"$" _obs_name = "BR("+M+l+"nu)" _obs = Observable(_obs_name) _obs.set_description(r"Total branching ratio of $" + _process_tex + r"$") _obs.tex = r"$\text{BR}(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy) Prediction(_obs_name, BR_tot_function(_hadr[M]['K'], _hadr[M]['P'], l))
def ADeltaGamma_func(B, lep): def ADG_func(wc_obj, par): scale = config['renormalization scale']['bll'] label = meson_quark[B]+lep+lep wc = wctot_dict(wc_obj, label, scale, par) return ADeltaGamma(par, wc, B, lep) return ADG_func # Observable and Prediction instances _tex = {'e': 'e', 'mu': '\mu', 'tau': r'\tau'} for l in ['e', 'mu', 'tau']: _process_taxonomy = r'Process :: $b$ hadron decays :: FCNC decays :: $B\to\ell^+\ell^-$ :: $' # For the B^0 decay, we take the time-integrated branching ratio _obs_name = "BR(Bs->"+l+l+")" _obs = Observable(_obs_name) _process_tex = r"B_s\to "+_tex[l]+r"^+"+_tex[l]+r"^-" _obs.set_description(r"Time-integrated branching ratio of $" + _process_tex + r"$.") _obs.tex = r"$\overline{\text{BR}}(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy + _process_tex + r"$") Prediction(_obs_name, bqll_obs_function(br_timeint, 'Bs', l, l)) # Add the effective lifetimes for Bs _obs_name = 'tau_'+l+l _obs = Observable(_obs_name) _obs.set_description(r"Effective lifetime for $"+ _process_tex + r"$.") _obs.tex = r"$\tau_{B_s \to " +_tex[l] +_tex[l] + "}$" _obs.add_taxonomy(_process_taxonomy + _process_tex + r"$") if l=='e': Prediction(_obs_name, lambda wc_obj, par: tau_ll_func(wc_obj, par, 'Bs', 'e'))
def _load(obj): """Read measurements from a YAML stream or file.""" measurements = yaml.load(obj) for m_name, m_data in measurements.items(): m = Measurement(m_name) for arg in ['inspire', 'hepdata', 'experiment', 'url']: if arg in m_data: setattr(m, arg, m_data[arg]) if 'correlation' not in m_data: if isinstance(m_data['values'], list): for value_dict in m_data['values']: # if "value" is a list, it contains the values of observable # arguments (like q^2) args = Observable.get_instance(value_dict['name']).arguments args_num = [value_dict[a] for a in args] error_dict = errors_from_string(value_dict['value']) central_value = error_dict['central_value'] squared_error = 0. for sym_err in error_dict['symmetric_errors']: squared_error += sym_err**2 for asym_err in error_dict['asymmetric_errors']: squared_error += asym_err[0]*asym_err[1] args_num.insert(0, value_dict['name']) obs_tuple = tuple(args_num) m.add_constraint([obs_tuple], probability.NormalDistribution(central_value, sqrt(squared_error))) else: # otherwise, 'values' is a dict just containing name: constraint_string for obs, value in m_data['values'].items(): error_dict = errors_from_string(value) central_value = error_dict['central_value'] squared_error = 0. for sym_err in error_dict['symmetric_errors']: squared_error += sym_err**2 for asym_err in error_dict['asymmetric_errors']: squared_error += asym_err[0]*asym_err[1] m.add_constraint([obs], probability.NormalDistribution(central_value, sqrt(squared_error))) else: observables = [] central_values = [] errors = [] if isinstance(m_data['values'], list): for value_dict in m_data['values']: # if "value" is a list, it contains the values of observable # arguments (like q^2) args = Observable.get_instance(value_dict['name']).arguments args_num = [value_dict[a] for a in args] error_dict = errors_from_string(value_dict['value']) args_num.insert(0, value_dict['name']) obs_tuple = tuple(args_num) observables.append(obs_tuple) central_values.append(error_dict['central_value']) squared_error = 0. for sym_err in error_dict['symmetric_errors']: squared_error += sym_err**2 for asym_err in error_dict['asymmetric_errors']: squared_error += asym_err[0]*asym_err[1] errors.append(sqrt(squared_error)) else: # otherwise, 'values' is a dict just containing name: constraint_string for obs, value in m_data['values'].items(): observables.append(obs) error_dict = errors_from_string(value) central_values.append(error_dict['central_value']) squared_error = 0. for sym_err in error_dict['symmetric_errors']: squared_error += sym_err**2 for asym_err in error_dict['asymmetric_errors']: squared_error += asym_err[0]*asym_err[1] errors.append(sqrt(squared_error)) correlation = _fix_correlation_matrix(m_data['correlation'], len(observables)) covariance = np.outer(np.asarray(errors), np.asarray(errors))*correlation if not np.all(np.linalg.eigvals(covariance) > 0): # if the covariance matrix is not positive definite, try a dirty trick: # multiply all the correlations by 0.99. n_dim = len(correlation) correlation = (correlation - np.eye(n_dim))*0.99 + np.eye(n_dim) covariance = np.outer(np.asarray(errors), np.asarray(errors))*correlation # if it still isn't positive definite, give up. assert np.all(np.linalg.eigvals(covariance) > 0), "The covariance matrix is not positive definite!" + str(covariance) m.add_constraint(observables, probability.MultivariateNormalDistribution(central_values, covariance))
} _hadr_lnC = { 'K->pi': { 'tex': r"K\to \pi", 'K': 'KL', 'P': 'pi+', }, } for l in ['e', 'mu', 'l']: for M in _hadr.keys(): _process_tex = _hadr[M]['tex'] + _tex[l] + r"^+\nu" _process_taxonomy = r'Process :: $s$ hadron decays :: Semi-leptonic tree-level decays :: $K\to P\ell\nu$ :: $' + _process_tex + r"$" _obs_name = "BR(" + M + l + "nu)" _obs = Observable(_obs_name) _obs.set_description(r"Total branching ratio of $" + _process_tex + r"$") _obs.tex = r"$\text{BR}(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy) Prediction(_obs_name, BR_tot_function(_hadr[M]['K'], _hadr[M]['P'], l)) for M in _hadr_lnC.keys(): _obs_name = "lnC(" + M + l + "nu)" _obs = Observable(_obs_name) _obs.set_description(r"Effective scalar form factor in $" + _process_tex + r"$") _obs.tex = r"$\ln(C)(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy) Prediction(_obs_name, logC_function(l))
symbol = re.search(r'[A-Z].*', nuclide).group() Z = elements.Z(symbol) daughter_symbol = elements.symbol(Z - 1) return { 'name': '{}{}'.format(A, daughter_symbol), 'tex': r'{{}}^{{{}}}\text{{{}}}'.format(A, daughter_symbol) } # Observable and Prediction instances for _A, _Ad in nuclei_superallowed.items(): Dd = get_daughter(_A) _process_tex = _Ad['tex'] + r"\to " + Dd['tex'] + r"\,e^+\nu_e" _process_taxonomy = r'Process :: Nucleon decays :: Beta decays :: Superallowed $0^+\to 0^+$ decays :: $' + _process_tex + r"$" _obs_name = "Ft(" + _A + ")" _obs = Observable(_obs_name) _obs.set_description(r"$\mathcal Ft$ value of $" + _Ad['tex'] + r"$ beta decay") _obs.tex = r"$\mathcal{F}t(" + _Ad['tex'] + r")$" _obs.add_taxonomy(_process_taxonomy) Prediction(_obs_name, Ft_fct(_A)) _process_tex = r"n\to p^+ e^-\bar\nu_e" _process_taxonomy = r'Process :: Nucleon decays :: Beta decays :: Neutron decay :: $' + _process_tex + r"$" _obs_name = "tau_n" _obs = Observable(_obs_name, arguments=['me_E']) _obs.set_description(r"Neutron lifetime") _obs.tex = r"$\tau_n$" _obs.add_taxonomy(_process_taxonomy) func = lambda wc_obj, par, me_E: Neutron_tau(wc_obj, par, me_E)() Prediction(_obs_name, func)
def bxll_dbrdq2_func(q, lep): def fct(wc_obj, par, q2): return bxll_dbrdq2(q2, wc_obj, par, q, lep) return fct # Observable instances _tex = {'e': 'e', 'mu': '\mu', 'tau': r'\tau', 'l': r'\ell'} for l in ['e', 'mu', 'tau', 'l']: for q in ['s', 'd']: _process_tex = r"B\to X_" + q +_tex[l]+r"^+"+_tex[l]+r"^-" _process_taxonomy = r'Process :: $b$ hadron decays :: FCNC decays :: $B\to X\ell^+\ell^-$ :: $' + _process_tex + r"$" # binned branching ratio _obs_name = "<BR>(B->X"+q+l+l+")" _obs = Observable(name=_obs_name, arguments=['q2min', 'q2max']) _obs.set_description(r"Binned branching ratio of $" + _process_tex + r"$") _obs.tex = r"$\langle \text{BR} \rangle(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy) Prediction(_obs_name, bxll_br_int_func(q, l)) # differential branching ratio _obs_name = "dBR/dq2(B->X"+q+l+l+")" _obs = Observable(name=_obs_name, arguments=['q2']) _obs.set_description(r"Differential branching ratio of $" + _process_tex + r"$") _obs.tex = r"$\frac{d\text{BR}}{dq^2}(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy) Prediction(_obs_name, bxll_dbrdq2_func(q, l))
return (1 - A * y) / (1 - y**2) * BR0 def BVgamma_function(function, B, V): return lambda wc_obj, par: function(wc_obj, par, B, V) # Observable and Prediction instances _func = {'BR': BR, 'ACP': ACP} _tex = {'BR': r'\text{BR}', 'ACP': r'A_{CP}'} _desc = {'BR': 'Branching ratio', 'ACP': 'Direct CP asymmetry'} for key in _func.keys(): _obs_name = key + "(B+->K*gamma)" _obs = Observable(_obs_name) _obs.set_description(_desc[key] + r" of $B^+\to K^{*+}\gamma$") _obs.tex = r'$' + _tex[key] + r"(B^+\to K^{*+}\gamma)$" Prediction(_obs_name, BVgamma_function(_func[key], 'B+', 'K*+')) _obs_name = key + "(B0->K*gamma)" _obs = Observable(_obs_name) _obs.set_description(_desc[key] + r" of $B^0\to K^{*0}\gamma$") _obs.tex = r'$' + _tex[key] + r"(B^0\to K^{*0}\gamma)$" Prediction(_obs_name, BVgamma_function(_func[key], 'B0', 'K*0')) _obs_name = "ACP(Bs->phigamma)" _obs = Observable(_obs_name) _obs.set_description(_desc['ACP'] + r" of $B_s\to \phi\gamma$") _obs.tex = r'$' + _tex['ACP'] + r"(B_s\to \phi\gamma)$" Prediction(_obs_name, BVgamma_function(_func['ACP'], 'Bs', 'phi'))
y = par['DeltaGamma/Gamma_'+B]/2. return (1 - A*y)/(1-y**2) * BR0 def BVgamma_function(function, B, V): return lambda wc_obj, par: function(wc_obj, par, B, V) # Observable and Prediction instances _func = {'BR': BR, 'ACP': ACP} _tex = {'BR': r'\text{BR}', 'ACP': r'A_{CP}'} _desc = {'BR': 'Branching ratio', 'ACP': 'Direct CP asymmetry'} for key in _func.keys(): _obs_name = key + "(B+->K*gamma)" _obs = Observable(_obs_name) _obs.set_description(_desc[key] + r" of $B^+\to K^{*+}\gamma$") _obs.tex = r'$' + _tex[key] + r"(B^+\to K^{*+}\gamma)$" Prediction(_obs_name, BVgamma_function(_func[key], 'B+', 'K*+')) _obs_name = key + "(B0->K*gamma)" _obs = Observable(_obs_name) _obs.set_description(_desc[key] + r" of $B^0\to K^{*0}\gamma$") _obs.tex = r'$' + _tex[key] + r"(B^0\to K^{*0}\gamma)$" Prediction(_obs_name, BVgamma_function(_func[key], 'B0', 'K*0')) _obs_name = "ACP(Bs->phigamma)" _obs = Observable(_obs_name) _obs.set_description(_desc['ACP'] + r" of $B_s\to \phi\gamma$") _obs.tex = r'$' + _tex['ACP'] + r"(B_s\to \phi\gamma)$" Prediction(_obs_name, BVgamma_function(_func['ACP'], 'Bs', 'phi'))
den = (BR_BXclnu(par, wc_obj, 'e') + BR_BXclnu(par, wc_obj, 'mu'))/2. else: den = BR_BXclnu(par, wc_obj, lden) return num/den def BR_tot_leptonflavour_function(lnum, lden): return lambda wc_obj, par: BR_tot_leptonflavour(wc_obj, par, lnum, lden) _process_taxonomy = r'Process :: $b$ hadron decays :: Semi-leptonic tree-level decays :: $B\to X\ell\nu$ :: $' _lep = {'e': 'e', 'mu': r'\mu', 'tau': r'\tau', 'l': r'\ell'} for l in _lep: _obs_name = "BR(B->Xc"+l+"nu)" _process_tex = r"B\to X_c"+_lep[l]+r"^+\nu_"+_lep[l] _obs = Observable(_obs_name) _obs.set_description(r"Total branching ratio of $" + _process_tex + r"$") _obs.tex = r"$\text{BR}(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy + _process_tex + r"$") Prediction(_obs_name, BR_tot_function(l)) # Lepton flavour ratios for l in [('mu','e'), ('tau','mu'), ('tau', 'l')]: _obs_name = "R"+l[0]+l[1]+"(B->Xclnu)" _obs = Observable(name=_obs_name) _process_1 = r"B\to X_c"+_lep[l[0]]+r"^+\nu_"+_lep[l[0]] _process_2 = r"B\to X_c"+_lep[l[1]]+r"^+\nu_"+_lep[l[1]] _obs.set_description(r"Ratio of total branching ratios of $" + _process_1 + r"$" + " and " + r"$" + _process_2 +r"$") _obs.tex = r"$R_{" + _lep[l[0]] + ' ' + _lep[l[1]] + r"}(B\to X_c\ell^+\nu)$" # add taxonomy for both processes (e.g. B->Xcenu and B->Xcmunu) _obs.add_taxonomy(_process_taxonomy + _process_1 + r"$")
return (-par['omega+'] / (sqrt(2) * par['eps_K']) * (ImA0 / ReA0 * (1 - par['Omegahat_eff']) - 1 / a * ImA2 / ReA2).real) def epsprime_NP(wc_obj, par): r"""Compute the NP contribution to $\epsilon'/\epsilon$.""" # Neglecting isospin breaking corrections! A = Kpipi_amplitudes_NP(wc_obj, par) ImA0 = A[0].imag ImA2 = A[2].imag ReA0 = par['ReA0(K->pipi)'] ReA2 = par['ReA2(K->pipi)'] a = par['epsp a'] # eq. (16) # dividing by a to remove the isospin brk corr in omega+, cf. (16) in 1507.06345 return (-par['omega+'] / a / (sqrt(2) * par['eps_K']) * (ImA0 / ReA0 - ImA2 / ReA2).real) def epsprime(wc_obj, par): r"""Compute $\epsilon'/\epsilon$, parametrizing direct CPV in $K\to\pi\pi$.""" return epsprime_SM(par) + epsprime_NP(wc_obj, par) # Observable and Prediction instances o = Observable('epsp/eps') o.tex = r"$\epsilon^\prime/\epsilon$" Prediction('epsp/eps', epsprime) o.set_description(r"Direct CP violation parameter") o.add_taxonomy(r'Process :: $s$ hadron decays :: Non-leptonic decays :: $K\to \pi\pi$')
_tex = {'e': 'e', 'mu': '\mu', 'tau': r'\tau'} _observables = { 'FL': {'func_num': FL_num, 'tex': r'F_L', 'desc': 'longitudinal polarization fraction'}, 'AFBl': {'func_num': AFBl_num, 'tex': r'A_\text{FB}^\ell', 'desc': 'leptonic forward-backward asymmetry'}, 'AFBh': {'func_num': AFBh_num, 'tex': r'A_\text{FB}^h', 'desc': 'hadronic forward-backward asymmetry'}, 'AFBlh': {'func_num': AFBlh_num, 'tex': r'A_\text{FB}^{\ell h}', 'desc': 'lepton-hadron forward-backward asymmetry'}, } for l in ['e', 'mu', ]: # tau requires lepton mass dependence! _process_tex = r"\Lambda_b\to\Lambda " +_tex[l]+r"^+"+_tex[l]+r"^-" _process_taxonomy = r'Process :: $b$ hadron decays :: FCNC decays :: $\Lambda_b\to \Lambda\ell^+\ell^-$ :: $' + _process_tex + r"$" # binned branching ratio _obs_name = "<dBR/dq2>(Lambdab->Lambda"+l+l+")" _obs = Observable(name=_obs_name, arguments=['q2min', 'q2max']) _obs.set_description(r"Binned differential branching ratio of $" + _process_tex + r"$") _obs.tex = r"$\langle \frac{d\text{BR}}{dq^2} \rangle(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy) Prediction(_obs_name, dbrdq2_int_func(l)) # differential branching ratio _obs_name = "dBR/dq2(Lambdab->Lambda"+l+l+")" _obs = Observable(name=_obs_name, arguments=['q2']) _obs.set_description(r"Differential branching ratio of $" + _process_tex + r"$") _obs.tex = r"$\frac{d\text{BR}}{dq^2}(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy) Prediction(_obs_name, dbrdq2_func(l)) for obs in _observables: # binned angular observables
def test_bsll_classes(self): par_default = default_parameters.get_central_all() self.assertAlmostEqual(br_timeint(par_default, wc_tau, 'Bs', 'tau', 'tau')/Observable.get_instance('BR(Bs->tautau)').prediction_central(default_parameters, wc_obj), 1, places=4) self.assertAlmostEqual(br_timeint(par_default, wc_e, 'Bs', 'e', 'e')/Observable.get_instance('BR(Bs->ee)').prediction_central(default_parameters, wc_obj), 1, places=4) self.assertAlmostEqual(br_timeint(par_default, wc, 'Bs', 'mu', 'mu')/Observable.get_instance('BR(Bs->mumu)').prediction_central(default_parameters, wc_obj), 1, places=4)
label = meson_quark[B] + lep + lep wc = wctot_dict(wc_obj, label, scale, par) return ADeltaGamma(par, wc, B, lep) return ADG_func # Observable and Prediction instances _tex = {'e': 'e', 'mu': '\mu', 'tau': r'\tau'} for l in ['e', 'mu', 'tau']: _process_taxonomy = r'Process :: $b$ hadron decays :: FCNC decays :: $B\to\ell^+\ell^-$ :: $' # For the Bs decay, we take the time-integrated branching ratio _obs_name = "BR(Bs->" + l + l + ")" _obs = Observable(_obs_name) _process_tex = r"B_s\to " + _tex[l] + r"^+" + _tex[l] + r"^-" _obs.set_description(r"Time-integrated branching ratio of $" + _process_tex + r"$.") _obs.tex = r"$\overline{\text{BR}}(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy + _process_tex + r"$") Prediction(_obs_name, bqll_obs_function(br_timeint, 'Bs', l, l)) # Add the effective lifetimes for Bs _obs_name = 'tau_' + l + l _obs = Observable(_obs_name) _obs.set_description(r"Effective lifetime for $" + _process_tex + r"$.") _obs.tex = r"$\tau_{B_s \to " + _tex[l] + _tex[l] + "}$" _obs.add_taxonomy(_process_taxonomy + _process_tex + r"$") if l == 'e': Prediction(_obs_name,
def predict(obs): d = Observable.argument_format(obs, 'dict') return flavio.np_prediction(d.pop('name'), w, **d)
return bxll_afb(q2, wc_obj, par, q, lep) return fct # Observable instances _tex = {'e': 'e', 'mu': '\mu', 'tau': r'\tau', 'l': r'\ell'} for l in ['e', 'mu', 'tau', 'l']: for q in ['s', 'd']: _process_tex = r"B\to X_" + q +_tex[l]+r"^+"+_tex[l]+r"^-" _process_taxonomy = r'Process :: $b$ hadron decays :: FCNC decays :: $B\to X\ell^+\ell^-$ :: $' + _process_tex + r"$" # binned branching ratio _obs_name = "<BR>(B->X"+q+l+l+")" _obs = Observable(name=_obs_name, arguments=['q2min', 'q2max']) _obs.set_description(r"Binned branching ratio of $" + _process_tex + r"$") _obs.tex = r"$\langle \text{BR} \rangle(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy) Prediction(_obs_name, bxll_br_int_func(q, l)) # differential branching ratio _obs_name = "dBR/dq2(B->X"+q+l+l+")" _obs = Observable(name=_obs_name, arguments=['q2']) _obs.set_description(r"Differential branching ratio of $" + _process_tex + r"$") _obs.tex = r"$\frac{d\text{BR}}{dq^2}(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy) Prediction(_obs_name, bxll_dbrdq2_func(q, l)) if l != 'tau': # AFB not yet implemented for tau! (ml=0)
xi_t_d = flavio.physics.ckm.xi("t", "bd")(par) xi_t_s = flavio.physics.ckm.xi("t", "bs")(par) wc_d = flavio.physics.bdecays.wilsoncoefficients.wctot_dict(wc_obj, "bdee", scale, par, nf_out=5) wc_s = flavio.physics.bdecays.wilsoncoefficients.wctot_dict(wc_obj, "bsee", scale, par, nf_out=5) br_d = abs(xi_t_d) ** 2 * PE0_BR_BXgamma(wc_d, par, "d", E0) br_s = abs(xi_t_s) ** 2 * PE0_BR_BXgamma(wc_s, par, "s", E0) as_d = abs(xi_t_d) ** 2 * PE0_ACP_BXgamma(wc_d, par, "d", E0) as_s = abs(xi_t_s) ** 2 * PE0_ACP_BXgamma(wc_s, par, "s", E0) # return (as_s)/(br_s + br_d) return (as_s + as_d) / (br_s + br_d) _process_taxonomy = r"Process :: $b$ hadron decays :: FCNC decays :: $B\to X\gamma$ :: " _obs_name = "BR(B->Xsgamma)" _obs = Observable(_obs_name) _obs.set_description(r"CP-averaged branching ratio of $B\to X_s\gamma$ for $E_\gamma>1.6$ GeV") _obs.tex = r"$\text{BR}(B\to X_s\gamma)$" _obs.add_taxonomy(_process_taxonomy + r"$B\to X_s\gamma$") Prediction(_obs_name, lambda wc_obj, par: BRBXgamma(wc_obj, par, "s", 1.6)) _obs_name = "BR(B->Xdgamma)" _obs = Observable(_obs_name) _obs.set_description(r"CP-averaged branching ratio of $B\to X_d\gamma$ for $E_\gamma>1.6$ GeV") _obs.tex = r"$\text{BR}(B\to X_d\gamma)$" _obs.add_taxonomy(_process_taxonomy + r"$B\to X_d\gamma$") Prediction(_obs_name, lambda wc_obj, par: BRBXgamma(wc_obj, par, "d", 1.6)) _obs_name = "ACP(B->Xgamma)" _obs = Observable(_obs_name) _obs.set_description(r"Direct CP asymmetry in $B\to X_{s+d}\gamma$ for $E_\gamma>1.6$ GeV")
'Bs->K*': { 'tex': r"B_s\to K^{* -} ", 'B': 'Bs', 'V': 'K*+', 'decays': ['Bs->K*'], }, } _process_taxonomy = r'Process :: $b$ hadron decays :: Semi-leptonic tree-level decays :: $B\to V\ell\nu$ :: $' for l in ['e', 'mu', 'tau', 'l']: for br in ['dBR/dq2', 'BR', '<BR>']: for M in _hadr.keys(): _process_tex = _hadr[M]['tex'] + _tex[l] + r"^+\nu_" + _tex[l] _obs_name = br + "(" + M + l + "nu)" _obs = Observable(_obs_name) _obs.set_description(_desc[br] + r" branching ratio of $" + _process_tex + "$") _obs.tex = r'$' + _tex_br[br] + r"(" + _process_tex + ")$" _obs.arguments = _args[br] _obs.add_taxonomy(_process_taxonomy + _process_tex + r'$') Prediction(_obs_name, _func[br](_hadr[M]['B'], _hadr[M]['V'], l)) # Lepton flavour ratios for l in [('mu', 'e'), ('tau', 'mu'), ('tau', 'l')]: for M in _hadr_l.keys(): # binned ratio of BRs _obs_name = "<R" + l[0] + l[1] + ">(" + M + "lnu)" _obs = Observable(name=_obs_name, arguments=['q2min', 'q2max']) _obs.set_description(r"Ratio of partial branching ratios of $" +
} _tex_lfv = {'emu': r'e^+\mu^-', 'mue': r'\mu^+e^-', 'taue': r'\tau^+e^-', 'etau': r'e^+\tau^-', 'taumu': r'\tau^+\mu^-', 'mutau': r'\mu^+\tau^-', 'emu,mue': r'e^\pm\mu^\mp', 'etau,taue': r'e^\pm\tau^\mp', 'mutau,taumu': r'\mu^\pm\tau^\mp'} for l in ['e', 'mu', 'tau']: for M in _hadr.keys(): _process_tex = _hadr[M]['tex'] +_tex[l]+r"^+"+_tex[l]+r"^-" _process_taxonomy = r'Process :: $b$ hadron decays :: FCNC decays :: $B\to P\ell^+\ell^-$ :: $' + _process_tex + r"$" for obs in sorted(_observables.keys()): _obs_name = "<" + obs + ">("+M+l+l+")" _obs = Observable(name=_obs_name, arguments=['q2min', 'q2max']) _obs.set_description('Binned ' + _observables[obs]['desc'] + r" in $" + _process_tex + r"$") _obs.tex = r"$\langle " + _observables[obs]['tex'] + r"\rangle(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy) Prediction(_obs_name, bpll_obs_int_ratio_func(_observables[obs]['func_num'], dGdq2_cpaverage, _hadr[M]['B'], _hadr[M]['P'], l)) _obs_name = obs + "("+M+l+l+")" _obs = Observable(name=_obs_name, arguments=['q2']) _obs.set_description(_observables[obs]['desc'][0].capitalize() + _observables[obs]['desc'][1:] + r" in $" + _process_tex + r"$") _obs.tex = r"$" + _observables[obs]['tex'] + r"(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy) Prediction(_obs_name, bpll_obs_ratio_func(_observables[obs]['func_num'], dGdq2_cpaverage, _hadr[M]['B'], _hadr[M]['P'], l)) # binned branching ratio _obs_name = "<dBR/dq2>("+M+l+l+")" _obs = Observable(name=_obs_name, arguments=['q2min', 'q2max'])
qp = common.q_over_p(M12, G12) A = amplitude(par) A_bar = amplitude(conjugate_par(par)) xi = etaCP * qp * A / A_bar return -2*xi.imag / ( 1 + abs(xi)**2 ) def S_BJpsiK(wc_obj, par): return S(wc_obj, par, 'B0', amplitude_BJpsiK, etaCP=-1) def S_Bspsiphi(wc_obj, par): return S(wc_obj, par, 'Bs', amplitude_Bspsiphi, etaCP=+1) # Observable and Prediction instances o = Observable('DeltaM_s') o.set_description(r"Mass difference in the $B_s$-$\bar B_s$ system") o.tex = r"$\Delta M_s$" o.add_taxonomy(r'Process :: Meson-antimeson mixing :: $B_s$-$\bar B_s$ mixing') Prediction('DeltaM_s', lambda wc_obj, par: DeltaM(wc_obj, par, 'Bs')) o = Observable('DeltaM_d') o.set_description(r"Mass difference in the $B^0$-$\bar B^0$ system") o.tex = r"$\Delta M_d$" o.add_taxonomy(r'Process :: Meson-antimeson mixing :: $B^0$-$\bar B^0$ mixing') Prediction('DeltaM_d', lambda wc_obj, par: DeltaM(wc_obj, par, 'B0')) o = Observable('a_fs_s') o.set_description(r"CP asymmetry in flavour-specific $B_s$ decays") o.tex = r"$a_\text{fs}^s$" o.add_taxonomy(r'Process :: Meson-antimeson mixing :: $B_s$-$\bar B_s$ mixing')
def _load(obj): """Read measurements from a YAML stream or file.""" measurements = yaml.load(obj) for m_name, m_data in measurements.items(): m = Measurement(m_name) for arg in ['inspire', 'hepdata', 'experiment', 'url']: if arg in m_data: setattr(m, arg, m_data[arg]) if 'correlation' not in m_data: if isinstance(m_data['values'], list): for value_dict in m_data['values']: # if "value" is a list, it contains the values of observable # arguments (like q^2) args = Observable.get_instance(value_dict['name']).arguments args_num = [value_dict[a] for a in args] constraints = constraints_from_string(value_dict['value']) error_dict = errors_from_string(value_dict['value']) central_value = error_dict['central_value'] squared_error = 0. for sym_err in error_dict['symmetric_errors']: squared_error += sym_err**2 for asym_err in error_dict['asymmetric_errors']: squared_error += asym_err[0]*asym_err[1] args_num.insert(0, value_dict['name']) obs_tuple = tuple(args_num) m.add_constraint([obs_tuple], probability.NormalDistribution(central_value, sqrt(squared_error))) else: # otherwise, 'values' is a dict just containing name: constraint_string for obs, value in m_data['values'].items(): constraints = constraints_from_string(value) for constraint in constraints: m.add_constraint([obs], constraint) else: observables = [] central_values = [] errors = [] if isinstance(m_data['values'], list): for value_dict in m_data['values']: # if "value" is a list, it contains the values of observable # arguments (like q^2) args = Observable.get_instance(value_dict['name']).arguments args_num = [value_dict[a] for a in args] error_dict = errors_from_string(value_dict['value']) args_num.insert(0, value_dict['name']) obs_tuple = tuple(args_num) observables.append(obs_tuple) central_values.append(error_dict['central_value']) squared_error = 0. for sym_err in error_dict['symmetric_errors']: squared_error += sym_err**2 for asym_err in error_dict['asymmetric_errors']: squared_error += asym_err[0]*asym_err[1] errors.append(sqrt(squared_error)) else: # otherwise, 'values' is a dict just containing name: constraint_string for obs, value in m_data['values'].items(): observables.append(obs) error_dict = errors_from_string(value) central_values.append(error_dict['central_value']) squared_error = 0. for sym_err in error_dict['symmetric_errors']: squared_error += sym_err**2 for asym_err in error_dict['asymmetric_errors']: squared_error += asym_err[0]*asym_err[1] errors.append(sqrt(squared_error)) correlation = _fix_correlation_matrix(m_data['correlation'], len(observables)) covariance = np.outer(np.asarray(errors), np.asarray(errors))*correlation if not np.all(np.linalg.eigvals(covariance) > 0): # if the covariance matrix is not positive definite, try a dirty trick: # multiply all the correlations by 0.99. n_dim = len(correlation) correlation = (correlation - np.eye(n_dim))*0.99 + np.eye(n_dim) covariance = np.outer(np.asarray(errors), np.asarray(errors))*correlation # if it still isn't positive definite, give up. assert np.all(np.linalg.eigvals(covariance) > 0), "The covariance matrix is not positive definite!" + str(covariance) m.add_constraint(observables, probability.MultivariateNormalDistribution(central_values, covariance))
'dBR/dq2': r'\frac{d\text{BR}}{dq^2}', 'BR': r'\text{BR}', '<BR>': r'\langle\text{BR}\rangle' } _args = {'dBR/dq2': ['q2'], 'BR': None, '<BR>': ['q2min', 'q2max']} _hadr = { 'KL->pi': { 'tex': r"K_L\to \pi^+", 'K': 'KL', 'P': 'pi+', }, 'K+->pi': { 'tex': r"K^+\to \pi^0", 'K': 'K+', 'P': 'pi0', }, } for l in ['e', 'mu', 'l']: for M in _hadr.keys(): _process_tex = _hadr[M]['tex'] + _tex[l] + r"^+\nu_" + _tex[l] _process_taxonomy = r'Process :: $s$ hadron decays :: Semi-leptonic tree-level decays :: $K\to P\ell\nu$ :: $' + _process_tex + r"$" _obs_name = "BR(" + M + l + "nu)" _obs = Observable(_obs_name) _obs.set_description(r"Total branching ratio of $" + _process_tex + r"$") _obs.tex = r"$\text{BR}(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy) Prediction(_obs_name, BR_tot_function(_hadr[M]['K'], _hadr[M]['P'], l))
def BVgamma_function(function, B, V): return lambda wc_obj, par: function(wc_obj, par, B, V) # Observable and Prediction instances _func = {'BR': BR, 'ACP': ACP} _tex = {'BR': r'\text{BR}', 'ACP': r'A_{CP}'} _desc = {'BR': 'Branching ratio', 'ACP': 'Direct CP asymmetry'} _process_taxonomy = r'Process :: $b$ hadron decays :: FCNC decays :: $B\to V\gamma$ :: $' for key in _func.keys(): _obs_name = key + "(B+->K*gamma)" _obs = Observable(_obs_name) _process_tex = r"B^+\to K^{*+}\gamma" _obs.set_description(_desc[key] + r" of $" + _process_tex + r"$") _obs.tex = r'$' + _tex[key] + r"(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy + _process_tex + r"$") Prediction(_obs_name, BVgamma_function(_func[key], 'B+', 'K*+')) _obs_name = key + "(B0->K*gamma)" _obs = Observable(_obs_name) _process_tex = r"B^0\to K^{*0}\gamma" _obs.set_description(_desc[key] + r" of $" + _process_tex + r"$") _obs.tex = r'$' + _tex[key] + r"(" + _process_tex + r")$" _obs.add_taxonomy(_process_taxonomy + _process_tex + r"$") Prediction(_obs_name, BVgamma_function(_func[key], 'B0', 'K*0')) _obs_name = "ACP(Bs->phigamma)"