Skip to content
Snippets Groups Projects
observables.cpp 8.02 KiB
Newer Older
  • Learn to ignore specific revisions
  • // Abstract class for an amplitude. Used so we can easily build observables
    // as the incoherent sum of amplitudes in s, t, and u channels.
    //
    // Author:       Daniel Winney (2020)
    // Affiliation:  Joint Physics Analysis Center (JPAC)
    // Email:        dwinney@iu.edu
    // ---------------------------------------------------------------------------
    
    #include "amplitudes/amplitude.hpp"
    
    
    // ---------------------------------------------------------------------------
    
    
    Daniel Winney's avatar
    Daniel Winney committed
    void jpacPhoto::amplitude::check_cache(double s, double t)
    
        // check if saved version its the one we want
    
    Daniel Winney's avatar
    Daniel Winney committed
        if (  (abs(_cached_s - s) < 0.00001) && 
              (abs(_cached_t - t) < 0.00001) &&
              (abs(_cached_mX2 - _kinematics->_mX2) < 0.00001) // important to make sure the value of mX2 hasnt chanced since last time
    
            return; // do nothing
        }
        else // save a new set
        {
    
    Daniel Winney's avatar
    Daniel Winney committed
            _cached_helicity_amplitude.clear();
            for (int i = 0; i < _kinematics->_nAmps; i++)
    
    Daniel Winney's avatar
    Daniel Winney committed
                _cached_helicity_amplitude.push_back(helicity_amplitude(_kinematics->_helicities[i], s, t));
    
            // update cache info
    
    Daniel Winney's avatar
    Daniel Winney committed
            _cached_mX2 = _kinematics->_mX2; _cached_s = s; _cached_t = t;
    
    dwinney's avatar
    dwinney committed
    // ---------------------------------------------------------------------------
    
    Daniel Winney's avatar
    Daniel Winney committed
    // Square of the spin averaged amplitude squared
    
    double jpacPhoto::amplitude::probability_distribution(double s, double t)
    
        // Check we have the right amplitudes cached
        check_cache(s, t);
    
        double sum = 0.;
    
    Daniel Winney's avatar
    Daniel Winney committed
        for (int i = 0; i < _kinematics->_nAmps; i++)
    
    Daniel Winney's avatar
    Daniel Winney committed
            std::complex<double> amp_i = _cached_helicity_amplitude[i];
    
            sum += std::real(amp_i * conj(amp_i));
        }
    
        return sum;
    
    };
    
    // ---------------------------------------------------------------------------
    // Differential cross section dsigma / dt
    // in NANOBARN
    
    Daniel Winney's avatar
    Daniel Winney committed
    double jpacPhoto::amplitude::differential_xsection(double s, double t)
    
        double sum = probability_distribution(s, t);
    
        double norm = 1.;
    
    Daniel Winney's avatar
    Daniel Winney committed
        norm /= 64. * PI * s;
        norm /= real(pow(_kinematics->_initial_state->momentum(s), 2.));
    
        norm /= (2.56819E-6); // Convert from GeV^-2 -> nb
        norm /= 4.; // Average over initial state helicites
    
        return norm * sum;
    
    dwinney's avatar
    dwinney committed
    };
    
    // ---------------------------------------------------------------------------
    // Inegrated total cross-section
    
    dwinney's avatar
    dwinney committed
    // IN NANOBARN
    
    double jpacPhoto::amplitude::integrated_xsection(double s)
    
        auto F = [&](double t)
        {
            return differential_xsection(s, t);
        };
    
        ROOT::Math::GSLIntegrator ig(ROOT::Math::IntegrationOneDim::kADAPTIVE, ROOT::Math::Integration::kGAUSS61);
        ROOT::Math::Functor1D wF(F);
        ig.SetFunction(wF);
    
    Daniel Winney's avatar
    Daniel Winney committed
        double t_min = _kinematics->t_man(s, 0.);
        double t_max = _kinematics->t_man(s, PI);
    
        return ig.Integral(t_max, t_min);
    
    dwinney's avatar
    dwinney committed
    // ---------------------------------------------------------------------------
    // Polarizatiopn asymmetry between beam and recoil proton
    
    Daniel Winney's avatar
    Daniel Winney committed
    double jpacPhoto::amplitude::K_LL(double s, double t)
    
    dwinney's avatar
    dwinney committed
    {
    
        // Check we have the right amplitudes cached
        check_cache(s, t);
    
        double sigmapp = 0., sigmapm = 0.;
        for (int i = 0; i < 6; i++)
        {
            std::complex<double> squarepp, squarepm;
    
            // Amplitudes with lam_gam = + and lam_recoil = +
    
    Daniel Winney's avatar
    Daniel Winney committed
            squarepp  = _cached_helicity_amplitude[2*i+1];
    
            squarepp *= conj(squarepp);
    
    Daniel Winney's avatar
    Daniel Winney committed
            sigmapp  += real(squarepp);
    
    
            // Amplitudes with lam_gam = + and lam_recoil = -
    
    Daniel Winney's avatar
    Daniel Winney committed
            squarepm  = _cached_helicity_amplitude[2*i];
    
            squarepm *= conj(squarepm);
    
    Daniel Winney's avatar
    Daniel Winney committed
            sigmapm  += real(squarepm);
    
        }
    
        return (sigmapp - sigmapm) / (sigmapp + sigmapm);
    
    dwinney's avatar
    dwinney committed
    }
    
    // ---------------------------------------------------------------------------
    
    // Polarization asymmetry between beam and target proton
    
    Daniel Winney's avatar
    Daniel Winney committed
    double jpacPhoto::amplitude::A_LL(double s, double t)
    
    dwinney's avatar
    dwinney committed
    {
    
        // Check we have the right amplitudes cached
        check_cache(s, t);
    
        double sigmapp = 0., sigmapm = 0.;
        for (int i = 0; i < 6; i++)
        {
            std::complex<double> squarepp, squarepm;
    
            // Amplitudes with lam_gam = + and lam_targ = +
    
    Daniel Winney's avatar
    Daniel Winney committed
            squarepp  = _cached_helicity_amplitude[i+6];
    
            squarepp *= conj(squarepp);
    
    Daniel Winney's avatar
    Daniel Winney committed
            sigmapp  += real(squarepp);
    
    
            // Amplitudes with lam_gam = + and lam_targ = -
    
    Daniel Winney's avatar
    Daniel Winney committed
            squarepm  = _cached_helicity_amplitude[i];
    
            squarepm *= conj(squarepm);
    
    Daniel Winney's avatar
    Daniel Winney committed
            sigmapm  += real(squarepm);
    
        }
    
        return (sigmapp - sigmapm) / (sigmapp + sigmapm);
    
    dwinney's avatar
    dwinney committed
    }
    
    dwinney's avatar
    dwinney committed
    
    // ---------------------------------------------------------------------------
    
    // Photon spin-density matrix elements
    
    Daniel Winney's avatar
    Daniel Winney committed
    std::complex<double> jpacPhoto::amplitude::SDME(int alpha, int lam, int lamp, double s, double t)
    
    dwinney's avatar
    dwinney committed
    {
    
        if (alpha < 0 || alpha > 2 || std::abs(lam) > 1 || std::abs(lamp) > 1)
        {
            std::cout << "\nError! Invalid parameter passed to SDME. Returning 0!\n";
            return 0.;
        };
    
        // Phase and whether to conjugate at the end
        bool CONJ = false;
        double phase = 1.;
    
        // if first index smaller, switch them
        if (std::abs(lam) < std::abs(lamp))
    
    dwinney's avatar
    dwinney committed
        {
    
            int temp = lam;
            lam = lamp;
            lamp = temp;
    
            CONJ = true;
    
    dwinney's avatar
    dwinney committed
        }
    
    
        // if first index is negative, flip to positive
        if (lam < 0)
        {
            lam *= -1;
            lamp *= -1;
    
            phase *= pow(-1., double(lam - lamp));
        }
    
        // Normalization (sum over all amplitudes squared)
        double norm = probability_distribution(s, t);
    
        // These are the indexes of the amplitudes in reaction_kinematics that have
        // lambda_V = +1
        std::vector<int> pos_iters = {0, 1, 6, 7, 12, 13, 18, 19};
        std::vector<int> neg_iters = {12, 13, 18, 19, 0, 1, 6, 7};
    
    dwinney's avatar
    dwinney committed
    
    
        // j and k filter the right helicity combinations for 00, 1-1, 10, 11
        int j, k;
        (lam == 0) ? (k = 2) : (k = 0);
    
        switch (lamp)
        {
            case -1: { j = 4; break; }
            case 0:  { j = 2; break; }
            case 1:  { j = 0; break; }
            default:
            {
                std::cout << "\nSDME: Invalid parameter. J/Psi helicity projection lamp = 0 or 1! Returning zero.";
                return 0.;;
            }
        }
    
        // Sum over the appropriate amplitude combinations
        std::complex<double> result = 0.;
        for (int i = 0; i < 8; i++)
        {
            int index;
            (alpha == 0) ? (index = pos_iters[i]) : (index = neg_iters[i]);
    
            std::complex<double> amp_i, amp_j;
    
    Daniel Winney's avatar
    Daniel Winney committed
            amp_i = _cached_helicity_amplitude[index + k];
            amp_j = _cached_helicity_amplitude[pos_iters[i] + j];
    
    Daniel Winney's avatar
    Daniel Winney committed
            (alpha == 2) ? (amp_j *= XI * double(_kinematics->_helicities[pos_iters[i] + j][0])) : (amp_j *= XR);
    
    
            result += real(amp_i * conj(amp_j));
        }
    
        if (CONJ == true)
        {
            result = conj(result);
        }
    
    dwinney's avatar
    dwinney committed
    
    
        result /= norm;
        result *= phase;
    
    dwinney's avatar
    dwinney committed
    
    
        return result;
    
    dwinney's avatar
    dwinney committed
    };
    
    
    // ---------------------------------------------------------------------------
    
    Daniel Winney's avatar
    Daniel Winney committed
    // Integrated beam asymmetry sigma_4pi
    double jpacPhoto::amplitude::beam_asymmetry_4pi(double s, double t)
    
        double rho100 = real(SDME(1, 0, 0, s, t));
        double rho111 = real(SDME(1, 1, 1, s, t));
        double rho000 = real(SDME(0, 0, 0, s, t));
        double rho011 = real(SDME(0, 1, 1, s, t));
    
        return -(rho100 + 2. * rho111) / (rho000 + 2. * rho011);
    
    dglazier's avatar
    dglazier committed
    // ---------------------------------------------------------------------------
    
    Daniel Winney's avatar
    Daniel Winney committed
    // Beam asymmetry along y axis sigma_y 
    double jpacPhoto::amplitude::beam_asymmetry_y(double s, double t)
    
    dglazier's avatar
    dglazier committed
    {
    
        double rho111  = real(SDME(1, 1,  1, s, t));
        double rho11m1 = real(SDME(1, 1, -1, s, t));
        double rho011  = real(SDME(0, 1,  1, s, t));
        double rho01m1 = real(SDME(0, 1, -1, s, t));
    
    dglazier's avatar
    dglazier committed
    
    
        return (rho111 + rho11m1) / (rho011 + rho01m1);
    
    dglazier's avatar
    dglazier committed
    };
    
    
    // ---------------------------------------------------------------------------
    // Parity asymmetry P_sigma
    
    Daniel Winney's avatar
    Daniel Winney committed
    double jpacPhoto::amplitude::parity_asymmetry(double s, double t)
    
        double rho100  = real(SDME(1, 0,  0, s, t));
        double rho11m1 = real(SDME(1, 1, -1, s, t));
    
        return 2. * rho11m1 - rho100;