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 helicity_couplings_from_ls(ja, jb, jc, lb, lc, bls): """Helicity couplings from a list of LS couplings. ja : spin of A (decaying) particle jb : spin of B (1st decay product) jc : spin of C (2nd decay product) lb : B helicity lc : C helicity bls : dictionary of LS couplings, where: keys are tuples corresponding to (L,S) pairs values are values of LS couplings Note that ALL j,l,s should be doubled, e.g. S=1 for spin-1/2, L=2 for p-wave etc. :param ja: :param jb: :param jc: :param lb: :param lc: :param bls: """ a = 0. # print("%d %d %d %d %d" % (ja, jb, jc, lb, lc)) for ls, b in bls.items(): l = ls[0] s = ls[1] coeff = math.sqrt((l+1)/(ja+1))*atfi.clebsch(jb, lb, jc, -lc, s, lb-lc)*\ atfi.clebsch( l, 0, s, lb-lc, ja, lb-lc) if coeff: a += atfi.complex(atfi.const(float(coeff)), atfi.const(0.)) * b return a
def model(x) : m2dp = phsp.m2ab(x) m2ppi = phsp.m2bc(x) p4d, p4p, p4pi = phsp.final_state_momenta(m2dp, m2ppi) dp_theta_r, dp_phi_r, dp_theta_d, dp_phi_d = atfk.helicity_angles_3body(p4d, p4p, p4pi) # List of intermediate resonances corresponds to arXiv link above. resonances = [ (atfd.breit_wigner_lineshape(m2dp, mass_lcst, width_lcst, md, mp, mpi, mlb, dr, db, OrbitalMomentum(5, 1), 2), 5, 1, couplings[0][0], couplings[0][1] ), (atfd.breit_wigner_lineshape(m2dp, mass_lcx, width_lcx, md, mp, mpi, mlb, dr, db, OrbitalMomentum(3, 1), 1), 3, 1, couplings[1][0], couplings[1][1] ), (atfd.breit_wigner_lineshape(m2dp, mass_lcstst, width_lcstst, md, mp, mpi, mlb, dr, db, OrbitalMomentum(3, -1), 1), 3, -1, couplings[2][0], couplings[2][1] ), (atfd.exponential_nonresonant_lineshape(m2dp, mass0, alpha12p, md, mp, mpi, mlb, OrbitalMomentum(1, 1), 0), 1, 1, couplings[3][0], couplings[3][1] ), (atfd.exponential_nonresonant_lineshape(m2dp, mass0, alpha12m, md, mp, mpi, mlb, OrbitalMomentum(1, -1), 0), 1, -1, couplings[4][0], couplings[4][1] ), (atfd.exponential_nonresonant_lineshape(m2dp, mass0, alpha32p, md, mp, mpi, mlb, OrbitalMomentum(3, 1), 1), 3, 1, couplings[5][0], couplings[5][1] ), (atfd.exponential_nonresonant_lineshape(m2dp, mass0, alpha32m, md, mp, mpi, mlb, OrbitalMomentum(3, -1), 1), 3, -1, couplings[6][0], couplings[6][1] ), ] density = atfi.const(0.) # Decay density is an incoherent sum over initial and final state polarisations # (assumong no polarisation for Lambda_b^0), and for each polarisation combination # it is a coherent sum over intermediate states (including two polarisations of # the intermediate resonance). for pol_lb in [-1, 1] : for pol_p in [-1, 1] : ampl = atfi.complex(atfi.const(0.), atfi.const(0.)) for r in resonances : lineshape = r[0] spin = r[1] parity = r[2] if pol_p == -1 : sign = CouplingSign(spin, parity) coupling1 = atfi.complex(r[3][0], r[3][1]) * sign coupling2 = atfi.complex(r[4][0], r[4][1]) * sign else : coupling1 = atfi.complex(r[3][0], r[3][1]) coupling2 = atfi.complex(r[4][0], r[4][1]) ampl += coupling1*lineshape*\ atfk.helicity_amplitude_3body(dp_theta_r, dp_phi_r, dp_theta_d, dp_phi_d, 1, spin, pol_lb, 1, 0, pol_p, 0) ampl += coupling2*lineshape*\ atfk.helicity_amplitude_3body(dp_theta_r, dp_phi_r, dp_theta_d, dp_phi_d, 1, spin, pol_lb, -1, 0, pol_p, 0) density += atfi.density(ampl) return density
def square_dalitz_plot_jacobian(self, sample): """ sample: [mAB^2, mBC^2] Return the jacobian determinant (|J|) of tranformation from dmAB^2*dmBC^2 -> |J|*dMpr*dThpr where Mpr, Thpr are defined in (AC) frame. """ mPrime = self.m_prime_ac(sample) thPrime = self.theta_prime_ac(sample) diff_AC = tf.cast( atfi.sqrt(self.maxac) - atfi.sqrt(self.minac), atfi.fptype()) mAC = atfi.const(0.5) * diff_AC * ( Const(1.0) + atfi.cos(atfi.pi() * mPrime)) + tf.cast( atfi.sqrt(self.minac), atfi.fptype()) mACSq = mAC * mAC eAcmsAC = (atfi.const(0.5) * (mACSq - tf.cast(self.mc2, atfi.fptype()) + tf.cast(self.ma2, atfi.fptype())) / mAC) eBcmsAC = (atfi.const(0.5) * (tf.cast(self.md, atfi.fptype())**2.0 - mACSq - tf.cast(self.mb2, atfi.fptype())) / mAC) pAcmsAC = atfi.sqrt(eAcmsAC**2.0 - tf.cast(self.ma2, atfi.fptype())) pBcmsAC = atfi.sqrt(eBcmsAC**2.0 - tf.cast(self.mb2, atfi.fptype())) deriv1 = Pi() * atfi.const(0.5) * diff_AC * atfi.sin( atfi.pi() * mPrime) deriv2 = Pi() * atfi.sin(atfi.pi() * thPrime) return atfi.const(4.0) * pAcmsAC * pBcmsAC * mAC * deriv1 * deriv2
def zemach_tensor(m2ab, m2ac, m2bc, m2d, m2a, m2b, m2c, spin): """Zemach tensor for 3-body D->ABC decay :param m2ab: :param m2ac: :param m2bc: :param m2d: :param m2a: :param m2b: :param m2c: :param spin: """ z = None if spin == 0: z = atfi.complex(atfi.const(1.), atfi.const(0.)) if spin == 1: z = atfi.complex(m2ac - m2bc + (m2d - m2c) * (m2b - m2a) / m2ab, atfi.const(0.)) if spin == 2: z = atfi.complex( (m2bc - m2ac + (m2d - m2c) * (m2a - m2b) / m2ab)**2 - 1. / 3. * (m2ab - 2. * (m2d + m2c) + (m2d - m2c)**2 / m2ab) * (m2ab - 2. * (m2a + m2b) + (m2a - m2b)**2 / m2ab), atfi.const(0.)) return z
def uniform_random(rnd, x1, x2): """ Uniform random numbers from x1 to x2 """ if isinstance(x1, float): x1 = atfi.const(x1) if isinstance(x2, float): x2 = atfi.const(x2) return x1 + rnd * (x2 - x1)
def generate_combinatorial(cuts, rnd): """ Generate random combinations of three tracks """ meankpt = cuts[0] meanpipt = cuts[1] ptcut = cuts[2] p4pi1 = generate_4momenta(rnd[:, 0:3], meanpipt, ptcut, atfi.const(mpi)) p4pi2 = generate_4momenta(rnd[:, 3:6], meanpipt, ptcut, atfi.const(mpi)) p4k = generate_4momenta(rnd[:, 6:9], meankpt, ptcut, atfi.const(mk)) return p4k, p4pi1, p4pi2
def toymc_model(x, switches=4 * [1]): return model( x, switches=switches, mrho=atfi.const(0.770), wrho=atfi.const(0.150), mkst=atfi.const(0.892), wkst=atfi.const(0.050), a1r=atfi.const(1.0), a1i=atfi.const(0.0), a2r=atfi.const(0.5), a2i=atfi.const(0.0), a3r=atfi.const(2.0), a3i=atfi.const(0.0), )
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 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 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 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 spin_rotation_angle(pa, pb, pc, bachelor=2): """Calculate the angle between two spin-quantisation axes for the 3-body D->ABC decay aligned along the particle B and particle A. pa, pb, pc : 4-momenta of the final-state particles bachelor : index of the "bachelor" particle (0=A, 1=B, or 2=C) :param pa: :param pb: :param pc: :param bachelor: (Default value = 2) """ if bachelor == 2: return atfi.const(0.) pboost = lorentz_vector( -spatial_components(pb) / scalar(time_component(pb)), time_component(pb)) if bachelor == 0: pa1 = spatial_components(lorentz_boost(pa, pboost)) pc1 = spatial_components(lorentz_boost(pc, pboost)) return atfi.acos(scalar_product(pa1, pc1) / norm(pa1) / norm(pc1)) if bachelor == 1: pac = pa + pc pac1 = spatial_components(lorentz_boost(pac, pboost)) pa1 = spatial_components(lorentz_boost(pa, pboost)) return atfi.acos(scalar_product(pac1, pa1) / norm(pac1) / norm(pa1)) return None
def _with_form_factor(self, dataset: dict) -> tf.Tensor: inv_mass_squared = dataset[self._dynamics_props.inv_mass_name] inv_mass = atfi.sqrt(inv_mass_squared) mass0 = self._dynamics_props.resonance_mass gamma0 = self._dynamics_props.resonance_width m_a = atfi.sqrt(dataset[self._dynamics_props.inv_mass_name_prod1]) m_b = atfi.sqrt(dataset[self._dynamics_props.inv_mass_name_prod2]) meson_radius = self._dynamics_props.meson_radius l_orbit = self._dynamics_props.orbit_angular_momentum q_squared = two_body_momentum_squared(inv_mass, m_a, m_b) q0_squared = two_body_momentum_squared(mass0, m_a, m_b) ff2 = blatt_weisskopf_ff_squared(q_squared, meson_radius, l_orbit) ff02 = blatt_weisskopf_ff_squared(q0_squared, meson_radius, l_orbit) width = gamma0 * (mass0 / inv_mass) * (ff2 / ff02) # So far its all in float64, # but for the sqrt operation it has to be converted to complex width = atfi.complex(width, tf.constant( 0.0, dtype=tf.float64)) * atfi.sqrt( atfi.complex( (q_squared / q0_squared), tf.constant(0.0, dtype=tf.float64), )) return relativistic_breit_wigner( inv_mass_squared, mass0, width) * atfi.complex( mass0 * gamma0 * atfi.sqrt(ff2), atfi.const(0.0))
def _create_normalized_intensity(builder: IntensityBuilder, recipe: dict, **_: dict) -> Callable: model = builder.create_element(recipe["Intensity"]) dataset, volume = builder.get_normalization_data() # its important to convert the dataset to tf tensors (memory footprint) dataset = {x: tf.constant(y) for x, y in dataset.items()} return _NormalizedIntensity(model, dataset, atfi.const(volume))
def invariant_mass_jacobian(self, sample): """ sample: [mAB^2, mBC^2] Return the jacobian determinant (|J|) of tranformation from dmAB^2*dmBC^2 -> |J|*dmAB*dmBC. |J| = 4*mAB*mBC """ return (atfi.const(4.0) * atfi.sqrt(self.m2ab(sample)) * atfi.sqrt(self.m2bc(sample)))
def generate_exp(rnd, x1, x2, alpha=None): """ Exponential random distribution with constant "alpha", limited to the range x1 to x2 """ if isinstance(x1, float): x1 = atfi.const(x1) if isinstance(x2, float): x2 = atfi.const(x2) if alpha is None or alpha == 0: return uniform_random(rnd, x1, x2) else: if isinstance(alpha, float): alpha = atfi.const(alpha) xi1 = atfi.exp(-x1 / alpha) xi2 = atfi.exp(-x2 / alpha) ximin = atfi.min(xi1, xi2) ximax = atfi.max(xi1, xi2) return atfi.abs(alpha * atfi.log(uniform_random(rnd, ximin, ximax)))
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 model(x, mrho, wrho, mkst, wkst, a1r, a1i, a2r, a2i, a3r, a3i, switches): a1 = atfi.complex(a1r, a1i) a2 = atfi.complex(a2r, a2i) a3 = atfi.complex(a3r, a3i) m2ab = phsp.m2ab(x) m2bc = phsp.m2bc(x) m2ac = phsp.m2ac(x) hel_ab = phsp.cos_helicity_ab(x) hel_bc = phsp.cos_helicity_bc(x) hel_ac = phsp.cos_helicity_ac(x) ampl = atfi.complex(atfi.const(0.0), atfi.const(0.0)) if switches[0]: ampl += ( a1 * atfd.breit_wigner_lineshape( m2ab, mkst, wkst, mpi, mk, mpi, md, rd, rr, 1, 1 ) * atfd.helicity_amplitude(hel_ab, 1) ) if switches[1]: ampl += ( a2 * atfd.breit_wigner_lineshape( m2bc, mkst, wkst, mpi, mk, mpi, md, rd, rr, 1, 1 ) * atfd.helicity_amplitude(hel_bc, 1) ) if switches[2]: ampl += ( a3 * atfd.breit_wigner_lineshape( m2ac, mrho, wrho, mpi, mpi, mk, md, rd, rr, 1, 1 ) * atfd.helicity_amplitude(hel_ac, 1) ) if switches[3]: ampl += atfi.cast_complex(atfi.ones(m2ab)) * atfi.complex( atfi.const(5.0), atfi.const(0.0) ) return atfd.density(ampl)
def momentum_scale(dm, moms): """ Function to calculate the momentum scale factor for kinematic fit dm : invariant mass shift from the desired value moms : list of 4-momenta of the final state particles """ psum = sum(moms) # sum of 4-momenta pvecsum = atfk.spatial_components(psum) esum = atfk.time_component(psum) dedd = atfi.const(0.) pdpdd = atfi.const(0.) for mom in moms: pm = atfk.p(mom) # Absolute momentum em = atfk.time_component(mom) # Energy pvec = atfk.spatial_components(mom) # 3-momentum s = momentum_resolution(pm) dedd += s * pm**2 / em pdpdd += atfk.scalar_product(pvecsum, pvec) * s return -dm / (2. * esum * dedd - 2. * pdpdd)
def wigner_capital_d(phi, theta, psi, j, m1, m2): """Calculate Wigner capital-D function. phi, theta, psi : Rotation angles j : spin (in units of 1/2, e.g. 1 for spin=1/2) m1 and m2 : spin projections (in units of 1/2, e.g. 1 for projection 1/2) :param phi: :param theta: :param psi: :param j2: :param m2_1: :param m2_2: """ i = atfi.complex(atfi.const(0), atfi.const(1)) return Exp(-i*atfi.cast_complex(m1/2.*phi)) * \ atfi.cast_complex(wigner_small_d(theta, j, m1, m2)) * \ Exp(-i * atfi.cast_complex(m2 / 2. * psi))
def _model(a1r, a1i, a2r, a2i, a3r, a3i, switches=4 * [1]): a1 = atfi.complex(a1r, a1i) a2 = atfi.complex(a2r, a2i) a3 = atfi.complex(a3r, a3i) ampl = atfi.cast_complex(atfi.ones(m2ab)) * atfi.complex( atfi.const(0.0), atfi.const(0.0)) if switches[0]: ampl += a1 * bw1 * hel_ab if switches[1]: ampl += a2 * bw2 * hel_bc if switches[2]: ampl += a3 * bw3 * hel_ac if switches[3]: ampl += atfi.cast_complex(atfi.ones(m2ab)) * atfi.complex( atfi.const(5.0), atfi.const(0.0)) return atfd.density(ampl)
def relativistic_breit_wigner(m2, mres, wres): """ Relativistic Breit-Wigner """ if wres.dtype is atfi.ctype(): return tf.math.reciprocal( atfi.cast_complex(mres * mres - m2) - atfi.complex(atfi.const(0.), mres) * wres) if wres.dtype is atfi.fptype(): return tf.math.reciprocal(atfi.complex(mres * mres - m2, -mres * wres)) return None
def complex_two_body_momentum(md, ma, mb): """Momentum of two-body decay products D->AB in the D rest frame. Output value is a complex number, analytic continuation for the region below threshold. :param md: :param ma: :param mb: """ return atfi.sqrt( atfi.complex( (md**2 - (ma + mb)**2) * (md**2 - (ma - mb)**2) / (4 * md**2), atfi.const(0.)))
def _with_form_factor(self, dataset: dict) -> tf.Tensor: inv_mass = atfi.sqrt(dataset[self._dynamics_props.inv_mass_name]) m_a = atfi.sqrt(dataset[self._dynamics_props.inv_mass_name_prod1]) m_b = atfi.sqrt(dataset[self._dynamics_props.inv_mass_name_prod2]) meson_radius = self._dynamics_props.meson_radius l_orbit = self._dynamics_props.orbit_angular_momentum q_squared = two_body_momentum_squared(inv_mass, m_a, m_b) return atfi.complex( atfi.sqrt( blatt_weisskopf_ff_squared(q_squared, meson_radius, l_orbit)), atfi.const(0.0), )
def _bw_ff_squared(x): if l_orbit == 0: return atfi.const(1.0) if l_orbit == 1: return (2 * x) / (x + 1) if l_orbit == 2: return (13 * x * x) / ((x - 3) * (x - 3) + 9 * x) if l_orbit == 3: return (277 * x * x * x) / (x * (x - 15) * (x - 15) + 9 * (2 * x - 5) * (2 * x - 5)) if l_orbit == 4: return (12746 * x * x * x * x) / ((x * x - 45 * x + 105) * (x * x - 45 * x + 105) + 25 * x * (2 * x - 21) * (2 * x - 21))
def breit_wigner_decay_lineshape(m2, m0, gamma0, ma, mb, meson_radius, l_orbit): """ Breit-Wigner amplitude with Blatt-Weisskopf form factor for the decay products, mass-dependent width and orbital barriers Note: This function does not include the production form factor. """ inv_mass = atfi.sqrt(m2) q_squared = atfk.two_body_momentum_squared(inv_mass, ma, mb) q0_squared = atfk.two_body_momentum_squared(m0, ma, mb) ff2 = blatt_weisskopf_ff_squared(q_squared, meson_radius, l_orbit) ff02 = blatt_weisskopf_ff_squared(q0_squared, meson_radius, l_orbit) width = gamma0 * (m0 / inv_mass) * (ff2 / ff02) # So far its all in float64, # but for the sqrt operation it has to be converted to complex width = atfi.complex(width, atfi.const(0.0)) * atfi.sqrt( atfi.complex( (q_squared / q0_squared), atfi.const(0.0), )) return relativistic_breit_wigner(m2, m0, width) * atfi.complex( m0 * gamma0 * atfi.sqrt(ff2), atfi.const(0.0))
def hankel1(x): if l == 0: return atfi.const(1.0) if l == 1: return 1 + x * x if l == 2: x2 = x * x return 9 + x2 * (3.0 + x2) if l == 3: x2 = x * x return 225 + x2 * (45 + x2 * (6 + x2)) if l == 4: x2 = x * x return 11025.0 + x2 * (1575.0 + x2 * (135.0 + x2 * (10.0 + x2)))
def generate_4momenta(rnd, meanpt, ptcut, m): """ Generate random 4-momenta according to specified mean Pt, minimum Pt, and mass of the particle, flat in eta and phi """ pt = generate_pt(rnd[:, 0], meanpt, ptcut, atfi.const(200.)) # Pt in GeV eta = generate_eta(rnd[:, 1]) # Eta phi = generate_phi(rnd[:, 2]) # Phi theta = 2. * atfi.atan(atfi.exp(-eta)) p = pt / atfi.sin(theta) # Full momentum e = atfi.sqrt(p**2 + m**2) # Energy px = p * atfi.sin(theta) * atfi.sin(phi) py = p * atfi.sin(theta) * atfi.cos(phi) pz = p * atfi.cos(theta) return atfk.lorentz_vector(atfk.vector(px, py, pz), e)
def toymc_model(x, switches=4 * [1]): return model(x)( switches=switches, a1r=atfi.const(1.0), a1i=atfi.const(0.0), a2r=atfi.const(0.5), a2i=atfi.const(0.0), a3r=atfi.const(2.0), a3i=atfi.const(0.0), )