Module flavio.physics.bdecays.bpll

Functions for exclusive $B\to P\ell^+\ell^-$ decays.

Functions

def AFB_cpaverage_num(J, J_bar)
Expand source code
def AFB_cpaverage_num(J, J_bar):
    return (AFB_num(J) + AFB_num(J_bar))/2.
def AFB_num(J)
Expand source code
def AFB_num(J):
    return J['b']
def FH_cpaverage_num(J, J_bar)
Expand source code
def FH_cpaverage_num(J, J_bar):
    return (FH_num(J) + FH_num(J_bar))/2.
def FH_num(J)
Expand source code
def FH_num(J):
    return 2 * (J['a'] + J['c'])
def bpll_dbrdq2(q2, wc_obj, par, B, P, lep)
Expand source code
def bpll_dbrdq2(q2, wc_obj, par, B, P, lep):
    tauB = par['tau_'+B]
    dBR = tauB * bpll_obs(dGdq2_cpaverage, q2, wc_obj, par, B, P, lep)
    if P == 'pi0':
        # factor of 1/2 for neutral pi due to pi = (uubar-ddbar)/sqrt(2)
        return dBR / 2.
    else:
        return dBR
def bpll_dbrdq2_Belle_func(B, P, lep)
Expand source code
def bpll_dbrdq2_Belle_func(B, P, lep):
    def fct(wc_obj, par):
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore", message="The predictions in the region of narrow charmonium resonances are not meaningful")
            warnings.filterwarnings("ignore", message="The QCDF corrections should not be trusted .*")
            mB = par['m_'+B]
            mP = par['m_'+P]
            ml = par['m_'+lep]
            ml = par['m_'+lep]
            q2max = (mB-mP)**2
            q2min = (ml+ml)**2
            return bpll_dbrdq2_int(q2min, q2max, wc_obj, par, B, P, lep, epsrel=0.0002)*(q2max-q2min)
    return fct
def bpll_dbrdq2_func(B, P, lep)
Expand source code
def bpll_dbrdq2_func(B, P, lep):
    def fct(wc_obj, par, q2):
        return bpll_dbrdq2(q2, wc_obj, par, B, P, lep)
    return fct
def bpll_dbrdq2_int(q2min, q2max, wc_obj, par, B, P, lep, epsrel=0.005)
Expand source code
def bpll_dbrdq2_int(q2min, q2max, wc_obj, par, B, P, lep, epsrel=0.005):
    def obs(q2):
        return bpll_dbrdq2(q2, wc_obj, par, B, P, lep)
    return flavio.math.integrate.nintegrate(obs, q2min, q2max, epsrel=epsrel)/(q2max-q2min)
def bpll_dbrdq2_int_func(B, P, lep)
Expand source code
def bpll_dbrdq2_int_func(B, P, lep):
    def fct(wc_obj, par, q2min, q2max):
        return bpll_dbrdq2_int(q2min, q2max, wc_obj, par, B, P, lep)
    return fct
def bpll_dbrdq2_tot_func(B, P, lep)
Expand source code
def bpll_dbrdq2_tot_func(B, P, lep):
    def fct(wc_obj, par):
        mB = par['m_'+B]
        mP = par['m_'+P]
        ml = par['m_'+lep]
        ml = par['m_'+lep]
        q2max = (mB-mP)**2
        q2min = (ml+ml)**2
        return bpll_dbrdq2_int(q2min, q2max, wc_obj, par, B, P, lep)*(q2max-q2min)
    return fct
def bpll_obs(function, q2, wc_obj, par, B, P, lep)
Expand source code
def bpll_obs(function, q2, wc_obj, par, B, P, lep):
    ml = par['m_'+lep]
    mB = par['m_'+B]
    mP = par['m_'+P]
    if q2 <= (ml+ml)**2 or q2 > (mB-mP)**2:
        return 0
    scale = config['renormalization scale']['bpll']
    mb = running.get_mb(par, scale)
    h     = helicity_amps(q2, wc_obj, par, B, P, lep)
    J     = angular.angularcoeffs_general_p(h, q2, mB, mP, mb, 0, ml, ml)
    if lep == lep:
        h_bar = helicity_amps_bar(q2, wc_obj, par, B, P, lep)
        J_bar = angular.angularcoeffs_general_p(h_bar, q2, mB, mP, mb, 0, ml, ml)
    else:
        # for LFV decays, don't bother about the CP average. There is no strong phase.
        J_bar = J
    return function(J, J_bar)
def bpll_obs_int(function, q2min, q2max, wc_obj, par, B, P, lep, epsrel=0.005)
Expand source code
def bpll_obs_int(function, q2min, q2max, wc_obj, par, B, P, lep, epsrel=0.005):
    def obs(q2):
        return bpll_obs(function, q2, wc_obj, par, B, P, lep)
    return flavio.math.integrate.nintegrate(obs, q2min, q2max, epsrel=epsrel)
def bpll_obs_int_ratio_func(func_num, func_den, B, P, lep)
Expand source code
def bpll_obs_int_ratio_func(func_num, func_den, B, P, lep):
    def fct(wc_obj, par, q2min, q2max):
        num = bpll_obs_int(func_num, q2min, q2max, wc_obj, par, B, P, lep)
        if num == 0:
            return 0
        den = bpll_obs_int(func_den, q2min, q2max, wc_obj, par, B, P, lep)
        return num/den
    return fct
