#include "AMISIC++/Tools/Hadronic_XSec_Calculator.H" #include "MODEL/Main/Model_Base.H" #include "MODEL/Main/Running_AlphaQED.H" #include "ATOOLS/Org/Run_Parameter.H" #include "ATOOLS/Org/Message.H" using namespace AMISIC; using namespace ATOOLS; using namespace std; // will have to make sure that pions are initialised below. // // All cross sections here are returned in GeV^{-2}, with s in GeV^2 // // sigma(s) = X_pomeron s^{0.0808} + X_reggeon s^{-0.4525} // // The X_{pomeron/reggeon} (m_xsecpom and m_xsecregge) are given in units of mb, // to make comparison with literature simpler. // We use units of mb^{1/2} for the (constant) triple pomeron vertex. Hadronic_XSec_Calculator:: Hadronic_XSec_Calculator(MODEL::Model_Base * model, const Flavour & fl1,const Flavour & fl2) : m_mass_proton(Flavour(kf_p_plus).Mass()),m_mass_proton2(sqr(m_mass_proton)), m_mass_pi(Flavour(kf_pi).Mass()), m_mres(2.), m_cres(2.), m_s1(sqr(20.)), m_Ypp(-1.), m_c0(2.24), m_c1(2.1), m_testmode(0) { m_flavs[0] = fl1; m_flavs[1] = fl2; for (size_t i=0;i<2;i++) { m_masses[i] = m_flavs[i].HadMass(); m_masses2[i] = sqr(m_masses[i]); } m_alphaQED = (dynamic_cast (model->GetScalarFunction("alpha_QED")))->AqedThomson(); m_eps_pomeron = (*mipars)("PomeronIntercept"); m_alphaP_pomeron = (*mipars)("PomeronSlope"); m_triple_pomeron = (*mipars)("TriplePomeronCoupling"); m_eta_reggeon = (*mipars)("ReggeonIntercept"); m_xsnd_norm = (*mipars)("SigmaND_Norm"); ////////////////////////////////////////////////////////////////////////////////////////// // Prefactors, converted to mb, 1/{mb^1/2 GeV^2}, 1/mb for elastic, SD, and DD // elastic: 1. / (16 pi) // single diffractive: g_3P * s_1^{3 eps_P/2}/ (16 pi) // double diffractive: (g_3P)^2 * s_1^{2 eps_P/2}/ (16 pi) // for single & double diffractive add a factor to compensate the scaling of the // pomeron-hadron couplings beta0 with s, from a safe E_cm = 20 GeV down to zero. ////////////////////////////////////////////////////////////////////////////////////////// for (size_t i=0;i<4;i++) m_beta0[i] = sqrt(s_X[i][i]); m_prefElastic = 1.e9/(rpa->Picobarn()*16.*M_PI); m_prefSD = m_triple_pomeron * pow(m_s1,3.*m_eps_pomeron/2.)/(16.*M_PI) / (rpa->Picobarn()/1e9); m_prefDD = sqr(m_triple_pomeron) * pow(m_s1,m_eps_pomeron)/(16.*M_PI) / (rpa->Picobarn()/1e9); FixType(); FixTables(); if (m_testmode>0) TestXSecs(); } void Hadronic_XSec_Calculator::FixType() { m_type = xsec_type::none; if (m_flavs[0].IsPhoton() && m_flavs[1].IsPhoton()) m_type = xsec_type::photon_photon; else if (m_flavs[0].IsPhoton() && m_flavs[1].IsNucleon()) m_type = xsec_type::photon_nucleon; else if (m_flavs[0].IsNucleon() && m_flavs[1].IsPhoton()) m_type = xsec_type::nucleon_photon; else if (m_flavs[0].IsNucleon() && m_flavs[1].IsNucleon()) { m_type = xsec_type::nucleon_nucleon; if (m_flavs[0].IsAnti() != m_flavs[1].IsAnti()) m_Ypp = 98.39; } if (m_type==xsec_type::none) THROW(fatal_error,"Unknown type of hadronic cross section."); } void Hadronic_XSec_Calculator::TestXSecs() { list Es = { 23.5, 62.5, 546., 1800., 16000., 40000. }; for (size_t i=0;i<2;i++) { switch (m_testmode) { case 3: m_flavs[i] = Flavour(kf_photon); m_type = xsec_type::nucleon_photon; break; case 2: m_flavs[i] = (i==0) ? Flavour(kf_p_plus) : Flavour(kf_photon); m_type = xsec_type::nucleon_photon; break; case 1: m_flavs[i] = Flavour(kf_p_plus); m_type = xsec_type::nucleon_nucleon; break; default: return; } m_masses[i] = m_flavs[i].HadMass(); m_masses2[i] = sqr(m_masses[i]); } for (auto E : Es) { (*this)(sqr(E)); Output(); } THROW(normal_exit,"testing complete"); } void Hadronic_XSec_Calculator::operator()(double s) { m_s = s; m_xstot = m_xsel = m_xssdA = m_xssdB = m_xsdd = 0.; //////////////////////////////////////////////////////////////////////////////////////////// // All cross sections in mb so far. //////////////////////////////////////////////////////////////////////////////////////////// switch (m_type) { case xsec_type::nucleon_nucleon: CalculateHHXSecs(); break; case xsec_type::photon_nucleon: CalculateHGammaXSecs(0); break; case xsec_type::nucleon_photon: CalculateHGammaXSecs(1); break; case xsec_type::photon_photon: CalculatePhotonPhotonXSecs(); break; default: THROW(fatal_error, "Not yet implemented for unknown type"); } m_xsnd = m_xstot - m_xsel - m_xssdA - m_xssdB - m_xsdd; // convert non-diffractive cross section from millibarn to 1/GeV^2 m_xsnd *= 1.e9/rpa->Picobarn(); } void Hadronic_XSec_Calculator::CalculateHHXSecs() { size_t hadtags[2]; hadtags[0] = hadtags[1] = 0; double masses[2]; masses[0] = m_masses[0];masses[1] = m_masses[1]; m_xstot = TotalXSec(hadtags); m_xsel = IntElXSec(hadtags,m_xstot); m_xssdA = IntSDXSec(hadtags,0,masses); m_xssdB = IntSDXSec(hadtags,1,masses); m_xsdd = IntDDXSec(hadtags,masses); } void Hadronic_XSec_Calculator::CalculateHGammaXSecs(const size_t photon) { size_t hadtags[2]; hadtags[1-photon] = 0; double xstot, prefV, masses[2]; masses[1-photon] = m_masses[1-photon]; // Iterate over VMD hadrons and add cross sections for (std::map::const_iterator flit=m_fVs.begin(); flit!=m_fVs.end();flit++) { hadtags[photon] = m_indexmap[flit->first]; masses[photon] = flit->first.Mass(); prefV = m_alphaQED/m_fVs[flit->first]; m_xstot += prefV * (xstot = TotalXSec(hadtags)); m_xsel += prefV * IntElXSec(hadtags,xstot); m_xssdA += prefV * IntSDXSec(hadtags,0,masses); m_xssdB += prefV * IntSDXSec(hadtags,1,masses); m_xsdd += prefV * IntDDXSec(hadtags,masses); } } void Hadronic_XSec_Calculator::CalculatePhotonPhotonXSecs() { size_t hadtags[2]; double xstot, prefVV, masses[2]; //////////////////////////////////////////////////////////////////////////////////////////// // Iterate over VMD hadrons and add cross sections //////////////////////////////////////////////////////////////////////////////////////////// for (std::map::const_iterator flit0=m_fVs.begin(); flit0!=m_fVs.end();flit0++) { hadtags[0] = m_indexmap[flit0->first]; masses[0] = flit0->first.Mass(); for (std::map::const_iterator flit1=m_fVs.begin(); flit1!=m_fVs.end();flit1++) { hadtags[1] = m_indexmap[flit1->first]; masses[1] = flit0->first.Mass(); prefVV = sqr(m_alphaQED)/(m_fVs[flit0->first] * m_fVs[flit1->first]); m_xstot += prefVV * (xstot = TotalXSec(hadtags)); m_xsel += prefVV * IntElXSec(hadtags,xstot); m_xssdA += prefVV * IntSDXSec(hadtags,0,masses); m_xssdB += prefVV * IntSDXSec(hadtags,1,masses); m_xsdd += prefVV * IntDDXSec(hadtags,masses); } } } double Hadronic_XSec_Calculator::TotalXSec(const size_t hadtags[2]) const { //////////////////////////////////////////////////////////////////////////////////////////// // Eq.(4) in Schuler and Sjostrand, PRD 49 (Donnachie-Landshof fit) //////////////////////////////////////////////////////////////////////////////////////////// return ( s_X[hadtags[0]][hadtags[1]] * pow(m_s,m_eps_pomeron) + (m_Ypp>0 ? m_Ypp : s_Y[hadtags[0]][hadtags[1]]) * pow(m_s,m_eta_reggeon) ); } double Hadronic_XSec_Calculator::IntElXSec(const size_t hadtags[2],const double & xstot) const { //////////////////////////////////////////////////////////////////////////////////////////// // Eq.(7) in Schuler and Sjostrand, PRD 49 (Donnachie-Landshof fit) with elastic slope taken // from Eq.(11) ibidem. //////////////////////////////////////////////////////////////////////////////////////////// double b_elastic = 2.*(s_slopes[hadtags[0]] + s_slopes[hadtags[1]] + m_c0*pow(m_s/4.,m_eps_pomeron)-m_c1); return m_prefElastic * sqr(xstot) / b_elastic; } double Hadronic_XSec_Calculator::IntSDXSec(const size_t hadtags[2],const size_t & diff, const double masses[2]) const { //////////////////////////////////////////////////////////////////////////////////////////// // Eq.(24) in Schuler and Sjostrand, PRD 49 (Donnachie-Landshof fit) and // Eq. (19) in Schuler and Sjostrand Z fuer Physik C 73, with parameters // for pp taken from PRD 49 and for VMD states from Table 1 in ZfP C 73. // Note: To arrive at the correct prefactor, need to rescale the beta according to Eq.(27). //////////////////////////////////////////////////////////////////////////////////////////// size_t nodiff = 1-diff; double mmin2 = sqr(masses[diff]+2.*m_mass_pi), mmin = sqrt(mmin2); double mres = masses[nodiff]-m_mass_proton+m_mres, mres2 = sqr(mres); double mmax2 = s_c[hadtags[0]][hadtags[1]][0+4*diff]*m_s + s_c[hadtags[0]][hadtags[1]][1+4*diff]; if (m_s<=mmin2 || m_s<=mmin*mres) return 0.; double bA = s_slopes[hadtags[nodiff]]; double B_AX = s_c[hadtags[0]][hadtags[1]][2+4*diff] + s_c[hadtags[0]][hadtags[1]][3+4*diff]/m_s; double J_AX = Max(0., ( 1./(2.*m_alphaP_pomeron) * log((bA+m_alphaP_pomeron*log(m_s/mmin2))/ (bA+m_alphaP_pomeron*log(m_s/mmax2))) + m_cres/(2.*(bA+m_alphaP_pomeron*log(m_s/(mmin*mres)))+B_AX) * log(1.+mres2/mmin2) ) ); return m_prefSD * m_beta0[hadtags[nodiff]] * s_X[hadtags[0]][hadtags[1]] * J_AX; } double Hadronic_XSec_Calculator::IntDDXSec(const size_t hadtags[2], const double masses[2]) const { //////////////////////////////////////////////////////////////////////////////////////////// // Eq.(24) in Schuler and Sjostrand, PRD 49 (Donnachie-Landshof fit), with parameters // for pp taken from PRD 49 and for VMD states from Table 1 in Schuler and Sjostrand // Z fuer Physik C 73 //////////////////////////////////////////////////////////////////////////////////////////// double logs = log(m_s), log2s = sqr(logs); double s0 = 1./m_alphaP_pomeron, ss0 = m_s*s0; double m1min2 = sqr(masses[0]+2.*m_mass_pi), m1min = sqrt(m1min2); double m2min2 = sqr(masses[1]+2.*m_mass_pi), m2min = sqrt(m2min2); double m1res = masses[0]-m_mass_proton+m_mres, m1res2 = sqr(m1res); double m2res = masses[1]-m_mass_proton+m_mres, m2res2 = sqr(m2res); double mmax2 = ( s_d[hadtags[0]][hadtags[1]][3] + s_d[hadtags[0]][hadtags[1]][4]/logs + s_d[hadtags[0]][hadtags[1]][5]/log2s ) * m_s; if (m_s <= sqr(m1min+m2min) || m1min2 > mmax2 || m2min2 > mmax2|| ss0 <= m1min2*m2res*m2min || ss0 <= m2min2*m1res*m1min || ss0 <= mmax2*m1res*m1min || ss0 <= mmax2*m2res*m2min || ss0 <= m1res*m1min*m2res*m2min || m_s <= (m1min2*m2min2)/m_mass_proton2) return 0.; double arg11 = Max(1.001, ss0/(m1min2*m2res*m2min)), arg12 = Max(1.001, ss0/(mmax2*m2res*m2min)); double arg21 = Max(1.001, ss0/(m2min2*m1res*m1min)), arg22 = Max(1.001, ss0/(mmax2*m1res*m1min)); double Delta0 = ( s_d[hadtags[0]][hadtags[1]][0] + s_d[hadtags[0]][hadtags[1]][1]/logs + s_d[hadtags[0]][hadtags[1]][2]/log2s ); if (Delta0 <= 0.) return 0.; double Bxx = ( s_d[hadtags[0]][hadtags[1]][6] + s_d[hadtags[0]][hadtags[1]][7]/sqrt(m_s) + s_d[hadtags[0]][hadtags[1]][8]/m_s ); double Deltay = log((m_s * m_mass_proton2)/(m1min2 * m2min2)); double J_XX = Max(0., ( 1./(2.*m_alphaP_pomeron) * ( Deltay*( log(Deltay/Delta0) - 1.) + Delta0 ) + m_cres/(2.*m_alphaP_pomeron) * (log(1.+m2res2/m2min2) * log(log(arg11)/log(arg12)) + log(1.+m1res2/m1min2) * log(log(arg21)/log(arg22))) + sqr(m_cres)/(2.*m_alphaP_pomeron*log(ss0/(m1res*m1min*m2res*m2min))+Bxx) * log(1.+m1res2/m1min2) * log(1.+m2res2/m2min2) ) ); return m_prefDD * s_X[hadtags[0]][hadtags[1]] * J_XX; } void Hadronic_XSec_Calculator::Output() const { msg_Out()<