Exemple #1
0
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.))
Exemple #2
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
Exemple #3
0
    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
Exemple #5
0
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
Exemple #6
0
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)
Exemple #7
0
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
Exemple #8
0
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),
    )
Exemple #9
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
Exemple #10
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.))
Exemple #11
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.))
Exemple #12
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)
Exemple #13
0
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
Exemple #14
0
 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))
Exemple #15
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))
Exemple #16
0
 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)))
Exemple #17
0
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)))
Exemple #18
0
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
Exemple #19
0
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)
Exemple #20
0
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)
Exemple #21
0
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)
Exemple #23
0
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
Exemple #24
0
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.)))
Exemple #25
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),
        )
Exemple #26
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))
Exemple #27
0
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))
Exemple #28
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)))
Exemple #29
0
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),
    )