def bpll_obs_int_ratio_leptonflavour(func, B, P, lnum, lden)
Expand source code
def bpll_obs_int_ratio_leptonflavour(func, B, P, lnum, lden):
    def fct(wc_obj, par, q2min, q2max):
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore", message="The QCDF corrections should not be trusted .*")
            num = bpll_obs_int(func, q2min, q2max, wc_obj, par, B, P, lnum, epsrel=0.0005)
            if num == 0:
                return 0
            denom = bpll_obs_int(func, q2min, q2max, wc_obj, par, B, P, lden, epsrel=0.0005)
            return num/denom
    return fct
def bpll_obs_ratio_func(func_num, func_den, B, P, lep)
Expand source code
def bpll_obs_ratio_func(func_num, func_den, B, P, lep):
    def fct(wc_obj, par, q2):
        num = bpll_obs(func_num, q2, wc_obj, par, B, P, lep)
        if num == 0:
            return 0
        den = bpll_obs(func_den, q2, wc_obj, par, B, P, lep)
        return num/den
    return fct
def bpll_obs_ratio_leptonflavour(func, B, P, lnum, lden)
Expand source code
def bpll_obs_ratio_leptonflavour(func, B, P, lnum, lden):
    def fct(wc_obj, par, q2):
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore", message="The QCDF corrections should not be trusted .*")
            num = bpll_obs(func, q2, wc_obj, par, B, P, lnum)
            if num == 0:
                return 0
            denom = bpll_obs(func, q2, wc_obj, par, B, P, lden)
            return num/denom
    return fct
def dGdq2(J)
Expand source code
def dGdq2(J):
    return 2 * (J['a'] + J['c']/3.)
def dGdq2_cpaverage(J, J_bar)
Expand source code
def dGdq2_cpaverage(J, J_bar):
    return (dGdq2(J) + dGdq2(J_bar))/2.
def dGdq2_cpdiff(J, J_bar)
Expand source code
def dGdq2_cpdiff(J, J_bar):
    return (dGdq2(J) - dGdq2(J_bar))/2.
def get_ff(q2, par, B, P)
Expand source code
def get_ff(q2, par, B, P):
    ff_name = meson_ff[(B,P)] + ' form factor'
    return AuxiliaryQuantity[ff_name].prediction(par_dict=par, wc_obj=None, q2=q2)
def get_subleading(q2, wc_obj, par_dict, B, P, lep, cp_conjugate)
Expand source code
def get_subleading(q2, wc_obj, par_dict, B, P, lep, cp_conjugate):
    if 'B' in B and 'pi' in P:
        # skip subleading correction for B->pi decays
        return {}
    if q2 <= 9:
        sub_name = B+'->'+P + 'll subleading effects at low q2'
        return AuxiliaryQuantity[sub_name].prediction(par_dict=par_dict, wc_obj=wc_obj, q2=q2, cp_conjugate=cp_conjugate)
    elif q2 > 14:
        sub_name = B+'->'+P + 'll subleading effects at high q2'
        return AuxiliaryQuantity[sub_name].prediction(par_dict=par_dict, wc_obj=wc_obj, q2=q2, cp_conjugate=cp_conjugate)
    else:
        return {}
def helicity_amps(q2, wc_obj, par, B, P, lep)
Expand source code
def helicity_amps(q2, wc_obj, par, B, P, lep):
    if q2 >= 8.7 and q2 < 14 and lep != 'tau':
        warnings.warn("The predictions in the region of narrow charmonium resonances are not meaningful")
    return add_dict((
        helicity_amps_ff(q2, wc_obj, par, B, P, lep, cp_conjugate=False),
        get_subleading(q2, wc_obj, par, B, P, lep, cp_conjugate=False)
        ))
def helicity_amps_bar(q2, wc_obj, par, B, P, lep)
Expand source code
def helicity_amps_bar(q2, wc_obj, par, B, P, lep):
    if q2 >= 8.7 and q2 < 14 and lep != 'tau':
        warnings.warn("The predictions in the region of narrow charmonium resonances are not meaningful")
    return add_dict((
        helicity_amps_ff(q2, wc_obj, par, B, P, lep, cp_conjugate=True),
        get_subleading(q2, wc_obj, par, B, P, lep, cp_conjugate=True)
        ))
def helicity_amps_ff(q2, wc_obj, par_dict, B, P, lep, cp_conjugate)
Expand source code
def helicity_amps_ff(q2, wc_obj, par_dict, B, P, lep, cp_conjugate):
    par = par_dict.copy()
    if cp_conjugate:
        par = conjugate_par(par)
    scale = config['renormalization scale']['bpll']
    label = meson_quark[(B,P)] + lep + lep # e.g. bsmumu, bdtautau
    wc = wctot_dict(wc_obj, label, scale, par)
    if cp_conjugate:
        wc = conjugate_wc(wc)
    wc_eff = get_wceff(q2, wc, par, B, P, lep, scale)
    ml = par['m_'+lep]
    mB = par['m_'+B]
    mP = par['m_'+P]
    mb = running.get_mb(par, scale)
    N = prefactor(q2, par, B, P)
    ff = get_ff(q2, par, B, P)
    h = angular.helicity_amps_p(q2, mB, mP, mb, 0, ml, ml, ff, wc_eff, N)
    return h
def prefactor(q2, par, B, P)
Expand source code
def prefactor(q2, par, B, P):
    GF = par['GF']
    scale = config['renormalization scale']['bpll']
    alphaem = running.get_alpha(par, scale)['alpha_e']
    di_dj = meson_quark[(B,P)]
    xi_t = ckm.xi('t',di_dj)(par)
    return 4*GF/sqrt(2)*xi_t*alphaem/(4*pi)