def exponential_nonresonant_lineshape(m2, m0, alpha, ma, mb, mc, md, lr, ld, barrierFactor=True): """ Exponential nonresonant amplitude with orbital barriers """ if barrierFactor: m = atfi.sqrt(m2) q = atfk.two_body_momentum(md, m, mc) q0 = atfk.two_body_momentum(md, m0, mc) p = atfk.two_body_momentum(m, ma, mb) p0 = atfk.two_body_momentum(m0, ma, mb) b1 = orbital_barrier_factor(p, p0, lr) b2 = orbital_barrier_factor(q, q0, ld) return atfi.complex(b1 * b2 * atfi.exp(-alpha * (m2 - m0**2)), atfi.const(0.)) else: return atfi.complex(atfi.exp(-alpha * (m2 - m0**2)), atfi.const(0.))
def polynomial_nonresonant_lineshape(m2, m0, coeffs, ma, mb, mc, md, lr, ld, barrierFactor=True): """ 2nd order polynomial nonresonant amplitude with orbital barriers coeffs: list of atfi.complex polynomial coefficients [a0, a1, a2] """ def poly(x, cs): return cs[0] + cs[1] * atfi.complex( x, atfi.const(0.)) + cs[2] * atfi.complex(x**2, atfi.const(0.)) if barrierFactor: m = atfi.sqrt(m2) q = atfk.two_body_momentum(md, m, mc) q0 = atfk.two_body_momentum(md, m0, mc) p = atfk.two_body_momentum(m, ma, mb) p0 = atfk.two_body_momentum(m0, ma, mb) b1 = orbital_barrier_factor(p, p0, lr) b2 = orbital_barrier_factor(q, q0, ld) return poly(m - m0, coeffs) * atfi.complex(b1 * b2, atfi.const(0.)) else: return poly(m - m0, coeffs)
def breit_wigner_lineshape(m2, m0, gamma0, ma, mb, mc, md, dr, dd, lr, ld, barrier_factor=True, ma0=None, md0=None): """ Breit-Wigner amplitude with Blatt-Weisskopf formfactors, mass-dependent width and orbital barriers """ m = atfi.sqrt(m2) q = atfk.two_body_momentum(md, m, mc) q0 = atfk.two_body_momentum(md if md0 is None else md0, m0, mc) p = atfk.two_body_momentum(m, ma, mb) p0 = atfk.two_body_momentum(m0, ma if ma0 is None else ma0, mb) ffr = blatt_weisskopf_ff(p, p0, dr, lr) ffd = blatt_weisskopf_ff(q, q0, dd, ld) width = mass_dependent_width(m, m0, gamma0, p, p0, ffr, lr) bw = relativistic_breit_wigner(m2, m0, width) ff = ffr * ffd if barrier_factor: b1 = orbital_barrier_factor(p, p0, lr) b2 = orbital_barrier_factor(q, q0, ld) ff *= b1 * b2 return bw * atfi.complex(ff, atfi.const(0.))
def subthreshold_breit_wigner_lineshape(m2, m0, gamma0, ma, mb, mc, md, dr, dd, lr, ld, barrier_factor=True): """ Breit-Wigner amplitude (with the mass under kinematic threshold) with Blatt-Weisskopf formfactors, mass-dependent width and orbital barriers """ m = atfi.sqrt(m2) mmin = ma + mb mmax = md - mc tanhterm = atfi.tanh((m0 - ((mmin + mmax) / 2.)) / (mmax - mmin)) m0eff = mmin + (mmax - mmin) * (1. + tanhterm) / 2. q = atfk.two_body_momentum(md, m, mc) q0 = atfk.two_body_momentum(md, m0eff, mc) p = atfk.two_body_momentum(m, ma, mb) p0 = atfk.two_body_momentum(m0eff, ma, mb) ffr = blatt_weisskopf_ff(p, p0, dr, lr) ffd = blatt_weisskopf_ff(q, q0, dd, ld) width = mass_dependent_width(m, m0, gamma0, p, p0, ffr, lr) bw = relativistic_breit_wigner(m2, m0, width) ff = ffr * ffd if barrier_factor: b1 = orbital_barrier_factor(p, p0, lr) b2 = orbital_barrier_factor(q, q0, ld) ff *= b1 * b2 return bw * atfi.complex(ff, atfi.const(0.))
def final_state_momenta(self, x): """ Return final state momenta p(A1), p(A2), p(B1), p(B2) for the decay defined by the phase space vector x. The momenta are calculated in the D rest frame. """ ma1a2 = self.m_a1a2(x) mb1b2 = self.m_b1b2(x) ctha = self.cos_helicity_a(x) cthb = self.cos_helicity_b(x) phi = self.phi(x) p0 = atfk.two_body_momentum(self.md, ma1a2, mb1b2) pA = atfk.two_body_momentum(ma1a2, self.ma1, self.ma2) pB = atfk.two_body_momentum(mb1b2, self.mb1, self.mb2) zeros = atfi.zeros(pA) p3A = atfk.rotate_euler(Vector(zeros, zeros, pA), zeros, Acos(ctha), zeros) p3B = atfk.rotate_euler(Vector(zeros, zeros, pB), zeros, Acos(cthb), phi) ea = atfi.sqrt(p0 ** 2 + ma1a2 ** 2) eb = atfi.sqrt(p0 ** 2 + mb1b2 ** 2) v0a = atfk.vector(zeros, zeros, p0 / ea) v0b = atfk.vector(zeros, zeros, -p0 / eb) p4A1 = atfk.lorentz_boost(atfk.lorentz_vector(p3A, atfi.sqrt(self.ma1 ** 2 + pA ** 2)), v0a) p4A2 = atfk.lorentz_boost(atfk.lorentz_vector(-p3A, atfi.sqrt(self.ma2 ** 2 + pA ** 2)), v0a) p4B1 = atfk.lorentz_boost(atfk.lorentz_vector(p3B, atfi.sqrt(self.mb1 ** 2 + pB ** 2)), v0b) p4B2 = atfk.lorentz_boost(atfk.lorentz_vector(-p3B, atfi.sqrt(self.mb2 ** 2 + pB ** 2)), v0b) return (p4A1, p4A2, p4B1, p4B2)
def density(self, x): ma1a2 = self.m_a1a2(x) mb1b2 = self.m_b1b2(x) d1 = atfk.two_body_momentum(self.md, ma1a2, mb1b2) d2 = atfk.two_body_momentum(ma1a2, self.ma1, self.ma2) d3 = atfk.two_body_momentum(mb1b2, self.mb1, self.mb2) return d1 * d2 * d3 / self.md
def final_state_momenta(self, m2ab, m2bc): """ Calculate 4-momenta of final state tracks in a certain reference frame (decay is in x-z plane, particle A moves along z axis) m2ab, m2bc : invariant masses of AB and BC combinations """ m2ac = self.msqsum - m2ab - m2bc p_a = atfk.two_body_momentum(self.md, self.ma, atfi.sqrt(m2bc)) p_b = atfk.two_body_momentum(self.md, self.mb, atfi.sqrt(m2ac)) p_c = atfk.two_body_momentum(self.md, self.mc, atfi.sqrt(m2ab)) cos_theta_b = (p_a * p_a + p_b * p_b - p_c * p_c) / (2. * p_a * p_b) cos_theta_c = (p_a * p_a + p_c * p_c - p_b * p_b) / (2. * p_a * p_c) p4a = atfk.lorentz_vector( atfk.vector(atfi.zeros(p_a), atfi.zeros(p_a), p_a), atfi.sqrt(p_a**2 + self.ma2)) p4b = atfk.lorentz_vector( atfk.vector(p_b * atfi.sqrt(1. - cos_theta_b**2), atfi.zeros(p_b), -p_b * cos_theta_b), atfi.sqrt(p_b**2 + self.mb2)) p4c = atfk.lorentz_vector( atfk.vector(-p_c * atfi.sqrt(1. - cos_theta_c**2), atfi.zeros(p_c), -p_c * cos_theta_c), atfi.sqrt(p_c**2 + self.mc2)) return (p4a, p4b, p4c)
def final_state_momenta(data): # Obtain the vectors of angles from the input tensor using the functions # provided by phasespace object cos_theta_jpsi = phsp.cos_theta1(data) cos_theta_phi = phsp.cos_theta2(data) phi = phsp.phi(data) # Rest-frame momentum of two-body Bs->Jpsi phi decay p0 = atfk.two_body_momentum(mb, mjpsi, mphi) # Rest-frame momentum of two-body Jpsi->mu mu decay pjpsi = atfk.two_body_momentum(mjpsi, mmu, mmu) # Rest-frame momentum of two-body phi->K K decay pphi = atfk.two_body_momentum(mphi, mk, mk) # Vectors of zeros and ones of the same size as the data sample # (needed to use constant values that do not depend on the event) zeros = atfi.zeros(phi) ones = atfi.ones(phi) # 3-vectors of Jpsi->mumu and phi->KK decays (in the corresponding rest frames), # rotated by the helicity angles p3jpsi = atfk.rotate_euler( atfk.vector(zeros, zeros, pjpsi * ones), zeros, atfi.acos(cos_theta_jpsi), zeros ) p3phi = atfk.rotate_euler( atfk.vector(zeros, zeros, pphi * ones), zeros, atfi.acos(cos_theta_phi), phi ) ejpsi = atfi.sqrt(p0 ** 2 + mjpsi ** 2) # Energy of Jpsi in Bs rest frame ephi = atfi.sqrt(p0 ** 2 + mphi ** 2) # Energy of phi in Bs rest frame v0jpsi = atfk.vector( zeros, zeros, p0 / ejpsi * ones ) # 3-vector of Jpsi in Bs rest frame v0phi = atfk.vector( zeros, zeros, -p0 / ephi * ones ) # 3-vector of phi in Bs rest frame # Boost momenta of final-state particles into Bs rest frame p4mu1 = atfk.lorentz_boost( atfk.lorentz_vector(p3jpsi, atfi.sqrt(mmu ** 2 + pjpsi ** 2) * ones), v0jpsi ) p4mu2 = atfk.lorentz_boost( atfk.lorentz_vector(-p3jpsi, atfi.sqrt(mmu ** 2 + pjpsi ** 2) * ones), v0jpsi ) p4k1 = atfk.lorentz_boost( atfk.lorentz_vector(p3phi, atfi.sqrt(mk ** 2 + pphi ** 2) * ones), v0phi ) p4k2 = atfk.lorentz_boost( atfk.lorentz_vector(-p3phi, atfi.sqrt(mk ** 2 + pphi ** 2) * ones), v0phi ) return (p4mu1, p4mu2, p4k1, p4k2)
def resonant_lass_lineshape(m2ab, m0, gamma0, a, r, ma, mb): """ LASS line shape, resonant part """ m = atfi.sqrt(m2ab) q0 = atfk.two_body_momentum(m0, ma, mb) q = atfk.two_body_momentum(m, ma, mb) cot_deltab = 1. / a / q + 1. / 2. * r * q phase = atfi.atan(1. / cot_deltab) width = gamma0 * q / m * m0 / q0 ampl = relativistic_breit_wigner(m2ab, m0, width) * atfi.complex( atfi.cos(phase), atfi.sin(phase)) * atfi.cast_complex( m2ab * gamma0 / q0) return ampl
def generate_rho(cuts, rnd): """ Generate random combinations of rho -> pi pi and a kaon track """ meanrhopt = cuts[5] meankpt = cuts[0] ptcut = cuts[2] mrhogen = breit_wigner_random(rnd[:, 0], mrho, wrho) ones = atfi.ones(rnd[:, 0]) p = atfk.two_body_momentum(mrhogen, mpi * ones, mpi * ones) zeros = atfi.zeros(p) mom = [ atfk.lorentz_vector(atfk.vector(p, zeros, zeros), atfi.sqrt(p**2 + mpi**2)), atfk.lorentz_vector(-atfk.vector(p, zeros, zeros), atfi.sqrt(p**2 + mpi**2)) ] mom = generate_rotation_and_boost(mom, mrhogen, meanrhopt, ptcut, rnd[:, 2:8]) p4k = generate_4momenta(rnd[:, 8:11], meankpt, ptcut, atfi.const(mk)) p4pi1 = mom[0] p4pi2 = mom[1] return p4k, p4pi1, p4pi2
def generate_kstar(cuts, rnd): """ Generate random combinations of Kstar and a pion track """ meankstarpt = cuts[4] meanpipt = cuts[1] ptcut = cuts[2] mkstargen = breit_wigner_random(rnd[:, 0], mkstar, wkstar) ones = atfi.ones(rnd[:, 0]) p = atfk.two_body_momentum(mkstargen, mk * ones, mpi * ones) zeros = atfi.zeros(p) mom = [ atfk.lorentz_vector(atfk.vector(p, zeros, zeros), atfi.sqrt(p**2 + mk**2)), atfk.lorentz_vector(-atfk.vector(p, zeros, zeros), atfi.sqrt(p**2 + mpi**2)) ] mom = generate_rotation_and_boost(mom, mkstargen, meankstarpt, ptcut, rnd[:, 2:8]) p4k = mom[0] p4pi1 = mom[1] p4pi2 = generate_4momenta(rnd[:, 8:11], meanpipt, ptcut, atfi.const(mpi)) return p4k, p4pi1, p4pi2
def final_state_momenta(self, m2ab, m2bc, costhetaa, phia, phibc): """ Calculate 4-momenta of final state tracks in the 5D phase space m2ab, m2bc : invariant masses of AB and BC combinations (cos)thetaa, phia : direction angles of the particle A in the D reference frame phibc : angle of BC plane wrt. polarisation plane z x p_a """ thetaa = atfi.acos(costhetaa) m2ac = self.msqsum - m2ab - m2bc # Magnitude of the momenta p_a = atfk.two_body_momentum(self.md, self.ma, atfi.sqrt(m2bc)) p_b = atfk.two_body_momentum(self.md, self.mb, atfi.sqrt(m2ac)) p_c = atfk.two_body_momentum(self.md, self.mc, atfi.sqrt(m2ab)) cos_theta_b = (p_a * p_a + p_b * p_b - p_c * p_c) / (2. * p_a * p_b) cos_theta_c = (p_a * p_a + p_c * p_c - p_b * p_b) / (2. * p_a * p_c) # Fix momenta with p3a oriented in z (quantisation axis) direction p3a = atfk.vector(atfi.zeros(p_a), atfi.zeros(p_a), p_a) p3b = atfk.vector(p_b * Sqrt(1. - cos_theta_b**2), atfi.zeros(p_b), -p_b * cos_theta_b) p3c = atfk.vector(-p_c * Sqrt(1. - cos_theta_c**2), atfi.zeros(p_c), -p_c * cos_theta_c) # rotate vectors to have p3a with thetaa as polar helicity angle p3a = atfk.rotate_euler(p3a, atfi.const(0.), thetaa, atfi.const(0.)) p3b = atfk.rotate_euler(p3b, atfi.const(0.), thetaa, atfi.const(0.)) p3c = atfk.rotate_euler(p3c, atfi.const(0.), thetaa, atfi.const(0.)) # rotate vectors to have p3a with phia as azimuthal helicity angle p3a = atfk.rotate_euler(p3a, phia, atfi.const(0.), atfi.const(0.)) p3b = atfk.rotate_euler(p3b, phia, atfi.const(0.), atfi.const(0.)) p3c = atfk.rotate_euler(p3c, phia, atfi.const(0.), atfi.const(0.)) # rotate BC plane to have phibc as angle with the polarization plane p3b = atfk.rotate(p3b, phibc, p3a) p3c = atfk.rotate(p3c, phibc, p3a) # Define 4-vectors p4a = atfk.lorentz_vector(p3a, atfi.sqrt(p_a**2 + self.ma2)) p4b = atfk.lorentz_vector(p3b, atfi.sqrt(p_b**2 + self.mb2)) p4c = atfk.lorentz_vector(p3c, atfi.sqrt(p_c**2 + self.mc2)) return (p4a, p4b, p4c)
def nonresonant_lass_lineshape(m2ab, a, r, ma, mb): """ LASS line shape, nonresonant part """ m = atfi.sqrt(m2ab) q = atfk.two_body_momentum(m, ma, mb) cot_deltab = 1. / a / q + 1. / 2. * r * q ampl = atfi.cast_complex(m) / atfi.complex(q * cot_deltab, -q) return ampl
def flatte_lineshape(s, m, g1, g2, ma1, mb1, ma2, mb2): """ Flatte line shape s : squared inv. mass m : resonance mass g1 : coupling to ma1, mb1 g2 : coupling to ma2, mb2 """ mab = atfi.sqrt(s) pab1 = atfk.two_body_momentum(mab, ma1, mb1) rho1 = 2. * pab1 / mab pab2 = atfk.complex_two_body_momentum(mab, ma2, mb2) rho2 = 2. * pab2 / atfi.cast_complex(mab) gamma = (atfi.cast_complex(g1**2 * rho1) + atfi.cast_complex(g2**2) * rho2) / atfi.cast_complex(m) return relativistic_breit_wigner(s, m, gamma)
def special_flatte_lineshape(m2, m0, gamma0, ma, mb, mc, md, dr, dd, lr, ld, barrier_factor=True): """ Flatte amplitude with Blatt-Weisskopf formfactors, 2 component mass-dependent width and orbital barriers as done in Pentaquark analysis for L(1405) that peaks below pK threshold. ma = [ma1, ma2] and mb = [mb1, mb2] NB: The dominant decay for a given resonance should be the 2nd channel i.e. R -> a2 b2. This is because (as done in pentaquark analysis) in calculating p0 (used in Blatt-Weisskopf FF) for both channels, the dominant decay is used. Another assumption made in pentaquark is equal couplings ie. gamma0_1 = gamma0_2 = gamma and only differ in phase space factors """ ma1, ma2 = ma[0], ma[1] mb1, mb2 = mb[0], mb[1] m = atfi.sqrt(m2) # D->R c q = atfk.two_body_momentum(md, m, mc) q0 = atfk.two_body_momentum(md, m0, mc) ffd = blatt_weisskopf_ff(q, q0, dd, ld) # R -> a1 b1 p_1 = atfk.two_body_momentum(m, ma1, mb1) p0_1 = atfk.two_body_momentum(m0, ma1, mb1) ffr_1 = blatt_weisskopf_ff(p_1, p0_1, dr, lr) # R -> a2 b2 p_2 = atfk.two_body_momentum(m, ma2, mb2) p0_2 = atfk.two_body_momentum(m0, ma2, mb2) ffr_2 = blatt_weisskopf_ff(p_2, p0_2, dr, lr) # lineshape width_1 = mass_dependent_width(m, m0, gamma0, p_1, p0_2, blatt_weisskopf_ff(p_1, p0_2, dr, lr), lr) width_2 = mass_dependent_width(m, m0, gamma0, p_2, p0_2, ffr_2, lr) width = width_1 + width_2 bw = relativistic_breit_wigner(m2, m0, width) # Form factor def ff = ffr_1 * ffd if barrier_factor: b1 = orbital_barrier_factor(p_1, p0_1, lr) b2 = orbital_barrier_factor(q, q0, ld) ff *= b1 * b2 return bw * atfi.complex(ff, atfi.const(0.))