diff --git a/CepGen/Physics/FormFactors.cpp b/CepGen/Physics/FormFactors.cpp index 17c6d4d..e27b879 100644 --- a/CepGen/Physics/FormFactors.cpp +++ b/CepGen/Physics/FormFactors.cpp @@ -1,71 +1,74 @@ #include "FormFactors.h" namespace CepGen { FormFactors FormFactors::Trivial() { return FormFactors( 1.0, 1.0 ); } FormFactors FormFactors::ProtonElastic( double q2 ) { const double mp = Particle::massFromPDGId( Particle::Proton ), mp2 = mp*mp; const double GE = pow( 1.+q2/0.71, -2. ), GE2 = GE*GE; const double GM = 2.79*GE, GM2 = GM*GM; return FormFactors( ( 4.*mp2*GE2 + q2*GM2 ) / ( 4.*mp2 + q2 ), GM2 ); } FormFactors FormFactors::ProtonInelastic( const StructureFunctionsType& sf, double q2, double mi2, double mf2 ) { switch ( sf ) { case StructureFunctionsType::ElasticProton: InWarning( "Elastic proton form factors requested! Check your process definition!" ); return FormFactors::ProtonElastic( q2 ); case StructureFunctionsType::SuriYennie: return FormFactors::SuriYennie( q2, mi2, mf2 ); case StructureFunctionsType::SzczurekUleshchenko: return FormFactors::SzczurekUleshchenko( q2, mi2, mf2 ); case StructureFunctionsType::Fiore: case StructureFunctionsType::FioreSea: case StructureFunctionsType::FioreVal: return FormFactors::FioreBrasse( q2, mi2, mf2 ); default: throw Exception( __PRETTY_FUNCTION__, "Invalid structure functions required!", FatalError ); } } FormFactors FormFactors::SuriYennie( double q2, double mi2, double mf2 ) { const double x = q2 / ( q2 + mf2 - mi2 ); - const StructureFunctions sy = SF::SuriYennie( q2, x ); + SF::SuriYennie suriyennie; + const StructureFunctions sy = suriyennie( q2, x ); //std::cout << "---> " << sy.FM << "\t" << sy.F2*x/q2 << "\t" << sy.F2*x*sqrt(mi2)/q2 << std::endl; return FormFactors( sy.F2 * x * sqrt( mi2 ) / q2, sy.FM ); //FIXME } FormFactors FormFactors::FioreBrasse( double q2, double mi2, double mf2 ) { const double x = q2 / ( q2 + mf2 - mi2 ); - StructureFunctions sf = SF::FioreBrasse( q2, x ); + SF::FioreBrasse fb; + StructureFunctions sf = fb( q2, x ); return FormFactors( sf.F2 * x / q2, -2.*sf.F1 / q2 ); } FormFactors FormFactors::SzczurekUleshchenko( double q2, double mi2, double mf2 ) { const double x = q2 / ( q2 + mf2 - mi2 ); - StructureFunctions sf = SF::SzczurekUleshchenko( q2, x ); + SF::SzczurekUleshchenko su; + StructureFunctions sf = su( q2, x ); return FormFactors( sf.F2 * x / q2, -2.*sf.F1 / q2 ); } std::ostream& operator<<( std::ostream& os, const FormFactors& ff ) { os << Form( "Form factors: electric: Fe = %.3e ; magnetic: Fm = %.3e", ff.FE, ff.FM ).c_str(); return os; } } diff --git a/CepGen/Processes/GenericKTProcess.cpp b/CepGen/Processes/GenericKTProcess.cpp index c504d47..dabab26 100644 --- a/CepGen/Processes/GenericKTProcess.cpp +++ b/CepGen/Processes/GenericKTProcess.cpp @@ -1,274 +1,279 @@ #include "GenericKTProcess.h" namespace CepGen { namespace Process { GenericKTProcess::GenericKTProcess( const std::string& name, const std::string& description, const unsigned int& num_user_dimensions, const std::array<Particle::ParticleCode,2>& partons, const std::vector<Particle::ParticleCode>& central ) : GenericProcess( name, description+" (kT-factorisation approach)" ), kNumUserDimensions( num_user_dimensions ), kIntermediateParts( partons ), kProducedParts( central ) {} GenericKTProcess::~GenericKTProcess() {} void GenericKTProcess::addEventContent() { GenericProcess::setEventContent( { // incoming state { Particle::IncomingBeam1, Particle::Proton }, { Particle::IncomingBeam2, Particle::Proton }, { Particle::Parton1, kIntermediateParts[0] }, { Particle::Parton2, kIntermediateParts[1] } }, { // outgoing state { Particle::OutgoingBeam1, { Particle::Proton } }, { Particle::OutgoingBeam2, { Particle::Proton } }, { Particle::CentralSystem, kProducedParts } } ); setExtraContent(); } unsigned int GenericKTProcess::numDimensions( const Kinematics::ProcessMode& process_mode ) const { switch ( process_mode ) { default: case Kinematics::ElasticElastic: return kNumRequiredDimensions+kNumUserDimensions; case Kinematics::ElasticInelastic: case Kinematics::InelasticElastic: return kNumRequiredDimensions+kNumUserDimensions+1; case Kinematics::InelasticInelastic: return kNumRequiredDimensions+kNumUserDimensions+2; } } void GenericKTProcess::addPartonContent() { // Incoming partons qt1_ = exp( log_qmin_+( log_qmax_-log_qmin_ )*x( 0 ) ); qt2_ = exp( log_qmin_+( log_qmax_-log_qmin_ )*x( 1 ) ); phi_qt1_ = 2.*M_PI*x( 2 ); phi_qt2_ = 2.*M_PI*x( 3 ); DebuggingInsideLoop( Form( "photons transverse virtualities (qt):\n\t" " mag = %f / %f (%.2f < log(qt) < %.2f)\n\t" " phi = %f / %f", qt1_, qt2_, log_qmin_, log_qmax_, phi_qt1_, phi_qt2_ ) ); } void GenericKTProcess::setKinematics( const Kinematics& kin ) { cuts_ = kin; log_qmin_ = -10.; // FIXME //log_qmin_ = std::log( std::sqrt( cuts_.q2min ) ); log_qmax_ = log( cuts_.initial_cuts[Cuts::qt].max() ); } double GenericKTProcess::computeWeight() { addPartonContent(); prepareKTKinematics(); computeOutgoingPrimaryParticlesMasses(); const double jac = computeJacobian(), integrand = computeKTFactorisedMatrixElement(), weight = jac*integrand; DebuggingInsideLoop( Form( "Jacobian = %f\n\tIntegrand = %f\n\tdW = %f", jac, integrand, weight ) ); return weight; } void GenericKTProcess::computeOutgoingPrimaryParticlesMasses() { const unsigned int op_index = kNumRequiredDimensions+kNumUserDimensions; const Kinematics::Limits remn_mx_cuts = cuts_.remnant_cuts[Cuts::mass]; switch ( cuts_.mode ) { case Kinematics::ElectronProton: default: { InError( "This kT factorisation process is intended for p-on-p collisions! Aborting!" ); exit( 0 ); } break; case Kinematics::ElasticElastic: { MX_ = event_->getOneByRole( Particle::IncomingBeam1 ).mass(); MY_ = event_->getOneByRole( Particle::IncomingBeam2 ).mass(); } break; case Kinematics::ElasticInelastic: { const double mx_min = remn_mx_cuts.min(), mx_range = remn_mx_cuts.range(); MX_ = event_->getOneByRole( Particle::IncomingBeam1 ).mass(); MY_ = mx_min + mx_range*x( op_index ); } break; case Kinematics::InelasticElastic: { const double mx_min = remn_mx_cuts.min(), mx_range = remn_mx_cuts.range(); MX_ = mx_min + mx_range*x( op_index ); MY_ = event_->getOneByRole( Particle::IncomingBeam2 ).mass(); } break; case Kinematics::InelasticInelastic: { const double mx_min = remn_mx_cuts.min(), mx_range = remn_mx_cuts.range(); MX_ = mx_min + mx_range*x( op_index ); MY_ = mx_min + mx_range*x( op_index+1 ); } break; } DebuggingInsideLoop( Form( "outgoing remnants invariant mass: %f / %f (%.2f < M(X/Y) < %.2f)", MX_, MY_, remn_mx_cuts.min(), remn_mx_cuts.max() ) ); } void GenericKTProcess::computeIncomingFluxes( double x1, double q1t2, double x2, double q2t2 ) { flux1_ = flux2_ = 0.; switch ( cuts_.mode ) { case Kinematics::ElasticElastic: flux1_ = elasticFlux( x1, q1t2 ); flux2_ = elasticFlux( x2, q2t2 ); break; case Kinematics::ElasticInelastic: flux1_ = elasticFlux( x1, q1t2 ); flux2_ = inelasticFlux( x2, q2t2, MY_ ); break; case Kinematics::InelasticElastic: flux1_ = inelasticFlux( x1, q1t2, MX_ ); flux2_ = elasticFlux( x2, q2t2 ); break; case Kinematics::InelasticInelastic: flux1_ = inelasticFlux( x1, q1t2, MX_ ); flux2_ = inelasticFlux( x2, q2t2, MY_ ); break; default: return; } flux1_ = std::max( flux1_, 1.e-20 ); flux2_ = std::max( flux2_, 1.e-20 ); DebuggingInsideLoop( Form( "Form factors: %e / %e", flux1_, flux2_ ) ); } void GenericKTProcess::fillKinematics( bool ) { fillPrimaryParticlesKinematics(); fillCentralParticlesKinematics(); } void GenericKTProcess::fillPrimaryParticlesKinematics() { //================================================================= // outgoing protons //================================================================= Particle& op1 = event_->getOneByRole( Particle::OutgoingBeam1 ), &op2 = event_->getOneByRole( Particle::OutgoingBeam2 ); op1.setMomentum( PX_ ); op2.setMomentum( PY_ ); switch ( cuts_.mode ) { case Kinematics::ElasticElastic: op1.setStatus( Particle::FinalState ); op2.setStatus( Particle::FinalState ); break; case Kinematics::ElasticInelastic: op1.setStatus( Particle::FinalState ); op2.setStatus( Particle::Undecayed ); op2.setMass( MY_ ); break; case Kinematics::InelasticElastic: op1.setStatus( Particle::Undecayed ); op1.setMass( MX_ ); op2.setStatus( Particle::FinalState ); break; case Kinematics::InelasticInelastic: op1.setStatus( Particle::Undecayed ); op1.setMass( MX_ ); op2.setStatus( Particle::Undecayed ); op2.setMass( MY_ ); break; default: { FatalError( "This kT factorisation process is intended for p-on-p collisions! Aborting!" ); } break; } //================================================================= // incoming partons (photons, pomerons, ...) //================================================================= //FIXME ensure the validity of this approach Particle& g1 = event_->getOneByRole( Particle::Parton1 ), &g2 = event_->getOneByRole( Particle::Parton2 ); g1.setMomentum( event_->getOneByRole( Particle::IncomingBeam1 ).momentum()-PX_, true ); g1.setStatus( Particle::Incoming ); g2.setMomentum( event_->getOneByRole( Particle::IncomingBeam2 ).momentum()-PY_, true ); g2.setStatus( Particle::Incoming ); } double GenericKTProcess::minimalJacobian() const { double jac = 1.; jac *= ( log_qmax_-log_qmin_ )*qt1_; // d(q1t) . q1t jac *= ( log_qmax_-log_qmin_ )*qt2_; // d(q2t) . q2t jac *= 2.*M_PI; // d(phi1) jac *= 2.*M_PI; // d(phi2) const double mx_range = cuts_.remnant_cuts.at( Cuts::mass ).range(); switch ( cuts_.mode ) { case Kinematics::ElasticElastic: default: break; case Kinematics::ElasticInelastic: jac *= 2.* mx_range * MY_; break; case Kinematics::InelasticElastic: jac *= 2.* mx_range * MX_; break; case Kinematics::InelasticInelastic: jac *= 2.* mx_range * MX_; jac *= 2.* mx_range * MY_; break; } // d(mx/y**2) return jac; } double GenericKTProcess::elasticFlux( double x, double kt2 ) { const double mp = Particle::massFromPDGId( Particle::Proton ), mp2 = mp*mp; const double Q2_min = x*x*mp2/( 1.-x ), Q2_ela = Q2_min + kt2/( 1.-x ); const FormFactors ela = FormFactors::ProtonElastic( Q2_ela ); const double ela1 = ( 1.-x )*( 1.-Q2_min/Q2_ela ); const double ela2 = ela.FE; //const double ela3 = 1.-( Q2_ela-kt2 )/Q2_ela; const double f_ela = Constants::alphaEM/M_PI/kt2*( ela1*ela2 + 0.5*x*x*ela.FM ); return f_ela * ( 1.-x ) * kt2 / Q2_ela; } double GenericKTProcess::inelasticFlux( double x, double kt2, double mx ) { const double mx2 = mx*mx, mp = Particle::massFromPDGId( Particle::Proton ), mp2 = mp*mp; // F2 structure function const double Q2min = 1. / ( 1.-x )*( x*( mx2-mp2 ) + x*x*mp2 ), Q2 = Q2min + kt2 / ( 1.-x ); float xbj = Q2 / ( Q2 + mx2 - mp2 ); StructureFunctions sf; switch ( cuts_.structure_functions ) { - case StructureFunctionsType::SzczurekUleshchenko: - sf = SF::SzczurekUleshchenko( Q2, xbj ); break; - case StructureFunctionsType::SuriYennie: - sf = SF::SuriYennie( Q2, xbj ); break; - case StructureFunctionsType::Fiore: - sf = SF::FioreBrasse( Q2, xbj ); break; - case StructureFunctionsType::ALLM91: - sf = SF::ALLM( Q2, xbj, SF::ALLMParameterisation::allm91() ); break; - case StructureFunctionsType::ALLM97: - sf = SF::ALLM( Q2, xbj, SF::ALLMParameterisation::allm97() ); break; + case StructureFunctionsType::SzczurekUleshchenko: { + SF::SzczurekUleshchenko su; + sf = su( Q2, xbj ); } break; + case StructureFunctionsType::SuriYennie: { + SF::SuriYennie sy; + sf = sy( Q2, xbj ); } break; + case StructureFunctionsType::Fiore: { + SF::FioreBrasse fb; + sf = fb( Q2, xbj ); } break; + case StructureFunctionsType::ALLM91: { + SF::ALLM allm91( SF::ALLM::Parameterisation::allm91() ); + sf = allm91( Q2, xbj ); } break; + case StructureFunctionsType::ALLM97: { + SF::ALLM allm97( SF::ALLM::Parameterisation::allm97() ); + sf = allm97( Q2, xbj ); } break; default: break; //FIXME } // Longitudinal/transverse virtual photon cross section R // from Sibirtsev and Blunden (Phys Rev C 88,065202 (2013)) const double R = 0.014 * Q2 * ( exp( -0.07*Q2 ) + 41.*exp( -0.8*Q2 ) ); const double F1 = sf.F2 * ( 1.+4*xbj*xbj*mp2/Q2 )/( 1.+R )/( 2.*xbj ); const double ine1 = ( 1.-x )*( 1.-Q2min / Q2 ); const double f_D = sf.F2/( Q2 + mx2 - mp2 ) * ine1, f_C= 2.*F1/Q2; const double f_ine = Constants::alphaEM/M_PI/kt2*( f_D + 0.5*x*x*f_C ); return f_ine * ( 1.-x ) * kt2 / Q2; } } } diff --git a/CepGen/StructureFunctions/ALLM.cpp b/CepGen/StructureFunctions/ALLM.cpp index 4ff74f0..32c7f54 100644 --- a/CepGen/StructureFunctions/ALLM.cpp +++ b/CepGen/StructureFunctions/ALLM.cpp @@ -1,154 +1,154 @@ #include "ALLM.h" namespace CepGen { namespace SF { - ALLMParameterisation - ALLMParameterisation::allm91() + ALLM::Parameterisation + ALLM::Parameterisation::allm91() { - ALLMParameterisation p; - p.pomeron = Parameters( + Parameterisation p; + p.pomeron = Parameters( { { 0.26550, 0.04856, 1.04682 }, { -0.04503, -0.36407, 8.17091 }, - { 0.49222, 0.52116, 3.5515 } ); - p.reggeon = Parameters( + { 0.49222, 0.52116, 3.5515 } } ); + p.reggeon = Parameters( { { 0.67639, 0.49027, 2.66275 }, { 0.60408, 0.17353, 1.61812 }, - { 1.26066, 1.83624, 0.81141 } ); + { 1.26066, 1.83624, 0.81141 } } ); p.m02 = 0.30508; p.mp2 = 10.676; p.mr2 = 0.20623; p.q02 = 0.27799; p.lambda2 = 0.06527; return p; } - ALLMParameterisation - ALLMParameterisation::allm97() + ALLM::Parameterisation + ALLM::Parameterisation::allm97() { - ALLMParameterisation p; - p.pomeron = Parameters( + Parameterisation p; + p.pomeron = Parameters( { { 0.28067, 0.22291, 2.1979 }, { -0.0808, -0.44812, 1.1709 }, - { 0.36292, 1.8917, 1.8439 } ); - p.reggeon = Parameters( + { 0.36292, 1.8917, 1.8439 } } ); + p.reggeon = Parameters( { { 0.80107, 0.97307, 3.4924 }, { 0.58400, 0.37888, 2.6063 }, - { 0.01147, 3.7582, 0.49338 } ); + { 0.01147, 3.7582, 0.49338 } } ); p.m02 = 0.31985; p.mp2 = 49.457; p.mr2 = 0.15052; p.q02 = 0.52544; p.lambda2 = 0.06526; return p; } - ALLMParameterisation - ALLMParameterisation::hht_allm() + ALLM::Parameterisation + ALLM::Parameterisation::hht_allm() { - ALLMParameterisation p; - p.pomeron = Parameters( + Parameterisation p; + p.pomeron = Parameters( { { 0.412, 0.164, 17.7 }, { -0.835, -0.446, 10.6 }, - { -45.8, 55.7, -0.031 } ); - p.reggeon = Parameters( + { -45.8, 55.7, -0.031 } } ); + p.reggeon = Parameters( { { -1.04, 2.97, 0.163 }, { 0.706, 0.185, -16.4 }, - { -1.29, 4.51, 1.16 } ); + { -1.29, 4.51, 1.16 } } ); p.m02 = 0.446; p.mp2 = 74.2; p.mr2 = 29.3; p.q02 = 4.74e-5; p.lambda2 = 2.2e-8; return p; } - ALLMParameterisation - ALLMParameterisation::hht_allm_ft() + ALLM::Parameterisation + ALLM::Parameterisation::hht_allm_ft() { - ALLMParameterisation p; - p.pomeron = Parameters( + Parameterisation p; + p.pomeron = Parameters( { { 0.356, 0.171, 18.6 }, { -0.075, -0.470, 9.2 }, - { -0.477, 54.0, 0.073 } ); - p.reggeon = Parameters( + { -0.477, 54.0, 0.073 } } ); + p.reggeon = Parameters( { { -0.636, 3.37, -0.660 }, { 0.882, 0.082, -8.5 }, - { 0.339, 3.38, 1.07 } ); + { 0.339, 3.38, 1.07 } } ); p.m02 = 0.388; p.mp2 = 50.8; p.mr2 = 0.838; p.q02 = 1.87e-5; p.lambda2 = 4.4e-9; return p; } - ALLMParameterisation - ALLMParameterisation::gd07p() + ALLM::Parameterisation + ALLM::Parameterisation::gd07p() { - ALLMParameterisation p; - p.pomeron = Parameters( + Parameterisation p; + p.pomeron = Parameters( { { 0.339, 0.127, 1.16 }, { -0.105, -0.495, 1.29 }, - { -1.42, 4.51, 0.551 } ); - p.reggeon = Parameters( + { -1.42, 4.51, 0.551 } } ); + p.reggeon = Parameters( { { 0.838, 2.36, 1.77 }, { 0.374, 0.998, 0.775 }, - { 2.71, 1.83, 1.26 } ); + { 2.71, 1.83, 1.26 } } ); p.m02 = 0.454; p.mp2 = 30.7; p.mr2 = 0.117; p.q02 = 1.15; p.lambda2 = 0.06527; return p; } - ALLMParameterisation - ALLMParameterisation::gd11p() + ALLM::Parameterisation + ALLM::Parameterisation::gd11p() { - ALLMParameterisation p; - p.pomeron = Parameters( + Parameterisation p; + p.pomeron = Parameters( { { 0.3638, 0.1211, 1.166 }, // c { -0.11895, -0.4783, 1.353 }, // a - { 1.0833, 2.656, 1.771 } ); // b - p.reggeon = Parameters( + { 1.0833, 2.656, 1.771 } } ); // b + p.reggeon = Parameters( { { 1.3633, 2.256, 2.209 }, { 0.3425, 1.0603, 0.5164 }, - { -10.408, 14.857, 0.07739 } ); + { -10.408, 14.857, 0.07739 } } ); p.m02 = 0.5063; p.mp2 = 34.75; p.mr2 = 0.03190; p.q02 = 1.374; p.lambda2 = 0.06527; return p; } StructureFunctions - ALLM( double q2, double xbj, const ALLMParameterisation& param ) + ALLM::operator()( double q2, double xbj ) const { - const double factor = q2/( q2+param.m02 ); + const double factor = q2/( q2+params_.m02 ); const double W2_eff = q2*( 1.-xbj )/xbj; - const double xp = ( q2+param.mp2 )/( q2+W2_eff+param.mp2 ), - xr = ( q2+param.mr2 )/( q2+W2_eff+param.mr2 ); + const double xp = ( q2+params_.mp2 )/( q2+W2_eff+params_.mp2 ), + xr = ( q2+params_.mr2 )/( q2+W2_eff+params_.mr2 ); - const double xlog1 = log( ( q2+param.q02 )/ param.lambda2 ), xlog2 = log( param.q02/param.lambda2 ); + const double xlog1 = log( ( q2+params_.q02 )/ params_.lambda2 ), xlog2 = log( params_.q02/params_.lambda2 ); const double t = log( xlog1/xlog2 ); - const double apom = param.pomeron.a[0] + ( param.pomeron.a[0]-param.pomeron.a[1] )*( 1./( 1.+pow( t, param.pomeron.a[2] ) ) - 1. ); - const double bpom = param.pomeron.b[0] + param.pomeron.b[1]*pow( t, param.pomeron.b[2] ); - const double cpom = param.pomeron.c[0] + ( param.pomeron.c[0]-param.pomeron.c[1] )*( 1./( 1.+pow( t, param.pomeron.c[2] ) ) - 1. ); + const double apom = params_.pomeron.a[0] + ( params_.pomeron.a[0]-params_.pomeron.a[1] )*( 1./( 1.+pow( t, params_.pomeron.a[2] ) ) - 1. ); + const double bpom = params_.pomeron.b[0] + params_.pomeron.b[1]*pow( t, params_.pomeron.b[2] ); + const double cpom = params_.pomeron.c[0] + ( params_.pomeron.c[0]-params_.pomeron.c[1] )*( 1./( 1.+pow( t, params_.pomeron.c[2] ) ) - 1. ); - const double areg = param.reggeon.a[0] + param.reggeon.a[1]*pow( t, param.reggeon.a[2] ); - const double breg = param.reggeon.b[0] + param.reggeon.b[1]*pow( t, param.reggeon.b[2] ); - const double creg = param.reggeon.c[0] + param.reggeon.c[1]*pow( t, param.reggeon.c[2] ); + const double areg = params_.reggeon.a[0] + params_.reggeon.a[1]*pow( t, params_.reggeon.a[2] ); + const double breg = params_.reggeon.b[0] + params_.reggeon.b[1]*pow( t, params_.reggeon.b[2] ); + const double creg = params_.reggeon.c[0] + params_.reggeon.c[1]*pow( t, params_.reggeon.c[2] ); const double F2_Pom = cpom*pow( xp, apom )*pow( 1.-xbj, bpom ), F2_Reg = creg*pow( xr, areg )*pow( 1.-xbj, breg ); StructureFunctions allm; allm.F2 = factor * ( F2_Pom + F2_Reg ); return allm; } } } diff --git a/CepGen/StructureFunctions/ALLM.h b/CepGen/StructureFunctions/ALLM.h index 6884037..9c20cb0 100644 --- a/CepGen/StructureFunctions/ALLM.h +++ b/CepGen/StructureFunctions/ALLM.h @@ -1,47 +1,55 @@ #ifndef CepGen_StructureFunctions_ALLM_h #define CepGen_StructureFunctions_ALLM_h #include "StructureFunctions.h" namespace CepGen { namespace SF { - class ALLMParameterisation + class ALLM { - private: - struct Parameters { - Parameters() : - a( { 0., 0., 0. } ), b( { 0., 0., 0. } ), c( { 0., 0., 0. } ) {} - Parameters( std::vector<double> c, std::vector<double> a, std::vector<double> b ) : - a( a ), b( b ), c( c ) {} - std::vector<double> a, b, c; + public: + class Parameterisation + { + private: + struct Parameters { + Parameters() : + a( { 0., 0., 0. } ), b( { 0., 0., 0. } ), c( { 0., 0., 0. } ) {} + Parameters( std::vector<double> c, std::vector<double> a, std::vector<double> b ) : + a( a ), b( b ), c( c ) {} + std::vector<double> a, b, c; + }; + + public: + /// Pre-HERA data fit (694 data points) + static Parameterisation allm91(); + /// Fixed target and HERA photoproduction total cross sections (1356 points) + static Parameterisation allm97(); + static Parameterisation hht_allm(); + static Parameterisation hht_allm_ft(); + static Parameterisation gd07p(); + static Parameterisation gd11p(); + + Parameters pomeron, reggeon; + /// Effective photon squared mass + double m02; + /// Effective pomeron squared mass + double mp2; + /// Effective reggeon squared mass + double mr2; + double q02; + /// Squared QCD scale + double lambda2; }; - public: - /// Pre-HERA data fit (694 data points) - static ALLMParameterisation allm91(); - /// Fixed target and HERA photoproduction total cross sections (1356 points) - static ALLMParameterisation allm97(); - static ALLMParameterisation hht_allm(); - static ALLMParameterisation hht_allm_ft(); - static ALLMParameterisation gd07p(); - static ALLMParameterisation gd11p(); + ALLM( const ALLM::Parameterisation& param = ALLM::Parameterisation::allm97() ) : params_( param ) {} + StructureFunctions operator()( double q2, double xbj ) const; - Parameters pomeron, reggeon; - /// Effective photon squared mass - double m02; - /// Effective pomeron squared mass - double mp2; - /// Effective reggeon squared mass - double mr2; - double q02; - /// Squared QCD scale - double lambda2; + private: + Parameterisation params_; }; - - StructureFunctions ALLM( double q2, double xbj, const ALLMParameterisation& param=ALLMParameterisation::allm97() ); } } #endif diff --git a/CepGen/StructureFunctions/BlockDurandHa.cpp b/CepGen/StructureFunctions/BlockDurandHa.cpp index 149768a..2c3dce1 100644 --- a/CepGen/StructureFunctions/BlockDurandHa.cpp +++ b/CepGen/StructureFunctions/BlockDurandHa.cpp @@ -1,40 +1,41 @@ #include "BlockDurandHa.h" namespace CepGen { namespace SF { - BlockDurandHaParameters - BlockDurandHaParameters::standard() + BlockDurandHa::Parameterisation + BlockDurandHa::Parameterisation::standard() { - BlockDurandHaParameters p; - p.a = { 8.205e-4, -5.148e-2, -4.725e-3 }; - p.b = { 2.217e-3, 1.244e-2, 5.958e-4 }; - p.c = { 0.255e0, 1.475e-1 }; + Parameterisation p; + p.a = { { 8.205e-4, -5.148e-2, -4.725e-3 } }; + p.b = { { 2.217e-3, 1.244e-2, 5.958e-4 } }; + p.c = { { 0.255e0, 1.475e-1 } }; p.n = 11.49; p.lambda = 2.430; p.mu2 = 2.82; p.m2 = 0.753; return p; } - StructureFunctions BlockDurandHa( double q2, double xbj, const BlockDurandHaParameters& params ) + StructureFunctions + BlockDurandHa::operator()( double q2, double xbj ) const { StructureFunctions bdh; if ( q2 <= 0. ) return bdh; - const double tau = q2 / ( q2 + params.mu2 ); - const double xl = log( 1. + q2 / params.mu2 ); + const double tau = q2 / ( q2 + params_.mu2 ); + const double xl = log( 1. + q2 / params_.mu2 ); const double xlx = log( tau/xbj ); - const double A = params.a[0] + params.a[1]*xl + params.a[2]*xl*xl; - const double B = params.b[0] + params.b[1]*xl + params.b[2]*xl*xl; - const double C = params.c[0] + params.c[1]*xl; - const double D = q2*( q2+params.lambda*params.m2 ) / pow( q2+params.m2, 2 ); + const double A = params_.a[0] + params_.a[1]*xl + params_.a[2]*xl*xl; + const double B = params_.b[0] + params_.b[1]*xl + params_.b[2]*xl*xl; + const double C = params_.c[0] + params_.c[1]*xl; + const double D = q2*( q2+params_.lambda*params_.m2 ) / pow( q2+params_.m2, 2 ); - bdh.F2 = D*pow( 1.-xbj, params.n ) * ( C + A*xlx + B*xlx*xlx ); + bdh.F2 = D*pow( 1.-xbj, params_.n ) * ( C + A*xlx + B*xlx*xlx ); return bdh; } } } diff --git a/CepGen/StructureFunctions/BlockDurandHa.h b/CepGen/StructureFunctions/BlockDurandHa.h index 44feb75..0833d68 100644 --- a/CepGen/StructureFunctions/BlockDurandHa.h +++ b/CepGen/StructureFunctions/BlockDurandHa.h @@ -1,28 +1,36 @@ #ifndef CepGen_StructureFunctions_BlockDurandHa_h #define CepGen_StructureFunctions_BlockDurandHa_h #include "StructureFunctions.h" #include <array> namespace CepGen { namespace SF { - struct BlockDurandHaParameters + class BlockDurandHa { - std::array<double,3> a, b; - std::array<double,2> c; - double n; - /// Effective mass spread parameter - double lambda; - /// Asymptotic log-behaviour transition scale factor - double mu2; - /// Squared effective mass (~VM mass) - double m2; - static BlockDurandHaParameters standard(); + public: + struct Parameterisation + { + std::array<double,3> a, b; + std::array<double,2> c; + double n; + /// Effective mass spread parameter + double lambda; + /// Asymptotic log-behaviour transition scale factor + double mu2; + /// Squared effective mass (~VM mass) + double m2; + static Parameterisation standard(); + }; + BlockDurandHa( const BlockDurandHa::Parameterisation params = BlockDurandHa::Parameterisation::standard() ) : params_( params ) {} + StructureFunctions operator()( double q2, double xbj ) const; + + private: + Parameterisation params_; }; - StructureFunctions BlockDurandHa( double q2, double xbj, const BlockDurandHaParameters& params=BlockDurandHaParameters::standard() ); } } #endif diff --git a/CepGen/StructureFunctions/ChristyBosted.cpp b/CepGen/StructureFunctions/ChristyBosted.cpp index b1a3649..fec09d9 100644 --- a/CepGen/StructureFunctions/ChristyBosted.cpp +++ b/CepGen/StructureFunctions/ChristyBosted.cpp @@ -1,260 +1,256 @@ #include "ChristyBosted.h" namespace CepGen { namespace SF { - ChristyBosted::ChristyBosted( const ChristyBostedParameterisation& params ) : - params_( params ) - {} - double ChristyBosted::resmod507( char sf, double w2, double q2 ) const { const double mp = Constants::mp, mp2 = mp*mp, mpi = Constants::mpi, mpi2 = mpi*mpi, meta = Particle::massFromPDGId( Particle::Eta ), meta2 = meta*meta; const double w = sqrt( w2 ); const double xb = q2/( q2+w2-mp2 ); double m0 = 0., q20 = 0.; if ( sf == 'T' ) { // transverse m0 = 0.125; q20 = 0.05; } else if ( sf == 'L' ) { m0 = params_.m0; q20 = 0.125; } else { InError( "Invalid direction retrieved! Aborting." ) return 0.; } const double norm_q2 = 1./0.330/0.330; const double t = log( log( ( q2+m0 )*norm_q2 )/log( m0*norm_q2 ) ); //--- calculate kinematics needed for threshold relativistic B-W // equivalent photon energies const double k = 0.5 * ( w2-mp2 )/mp; const double kcm = 0.5 * ( w2-mp2 )/w; const double epicm = 0.5 * ( w2+mpi2-mp2 )/w, ppicm = sqrt( std::max( 0., epicm*epicm-mpi2 ) ); const double epi2cm = 0.5 * ( w2 + 4.*mpi2 - mp2 )/w, ppi2cm = sqrt( std::max( 0., epi2cm*epi2cm-4*mpi2 ) ); const double eetacm = 0.5 * ( w2 + meta2 - mp2 )/w, petacm = sqrt( std::max( 0., eetacm*eetacm-meta2 ) ); std::array<double,7> width, height, pgam; for ( unsigned short i = 0; i < 7; ++i ) { - const ChristyBostedParameterisation::ResonanceParameters& res = params_.resonances[i]; + const Parameterisation::ResonanceParameters& res = params_.resonances[i]; width[i] = res.width; //--- calculate partial widths //----- 1-pion decay mode const double x02 = res.x0*res.x0; const double partial_width_singlepi = pow( ppicm /res.pcmr( mpi2 ), 2.*res.angular_momentum+1. ) * pow( ( res.pcmr( mpi2 )*res.pcmr( mpi2 )+x02 )/( ppicm *ppicm +x02 ), res.angular_momentum ); //----- 2-pion decay mode const double partial_width_doublepi = pow( ppi2cm/res.pcmr( 4.*mpi2 ), 2.*( res.angular_momentum+2. ) ) * pow( ( res.pcmr( 4.*mpi2 )*res.pcmr( 4.*mpi2 )+x02 )/( ppi2cm*ppi2cm+x02 ), res.angular_momentum+2 ) * w / res.mass; //----- eta decay mode (only for S11's) const double partial_width_eta = ( res.br.eta == 0. ) ? 0. : pow( petacm/res.pcmr( meta2 ), 2.*res.angular_momentum+1. ) * pow( ( res.pcmr( meta2 )*res.pcmr( meta2 )+x02 )/( petacm*petacm+x02 ), res.angular_momentum ); // virtual photon width pgam[i] = res.width * pow( kcm/res.kcmr(), 2 ) * ( res.kcmr()*res.kcmr()+x02 )/( kcm*kcm+x02 ); width[i] = ( partial_width_singlepi * res.br.singlepi + partial_width_doublepi * res.br.doublepi + partial_width_eta * res.br.eta ) * res.width; //std::cout << i << "\t" << width[i] << "\t" << partial_width_doublepi << "\t" << pow( ppi2cm/res.pcmr( 4.*mpi2 ), 2.*( res.angular_momentum+2. ) ) << std::endl; //--- resonance Q^2 dependence calculations if ( sf == 'T' ) height[i] = res.A0_T*( 1.+res.fit_parameters[0]*q2/( 1.+res.fit_parameters[1]*q2 ) )/pow( 1.+q2/0.91, res.fit_parameters[2] ); else if ( sf == 'L' ) height[i] = res.A0_L/( 1.+res.fit_parameters[3]*q2 )*q2*exp( -q2*res.fit_parameters[4] ); //std::cout << sf << "//////" << height[i] << "\t" << res.fit_parameters[4] << std::endl; height[i] = height[i]*height[i]; } //--- calculate Breit-Wigners for all resonances double sig_res = 0.; for ( unsigned short i = 0; i < 7; ++i ) { - const ChristyBostedParameterisation::ResonanceParameters res = params_.resonances[i]; + const Parameterisation::ResonanceParameters res = params_.resonances[i]; const double mass2 = res.mass*res.mass, width2 = width[i]*width[i]; const double sigr = height[i]*res.kr()/k*res.kcmr()/kcm/res.width * ( width[i]*pgam[i] / ( pow( w2-mass2, 2 ) + mass2*width2 ) ); sig_res += sigr; } sig_res *= w; //--- finish resonances / start non-res background calculation const double xpr = 1./( 1.+( w2-pow( mp+mpi, 2 ) )/( q2+q20 ) ); double sig_nr = 0.; if ( sf == 'T' ) { // transverse const double wdif = w - ( mp + mpi ); for ( unsigned short i = 0; i < 2; ++i ) { const double expo = params_.continuum.transverse[i].fit_parameters[1] + params_.continuum.transverse[i].fit_parameters[2]*q2 + params_.continuum.transverse[i].fit_parameters[3]*q2*q2; sig_nr += params_.continuum.transverse[i].sig0 / pow( q2+params_.continuum.transverse[i].fit_parameters[0], expo ) * pow( wdif, i+1.5 ); } sig_nr *= xpr; } else if ( sf == 'L' ) { // longitudinal for ( unsigned short i = 0; i < 1; ++i ) { const double expo = params_.continuum.longitudinal[i].fit_parameters[0] + params_.continuum.longitudinal[i].fit_parameters[1]; sig_nr += params_.continuum.longitudinal[i].sig0 * pow( 1.-xpr, expo )/( 1.-xb ) * pow( q2/( q2+q20 ), params_.continuum.longitudinal[i].fit_parameters[2] )/( q2+q20 ) * pow( xpr, params_.continuum.longitudinal[i].fit_parameters[3]+params_.continuum.longitudinal[i].fit_parameters[4]*t ); } } return sig_res + sig_nr; } - ChristyBosted::ChristyBostedParameterisation - ChristyBosted::ChristyBostedParameterisation::standard() + ChristyBosted::Parameterisation + ChristyBosted::Parameterisation::standard() { - ChristyBostedParameterisation params; + Parameterisation params; params.m0 = 4.2802; params.continuum.transverse = { ContinuumParameters::DirectionParameters( 246.06, { 0.067469, 1.3501, 0.12054, -0.0038495 } ), ContinuumParameters::DirectionParameters( -89.360, { 0.20977, 1.5715, 0.090736, 0.010362 } ) }; params.continuum.longitudinal = { ContinuumParameters::DirectionParameters( 86.746, { 0., 4.0294, 3.1285, 0.33403, 4.9623 } ) }; //--- P33(1232) ResonanceParameters p33; p33.br = ResonanceParameters::BranchingRatios( 1., 0., 0. ); p33.angular_momentum = 1.; //p33.x0 = 0.15; p33.x0 = 0.14462; p33.mass = 1.2298; p33.width = 0.13573; p33.fit_parameters = { 4.2291, 1.2598, 2.1242, 19.910, 0.22587 }; p33.A0_T = 7.7805; p33.A0_L = 29.414; params.resonances.emplace_back( p33 ); //--- S11(1535) ResonanceParameters s11_1535; s11_1535.br = ResonanceParameters::BranchingRatios( 0.45, 0.1, 0.45 ); s11_1535.angular_momentum = 0.; s11_1535.x0 = 0.215; s11_1535.mass = 1.5304; s11_1535.width = 0.220; s11_1535.fit_parameters = { 6823.2, 33521., 2.5686, 0., 0. }; s11_1535.A0_T = 6.3351; s11_1535.A0_L = 0.; params.resonances.emplace_back( s11_1535 ); //--- D13(1520) ResonanceParameters d13; d13.br = ResonanceParameters::BranchingRatios( 0.65, 0.35, 0. ); d13.angular_momentum = 2.; d13.x0 = 0.215; d13.mass = 1.5057; d13.width = 0.082956; d13.fit_parameters = { 21.240, 0.055746, 2.4886, 97.046, 0.31042 }; d13.A0_T = 0.60347; d13.A0_L = 157.92; params.resonances.emplace_back( d13 ); //--- F15(1680) ResonanceParameters f15; f15.br = ResonanceParameters::BranchingRatios( 0.65, 0.35, 0. ); f15.angular_momentum = 3.; f15.x0 = 0.215; f15.mass = 1.6980; f15.width = 0.095782; f15.fit_parameters = { -0.28789, 0.18607, 0.063534, 0.038200, 1.2182 }; f15.A0_T = 2.3305; f15.A0_L = 4.2160; params.resonances.emplace_back( f15 ); //--- S11(1650) ResonanceParameters s11_1650; s11_1650.br = ResonanceParameters::BranchingRatios( 0.4, 0.5, 0.1 ); s11_1650.angular_momentum = 0.; s11_1650.x0 = 0.215; s11_1650.mass = 1.6650; s11_1650.width = 0.10936; s11_1650.fit_parameters = { -0.56175, 0.38964, 0.54883, 0.31393, 2.9997 }; s11_1650.A0_T = 1.9790; s11_1650.A0_L = 13.764; params.resonances.emplace_back( s11_1650 ); //--- P11(1440) roper ResonanceParameters p11; p11.br = ResonanceParameters::BranchingRatios( 0.65, 0.35, 0. ); p11.angular_momentum = 1.; p11.x0 = 0.215; p11.mass = 1.4333; p11.width = 0.37944; p11.fit_parameters = { 46.213, 0.19221, 1.9141, 0.053743, 1.3091 }; p11.A0_T = 0.022506; p11.A0_L = 5.5124; params.resonances.emplace_back( p11 ); //--- F37(1950) ResonanceParameters f37; f37.br = ResonanceParameters::BranchingRatios( 0.5, 0.5, 0. ); f37.angular_momentum = 3.; f37.x0 = 0.215; f37.mass = 1.9341; f37.width = 0.380; f37.fit_parameters = { 0., 0., 1., 1.8951, 0.51376 }; f37.A0_T = 3.4187; f37.A0_L = 1.8951; params.resonances.emplace_back( f37 ); return params; } StructureFunctions ChristyBosted::operator()( double q2, double xbj ) const { const double mp2 = Constants::mp*Constants::mp; const double w2 = mp2 + q2*( 1.-xbj )/xbj; const double w_min = Constants::mp+Constants::mpi; StructureFunctions cb; if ( sqrt( w2 ) < w_min ) return cb; //----------------------------- // modification of Christy-Bosted at large q2 as described in the LUXqed paper //----------------------------- const double q21 = 30., q20 = 8.; const double delq2 = q2 - q20; const double qq = q21 - q20; const double prefac = 1./( 4.*M_PI*M_PI*Constants::alphaEM ) * ( 1.-xbj ); //------------------------------ double q2_eff = q2, w2_eff = w2; if ( q2 > q20 ) { q2_eff = q20 + delq2/( 1.+delq2/qq ); w2_eff = mp2 + q2_eff*( 1.-xbj )/xbj; } const double tau = 4.*xbj*xbj*mp2/q2_eff; const double sigT = resmod507( 'T', w2_eff, q2_eff ), sigL = resmod507( 'L', w2_eff, q2_eff ); cb.F2 = prefac * q2_eff / ( 1+tau ) * ( sigT+sigL ) / Constants::GeV2toBarn * 1.e6; if ( q2 > q20 ) cb.F2 *= q21/( q21 + delq2 ); const double R = sigL/sigT; cb.FL = cb.F2*( 1+tau )*R/( 1.+R ); return cb; } } } diff --git a/CepGen/StructureFunctions/ChristyBosted.h b/CepGen/StructureFunctions/ChristyBosted.h index 3a1f1cc..cd03870 100644 --- a/CepGen/StructureFunctions/ChristyBosted.h +++ b/CepGen/StructureFunctions/ChristyBosted.h @@ -1,79 +1,79 @@ #ifndef CepGen_StructureFunctions_ChristyBosted_h #define CepGen_StructureFunctions_ChristyBosted_h #include "StructureFunctions.h" #include <array> #include <vector> namespace CepGen { namespace SF { class ChristyBosted { public: - struct ChristyBostedParameterisation + struct Parameterisation { - static ChristyBostedParameterisation standard(); + static Parameterisation standard(); struct ResonanceParameters { struct BranchingRatios { BranchingRatios() : singlepi( 0. ), doublepi( 0. ), eta( 0. ) {} BranchingRatios( double singlepi, double doublepi, double eta ) : singlepi( singlepi ), doublepi( doublepi ), eta( eta ) {} bool valid() const { return ( singlepi+doublepi+eta == 1. ); } /// single pion branching ratio double singlepi; /// double pion branching ratio double doublepi; /// eta meson branching ratio double eta; }; ResonanceParameters() : angular_momentum( 0. ), x0( 0. ), mass( 0. ), width( 0. ), A0_T( 0. ), A0_L( 0. ) {} double kr() const { return 0.5 * ( mass*mass-Constants::mp*Constants::mp )/Constants::mp; } double ecmr( double m2 ) const { return ( mass == 0. ) ? 0. : 0.5 * ( mass*mass+m2-Constants::mp*Constants::mp ) / mass; } double kcmr() const { return ecmr( 0. ); } double pcmr( double m2 ) const { return sqrt( std::max( 0., ecmr( m2 )*ecmr( m2 )-m2 ) ); } BranchingRatios br; /// meson angular momentum double angular_momentum; /// damping parameter double x0; /// mass, in GeV/c2 double mass; /// full width, in GeV double width; double A0_T; double A0_L; std::array<double,5> fit_parameters; }; struct ContinuumParameters { struct DirectionParameters { DirectionParameters() : sig0( 0. ) {} DirectionParameters( double sig0, const std::vector<double>& params ) : sig0( sig0 ), fit_parameters( params ) {} double sig0; std::vector<double> fit_parameters; }; std::array<DirectionParameters,2> transverse; std::array<DirectionParameters,1> longitudinal; }; double m0; std::vector<ResonanceParameters> resonances; ContinuumParameters continuum; }; - ChristyBosted( const ChristyBostedParameterisation& params = ChristyBostedParameterisation::standard() ); + ChristyBosted( const ChristyBosted::Parameterisation& params = ChristyBosted::Parameterisation::standard() ) : params_( params ) {} StructureFunctions operator()( double q2, double xbj ) const; private: double resmod507( char sf, double w2, double q2 ) const; - ChristyBostedParameterisation params_; + Parameterisation params_; }; } } #endif diff --git a/CepGen/StructureFunctions/FioreBrasse.cpp b/CepGen/StructureFunctions/FioreBrasse.cpp index bc6f117..b3991cd 100644 --- a/CepGen/StructureFunctions/FioreBrasse.cpp +++ b/CepGen/StructureFunctions/FioreBrasse.cpp @@ -1,153 +1,152 @@ #include "FioreBrasse.h" namespace CepGen { namespace SF { - FioreBrasseParameterisation - FioreBrasseParameterisation::standard() + FioreBrasse::Parameterisation + FioreBrasse::Parameterisation::standard() { - FioreBrasseParameterisation p; + Parameterisation p; p.s0 = 1.14; p.norm = 0.021; p.resonances.emplace_back( -0.8377, 0.95, 0.1473, 1.0, 2.4617, 3./2. ); p.resonances.emplace_back( -0.37, 0.95, 0.1471, 0.5399, 2.4617, 5./2. ); p.resonances.emplace_back( 0.0038, 0.85, 0.1969, 4.2225, 1.5722, 3./2. ); p.resonances.emplace_back( 0.5645, 0.1126, 1.3086, 19.2694, 4.5259, 1. ); return p; } - FioreBrasseParameterisation - FioreBrasseParameterisation::alternative() + FioreBrasse::Parameterisation + FioreBrasse::Parameterisation::alternative() { - FioreBrasseParameterisation p; + Parameterisation p; p.s0 = 1.2871; p.norm = 0.0207; p.resonances.emplace_back( -0.8070, 0.9632, 0.1387, 1.0, 2.6066, 3./2. ); p.resonances.emplace_back( -0.3640, 0.9531, 0.1239, 0.6086, 2.6066, 5./2. ); p.resonances.emplace_back( -0.0065, 0.8355, 0.2320, 4.7279, 1.4828, 3./2. ); p.resonances.emplace_back( 0.5484, 0.1373, 1.3139, 14.7267, 4.6041, 1. ); return p; } StructureFunctions - FioreBrasse( double q2, double xbj ) + FioreBrasse::operator()( double q2, double xbj ) const { const double mp = Particle::massFromPDGId( Particle::Proton ), mp2 = mp*mp; const double akin = 1. + 4.*mp2 * xbj*xbj/q2; const double prefactor = q2*( 1.-xbj ) / ( 4.*M_PI*Constants::alphaEM*akin ); const double s = q2*( 1.-xbj )/xbj + mp2; - FioreBrasseParameterisation p = FioreBrasseParameterisation::standard(); double ampli_res = 0., ampli_tot = 0.; for ( unsigned short i = 0; i < 3; ++i ) { //FIXME 4?? - const FioreBrasseParameterisation::ResonanceParameters res = p.resonances[i]; + const Parameterisation::ResonanceParameters res = params_.resonances[i]; if ( !res.enabled ) continue; - const double sqrts0 = sqrt( p.s0 ); + const double sqrts0 = sqrt( params_.s0 ); std::complex<double> alpha; - if ( s > p.s0 ) - alpha = std::complex<double>( res.alpha0 + res.alpha2*sqrts0 + res.alpha1*s, res.alpha2*sqrt( s-p.s0 ) ); + if ( s > params_.s0 ) + alpha = std::complex<double>( res.alpha0 + res.alpha2*sqrts0 + res.alpha1*s, res.alpha2*sqrt( s-params_.s0 ) ); else - alpha = std::complex<double>( res.alpha0 + res.alpha1*s + res.alpha2*( sqrts0 - sqrt( p.s0 - s ) ), 0. ); + alpha = std::complex<double>( res.alpha0 + res.alpha1*s + res.alpha2*( sqrts0 - sqrt( params_.s0 - s ) ), 0. ); double formfactor = 1./pow( 1. + q2/res.q02, 2 ); double denom = pow( res.spin-std::real( alpha ), 2 ) + pow( std::imag( alpha ), 2 ); double ampli_imag = res.a*formfactor*formfactor*std::imag( alpha )/denom; ampli_res += ampli_imag; } { - const FioreBrasseParameterisation::ResonanceParameters res = p.resonances[3]; + const Parameterisation::ResonanceParameters res = params_.resonances[3]; double sE = res.alpha2, sqrtsE = sqrt( sE ); std::complex<double> alpha; if ( s > sE ) alpha = std::complex<double>( res.alpha0 + res.alpha1*sqrtsE, res.alpha1*sqrt( s-sE ) ); else alpha = std::complex<double>( res.alpha0 + res.alpha1*( sqrtsE - sqrt( sE-s ) ), 0. ); double formfactor = 1./pow( 1. + q2/res.q02, 2 ); double sp = 1.5*res.spin; double denom = pow( sp-std::real( alpha ), 2 ) + pow( std::imag( alpha ), 2 ); double ampli_bg = res.a*formfactor*formfactor*std::imag( alpha )/denom; ampli_res += ampli_bg; } - ampli_tot = p.norm*ampli_res; + ampli_tot = params_.norm*ampli_res; StructureFunctions fb; fb.F2 = prefactor*ampli_tot; return fb; } StructureFunctions - FioreBrasseOld( double q2, double xbj ) + FioreBrasse::operator()( double q2, double xbj, bool ) const { const double mp = Particle::massFromPDGId( Particle::Proton ), mp2 = mp*mp; //const double m_min = Particle::massFromPDGId(Particle::Proton)+0.135; const double m_min = mp+Particle::massFromPDGId( Particle::PiZero ); const double mx2 = mp2 + q2*( 1.-xbj )/xbj, mx = sqrt( mx2 ); if ( mx < m_min || mx > 1.99 ) { InWarning( Form( "Fiore-Brasse form factors to be retrieved for an invalid MX value:\n\t" "%.2e GeV, while allowed range is [1.07, 1.99] GeV", mx ) ); return StructureFunctions(); } int n_bin; double x_bin, dx; if ( mx < 1.11 ) { n_bin = 0; x_bin = mx-m_min; dx = 1.11-m_min; // Delta w bin sizes } else if ( mx < 1.77 ) { // w in [1.11, 1.77[ dx = 0.015; // Delta w bin sizes n_bin = ( mx-1.11 )/dx + 1; x_bin = fmod( mx-1.11, dx ); } else { // w in [1.77, 1.99[ dx = 0.02; // Delta w bin sizes n_bin = ( mx-1.77 )/dx + 45; x_bin = fmod( mx-1.77, dx ); } // values of a, b, c provided from the fits on ep data and retrieved from // http://dx.doi.org/10.1016/0550-3213(76)90231-5 with 1.110 <= w2 <=1.990 const double a[56] = { 5.045, 5.126, 5.390,5.621, 5.913, 5.955,6.139,6.178,6.125, 5.999, 5.769, 5.622, 5.431,5.288, 5.175, 5.131,5.003,5.065,5.045, 5.078, 5.145, 5.156, 5.234,5.298, 5.371, 5.457,5.543,5.519,5.465, 5.384, 5.341, 5.320, 5.275,5.290, 5.330, 5.375,5.428,5.478,5.443, 5.390, 5.333, 5.296, 5.223,5.159, 5.146, 5.143,5.125,5.158,5.159, 5.178, 5.182, 5.195, 5.160,5.195, 5.163, 5.172 }, b[56] = { 0.798, 1.052, 1.213,1.334,1.397,1.727,1.750,1.878,1.887,1.927, 2.041, 2.089, 2.148,2.205,2.344,2.324,2.535,2.464,2.564,2.610, 2.609, 2.678, 2.771,2.890,2.982,3.157,3.183,3.315,3.375,3.450, 3.477, 3.471, 3.554,3.633,3.695,3.804,3.900,4.047,4.290,4.519, 4.709, 4.757, 4.840,5.017,5.015,5.129,5.285,5.322,5.545,5.623, 5.775, 5.894, 6.138,6.151,6.301,6.542 }, c[56] = { 0.043, 0.024, 0.000,-0.013,-0.023,-0.069,-0.060,-0.080,-0.065,-0.056, -0.065,-0.056,-0.043,-0.034,-0.054,-0.018,-0.046,-0.015,-0.029,-0.048, -0.032,-0.045,-0.084,-0.115,-0.105,-0.159,-0.164,-0.181,-0.203,-0.223, -0.245,-0.254,-0.239,-0.302,-0.299,-0.318,-0.383,-0.393,-0.466,-0.588, -0.622,-0.568,-0.574,-0.727,-0.665,-0.704,-0.856,-0.798,-1.048,-0.980, -1.021,-1.092,-1.313,-1.341,-1.266,-1.473 }; const double d = 3.0; const double nu = 0.5 * ( q2 + mx2 - mp2 ) / mp, nu2 = nu*nu, logqq0 = 0.5 * log( ( nu2+q2 ) / pow( ( mx2-mp2 ) / ( 2.*mp ), 2 ) ); const double gd2 = pow( 1. / ( 1+q2 / .71 ), 4 ); // dipole form factor of the proton const double sigLow = ( n_bin == 0 ) ? 0. : gd2 * exp( a[n_bin-1] + b[n_bin-1]*logqq0 + c[n_bin-1]*pow( fabs( logqq0 ), d ) ); const double sigHigh = gd2 * exp( a[n_bin] + b[n_bin] *logqq0 + c[n_bin] *pow( fabs( logqq0 ), d ) ); const double sigma_t = sigLow + x_bin*( sigHigh-sigLow )/dx; const double w1 = ( mx2-mp2 )/( 8.*M_PI*M_PI*mp*Constants::alphaEM )/Constants::GeV2toBarn*1.e6 * sigma_t; const double w2 = w1 * q2 / ( q2+nu2 ); StructureFunctions fb_old; fb_old.F1 = w1; //FIXME fb_old.F2 = w2; //FIXME return fb_old; } } } diff --git a/CepGen/StructureFunctions/FioreBrasse.h b/CepGen/StructureFunctions/FioreBrasse.h index a3bd100..7c6e58e 100644 --- a/CepGen/StructureFunctions/FioreBrasse.h +++ b/CepGen/StructureFunctions/FioreBrasse.h @@ -1,37 +1,45 @@ #ifndef CepGen_StructureFunctions_FioreBrasse_h #define CepGen_StructureFunctions_FioreBrasse_h #include "StructureFunctions.h" #include <complex> namespace CepGen { namespace SF { - struct FioreBrasseParameterisation + class FioreBrasse { - static FioreBrasseParameterisation standard(); - static FioreBrasseParameterisation alternative(); + public: + struct Parameterisation + { + static Parameterisation standard(); + static Parameterisation alternative(); - struct ResonanceParameters { - ResonanceParameters( double a0, double a1, double a2, double a, double q02, float spin, bool on=true ) : - alpha0( a0 ), alpha1( a1 ), alpha2( a2 ), a( a ), q02( q02 ), spin( spin ), enabled( on ) {} - double alpha0, alpha1, alpha2, a, q02; - float spin; - bool enabled; - }; + struct ResonanceParameters { + ResonanceParameters( double a0, double a1, double a2, double a, double q02, float spin, bool on=true ) : + alpha0( a0 ), alpha1( a1 ), alpha2( a2 ), a( a ), q02( q02 ), spin( spin ), enabled( on ) {} + double alpha0, alpha1, alpha2, a, q02; + float spin; + bool enabled; + }; - std::vector<ResonanceParameters> resonances; - double s0, norm; + std::vector<ResonanceParameters> resonances; + double s0, norm; + }; + /// Fiore-Brasse proton structure functions (F.W Brasse et al., DESY 76/11 (1976), + /// http://dx.doi.org/10.1016/0550-3213(76)90231-5) + FioreBrasse( const FioreBrasse::Parameterisation& params = FioreBrasse::Parameterisation::standard() ) : params_( params ) {} + /// \param[in] q2 Squared 4-momentum transfer + /// \param[in] xbj Bjorken's x + /// \cite Brasse1976413 + StructureFunctions operator()( double q2, double xbj ) const; + StructureFunctions operator()( double q2, double xbj, bool old ) const; + + private: + Parameterisation params_; }; - /// Fiore-Brasse proton structure functions (F.W Brasse et al., DESY 76/11 (1976), - /// http://dx.doi.org/10.1016/0550-3213(76)90231-5) - /// \param[in] q2 Squared 4-momentum transfer - /// \param[in] xbj Bjorken's x - /// \cite Brasse1976413 - StructureFunctions FioreBrasse( double q2, double xbj ); - StructureFunctions FioreBrasseOld( double q2, double xbj ); } } #endif diff --git a/CepGen/StructureFunctions/SuriYennie.cpp b/CepGen/StructureFunctions/SuriYennie.cpp index 254e9a9..8b4318a 100644 --- a/CepGen/StructureFunctions/SuriYennie.cpp +++ b/CepGen/StructureFunctions/SuriYennie.cpp @@ -1,51 +1,51 @@ #include "SuriYennie.h" namespace CepGen { namespace SF { - SuriYennieParameterisation - SuriYennieParameterisation::standard() + SuriYennie::Parameterisation + SuriYennie::Parameterisation::standard() { - SuriYennieParameterisation p; + Parameterisation p; p.C1 = 0.86926; p.C2 = 2.23422; p.D1 = 0.12549; p.rho2 = 0.585; p.Cp = 0.96; p.Bp = 0.63; return p; } - SuriYennieParameterisation - SuriYennieParameterisation::alternative() + SuriYennie::Parameterisation + SuriYennie::Parameterisation::alternative() { - SuriYennieParameterisation p; + Parameterisation p; p.C1 = 0.6303; p.C2 = 2.3049; p.D1 = 0.04681; p.rho2 = 1.05; p.Cp = 1.23; p.Bp = 0.61; return p; } StructureFunctions - SuriYennie( double q2, double xbj, const SuriYennieParameterisation& param ) + SuriYennie::operator()( double q2, double xbj ) const { const double mp = Particle::massFromPDGId( Particle::Proton ), mp2 = mp*mp; const double mx2 = q2 * ( 1.-xbj )/xbj + mp2, // [GeV^2] nu = 0.5 * ( q2 + mx2 - mp2 ) / mp; // [GeV] - const double dm2 = mx2-mp2, Xpr = q2/( q2+mx2 ), En = dm2+q2, Tau = 0.25 * q2/mp2, MQ = param.rho2+q2; + const double dm2 = mx2-mp2, Xpr = q2/( q2+mx2 ), En = dm2+q2, Tau = 0.25 * q2/mp2, MQ = params_.rho2+q2; StructureFunctions sy; - sy.FM = ( param.C1*dm2*pow( param.rho2/MQ, 2 ) + ( param.C2*mp2*pow( 1.-Xpr, 4 ) ) / ( 1.+Xpr*( Xpr*param.Cp-2.*param.Bp ) ) )/q2; - const double FE = ( Tau*sy.FM + param.D1*dm2*q2*param.rho2/mp2*pow( dm2/MQ/En, 2 ) ) / ( 1.+0.25*En*En/mp2/q2 ); + sy.FM = ( params_.C1*dm2*pow( params_.rho2/MQ, 2 ) + ( params_.C2*mp2*pow( 1.-Xpr, 4 ) ) / ( 1.+Xpr*( Xpr*params_.Cp-2.*params_.Bp ) ) )/q2; + const double FE = ( Tau*sy.FM + params_.D1*dm2*q2*params_.rho2/mp2*pow( dm2/MQ/En, 2 ) ) / ( 1.+0.25*En*En/mp2/q2 ); const double w2 = 2.*mp*FE, w1 = 0.5 * sy.FM*q2/mp; sy.F2 = nu/mp*w2; return sy; } } } diff --git a/CepGen/StructureFunctions/SuriYennie.h b/CepGen/StructureFunctions/SuriYennie.h index 6c00cef..a6503b6 100644 --- a/CepGen/StructureFunctions/SuriYennie.h +++ b/CepGen/StructureFunctions/SuriYennie.h @@ -1,22 +1,30 @@ #ifndef CepGen_StructureFunctions_SuriYennie_h #define CepGen_StructureFunctions_SuriYennie_h #include "StructureFunctions.h" namespace CepGen { namespace SF { - struct SuriYennieParameterisation { - // values extracted from experimental fits - static SuriYennieParameterisation standard(); - static SuriYennieParameterisation alternative(); + class SuriYennie + { + public: + struct Parameterisation { + // values extracted from experimental fits + static Parameterisation standard(); + static Parameterisation alternative(); - double C1, C2, D1, rho2, Cp, Bp; - }; + double C1, C2, D1, rho2, Cp, Bp; + }; + + SuriYennie( const SuriYennie::Parameterisation& param = SuriYennie::Parameterisation::standard() ) : params_( param ) {} + StructureFunctions operator()( double q2, double xbj ) const; - StructureFunctions SuriYennie( double q2, double xbj, const SuriYennieParameterisation& param=SuriYennieParameterisation::standard() ); + private: + Parameterisation params_; + }; } } #endif diff --git a/CepGen/StructureFunctions/SzczurekUleshchenko.cpp b/CepGen/StructureFunctions/SzczurekUleshchenko.cpp index feee450..b471f43 100644 --- a/CepGen/StructureFunctions/SzczurekUleshchenko.cpp +++ b/CepGen/StructureFunctions/SzczurekUleshchenko.cpp @@ -1,39 +1,39 @@ #include "SzczurekUleshchenko.h" namespace CepGen { namespace SF { StructureFunctions - SzczurekUleshchenko( double q2, double xbj ) + SzczurekUleshchenko::operator()( double q2, double xbj ) const { #ifndef GRVPDF FatalError( "Szczurek-Uleshchenko structure functions cannot be computed" " as GRV PDF set is not linked to this instance!" ); #else const float q02 = 0.8; float amu2 = q2+q02; // shift the overall scale float xuv, xdv, xus, xds, xss, xg; float xbj_arg = xbj; grv95lo_( xbj_arg, amu2, xuv, xdv, xus, xds, xss, xg ); DebuggingInsideLoop( Form( "Form factor content at xB = %e (scale = %f GeV^2):\n\t" " valence quarks: u / d = %e / %e\n\t" " sea quarks: u / d / s = %e / %e / %e\n\t" " gluons: = %e", xbj, amu2, xuv, xdv, xus, xds, xss, xg ) ); // standard partonic structure function const double F2_aux = 4./9.*( xuv + 2.*xus ) + 1./9.*( xdv + 2.*xds ) + 1./9.*( 2.*xss ); StructureFunctions su; su.F2 = F2_aux * q2 / amu2; // F2 corrected for low Q^2 behaviour return su; #endif } } } diff --git a/CepGen/StructureFunctions/SzczurekUleshchenko.h b/CepGen/StructureFunctions/SzczurekUleshchenko.h index 2cc58be..869edef 100644 --- a/CepGen/StructureFunctions/SzczurekUleshchenko.h +++ b/CepGen/StructureFunctions/SzczurekUleshchenko.h @@ -1,20 +1,25 @@ #ifndef CepGen_StructureFunctions_SzczurekUleshchenko_h #define CepGen_StructureFunctions_SzczurekUleshchenko_h #include "StructureFunctions.h" extern "C" { extern void grv95lo_( float&, float&, float&, float&, float&, float&, float&, float& ); //extern void grv95lo_( double&, double&, double&, double&, double&, double&, double&, double& ); } namespace CepGen { namespace SF { - StructureFunctions SzczurekUleshchenko( double q2, double xbj ); + class SzczurekUleshchenko + { + public: + SzczurekUleshchenko() {} + StructureFunctions operator()( double q2, double xbj ) const; + }; } } #endif diff --git a/test/utils/structure_functions.cxx b/test/utils/structure_functions.cxx index ecb7b70..778c458 100644 --- a/test/utils/structure_functions.cxx +++ b/test/utils/structure_functions.cxx @@ -1,143 +1,147 @@ #include "CepGen/Physics/FormFactors.h" #include "CepGen/Event/Particle.h" #include "CepGen/StructureFunctions/ChristyBosted.h" #include "test/Canvas.h" #include "TGraph.h" #include "TMultiGraph.h" #include <iostream> using namespace std; int main( int argc, char* argv[] ) { const float min_xbj = 1.e-5, max_xbj = 0.99, q2 = ( argc>1 ) ? atof( argv[1] ) : 2.5; const char* q2_str = ( argc>2 ) ? argv[2] : std::to_string( q2 ).c_str(); const unsigned int npoints = 5000; TGraph g_sy_f2, g_fb_f2, g_su_f2, g_bdh_f2, g_cteq_f2, g_mrst_f2; TGraph g_allm97_f2, g_allm_hht_f2, g_allm_hht_ft_f2; TGraph g_lux_f2; TGraph g_cb_f2; const bool use_logarithmic_x = ( argc>3 ) ? atoi( argv[3] ) : false; /*CepGen::SF::GenericLHAPDF cteq( "cteq6l1" ); CepGen::SF::GenericLHAPDF mrst( "MRST2004qed_proton" ); CepGen::SF::GenericLHAPDF lux( "LUXqed17_plus_PDF4LHC15_nnlo_100" );*/ + CepGen::SF::SuriYennie sy; + CepGen::SF::SzczurekUleshchenko su; CepGen::SF::ChristyBosted cb; + CepGen::SF::ALLM allm97( CepGen::SF::ALLM::Parameterisation::allm97() ); + CepGen::SF::FioreBrasse fb; for ( unsigned int i=0; i<npoints; i++ ) { float xbj; if ( use_logarithmic_x ) { const float min_lxbj = log10( min_xbj ), max_lxbj = log10( max_xbj ); xbj = pow( 10, min_lxbj + i*( max_lxbj-min_lxbj )/( npoints-1 ) ); } else xbj = min_xbj + i*( max_xbj-min_xbj )/( npoints-1 ); - auto sf_sy = CepGen::SF::SuriYennie( q2, xbj ), - sf_fb = CepGen::SF::FioreBrasse( q2, xbj ), - sf_su = CepGen::SF::SzczurekUleshchenko( q2, xbj ), - sf_allm97 = CepGen::SF::ALLM( q2, xbj, CepGen::SF::ALLMParameterisation::allm97() ), + auto sf_sy = sy( q2, xbj ), + sf_fb = fb( q2, xbj ), + sf_su = su( q2, xbj ), + sf_allm97 = allm97( q2, xbj ), //sf_allm_hht = CepGen::SF::ALLM( q2, xbj, CepGen::SF::ALLMParameterisation::hht_allm() ), //sf_allm_hht_ft = CepGen::SF::ALLM( q2, xbj, CepGen::SF::ALLMParameterisation::hht_allm_ft() ), //sf_bdh = CepGen::SF::BlockDurandHa( q2, xbj ), //sf_cteq = cteq( q2, xbj ), //sf_mrst = mrst( q2, xbj ), //sf_lux = lux( q2, xbj ), sf_cb = cb( q2, xbj ); g_sy_f2.SetPoint( i, xbj, sf_sy.F2 ); g_fb_f2.SetPoint( i, xbj, sf_fb.F2 ); g_su_f2.SetPoint( i, xbj, sf_su.F2 ); //g_bdh_f2.SetPoint( i, xbj, sf_bdh.F2 ); //g_cteq_f2.SetPoint( i, xbj, sf_cteq.F2 ); //g_mrst_f2.SetPoint( i, xbj, sf_mrst.F2 ); //g_lux_f2.SetPoint( i, xbj, sf_lux.F2 ); g_cb_f2.SetPoint( i, xbj, sf_cb.F2 ); g_allm97_f2.SetPoint( i, xbj, sf_allm97.F2 ); //g_allm_hht_f2.SetPoint( i, xbj, sf_allm_hht.F2 ); //g_allm_hht_ft_f2.SetPoint( i, xbj, sf_allm_hht_ft.F2 ); } CepGen::Canvas c( "test", Form( "CepGen proton structure functions, Q^{2} = %s GeV^{2}", q2_str ) ); c.SetLegendX1( 0.4 ); TMultiGraph mg; /*g_sy_f2.SetLineStyle( 2 ); g_sy_f2.SetLineWidth( 3 ); mg.Add( &g_sy_f2, "l" ); - c.AddLegendEntry( &g_sy_f2, "Suri-Yennie", "l" ); + c.AddLegendEntry( &g_sy_f2, "Suri-Yennie", "l" );*/ //g_fb_f2.SetLineStyle( 2 ); g_fb_f2.SetLineColor( kRed+1 ); g_fb_f2.SetLineWidth( 3 ); mg.Add( &g_fb_f2, "l" ); c.AddLegendEntry( &g_fb_f2, "Fiore-Brasse", "l" ); //g_su_f2.SetLineStyle( 2 ); - g_su_f2.SetLineColor( kGreen+2 ); + /*g_su_f2.SetLineColor( kGreen+2 ); g_su_f2.SetLineWidth( 3 ); mg.Add( &g_su_f2, "l" ); c.AddLegendEntry( &g_su_f2, "Szczurek-Uleshchenko", "l" );*/ g_allm97_f2.SetLineColor( kBlue+1 ); g_allm97_f2.SetLineWidth( 3 ); mg.Add( &g_allm97_f2, "l" ); c.AddLegendEntry( &g_allm97_f2, "Abramowicz et al. 97", "l" ); /*g_allm_hht_f2.SetLineColor( kBlue+1 ); g_allm_hht_f2.SetLineWidth( 3 ); g_allm_hht_f2.SetLineStyle( 2 ); mg.Add( &g_allm_hht_f2, "l" ); c.AddLegendEntry( &g_allm_hht_f2, "Abramowicz et al. HHT", "l" ); g_allm_hht_ft_f2.SetLineColor( kBlue+1 ); g_allm_hht_ft_f2.SetLineWidth( 3 ); g_allm_hht_ft_f2.SetLineStyle( 3 ); mg.Add( &g_allm_hht_ft_f2, "l" ); c.AddLegendEntry( &g_allm_hht_ft_f2, "Abramowicz et al. HHT-FT", "l" );*/ g_cb_f2.SetLineColor( kMagenta ); g_cb_f2.SetLineWidth( 3 ); mg.Add( &g_cb_f2, "l" ); c.AddLegendEntry( &g_cb_f2, "Christy-Bosted", "l" ); /*g_bdh_f2.SetLineColor( kOrange ); g_bdh_f2.SetLineWidth( 3 ); mg.Add( &g_bdh_f2, "l" ); c.AddLegendEntry( &g_bdh_f2, "Block-Durand-Ha", "l" ); g_cteq_f2.SetLineColor( kMagenta ); g_cteq_f2.SetLineWidth( 3 ); mg.Add( &g_cteq_f2, "l" ); c.AddLegendEntry( &g_cteq_f2, "CTEQ6", "l" ); g_mrst_f2.SetLineColor( kMagenta+1 ); g_mrst_f2.SetLineWidth( 3 ); mg.Add( &g_mrst_f2, "l" ); c.AddLegendEntry( &g_mrst_f2, "MRST2004 (QED/proton)", "l" );*/ /*g_lux_f2.SetLineColor( kOrange ); g_lux_f2.SetLineWidth( 3 ); mg.Add( &g_lux_f2, "l" ); c.AddLegendEntry( &g_lux_f2, "LUXqed", "l" );*/ mg.Draw( "alpr" ); mg.SetTitle( "x_{Bj}\\Proton form factor F_{2}" ); c.Prettify( mg.GetHistogram() ); //mg.GetYaxis()->SetRangeUser( 1.e-10, 10. ); mg.GetYaxis()->SetRangeUser( 0., 0.8 ); mg.GetXaxis()->SetLimits( min_xbj, max_xbj ); if ( use_logarithmic_x ) c.SetLogx(); //c.SetLogy(); c.Save( "pdf" ); return 0; }