Page MenuHomeHEPForge

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/CepGen/Cards/Handler.h b/CepGen/Cards/Handler.h
index 20749c1..93b3ede 100644
--- a/CepGen/Cards/Handler.h
+++ b/CepGen/Cards/Handler.h
@@ -1,36 +1,36 @@
#ifndef CepGen_Cards_Handler_h
#define CepGen_Cards_Handler_h
#include "CepGen/Parameters.h"
-namespace CepGen
+namespace cepgen
{
class Parameters;
/// Location for all steering card parsers/writers
namespace cards
{
/// Generic steering card handler
class Handler
{
public:
/// Build a configuration from an external steering card
Handler() {}
~Handler() {}
/// Retrieve a configuration from a parsed steering cart
Parameters& parameters() { return params_; }
/// Small utility to retrieve the extension of a filename
/// (naive approach)
static std::string getExtension( const char* filename ) {
const std::string file( filename );
return file.substr( file.find_last_of( "." )+1 );
}
protected:
/// List of parameters parsed from a card handler
Parameters params_;
};
}
}
#endif
diff --git a/CepGen/Cards/LpairHandler.cpp b/CepGen/Cards/LpairHandler.cpp
index 9b886a8..2c8f24e 100644
--- a/CepGen/Cards/LpairHandler.cpp
+++ b/CepGen/Cards/LpairHandler.cpp
@@ -1,217 +1,217 @@
#include "CepGen/Cards/LpairHandler.h"
#include "CepGen/Core/ParametersList.h"
#include "CepGen/Core/Exception.h"
#include "CepGen/Physics/PDG.h"
#include "CepGen/StructureFunctions/StructureFunctions.h"
#include "CepGen/StructureFunctions/LHAPDF.h"
#include "CepGen/Processes/ProcessesHandler.h"
#include "CepGen/Hadronisers/Pythia8Hadroniser.h"
#include <fstream>
-namespace CepGen
+namespace cepgen
{
namespace cards
{
const int LpairHandler::kInvalid = 99999;
//----- specialization for LPAIR input cards
LpairHandler::LpairHandler( const char* file ) :
proc_params_( new ParametersList ),
str_fun_( 11 ), hi_1_( { 0, 0 } ), hi_2_( { 0, 0 } )
{
std::ifstream f( file, std::fstream::in );
if ( !f.is_open() )
throw CG_FATAL( "LpairHandler" ) << "Failed to parse file \"" << file << "%s\".";
init( &params_ );
//--- parse all fields
std::unordered_map<std::string, std::string> m_params;
std::string key, value;
std::ostringstream os;
while ( f >> key >> value ) {
if ( key[0] == '#' ) // FIXME need to ensure there is no extra space before!
continue;
setParameter( key, value );
m_params.insert( { key, value } );
if ( getDescription( key ) != "null" )
os << "\n>> " << key << " = " << std::setw( 15 ) << getParameter( key )
<< " (" << getDescription( key ) << ")";
}
f.close();
//--- parse the process name
- auto proc = CepGen::ProcessesHandler::get().build( proc_name_, *proc_params_ );
+ auto proc = cepgen::ProcessesHandler::get().build( proc_name_, *proc_params_ );
params_.setProcess( std::move( proc ) );
//--- parse the structure functions code
const unsigned long kLHAPDFCodeDec = 10000000, kLHAPDFPartDec = 1000000;
if ( str_fun_ / kLHAPDFCodeDec == 1 ) { // SF from parton
params_.kinematics.structure_functions = sf::Parameterisation::build( sf::Type::LHAPDF );
auto sf = dynamic_cast<sf::LHAPDF*>( params_.kinematics.structure_functions.get() );
const unsigned long icode = str_fun_ % kLHAPDFCodeDec;
sf->params.pdf_code = icode % kLHAPDFPartDec;
sf->params.mode = (sf::LHAPDF::Parameters::Mode)( icode / kLHAPDFPartDec ); // 0, 1, 2
}
else
params_.kinematics.structure_functions = sf::Parameterisation::build( (sf::Type)str_fun_ );
//--- parse the integration algorithm name
if ( integr_type_ == "plain" )
params_.integrator.type = Integrator::Type::plain;
else if ( integr_type_ == "Vegas" )
params_.integrator.type = Integrator::Type::Vegas;
else if ( integr_type_ == "MISER" )
params_.integrator.type = Integrator::Type::MISER;
else if ( integr_type_ != "" )
throw CG_FATAL( "LpairHandler" ) << "Unrecognized integrator type: " << integr_type_ << "!";
//--- parse the hadronisation algorithm name
if ( hadr_name_ == "pythia8" )
params_.setHadroniser( new hadroniser::Pythia8Hadroniser( params_, ParametersList() ) );
if ( m_params.count( "IEND" ) )
setValue<bool>( "IEND", ( std::stoi( m_params["IEND"] ) > 1 ) );
//--- check if we are dealing with heavy ions for incoming states
HeavyIon hi1{ hi_1_.first, (Element)hi_1_.second }, hi2{ hi_2_.first, (Element)hi_2_.second };
if ( hi1 )
params_.kinematics.incoming_beams.first.pdg = hi1;
if ( hi2 )
params_.kinematics.incoming_beams.second.pdg = hi2;
CG_INFO( "LpairHandler" ) << "File '" << file << "' succesfully opened!\n\t"
<< "The following parameters are set:" << os.str();
}
void
LpairHandler::init( Parameters* params )
{
//-------------------------------------------------------------------------------------------
// Process/integration/hadronisation parameters
//-------------------------------------------------------------------------------------------
registerParameter<std::string>( "PROC", "Process name to simulate", &proc_name_ );
registerParameter<std::string>( "ITYP", "Integration algorithm", &integr_type_ );
registerParameter<std::string>( "HADR", "Hadronisation algorithm", &hadr_name_ );
registerParameter<std::string>( "KMRG", "KMR grid interpolation path", &params_.kinematics.kmr_grid_path );
//-------------------------------------------------------------------------------------------
// General parameters
//-------------------------------------------------------------------------------------------
registerParameter<bool>( "IEND", "Generation type", &params->generation.enabled );
registerParameter<bool>( "NTRT", "Smoothen the integrand", &params->generation.treat );
registerParameter<int>( "DEBG", "Debugging verbosity", (int*)&Logger::get().level );
registerParameter<int>( "NCVG", "Number of function calls", (int*)&params->integrator.ncvg );
registerParameter<int>( "ITVG", "Number of integration iterations", (int*)&params->integrator.vegas.iterations );
registerParameter<int>( "SEED", "Random generator seed", (int*)&params->integrator.rng_seed );
registerParameter<int>( "NTHR", "Number of threads to use for events generation", (int*)&params->generation.num_threads );
registerParameter<int>( "MODE", "Subprocess' mode", (int*)&params->kinematics.mode );
registerParameter<int>( "NCSG", "Number of points to probe", (int*)&params->generation.num_points );
registerParameter<int>( "NGEN", "Number of events to generate", (int*)&params->generation.maxgen );
registerParameter<int>( "NPRN", "Number of events before printout", (int*)&params->generation.gen_print_every );
//-------------------------------------------------------------------------------------------
// Process-specific parameters
//-------------------------------------------------------------------------------------------
registerParameter<int>( "METH", "Computation method (kT-factorisation)", &proc_params_->operator[]<int>( "method" ) );
registerParameter<int>( "IPOL", "Polarisation states to consider", &proc_params_->operator[]<int>( "polarisationStates" ) );
//-------------------------------------------------------------------------------------------
// Process kinematics parameters
//-------------------------------------------------------------------------------------------
registerParameter<int>( "PMOD", "Outgoing primary particles' mode", &str_fun_ );
registerParameter<int>( "EMOD", "Outgoing primary particles' mode", &str_fun_ );
registerParameter<int>( "PAIR", "Outgoing particles' PDG id", (int*)&proc_params_->operator[]<int>( "pair" ) );
registerParameter<int>( "INA1", "Heavy ion atomic weight (1st incoming beam)", (int*)&hi_1_.first );
registerParameter<int>( "INZ1", "Heavy ion atomic number (1st incoming beam)", (int*)&hi_1_.second );
registerParameter<int>( "INA2", "Heavy ion atomic weight (1st incoming beam)", (int*)&hi_2_.first );
registerParameter<int>( "INZ2", "Heavy ion atomic number (1st incoming beam)", (int*)&hi_2_.second );
registerParameter<double>( "INP1", "Momentum (1st primary particle)", &params->kinematics.incoming_beams.first.pz );
registerParameter<double>( "INP2", "Momentum (2nd primary particle)", &params->kinematics.incoming_beams.second.pz );
registerParameter<double>( "INPP", "Momentum (1st primary particle)", &params->kinematics.incoming_beams.first.pz );
registerParameter<double>( "INPE", "Momentum (2nd primary particle)", &params->kinematics.incoming_beams.second.pz );
registerParameter<double>( "PTCT", "Minimal transverse momentum (single central outgoing particle)", &params->kinematics.cuts.central.pt_single.min() );
registerParameter<double>( "MSCT", "Minimal central system mass", &params->kinematics.cuts.central.mass_sum.min() );
registerParameter<double>( "ECUT", "Minimal energy (single central outgoing particle)", &params->kinematics.cuts.central.energy_single.min() );
registerParameter<double>( "ETMN", "Minimal pseudo-rapidity (central outgoing particles)", &params->kinematics.cuts.central.eta_single.min() );
registerParameter<double>( "ETMX", "Maximal pseudo-rapidity (central outgoing particles)", &params->kinematics.cuts.central.eta_single.max() );
registerParameter<double>( "YMIN", "Minimal rapidity (central outgoing particles)", &params->kinematics.cuts.central.rapidity_single.min() );
registerParameter<double>( "YMAX", "Maximal rapidity (central outgoing particles)", &params->kinematics.cuts.central.rapidity_single.max() );
registerParameter<double>( "Q2MN", "Minimal Q² = -q² (exchanged parton)", &params->kinematics.cuts.initial.q2.min() );
registerParameter<double>( "Q2MX", "Maximal Q² = -q² (exchanged parton)", &params->kinematics.cuts.initial.q2.max() );
registerParameter<double>( "MXMN", "Minimal invariant mass of proton remnants", &params->kinematics.cuts.remnants.mass_single.min() );
registerParameter<double>( "MXMX", "Maximal invariant mass of proton remnants", &params->kinematics.cuts.remnants.mass_single.max() );
}
void
LpairHandler::store( const char* file )
{
std::ofstream f( file, std::fstream::out | std::fstream::trunc );
if ( !f.is_open() ) {
CG_ERROR( "LpairHandler" ) << "Failed to open file \"" << file << "%s\" for writing.";
}
for ( const auto& it : p_strings_ )
if ( it.second.value )
f << it.first << " = " << *it.second.value << "\n";
for ( const auto& it : p_ints_ )
if ( it.second.value )
f << it.first << " = " << *it.second.value << "\n";
for ( const auto& it : p_doubles_ )
if ( it.second.value )
f << it.first << " = " << *it.second.value << "\n";
for ( const auto& it : p_bools_ )
if ( it.second.value )
f << it.first << " = " << *it.second.value << "\n";
f.close();
}
void
LpairHandler::setParameter( const std::string& key, const std::string& value )
{
try { setValue<double>( key.c_str(), std::stod( value ) ); } catch ( std::invalid_argument& ) {}
try { setValue<int>( key.c_str(), std::stoi( value ) ); } catch ( std::invalid_argument& ) {}
//setValue<bool>( key.c_str(), std::stoi( value ) );
setValue<std::string>( key.c_str(), value );
}
std::string
LpairHandler::getParameter( std::string key ) const
{
double dd = getValue<double>( key.c_str() );
if ( dd != -999. )
return std::to_string( dd );
int ui = getValue<int>( key.c_str() );
if ( ui != 999 )
return std::to_string( ui );
//if ( out = getValue<bool>( key.c_str() ) );
return getValue<std::string>( key.c_str() );
}
std::string
LpairHandler::getDescription( std::string key ) const
{
if ( p_strings_.count( key ) )
return p_strings_.find( key )->second.description;
if ( p_ints_.count( key ) )
return p_ints_.find( key )->second.description;
if ( p_doubles_.count( key ) )
return p_doubles_.find( key )->second.description;
if ( p_bools_.count( key ) )
return p_bools_.find( key )->second.description;
return "null";
}
}
}
diff --git a/CepGen/Cards/LpairHandler.h b/CepGen/Cards/LpairHandler.h
index bd5fc89..e256eba 100644
--- a/CepGen/Cards/LpairHandler.h
+++ b/CepGen/Cards/LpairHandler.h
@@ -1,114 +1,114 @@
#ifndef CepGen_Cards_LpairReader_h
#define CepGen_Cards_LpairReader_h
#include "CepGen/Cards/Handler.h"
#include <unordered_map>
using std::string;
-namespace CepGen
+namespace cepgen
{
class ParametersList;
namespace cards
{
/// LPAIR-like steering cards parser and writer
class LpairHandler : public Handler
{
public:
/// Read a LPAIR steering card
explicit LpairHandler( const char* file );
/// Store a configuration into a LPAIR steering card
void store( const char* file );
private:
template<class T> struct Parameter {
Parameter( const char* key, const char* descr, T* value ) : key( key ), description( descr ), value( value ) {}
std::string key, description;
T* value;
};
/// Register a parameter to be steered to a configuration variable
template<class T> void registerParameter( const char* key, const char* description, T* def ) {}
/// Set a parameter value
template<class T> void setValue( const char* key, const T& value ) {}
/// Retrieve a parameter value
template<class T> T getValue( const char* key ) const {}
void setParameter( const std::string& key, const std::string& value );
std::string getParameter( std::string key ) const;
std::string getDescription( std::string key ) const;
static const int kInvalid;
std::unordered_map<std::string, Parameter<std::string> > p_strings_;
std::unordered_map<std::string, Parameter<double> > p_doubles_;
std::unordered_map<std::string, Parameter<int> > p_ints_;
std::unordered_map<std::string, Parameter<bool> > p_bools_;
void init( Parameters* );
std::shared_ptr<ParametersList> proc_params_;
int str_fun_;
std::string proc_name_, hadr_name_, integr_type_;
std::pair<unsigned short,unsigned short> hi_1_, hi_2_;
};
//----- specialised registerers
/// Register a string parameter
template<> inline void LpairHandler::registerParameter<std::string>( const char* key, const char* description, std::string* def ) { p_strings_.insert( std::make_pair( key, Parameter<std::string>( key, description, def ) ) ); }
/// Register a double floating point parameter
template<> inline void LpairHandler::registerParameter<double>( const char* key, const char* description, double* def ) { p_doubles_.insert( std::make_pair( key, Parameter<double>( key, description, def ) ) ); }
/// Register an integer parameter
template<> inline void LpairHandler::registerParameter<int>( const char* key, const char* description, int* def ) { p_ints_.insert( std::make_pair( key, Parameter<int>( key, description, def ) ) ); }
/// Register a boolean parameter
template<> inline void LpairHandler::registerParameter<bool>( const char* key, const char* description, bool* def ) { p_bools_.insert( std::make_pair( key, Parameter<bool>( key, description, def ) ) ); }
//----- specialised setters
template<> inline void LpairHandler::setValue<std::string>( const char* key, const std::string& value ) {
auto it = p_strings_.find( key );
if ( it != p_strings_.end() ) *it->second.value = value;
}
template<> inline void LpairHandler::setValue<double>( const char* key, const double& value ) {
auto it = p_doubles_.find( key );
if ( it != p_doubles_.end() ) *it->second.value = value;
}
template<> inline void LpairHandler::setValue<int>( const char* key, const int& value ) {
auto it = p_ints_.find( key );
if ( it != p_ints_.end() ) *it->second.value = value;
}
template<> inline void LpairHandler::setValue<bool>( const char* key, const bool& value ) {
auto it = p_bools_.find( key );
if ( it != p_bools_.end() ) *it->second.value = value;
}
//----- specialised getters
/// Retrieve a string parameter value
template<> inline std::string LpairHandler::getValue( const char* key ) const {
const auto& it = p_strings_.find( key );
if ( it != p_strings_.end() ) return *it->second.value;
return "null";
}
/// Retrieve a floating point parameter value
template<> inline double LpairHandler::getValue( const char* key ) const {
const auto& it = p_doubles_.find( key );
if ( it != p_doubles_.end() ) return *it->second.value;
return -999.;
}
/// Retrieve an integer parameter value
template<> inline int LpairHandler::getValue( const char* key ) const {
const auto& it = p_ints_.find( key );
if ( it != p_ints_.end() ) return *it->second.value;
return 999;
}
/// Retrieve a boolean parameter value
template<> inline bool LpairHandler::getValue( const char* key ) const {
const auto& it = p_bools_.find( key );
if ( it != p_bools_.end() ) return *it->second.value;
return true;
}
}
}
#endif
diff --git a/CepGen/Cards/PythonHandler.cpp b/CepGen/Cards/PythonHandler.cpp
index a31b208..e461569 100644
--- a/CepGen/Cards/PythonHandler.cpp
+++ b/CepGen/Cards/PythonHandler.cpp
@@ -1,404 +1,404 @@
#include "CepGen/Cards/PythonHandler.h"
#include "CepGen/Core/Exception.h"
#ifdef PYTHON
#include "CepGen/Core/TamingFunction.h"
#include "CepGen/Core/Exception.h"
#include "CepGen/Core/ParametersList.h"
#include "CepGen/Processes/ProcessesHandler.h"
#include "CepGen/StructureFunctions/StructureFunctions.h"
#include "CepGen/StructureFunctions/LHAPDF.h"
#include "CepGen/StructureFunctions/MSTWGrid.h"
#include "CepGen/StructureFunctions/Schaefer.h"
#include "CepGen/Hadronisers/Pythia8Hadroniser.h"
#include <algorithm>
#if PY_MAJOR_VERSION < 3
# define PYTHON2
#endif
-namespace CepGen
+namespace cepgen
{
namespace cards
{
//----- specialization for CepGen input cards
PythonHandler::PythonHandler( const char* file )
{
setenv( "PYTHONPATH", ".:..:Cards", 1 );
std::string filename = getPythonPath( file );
const size_t fn_len = filename.length()+1;
//Py_DebugFlag = 1;
//Py_VerboseFlag = 1;
#ifdef PYTHON2
char* sfilename = new char[fn_len];
snprintf( sfilename, fn_len, "%s", filename.c_str() );
#else
wchar_t* sfilename = new wchar_t[fn_len];
swprintf( sfilename, fn_len, L"%s", filename.c_str() );
#endif
if ( sfilename )
Py_SetProgramName( sfilename );
Py_InitializeEx( 1 );
if ( sfilename )
delete [] sfilename;
if ( !Py_IsInitialized() )
throw CG_FATAL( "PythonHandler" ) << "Failed to initialise the Python cards parser!";
CG_INFO( "PythonHandler" )
<< "Initialised the Python cards parser\n\t"
<< "Python version: " << Py_GetVersion() << "\n\t"
<< "Platform: " << Py_GetPlatform() << ".";
PyObject* cfg = PyImport_ImportModule( filename.c_str() ); // new
if ( !cfg )
throwPythonError( Form( "Failed to parse the configuration card %s", file ) );
PyObject* process = PyObject_GetAttrString( cfg, PROCESS_NAME ); // new
if ( !process )
throwPythonError( Form( "Failed to extract a \"%s\" keyword from the configuration card %s", PROCESS_NAME, file ) );
//--- list of process-specific parameters
ParametersList proc_params;
fillParameter( process, "processParameters", proc_params );
//--- type of process to consider
PyObject* pproc_name = getElement( process, MODULE_NAME ); // borrowed
if ( !pproc_name )
throwPythonError( Form( "Failed to extract the process name from the configuration card %s", file ) );
const std::string proc_name = get<std::string>( pproc_name );
//--- process mode
params_.kinematics.mode = (KinematicsMode)proc_params.get<int>( "mode", (int)KinematicsMode::invalid );
- auto proc = CepGen::ProcessesHandler::get().build( proc_name, proc_params );
+ auto proc = cepgen::ProcessesHandler::get().build( proc_name, proc_params );
params_.setProcess( std::move( proc ) );
//--- process kinematics
PyObject* pin_kinematics = getElement( process, "inKinematics" ); // borrowed
if ( pin_kinematics )
parseIncomingKinematics( pin_kinematics );
PyObject* pout_kinematics = getElement( process, "outKinematics" ); // borrowed
if ( pout_kinematics )
parseOutgoingKinematics( pout_kinematics );
//--- taming functions
PyObject* ptam = getElement( process, "tamingFunctions" ); // borrowed
if ( ptam )
parseTamingFunctions( ptam );
Py_CLEAR( process );
PyObject* plog = PyObject_GetAttrString( cfg, "logger" ); // new
if ( plog ) {
parseLogging( plog );
Py_CLEAR( plog );
}
//--- hadroniser parameters
PyObject* phad = PyObject_GetAttrString( cfg, "hadroniser" ); // new
if ( phad ) {
parseHadroniser( phad );
Py_CLEAR( phad );
}
//--- generation parameters
PyObject* pint = PyObject_GetAttrString( cfg, "integrator" ); // new
if ( pint ) {
parseIntegrator( pint );
Py_CLEAR( pint );
}
PyObject* pgen = PyObject_GetAttrString( cfg, "generator" ); // new
if ( pgen ) {
parseGenerator( pgen );
Py_CLEAR( pgen );
}
//--- finalisation
Py_CLEAR( cfg );
}
PythonHandler::~PythonHandler()
{
if ( Py_IsInitialized() )
Py_Finalize();
}
void
PythonHandler::parseIncomingKinematics( PyObject* kin )
{
//--- retrieve the beams PDG ids
std::vector<double> beams_pz;
fillParameter( kin, "pz", beams_pz );
if ( beams_pz.size() == 2 ) {
params_.kinematics.incoming_beams.first.pz = beams_pz.at( 0 );
params_.kinematics.incoming_beams.second.pz = beams_pz.at( 1 );
}
//--- retrieve the beams longitudinal momentum
std::vector<int> beams_pdg;
fillParameter( kin, "pdgIds", beams_pdg );
if ( beams_pdg.size() == 2 ) {
params_.kinematics.incoming_beams.first.pdg = (PDG)beams_pdg.at( 0 );
params_.kinematics.incoming_beams.second.pdg = (PDG)beams_pdg.at( 1 );
}
double sqrt_s = -1.;
fillParameter( kin, "cmEnergy", sqrt_s );
fillParameter( kin, "kmrGridPath", params_.kinematics.kmr_grid_path );
if ( sqrt_s != -1. )
params_.kinematics.setSqrtS( sqrt_s );
PyObject* psf = getElement( kin, "structureFunctions" ); // borrowed
if ( psf )
parseStructureFunctions( psf, params_.kinematics.structure_functions );
std::vector<int> kt_fluxes;
fillParameter( kin, "ktFluxes", kt_fluxes );
if ( kt_fluxes.size() > 0 )
params_.kinematics.incoming_beams.first.kt_flux = (KTFlux)kt_fluxes.at( 0 );
if ( kt_fluxes.size() > 1 )
params_.kinematics.incoming_beams.second.kt_flux = (KTFlux)kt_fluxes.at( 1 );
std::vector<int> hi_beam1, hi_beam2;
fillParameter( kin, "heavyIonA", hi_beam1 );
if ( hi_beam1.size() == 2 )
params_.kinematics.incoming_beams.first.pdg = HeavyIon{ (unsigned short)hi_beam1[0], (Element)hi_beam1[1] };
fillParameter( kin, "heavyIonB", hi_beam2 );
if ( hi_beam2.size() == 2 )
params_.kinematics.incoming_beams.second.pdg = HeavyIon{ (unsigned short)hi_beam2[0], (Element)hi_beam2[1] };
}
void
PythonHandler::parseStructureFunctions( PyObject* psf, std::shared_ptr<sf::Parameterisation>& sf_handler )
{
int str_fun = 0;
fillParameter( psf, "id", str_fun );
sf_handler = sf::Parameterisation::build( (sf::Type)str_fun );
switch( (sf::Type)str_fun ) {
case sf::Type::LHAPDF: {
auto sf = std::dynamic_pointer_cast<sf::LHAPDF>( params_.kinematics.structure_functions );
fillParameter( psf, "pdfSet", sf->params.pdf_set );
fillParameter( psf, "numFlavours", (unsigned int&)sf->params.num_flavours );
fillParameter( psf, "pdfMember", (unsigned int&)sf->params.pdf_member );
fillParameter( psf, "mode", (unsigned int&)sf->params.mode );
} break;
case sf::Type::MSTWgrid: {
auto sf = std::dynamic_pointer_cast<mstw::Grid>( params_.kinematics.structure_functions );
fillParameter( psf, "gridPath", sf->params.grid_path );
} break;
case sf::Type::Schaefer: {
auto sf = std::dynamic_pointer_cast<sf::Schaefer>( params_.kinematics.structure_functions );
fillParameter( psf, "Q2cut", sf->params.q2_cut );
std::vector<double> w2_lims;
fillParameter( psf, "W2limits", w2_lims );
if ( w2_lims.size() != 0 ) {
if ( w2_lims.size() != 2 )
throwPythonError( Form( "Invalid size for W2limits attribute: %d != 2!", w2_lims.size() ) );
else {
sf->params.w2_lo = *std::min_element( w2_lims.begin(), w2_lims.end() );
sf->params.w2_hi = *std::max_element( w2_lims.begin(), w2_lims.end() );
}
}
PyObject* pcsf = getElement( psf, "continuumSF" ); // borrowed
if ( pcsf )
parseStructureFunctions( pcsf, sf->params.continuum_model );
PyObject* ppsf = getElement( psf, "perturbativeSF" ); // borrowed
if ( ppsf )
parseStructureFunctions( ppsf, sf->params.perturbative_model );
PyObject* prsf = getElement( psf, "resonancesSF" ); // borrowed
if ( prsf )
parseStructureFunctions( prsf, sf->params.resonances_model );
fillParameter( psf, "higherTwist", (bool&)sf->params.higher_twist );
} break;
default: break;
}
}
void
PythonHandler::parseOutgoingKinematics( PyObject* kin )
{
PyObject* pparts = getElement( kin, "minFinalState" ); // borrowed
if ( pparts && PyTuple_Check( pparts ) )
for ( unsigned short i = 0; i < PyTuple_Size( pparts ); ++i )
params_.kinematics.minimum_final_state.emplace_back( (PDG)get<int>( PyTuple_GetItem( pparts, i ) ) );
PyObject* pcuts = getElement( kin, "cuts" ); // borrowed
if ( pcuts )
parseParticlesCuts( pcuts );
// for LPAIR/collinear matrix elements
fillLimits( kin, "q2", params_.kinematics.cuts.initial.q2 );
// for the kT factorised matrix elements
fillLimits( kin, "qt", params_.kinematics.cuts.initial.qt );
fillLimits( kin, "phiqt", params_.kinematics.cuts.initial.phi_qt );
fillLimits( kin, "ptdiff", params_.kinematics.cuts.central.pt_diff );
fillLimits( kin, "phiptdiff", params_.kinematics.cuts.central.phi_pt_diff );
fillLimits( kin, "rapiditydiff", params_.kinematics.cuts.central.rapidity_diff );
// generic phase space limits
fillLimits( kin, "rapidity", params_.kinematics.cuts.central.rapidity_single );
fillLimits( kin, "eta", params_.kinematics.cuts.central.eta_single );
fillLimits( kin, "pt", params_.kinematics.cuts.central.pt_single );
fillLimits( kin, "ptsum", params_.kinematics.cuts.central.pt_sum );
fillLimits( kin, "invmass", params_.kinematics.cuts.central.mass_sum );
fillLimits( kin, "mx", params_.kinematics.cuts.remnants.mass_single );
}
void
PythonHandler::parseParticlesCuts( PyObject* cuts )
{
if ( !PyDict_Check( cuts ) )
throwPythonError( "Particle cuts object should be a dictionary!" );
PyObject* pkey = nullptr, *pvalue = nullptr;
Py_ssize_t pos = 0;
while ( PyDict_Next( cuts, &pos, &pkey, &pvalue ) ) {
const PDG pdg = (PDG)get<int>( pkey );
fillLimits( pvalue, "pt", params_.kinematics.cuts.central_particles[pdg].pt_single );
fillLimits( pvalue, "energy", params_.kinematics.cuts.central_particles[pdg].energy_single );
fillLimits( pvalue, "eta", params_.kinematics.cuts.central_particles[pdg].eta_single );
fillLimits( pvalue, "rapidity", params_.kinematics.cuts.central_particles[pdg].rapidity_single );
}
}
void
PythonHandler::parseLogging( PyObject* log )
{
fillParameter( log, "level", (int&)Logger::get().level );
std::vector<std::string> enabled_modules;
fillParameter( log, "enabledModules", enabled_modules );
for ( const auto& mod : enabled_modules )
Logger::get().addExceptionRule( mod );
}
void
PythonHandler::parseIntegrator( PyObject* integr )
{
if ( !PyDict_Check( integr ) )
throwPythonError( "Integrator object should be a dictionary!" );
PyObject* palgo = getElement( integr, MODULE_NAME ); // borrowed
if ( !palgo )
throwPythonError( "Failed to retrieve the integration algorithm name!" );
std::string algo = get<std::string>( palgo );
if ( algo == "plain" )
params_.integrator.type = Integrator::Type::plain;
else if ( algo == "Vegas" ) {
params_.integrator.type = Integrator::Type::Vegas;
fillParameter( integr, "alpha", (double&)params_.integrator.vegas.alpha );
fillParameter( integr, "iterations", params_.integrator.vegas.iterations );
fillParameter( integr, "mode", (int&)params_.integrator.vegas.mode );
fillParameter( integr, "verbosity", (int&)params_.integrator.vegas.verbose );
std::string vegas_logging_output = "cerr";
fillParameter( integr, "loggingOutput", vegas_logging_output );
if ( vegas_logging_output == "cerr" )
// redirect all debugging information to the error stream
params_.integrator.vegas.ostream = stderr;
else if ( vegas_logging_output == "cout" )
// redirect all debugging information to the standard stream
params_.integrator.vegas.ostream = stdout;
else
params_.integrator.vegas.ostream = fopen( vegas_logging_output.c_str(), "w" );
}
else if ( algo == "MISER" ) {
params_.integrator.type = Integrator::Type::MISER;
fillParameter( integr, "estimateFraction", (double&)params_.integrator.miser.estimate_frac );
fillParameter( integr, "minCalls", params_.integrator.miser.min_calls );
fillParameter( integr, "minCallsPerBisection", params_.integrator.miser.min_calls_per_bisection );
fillParameter( integr, "alpha", (double&)params_.integrator.miser.alpha );
fillParameter( integr, "dither", (double&)params_.integrator.miser.dither );
}
else
throwPythonError( Form( "Invalid integration algorithm: %s", algo.c_str() ) );
fillParameter( integr, "numFunctionCalls", params_.integrator.ncvg );
fillParameter( integr, "seed", (unsigned long&)params_.integrator.rng_seed );
unsigned int rng_engine;
fillParameter( integr, "rngEngine", rng_engine );
switch ( rng_engine ) {
case 0: default: params_.integrator.rng_engine = (gsl_rng_type*)gsl_rng_mt19937; break;
case 1: params_.integrator.rng_engine = (gsl_rng_type*)gsl_rng_taus2; break;
case 2: params_.integrator.rng_engine = (gsl_rng_type*)gsl_rng_gfsr4; break;
case 3: params_.integrator.rng_engine = (gsl_rng_type*)gsl_rng_ranlxs0; break;
}
fillParameter( integr, "chiSqCut", params_.integrator.vegas_chisq_cut );
}
void
PythonHandler::parseGenerator( PyObject* gen )
{
if ( !PyDict_Check( gen ) )
throwPythonError( "Generation information object should be a dictionary!" );
params_.generation.enabled = true;
fillParameter( gen, "treat", params_.generation.treat );
fillParameter( gen, "numEvents", params_.generation.maxgen );
fillParameter( gen, "printEvery", params_.generation.gen_print_every );
fillParameter( gen, "numThreads", params_.generation.num_threads );
fillParameter( gen, "numPoints", params_.generation.num_points );
}
void
PythonHandler::parseTamingFunctions( PyObject* tf )
{
if ( !PyList_Check( tf ) )
throwPythonError( "Taming functions list should be a list!" );
for ( Py_ssize_t i = 0; i < PyList_Size( tf ); ++i ) {
PyObject* pit = PyList_GetItem( tf, i ); // borrowed
if ( !pit )
continue;
if ( !PyDict_Check( pit ) )
throwPythonError( Form( "Item %d has invalid type %s", i, pit->ob_type->tp_name ) );
PyObject* pvar = getElement( pit, "variable" ), *pexpr = getElement( pit, "expression" ); // borrowed
params_.taming_functions->add( get<std::string>( pvar ).c_str(), get<std::string>( pexpr ).c_str() );
}
}
void
PythonHandler::parseHadroniser( PyObject* hadr )
{
if ( !PyDict_Check( hadr ) )
throwPythonError( "Hadroniser object should be a dictionary!" );
PyObject* pname = getElement( hadr, MODULE_NAME ); // borrowed
if ( !pname )
throwPythonError( "Hadroniser name is required!" );
std::string hadr_name = get<std::string>( pname );
//--- list of module-specific parameters
ParametersList mod_params;
fillParameter( hadr, "moduleParameters", mod_params );
if ( hadr_name == "pythia8" )
params_.setHadroniser( new hadroniser::Pythia8Hadroniser( params_, mod_params ) );
else
throwPythonError( Form( "Unrecognised hadronisation algorithm: \"%s\"!", hadr_name.c_str() ) );
auto h = params_.hadroniser();
{ //--- before calling the init() method
std::vector<std::string> config;
fillParameter( hadr, "preConfiguration", config );
h->readStrings( config );
}
h->init();
{ //--- after init() has been called
std::vector<std::string> config;
fillParameter( hadr, "processConfiguration", config );
for ( const auto& block : config ) {
std::vector<std::string> config_blk;
fillParameter( hadr, block.c_str(), config_blk );
h->readStrings( config_blk );
}
}
}
}
}
#endif
diff --git a/CepGen/Cards/PythonHandler.h b/CepGen/Cards/PythonHandler.h
index 272a230..dc79e6e 100644
--- a/CepGen/Cards/PythonHandler.h
+++ b/CepGen/Cards/PythonHandler.h
@@ -1,71 +1,71 @@
#ifndef CepGen_Cards_PythonHandler_h
#define CepGen_Cards_PythonHandler_h
#ifdef PYTHON
#include <Python.h>
#include "Handler.h"
-namespace CepGen
+namespace cepgen
{
namespace sf { class Parameterisation; }
class ParametersList;
namespace cards
{
/// CepGen Python configuration cards reader/writer
class PythonHandler : public Handler
{
public:
/// Read a standard configuration card
explicit PythonHandler( const char* file );
~PythonHandler();
static PyObject* getElement( PyObject* obj, const char* key );
static PyObject* encode( const char* str );
private:
static constexpr const char* MODULE_NAME = "mod_name";
static constexpr const char* PROCESS_NAME = "process";
static void throwPythonError( const std::string& message );
static std::string getPythonPath( const char* file );
template<typename T> bool is( PyObject* obj ) const;
template<typename T> T get( PyObject* obj ) const;
void fillLimits( PyObject* obj, const char* key, Limits& lim );
void fillParameter( PyObject* parent, const char* key, bool& out );
void fillParameter( PyObject* parent, const char* key, int& out );
void fillParameter( PyObject* parent, const char* key, unsigned long& out );
void fillParameter( PyObject* parent, const char* key, unsigned int& out );
void fillParameter( PyObject* parent, const char* key, double& out );
void fillParameter( PyObject* parent, const char* key, std::string& out );
void fillParameter( PyObject* parent, const char* key, std::vector<int>& out );
void fillParameter( PyObject* parent, const char* key, std::vector<double>& out );
void fillParameter( PyObject* parent, const char* key, std::vector<std::string>& out );
void fillParameter( PyObject* parent, const char* key, ParametersList& out );
void parseIncomingKinematics( PyObject* );
void parseOutgoingKinematics( PyObject* );
void parseParticlesCuts( PyObject* );
void parseLogging( PyObject* );
void parseIntegrator( PyObject* );
void parseGenerator( PyObject* );
void parseTamingFunctions( PyObject* );
void parseHadroniser( PyObject* );
void parseStructureFunctions( PyObject*, std::shared_ptr<sf::Parameterisation>& sf_handler );
};
template<> bool PythonHandler::is<int>( PyObject* obj ) const;
template<> int PythonHandler::get<int>( PyObject* obj ) const;
template<> unsigned long PythonHandler::get<unsigned long>( PyObject* obj ) const;
template<> bool PythonHandler::is<ParametersList>( PyObject* obj ) const;
template<> ParametersList PythonHandler::get<ParametersList>( PyObject* obj ) const;
template<> bool PythonHandler::is<double>( PyObject* obj ) const;
template<> double PythonHandler::get<double>( PyObject* obj ) const;
template<> bool PythonHandler::is<std::string>( PyObject* obj ) const;
template<> std::string PythonHandler::get<std::string>( PyObject* obj ) const;
}
}
#endif
#endif
diff --git a/CepGen/Cards/PythonTypes.cpp b/CepGen/Cards/PythonTypes.cpp
index ed2bde2..6be29d7 100644
--- a/CepGen/Cards/PythonTypes.cpp
+++ b/CepGen/Cards/PythonTypes.cpp
@@ -1,170 +1,170 @@
#include "CepGen/Cards/PythonHandler.h"
#include "CepGen/Core/ParametersList.h"
#include "CepGen/Core/utils.h"
#ifdef PYTHON
#if PY_MAJOR_VERSION < 3
# define PYTHON2
#endif
-namespace CepGen
+namespace cepgen
{
namespace cards
{
//------------------------------------------------------------------
// typed retrieval helpers
//------------------------------------------------------------------
template<> bool
PythonHandler::is<int>( PyObject* obj ) const
{
#ifdef PYTHON2
return ( PyInt_Check( obj ) || PyBool_Check( obj ) );
#else
return ( PyLong_Check( obj ) || PyBool_Check( obj ) );
#endif
}
template<> int
PythonHandler::get<int>( PyObject* obj ) const
{
#ifdef PYTHON2
return PyInt_AsLong( obj );
#else
return PyLong_AsLong( obj );
#endif
}
template<> unsigned long
PythonHandler::get<unsigned long>( PyObject* obj ) const
{
#ifdef PYTHON2
return PyInt_AsUnsignedLongMask( obj );
#else
if ( !PyLong_Check( obj ) )
throwPythonError( Form( "Object \"%s\" has invalid type %s", key, obj->ob_type->tp_name ) );
return PyLong_AsUnsignedLong( obj );
#endif
}
template<> long long
PythonHandler::get<long long>( PyObject* obj ) const
{
return PyLong_AsLongLong( obj );
}
template<> bool
PythonHandler::is<double>( PyObject* obj ) const
{
return PyFloat_Check( obj );
}
template<> double
PythonHandler::get<double>( PyObject* obj ) const
{
return PyFloat_AsDouble( obj );
}
template<> bool
PythonHandler::is<std::string>( PyObject* obj ) const
{
#ifdef PYTHON2
return PyString_Check( obj );
#else
return PyUnicode_Check( obj );
#endif
}
template<> std::string
PythonHandler::get<std::string>( PyObject* obj ) const
{
std::string out;
#ifdef PYTHON2
out = PyString_AsString( obj ); // deprecated in python v3+
#else
PyObject* pstr = PyUnicode_AsEncodedString( obj, "utf-8", "strict" ); // new
if ( !pstr )
throwPythonError( "Failed to decode a Python object!" );
out = PyBytes_AS_STRING( pstr );
Py_CLEAR( pstr );
#endif
return out;
}
template<> bool
PythonHandler::is<ParametersList>( PyObject* obj ) const
{
return PyDict_Check( obj );
}
template<> ParametersList
PythonHandler::get<ParametersList>( PyObject* obj ) const
{
ParametersList out;
PyObject* pkey = nullptr, *pvalue = nullptr;
Py_ssize_t pos = 0;
while ( PyDict_Next( obj, &pos, &pkey, &pvalue ) ) {
const std::string skey = get<std::string>( pkey );
if ( is<int>( pvalue ) )
out.set<int>( skey, get<int>( pvalue ) );
else if ( is<double>( pvalue ) )
out.set<double>( skey, get<double>( pvalue ) );
else if ( is<std::string>( pvalue ) )
out.set<std::string>( skey, get<std::string>( pvalue ) );
else if ( is<ParametersList>( pvalue ) )
out.set<ParametersList>( skey, get<ParametersList>( pvalue ) );
else if ( PyTuple_Check( pvalue ) || PyList_Check( pvalue ) ) { // vector
PyObject* pfirst = PyTuple_GetItem( pvalue, 0 );
PyObject* pit = nullptr;
const bool tuple = PyTuple_Check( pvalue );
const Py_ssize_t num_entries = ( tuple )
? PyTuple_Size( pvalue )
: PyList_Size( pvalue );
if ( is<int>( pfirst ) ) {
std::vector<int> vec;
for ( Py_ssize_t i = 0; i < num_entries; ++i ) {
pit = ( tuple ) ? PyTuple_GetItem( pvalue, i ) : PyList_GetItem( pvalue, i );
if ( pit->ob_type != pfirst->ob_type )
throwPythonError( Form( "Mixed types detected in vector '%s'", skey.c_str() ) );
vec.emplace_back( get<int>( pit ) );
}
out.set<std::vector<int> >( skey, vec );
}
else if ( is<double>( pfirst ) ) {
std::vector<double> vec;
for ( Py_ssize_t i = 0; i < num_entries; ++i ) {
pit = ( tuple ) ? PyTuple_GetItem( pvalue, i ) : PyList_GetItem( pvalue, i );
if ( pit->ob_type != pfirst->ob_type )
throwPythonError( Form( "Mixed types detected in vector '%s'", skey.c_str() ) );
vec.emplace_back( get<double>( pit ) );
}
out.set<std::vector<double> >( skey, vec );
}
else if ( is<std::string>( pfirst ) ) {
std::vector<std::string> vec;
for ( Py_ssize_t i = 0; i < num_entries; ++i ) {
pit = ( tuple ) ? PyTuple_GetItem( pvalue, i ) : PyList_GetItem( pvalue, i );
if ( pit->ob_type != pfirst->ob_type )
throwPythonError( Form( "Mixed types detected in vector '%s'", skey.c_str() ) );
vec.emplace_back( get<std::string>( pit ) );
}
out.set<std::vector<std::string> >( skey, vec );
}
else if ( is<ParametersList>( pfirst ) ) {
std::vector<ParametersList> vec;
for ( Py_ssize_t i = 0; i < num_entries; ++i ) {
pit = ( tuple ) ? PyTuple_GetItem( pvalue, i ) : PyList_GetItem( pvalue, i );
if ( pit->ob_type != pfirst->ob_type )
throwPythonError( Form( "Mixed types detected in vector '%s'", skey.c_str() ) );
vec.emplace_back( get<ParametersList>( pit ) );
}
out.set<std::vector<ParametersList> >( skey, vec );
}
}
}
return out;
}
}
}
#endif
diff --git a/CepGen/Cards/PythonUtils.cpp b/CepGen/Cards/PythonUtils.cpp
index 32bca15..0960d92 100644
--- a/CepGen/Cards/PythonUtils.cpp
+++ b/CepGen/Cards/PythonUtils.cpp
@@ -1,251 +1,251 @@
#include "CepGen/Cards/PythonHandler.h"
#include "CepGen/Core/ParametersList.h"
#include "CepGen/Core/Exception.h"
#include "CepGen/Core/utils.h"
#ifdef PYTHON
#include <string>
#include <algorithm>
#include <frameobject.h>
#if PY_MAJOR_VERSION < 3
# define PYTHON2
#endif
-namespace CepGen
+namespace cepgen
{
namespace cards
{
//------------------------------------------------------------------
// Python API helpers
//------------------------------------------------------------------
std::string
PythonHandler::getPythonPath( const char* file )
{
std::string s_filename = file;
s_filename = s_filename.substr( 0, s_filename.find_last_of( "." ) ); // remove the extension
std::replace( s_filename.begin(), s_filename.end(), '/', '.' ); // replace all '/' by '.'
return s_filename;
}
void
PythonHandler::throwPythonError( const std::string& message )
{
PyObject* ptype = nullptr, *pvalue = nullptr, *ptraceback_obj = nullptr;
// retrieve error indicator and clear it to handle ourself the error
PyErr_Fetch( &ptype, &pvalue, &ptraceback_obj );
PyErr_Clear();
// ensure the objects retrieved are properly normalised and point to compatible objects
PyErr_NormalizeException( &ptype, &pvalue, &ptraceback_obj );
std::ostringstream oss; oss << message;
if ( ptype != nullptr ) { // we can start the traceback
oss << "\n\tError: "
#ifdef PYTHON2
<< PyString_AsString( PyObject_Str( pvalue ) ); // deprecated in python v3+
#else
<< PyUnicode_AsUTF8( PyObject_Str( pvalue ) );
#endif
PyTracebackObject* ptraceback = (PyTracebackObject*)ptraceback_obj;
std::string tabul = "↪ ";
if ( ptraceback != nullptr ) {
while ( ptraceback->tb_next != nullptr ) {
PyFrameObject* pframe = ptraceback->tb_frame;
if ( pframe != nullptr ) {
int line = PyCode_Addr2Line( pframe->f_code, pframe->f_lasti );
#ifdef PYTHON2
const char* filename = PyString_AsString( pframe->f_code->co_filename );
const char* funcname = PyString_AsString( pframe->f_code->co_name );
#else
const char* filename = PyUnicode_AsUTF8( pframe->f_code->co_filename );
const char* funcname = PyUnicode_AsUTF8( pframe->f_code->co_name );
#endif
oss << Form( "\n\t%s%s on %s (line %d)", tabul.c_str(), boldify( funcname ).c_str(), filename, line );
}
else
oss << Form( "\n\t%s issue in line %d", tabul.c_str(), ptraceback->tb_lineno );
tabul = std::string( " " )+tabul;
ptraceback = ptraceback->tb_next;
}
}
}
Py_Finalize();
throw CG_FATAL( "PythonHandler:error" ) << oss.str();
}
PyObject*
PythonHandler::encode( const char* str )
{
PyObject* obj = PyUnicode_FromString( str ); // new
if ( !obj )
throwPythonError( Form( "Failed to encode the following string:\n\t%s", str ) );
return obj;
}
PyObject*
PythonHandler::getElement( PyObject* obj, const char* key )
{
PyObject* pout = nullptr, *nink = encode( key );
if ( !nink )
return pout;
pout = PyDict_GetItem( obj, nink ); // borrowed
Py_CLEAR( nink );
if ( pout )
CG_DEBUG( "PythonHandler:getElement" )
<< "retrieved " << pout->ob_type->tp_name << " element \"" << key << "\" "
<< "from " << obj->ob_type->tp_name << " object\n\t"
<< "new reference count: " << pout->ob_refcnt;
else
CG_DEBUG( "PythonHandler:getElement" )
<< "did not retrieve a valid element \"" << key << "\"";
return pout;
}
void
PythonHandler::fillLimits( PyObject* obj, const char* key, Limits& lim )
{
PyObject* pobj = getElement( obj, key ); // borrowed
if ( !pobj )
return;
if ( !PyTuple_Check( pobj ) )
throw CG_FATAL( "PythonHandler:fillLimits" ) << "Invalid value retrieved for " << key << ".";
if ( PyTuple_Size( pobj ) < 1 )
throw CG_FATAL( "PythonHandler:fillLimits" ) << "Invalid number of values unpacked for " << key << "!";
double min = get<double>( PyTuple_GetItem( pobj, 0 ) );
lim.min() = min;
if ( PyTuple_Size( pobj ) > 1 ) {
double max = get<double>( PyTuple_GetItem( pobj, 1 ) );
if ( max != -1 )
lim.max() = max;
}
}
void
PythonHandler::fillParameter( PyObject* parent, const char* key, bool& out )
{
PyObject* pobj = getElement( parent, key ); // borrowed
if ( !pobj )
return;
if ( !PyBool_Check( pobj ) )
throwPythonError( Form( "Object \"%s\" has invalid type %s", key, pobj->ob_type->tp_name ) );
fillParameter( parent, key, (int&)out );
}
void
PythonHandler::fillParameter( PyObject* parent, const char* key, int& out )
{
PyObject* pobj = getElement( parent, key ); // borrowed
if ( !pobj )
return;
if ( !is<int>( pobj ) )
throwPythonError( Form( "Object \"%s\" has invalid type %s", key, pobj->ob_type->tp_name ) );
out = get<int>( pobj );
}
void
PythonHandler::fillParameter( PyObject* parent, const char* key, unsigned long& out )
{
PyObject* pobj = getElement( parent, key ); // borrowed
if ( !pobj )
return;
if ( !is<int>( pobj ) )
throwPythonError( Form( "Object \"%s\" has invalid type %s", key, pobj->ob_type->tp_name ) );
out = get<unsigned long>( pobj );
}
void
PythonHandler::fillParameter( PyObject* parent, const char* key, unsigned int& out )
{
PyObject* pobj = getElement( parent, key ); // borrowed
if ( !pobj )
return;
if ( !is<int>( pobj ) )
throwPythonError( Form( "Object \"%s\" has invalid type %s", key, pobj->ob_type->tp_name ) );
out = get<unsigned long>( pobj );
}
void
PythonHandler::fillParameter( PyObject* parent, const char* key, double& out )
{
PyObject* pobj = getElement( parent, key ); // borrowed
if ( !pobj )
return;
if ( !is<double>( pobj ) )
throwPythonError( Form( "Object \"%s\" has invalid type %s", key, pobj->ob_type->tp_name ) );
out = get<double>( pobj );
}
void
PythonHandler::fillParameter( PyObject* parent, const char* key, std::string& out )
{
PyObject* pobj = getElement( parent, key ); // borrowed
if ( !pobj )
return;
if ( !is<std::string>( pobj ) )
throwPythonError( Form( "Object \"%s\" has invalid type %s", key, pobj->ob_type->tp_name ) );
out = get<std::string>( pobj );
}
void
PythonHandler::fillParameter( PyObject* parent, const char* key, std::vector<double>& out )
{
out.clear();
PyObject* pobj = getElement( parent, key ); // borrowed
if ( !pobj )
return;
if ( !PyTuple_Check( pobj ) )
throwPythonError( Form( "Object \"%s\" has invalid type %s", key, pobj->ob_type->tp_name ) );
for ( Py_ssize_t i = 0; i < PyTuple_Size( pobj ); ++i ) {
PyObject* pit = PyTuple_GetItem( pobj, i ); // borrowed
if ( is<double>( pit ) )
out.emplace_back( get<double>( pit ) );
}
}
void
PythonHandler::fillParameter( PyObject* parent, const char* key, std::vector<std::string>& out )
{
out.clear();
PyObject* pobj = getElement( parent, key ); // borrowed
if ( !pobj )
return;
if ( !PyTuple_Check( pobj ) )
throwPythonError( Form( "Object \"%s\" has invalid type %s", key, pobj->ob_type->tp_name ) );
for ( Py_ssize_t i = 0; i < PyTuple_Size( pobj ); ++i ) {
PyObject* pit = PyTuple_GetItem( pobj, i ); // borrowed
out.emplace_back( get<std::string>( pit ) );
}
}
void
PythonHandler::fillParameter( PyObject* parent, const char* key, std::vector<int>& out )
{
out.clear();
PyObject* pobj = getElement( parent, key ); // borrowed
if ( !pobj )
return;
if ( !PyTuple_Check( pobj ) )
throwPythonError( Form( "Object \"%s\" has invalid type", key ) );
for ( Py_ssize_t i = 0; i < PyTuple_Size( pobj ); ++i ) {
PyObject* pit = PyTuple_GetItem( pobj, i );
if ( !is<int>( pit ) )
throwPythonError( Form( "Object %d has invalid type", i ) );
out.emplace_back( get<int>( pit ) );
}
}
void
PythonHandler::fillParameter( PyObject* parent, const char* key, ParametersList& out )
{
PyObject* pobj = getElement( parent, key ); // borrowed
if ( !pobj )
return;
if ( !PyDict_Check( pobj ) )
throwPythonError( Form( "Object \"%s\" has invalid type", key ) );
out += get<ParametersList>( pobj );
}
}
}
#endif
diff --git a/CepGen/Core/Exception.h b/CepGen/Core/Exception.h
index 38e0e0f..5963765 100644
--- a/CepGen/Core/Exception.h
+++ b/CepGen/Core/Exception.h
@@ -1,194 +1,194 @@
#ifndef CepGen_Core_Exception_h
#define CepGen_Core_Exception_h
#include <sstream>
#include <stdexcept>
#include <csignal>
#include "CepGen/Core/Logger.h"
#define CG_EXCEPT_MATCH( str, type ) \
- CepGen::Logger::get().passExceptionRule( str, CepGen::Logger::Level::type )
+ cepgen::Logger::get().passExceptionRule( str, cepgen::Logger::Level::type )
#define CG_LOG( mod ) \
( !CG_EXCEPT_MATCH( mod, information ) ) \
- ? CepGen::NullStream( mod ) \
- : CepGen::Exception( __PRETTY_FUNCTION__, mod, CepGen::Exception::Type::verbatim )
+ ? cepgen::NullStream( mod ) \
+ : cepgen::Exception( __PRETTY_FUNCTION__, mod, cepgen::Exception::Type::verbatim )
#define CG_INFO( mod ) \
( !CG_EXCEPT_MATCH( mod, information ) ) \
- ? CepGen::NullStream( mod ) \
- : CepGen::Exception( __PRETTY_FUNCTION__, mod, CepGen::Exception::Type::info )
+ ? cepgen::NullStream( mod ) \
+ : cepgen::Exception( __PRETTY_FUNCTION__, mod, cepgen::Exception::Type::info )
#define CG_DEBUG( mod ) \
( !CG_EXCEPT_MATCH( mod, debug ) ) \
- ? CepGen::NullStream( mod ) \
- : CepGen::Exception( __PRETTY_FUNCTION__, mod, CepGen::Exception::Type::debug )
+ ? cepgen::NullStream( mod ) \
+ : cepgen::Exception( __PRETTY_FUNCTION__, mod, cepgen::Exception::Type::debug )
#define CG_DEBUG_LOOP( mod ) \
( !CG_EXCEPT_MATCH( mod, debugInsideLoop ) ) \
- ? CepGen::NullStream( mod ) \
- : CepGen::Exception( __PRETTY_FUNCTION__, mod, CepGen::Exception::Type::debug )
+ ? cepgen::NullStream( mod ) \
+ : cepgen::Exception( __PRETTY_FUNCTION__, mod, cepgen::Exception::Type::debug )
#define CG_WARNING( mod ) \
( !CG_EXCEPT_MATCH( mod, warning ) ) \
- ? CepGen::NullStream( mod ) \
- : CepGen::Exception( __PRETTY_FUNCTION__, mod, CepGen::Exception::Type::warning )
+ ? cepgen::NullStream( mod ) \
+ : cepgen::Exception( __PRETTY_FUNCTION__, mod, cepgen::Exception::Type::warning )
#define CG_ERROR( mod ) \
( !CG_EXCEPT_MATCH( mod, error ) ) \
- ? CepGen::NullStream( mod ) \
- : CepGen::Exception( __PRETTY_FUNCTION__, mod, CepGen::Exception::Type::warning )
+ ? cepgen::NullStream( mod ) \
+ : cepgen::Exception( __PRETTY_FUNCTION__, mod, cepgen::Exception::Type::warning )
#define CG_FATAL( mod ) \
- CepGen::Exception( __PRETTY_FUNCTION__, mod, CepGen::Exception::Type::fatal )
+ cepgen::Exception( __PRETTY_FUNCTION__, mod, cepgen::Exception::Type::fatal )
-namespace CepGen
+namespace cepgen
{
/// \brief A simple exception handler
/// \author Laurent Forthomme <laurent.forthomme@cern.ch>
/// \date 24 Mar 2015
class Exception : public std::exception
{
public:
/// Enumeration of exception severities
/// \author Laurent Forthomme <laurent.forthomme@cern.ch>
/// \date 27 Mar 2015
enum class Type {
undefined = -1, debug, verbatim, info, warning, error, fatal };
/// Generic constructor
/// \param[in] module exception classifier
/// \param[in] type exception type
/// \param[in] id exception code (useful for logging)
explicit inline Exception( const char* module = "", Type type = Type::undefined, const int id = 0 ) :
module_( module ), type_( type ), error_num_( id ) {}
/// Generic constructor
/// \param[in] from method invoking the exception
/// \param[in] module exception classifier
/// \param[in] type exception type
/// \param[in] id exception code (useful for logging)
explicit inline Exception( const char* from, const char* module, Type type = Type::undefined, const int id = 0 ) :
from_( from ), module_( module ), type_( type ), error_num_( id ) {}
/// Generic constructor
/// \param[in] from method invoking the exception
/// \param[in] module exception classifier
/// \param[in] type exception type
/// \param[in] id exception code (useful for logging)
explicit inline Exception( const char* from, const std::string& module, Type type = Type::undefined, const int id = 0 ) :
from_( from ), module_( module ), type_( type ), error_num_( id ) {}
/// Copy constructor
inline Exception( const Exception& rhs ) :
from_( rhs.from_ ), module_( rhs.module_ ), message_( rhs.message_.str() ), type_( rhs.type_ ), error_num_( rhs.error_num_ ) {}
/// Default destructor (potentially killing the process)
inline ~Exception() noexcept override {
do { dump(); } while ( 0 );
// we stop this process' execution on fatal exception
if ( type_ == Type::fatal )
if ( raise( SIGINT ) != 0 )
exit( 0 );
}
//----- Overloaded stream operators
/// Generic templated message feeder operator
template<typename T>
inline friend const Exception& operator<<( const Exception& exc, T var ) {
Exception& nc_except = const_cast<Exception&>( exc );
nc_except.message_ << var;
return exc;
}
/// Pipe modifier operator
inline friend const Exception& operator<<( const Exception& exc, std::ios_base&( *f )( std::ios_base& ) ) {
Exception& nc_except = const_cast<Exception&>( exc );
f( nc_except.message_ );
return exc;
}
/// Exception message
/*inline const char* what() const noexcept override {
return message_.str().c_str();
}*/
/// Extract the origin of the exception
inline std::string from() const { return from_; }
/// Extract the exception code
inline int errorNumber() const { return error_num_; }
/// Extract the exception type
inline Type type() const { return type_; }
/// Extract a human-readable (and colourified) version of the exception type
inline std::string typeString() const {
switch ( type() ) {
case Type::warning: return "\033[34;1mWarning\033[0m";
case Type::info: return "\033[32;1mInfo.\033[0m";
case Type::debug: return "\033[33;1mDebug\033[0m";
case Type::error: return "\033[31;1mError\033[0m";
case Type::fatal: return "\033[31;1mFatal\033[0m";
case Type::undefined: default: return "\33[7;1mUndefined\033[0m";
}
}
/// Dump the full exception information in a given output stream
/// \param[inout] os the output stream where the information is dumped
inline void dump( std::ostream& os = *Logger::get().output ) const {
os << fullMessage() << std::endl;
}
/// Extract a one-line summary of the exception
inline std::string shortMessage() const {
std::ostringstream os;
os << "[" << typeString() << "]";
if ( type_ == Type::debug || type_ == Type::warning )
os << " \033[30;4m" << from_ << "\033[0m\n";
os << "\t" << message_.str();
return os.str();
}
private:
inline static char* now() {
static char buffer[10];
time_t rawtime;
time( &rawtime );
struct tm* timeinfo = localtime( &rawtime );
strftime( buffer, 10, "%H:%M:%S", timeinfo );
return buffer;
}
/// Extract a full exception message
inline std::string fullMessage() const {
if ( type_ == Type::info || type_ == Type::debug || type_ == Type::warning )
return shortMessage();
if ( type_ == Type::verbatim )
return message_.str();
std::ostringstream os;
os << "============================= Exception detected! =============================" << std::endl
<< " Class: " << typeString() << std::endl;
if ( !from_.empty() )
os << " Raised by: " << from_ << std::endl;
os << " Description: \t" << message_.str() << std::endl;
if ( errorNumber() != 0 )
os << "-------------------------------------------------------------------------------" << std::endl
<< " Error #" << error_num_ << std::endl;
os << "===============================================================================";
return os.str();
}
/// Origin of the exception
std::string from_;
/// Exception classificator
std::string module_;
/// Message to throw
std::ostringstream message_;
/// Exception type
Type type_;
/// Integer exception number
int error_num_;
};
/// \brief Placeholder for debugging messages if logging threshold is not reached
/// \date Apr 2018
struct NullStream
{
/// Construct from a module name
explicit NullStream( const char* ) {}
/// Construct from a module name
explicit NullStream( const std::string& ) {}
/// Copy constructor
NullStream( const Exception& ) {}
/// Stream operator (null and void)
template<class T> NullStream& operator<<( const T& ) { return *this; }
};
}
#endif
diff --git a/CepGen/Core/FortranInterface.cpp b/CepGen/Core/FortranInterface.cpp
index b02d21b..3a6cebe 100644
--- a/CepGen/Core/FortranInterface.cpp
+++ b/CepGen/Core/FortranInterface.cpp
@@ -1,66 +1,66 @@
#include "CepGen/StructureFunctions/StructureFunctions.h"
#include "CepGen/Physics/KTFlux.h"
#include "CepGen/Physics/HeavyIon.h"
#include "CepGen/Physics/ParticleProperties.h"
#include "CepGen/Core/Exception.h"
#ifdef __cplusplus
extern "C" {
#endif
/// Expose structure functions calculators to Fortran
void
cepgen_structure_functions_( int& sfmode, double& xbj, double& q2, double& f2, double& fl )
{
- using namespace CepGen;
+ using namespace cepgen;
sf::Type sf_mode = (sf::Type)sfmode;
CG_DEBUG( "cepgen_structure_functions" ) << sf_mode;
static auto& val = sf::Parameterisation::build( sf_mode )->operator()( xbj, q2 );
f2 = val.F2;
fl = val.FL;
}
double
cepgen_kt_flux_( int& fmode, double& x, double& kt2, int& sfmode, double& mx )
{
- using namespace CepGen;
+ using namespace cepgen;
static auto sf = sf::Parameterisation::build( (sf::Type)sfmode );
return ktFlux(
(KTFlux)fmode, x, kt2, *sf, mx );
}
double
cepgen_kt_flux_hi_( int& fmode, double& x, double& kt2, int& a, int& z )
{
- using namespace CepGen;
+ using namespace cepgen;
return ktFlux(
(KTFlux)fmode, x, kt2, HeavyIon{ (unsigned short)a, (Element)z } );
}
double
cepgen_particle_mass_( int& pdg_id )
{
try {
- return CepGen::part::mass( (CepGen::PDG)pdg_id );
- } catch ( const CepGen::Exception& e ) {
+ return cepgen::particleproperties::mass( (cepgen::PDG)pdg_id );
+ } catch ( const cepgen::Exception& e ) {
e.dump();
exit( 0 );
}
}
double
cepgen_particle_charge_( int& pdg_id )
{
try {
- return CepGen::part::charge( pdg_id );
- } catch ( const CepGen::Exception& e ) {
+ return cepgen::particleproperties::charge( pdg_id );
+ } catch ( const cepgen::Exception& e ) {
e.dump();
exit( 0 );
}
}
#ifdef __cplusplus
}
#endif
diff --git a/CepGen/Core/Functional.h b/CepGen/Core/Functional.h
index 5068313..47349f7 100644
--- a/CepGen/Core/Functional.h
+++ b/CepGen/Core/Functional.h
@@ -1,99 +1,99 @@
#ifndef CepGen_Core_Functional_h
#define CepGen_Core_Functional_h
#include <vector>
#include <array>
#include "CepGen/Core/utils.h"
#include "CepGen/Core/Exception.h"
#ifdef MUPARSER
#include <muParser.h>
#endif
using std::string;
-namespace CepGen
+namespace cepgen
{
/// \brief A string-to-functional parser
/// \tparam N Number of arguments
/// \author L. Forthomme <laurent.forthomme@cern.ch>
/// \date 21 Aug 2017
template<size_t N>
class Functional
{
public:
/// Default constructor
Functional() {}
/// Copy constructor
Functional( const Functional& rhs )
#ifdef MUPARSER
: values_( rhs.values_ ), vars_( rhs.vars_ ), expression_( rhs.expression_ ) {
for ( unsigned short i = 0; i < vars_.size(); ++i ) {
parser_.DefineVar( vars_[i], &values_[i] );
}
parser_.SetExpr( expression_ );
}
#else
{}
#endif
/// Build a parser from an expression and a variables list
/// \param[in] expr Expression to parse
/// \param[in] vars List of variables to parse
Functional( const std::string& expr, const std::array<std::string,N>& vars ) : vars_( vars ), expression_( expr ) {
#ifdef MUPARSER
try {
for ( unsigned short i = 0; i < vars_.size(); ++i ) {
parser_.DefineVar( vars_[i], &values_[i] );
}
parser_.SetExpr( expr );
} catch ( const mu::Parser::exception_type& e ) {
std::ostringstream os; for ( unsigned short i = 0; i < e.GetPos(); ++i ) os << "-"; os << "^";
throw CG_WARNING( "Functional" )
<< "Failed to define the function\n\t"
<< expression_ << "\n\t"
<< os.str() << "\n\t"
<< e.GetMsg();
}
#else
throw CG_FATAL( "Functional" ) << "muParser is not linked to this program! the math evaluator is hence disabled!";
#endif
}
/// Compute the functional for a given value of the variable (N=1 case)
/// \param[in] x Variable value
double eval( double x ) const {
static_assert( N == 1, "This function only works with single-dimensional functions" );
return eval( std::array<double,1>{ { x } } );
}
/// Compute the functional for a given value of the variables
/// \param[in] x Variables values
double eval( const std::array<double,N>& x ) const {
double ret = 0.0;
#ifdef MUPARSER
values_ = x;
try { ret = parser_.Eval(); } catch ( const mu::Parser::exception_type& e ) {
std::ostringstream os; for ( unsigned short i = 0; i < e.GetPos(); ++i ) os << "-"; os << "^";
throw CG_WARNING( "Functional" )
<< "Failed to evaluate the function\n\t"
<< expression_ << "\n\t"
<< os.str() << "\n\t"
<< e.GetMsg();
}
#else
throw CG_FATAL( "Functional" ) << "muParser is not linked to this program! the math evaluator is hence disabled!";
#endif
return ret;
}
/// Reference to the expression to be parsed
//const std::string& expression() { return parser_.expression(); }
private:
#ifdef MUPARSER
mu::Parser parser_;
mutable std::array<double,N> values_;
#endif
std::array<std::string,N> vars_;
std::string expression_;
};
}
#endif
diff --git a/CepGen/Core/Generator.cpp b/CepGen/Core/Generator.cpp
index d132743..63f4ce4 100644
--- a/CepGen/Core/Generator.cpp
+++ b/CepGen/Core/Generator.cpp
@@ -1,170 +1,170 @@
#include "CepGen/Generator.h"
#include "CepGen/Parameters.h"
#include "CepGen/Version.h"
#include "CepGen/Core/Integrator.h"
#include "CepGen/Core/Exception.h"
#include "CepGen/Core/Timer.h"
#include "CepGen/Physics/PDG.h"
#include "CepGen/Processes/GenericProcess.h"
#include "CepGen/Event/Event.h"
#include <fstream>
#include <chrono>
-namespace CepGen
+namespace cepgen
{
volatile int gSignal;
Generator::Generator() :
parameters( std::unique_ptr<Parameters>( new Parameters ) ), result_( -1. ), result_error_( -1. )
{
CG_DEBUG( "Generator:init" ) << "Generator initialized";
try {
printHeader();
} catch ( Exception& e ) {
e.dump();
}
// Random number initialization
std::chrono::system_clock::time_point time = std::chrono::system_clock::now();
srandom( time.time_since_epoch().count() );
}
Generator::Generator( Parameters* ip ) :
parameters( ip ), result_( -1. ), result_error_( -1. )
{}
Generator::~Generator()
{
if ( parameters->generation.enabled
&& parameters->process() && parameters->numGeneratedEvents() > 0 ) {
CG_INFO( "Generator" )
<< "Mean generation time / event: "
<< parameters->totalGenerationTime()*1.e3/parameters->numGeneratedEvents()
<< " ms.";
}
}
size_t
Generator::numDimensions() const
{
if ( !parameters->process() )
return 0;
parameters->process()->addEventContent();
parameters->process()->setKinematics( parameters->kinematics );
return parameters->process()->numDimensions();
}
void
Generator::clearRun()
{
integrator_.reset();
parameters->process()->first_run = true;
result_ = result_error_ = -1.;
}
void
Generator::setParameters( Parameters& ip )
{
parameters = std::unique_ptr<Parameters>( new Parameters( ip ) ); // copy constructor
}
void
Generator::printHeader()
{
std::string tmp;
std::ostringstream os; os << "version " << version() << std::endl;
std::ifstream hf( "README" );
if ( !hf.good() )
throw CG_WARNING( "Generator" ) << "Failed to open README file.";
while ( true ) {
if ( !hf.good() ) break;
getline( hf, tmp );
os << "\n " << tmp;
}
hf.close();
CG_INFO( "Generator" ) << os.str();
}
double
Generator::computePoint( double* x )
{
double res = integrand::eval( x, numDimensions(), (void*)parameters.get() );
std::ostringstream os;
for ( unsigned int i = 0; i < numDimensions(); ++i )
os << x[i] << " ";
CG_DEBUG( "Generator:computePoint" )
<< "Result for x[" << numDimensions() << "] = { " << os.str() << "}:\n\t"
<< res << ".";
return res;
}
void
Generator::computeXsection( double& xsec, double& err )
{
CG_INFO( "Generator" ) << "Starting the computation of the process cross-section.";
integrate();
xsec = result_;
err = result_error_;
if ( xsec < 1.e-2 )
CG_INFO( "Generator" )
<< "Total cross section: " << xsec*1.e3 << " +/- " << err*1.e3 << " fb.";
else if ( xsec > 5.e2 )
CG_INFO( "Generator" )
<< "Total cross section: " << xsec*1.e-3 << " +/- " << err*1.e-3 << " nb.";
else
CG_INFO( "Generator" )
<< "Total cross section: " << xsec << " +/- " << err << " pb.";
}
void
Generator::integrate()
{
// first destroy and recreate the integrator instance
if ( !integrator_ )
integrator_ = std::unique_ptr<Integrator>( new Integrator( numDimensions(), integrand::eval, parameters.get() ) );
else if ( integrator_->dimensions() != numDimensions() )
integrator_.reset( new Integrator( numDimensions(), integrand::eval, parameters.get() ) );
CG_DEBUG( "Generator:newInstance" )
<< "New integrator instance created\n\t"
<< "Considered topology: " << parameters->kinematics.mode << " case\n\t"
<< "Will proceed with " << numDimensions() << "-dimensional integration.";
const int res = integrator_->integrate( result_, result_error_ );
if ( res != 0 )
throw CG_FATAL( "Generator" )
<< "Error while computing the cross-section!\n\t"
<< "GSL error: " << gsl_strerror( res ) << ".";
}
std::shared_ptr<Event>
Generator::generateOneEvent()
{
integrator_->generateOne();
parameters->addGenerationTime( parameters->process()->last_event->time_total );
return parameters->process()->last_event;
}
void
Generator::generate( std::function<void( const Event&, unsigned long )> callback )
{
const Timer tmr;
CG_INFO( "Generator" )
<< parameters->generation.maxgen << " events will be generated.";
integrator_->generate( parameters->generation.maxgen, callback, &tmr );
const double gen_time_s = tmr.elapsed();
CG_INFO( "Generator" )
<< parameters->generation.ngen << " events generated "
<< "in " << gen_time_s << " s "
<< "(" << gen_time_s/parameters->generation.ngen*1.e3 << " ms/event).";
}
}
diff --git a/CepGen/Core/GridParameters.cpp b/CepGen/Core/GridParameters.cpp
index f35a775..e2c02ef 100644
--- a/CepGen/Core/GridParameters.cpp
+++ b/CepGen/Core/GridParameters.cpp
@@ -1,15 +1,15 @@
#include "CepGen/Core/GridParameters.h"
#include "CepGen/Core/Exception.h"
-namespace CepGen
+namespace cepgen
{
const unsigned short GridParameters::max_dimensions_ = 15;
const unsigned short GridParameters::mbin_ = 3;
const double GridParameters::inv_mbin_ = 1./mbin_;
GridParameters::GridParameters() :
max( 0 ), gen_prepared( false ),
correc( 0. ), correc2( 0. ),
f_max_global( 0. ), f_max2( 0. ), f_max_diff( 0. ), f_max_old( 0. )
{}
}
diff --git a/CepGen/Core/GridParameters.h b/CepGen/Core/GridParameters.h
index 098efa9..56a54aa 100644
--- a/CepGen/Core/GridParameters.h
+++ b/CepGen/Core/GridParameters.h
@@ -1,40 +1,40 @@
#ifndef CepGen_Core_GridParameters_h
#define CepGen_Core_GridParameters_h
#include <vector>
#include <map>
-namespace CepGen
+namespace cepgen
{
/// A parameters placeholder for the grid integration helper
class GridParameters
{
public:
/// Maximal number of dimensions handled by this integrator instance
static const unsigned short max_dimensions_;
/// Integration grid size parameter
static const unsigned short mbin_;
static const double inv_mbin_;
GridParameters();
std::map<unsigned int,std::vector<unsigned short> > n_map;
unsigned int max;
/// Has the generation been prepared?
bool gen_prepared;
double correc;
double correc2;
/// Maximal value of the function at one given point
std::vector<double> f_max;
/// Maximal value of the function in the considered integration range
double f_max_global;
double f_max2;
double f_max_diff;
double f_max_old;
std::vector<unsigned int> num;
};
}
#endif
diff --git a/CepGen/Core/Hasher.h b/CepGen/Core/Hasher.h
index 6dba163..d4c1149 100644
--- a/CepGen/Core/Hasher.h
+++ b/CepGen/Core/Hasher.h
@@ -1,37 +1,37 @@
#ifndef CepGen_Core_Hasher_h
#define CepGen_Core_Hasher_h
#include <cstddef>
#include <functional>
-namespace CepGen
+namespace cepgen
{
/// A hasher table for a given structure
template<class T,bool>
struct hasher
{
inline size_t operator()( const T& t ) const {
return std::hash<T>()( t );
}
};
/// A hasher table for a given structure
template<class T>
struct hasher<T, true>
{
inline size_t operator() ( const T& t ) {
typedef typename std::underlying_type<T>::type enumType;
return std::hash<enumType>()( static_cast<enumType>( t ) );
}
};
/// A hasher table for an enumeration
template<class T>
struct EnumHash
{
inline size_t operator()( const T& t ) const {
return hasher<T,std::is_enum<T>::value>()( t );
}
};
}
#endif
diff --git a/CepGen/Core/Integrand.cpp b/CepGen/Core/Integrand.cpp
index f73e8fb..d805b05 100644
--- a/CepGen/Core/Integrand.cpp
+++ b/CepGen/Core/Integrand.cpp
@@ -1,201 +1,201 @@
#include "CepGen/Core/Timer.h"
#include "CepGen/Core/Exception.h"
#include "CepGen/Core/TamingFunction.h"
#include "CepGen/Event/Event.h"
#include "CepGen/Event/Particle.h"
#include "CepGen/Physics/Kinematics.h"
#include "CepGen/Physics/PDG.h"
#include "CepGen/Processes/GenericProcess.h"
#include "CepGen/Hadronisers/GenericHadroniser.h"
#include "CepGen/Parameters.h"
#include <sstream>
#include <fstream>
-namespace CepGen
+namespace cepgen
{
namespace integrand
{
Logger::Level log_level;
Timer tmr;
double
eval( double* x, size_t ndim, void* params )
{
log_level = Logger::get().level;
std::shared_ptr<Event> ev;
Parameters* p = static_cast<Parameters*>( params );
if ( !p )
throw CG_FATAL( "Integrand" ) << "Failed to retrieve the run parameters!";
process::GenericProcess* proc = p->process();
if ( !proc )
throw CG_FATAL( "Integrand" ) << "Failed to retrieve the process!";
//=============================================================================================
// start the timer
//=============================================================================================
tmr.reset();
//=============================================================================================
// prepare the event content prior to the process generation
//=============================================================================================
if ( proc->hasEvent() ) {
ev = proc->event();
if ( proc->first_run ) {
CG_DEBUG( "Integrand" )
<< "Computation launched for " << p->processName() << " process "
<< "0x" << std::hex << p->process() << std::dec << ".\n\t"
<< "Process mode considered: " << p->kinematics.mode << "\n\t"
<< " pz(p1) = " << p->kinematics.incoming_beams.first.pz << "\n\t"
<< " pz(p2) = " << p->kinematics.incoming_beams.second.pz << "\n\t"
<< " structure functions: " << p->kinematics.structure_functions;
p->clearRunStatistics();
proc->first_run = false;
} // passed the first-run preparation
proc->clearEvent();
} // event is not empty
//=============================================================================================
// specify the phase space point to probe
//=============================================================================================
proc->setPoint( ndim, x );
//=============================================================================================
// from this step on, the phase space point is supposed to be set
//=============================================================================================
p->process()->beforeComputeWeight();
double integrand = p->process()->computeWeight();
//=============================================================================================
// invalidate any unphysical behaviour
//=============================================================================================
if ( integrand <= 0. )
return 0.;
//=============================================================================================
// speed up the integration process if no event needs to be generated
//=============================================================================================
if ( !p->storage()
&& !p->taming_functions
&& !p->hadroniser()
&& p->kinematics.cuts.central_particles.size() == 0 )
return integrand;
//=============================================================================================
// fill in the process' Event object
//=============================================================================================
p->process()->fillKinematics();
//=============================================================================================
// once the kinematics variables have been populated, can apply the collection of taming functions
//=============================================================================================
if ( p->taming_functions ) {
if ( p->taming_functions->has( "m_central" )
|| p->taming_functions->has( "pt_central" ) ) {
// build the kinematics of the central system
Particle::Momentum central_system;
for ( const auto& part : ev->getByRole( Particle::CentralSystem ) )
central_system += part.momentum();
// tame the cross-section by the reweighting function
if ( p->taming_functions->has( "m_central" ) )
integrand *= p->taming_functions->eval( "m_central", central_system.mass() );
if ( p->taming_functions->has( "pt_central" ) )
integrand *= p->taming_functions->eval( "pt_central", central_system.pt() );
}
if ( p->taming_functions->has( "q2" ) ) {
integrand *= p->taming_functions->eval( "q2", -ev->getOneByRole( Particle::Parton1 ).momentum().mass() );
integrand *= p->taming_functions->eval( "q2", -ev->getOneByRole( Particle::Parton2 ).momentum().mass() );
}
}
if ( integrand <= 0. )
return 0.;
//=============================================================================================
// set the CepGen part of the event generation
//=============================================================================================
if ( p->storage() )
ev->time_generation = tmr.elapsed();
//=============================================================================================
// event hadronisation and resonances decay
//=============================================================================================
if ( p->hadroniser() ) {
double br = -1.;
if ( !p->hadroniser()->run( *ev, br, p->storage() ) || br == 0. )
return 0.;
integrand *= br; // branching fraction for all decays
}
//=============================================================================================
// apply cuts on final state system (after hadronisation!)
// (watch out your cuts, as this might be extremely time-consuming...)
//=============================================================================================
if ( p->kinematics.cuts.central_particles.size() > 0 ) {
for ( const auto& part : ev->getByRole( Particle::CentralSystem ) ) {
// retrieve all cuts associated to this final state particle
if ( p->kinematics.cuts.central_particles.count( part.pdgId() ) == 0 )
continue;
const auto& cuts_pdgid = p->kinematics.cuts.central_particles.at( part.pdgId() );
// apply these cuts on the given particle
if ( !cuts_pdgid.pt_single.passes( part.momentum().pt() ) )
return 0.;
if ( !cuts_pdgid.energy_single.passes( part.momentum().energy() ) )
return 0.;
if ( !cuts_pdgid.eta_single.passes( part.momentum().eta() ) )
return 0.;
if ( !cuts_pdgid.rapidity_single.passes( part.momentum().rapidity() ) )
return 0.;
}
}
//=============================================================================================
// store the last event in the parameters for its usage by the end user
//=============================================================================================
if ( p->storage() ) {
p->process()->last_event = ev;
p->process()->last_event->time_total = tmr.elapsed();
CG_DEBUG( "Integrand" )
<< "[process 0x" << std::hex << p->process() << std::dec << "] "
<< "Individual time (gen+hadr+cuts): " << p->process()->last_event->time_total*1.e3 << " ms";
}
//=============================================================================================
// a bit of useful debugging
//=============================================================================================
if ( CG_EXCEPT_MATCH( "Integrand", debugInsideLoop ) ) {
std::ostringstream oss;
for ( unsigned short i = 0; i < ndim; ++i )
oss << Form( "%10.8f ", x[i] );
CG_DEBUG( "Integrand" )
<< "f value for dim-" << ndim << " point ( " << oss.str() << "): "
<< integrand;
}
return integrand;
}
}
}
diff --git a/CepGen/Core/Integrator.cpp b/CepGen/Core/Integrator.cpp
index 5929c10..220df77 100644
--- a/CepGen/Core/Integrator.cpp
+++ b/CepGen/Core/Integrator.cpp
@@ -1,502 +1,502 @@
#include "CepGen/Core/Integrator.h"
#include "CepGen/Core/GridParameters.h"
#include "CepGen/Core/utils.h"
#include "CepGen/Core/Exception.h"
#include "CepGen/Parameters.h"
#include "CepGen/Processes/GenericProcess.h"
#include "CepGen/Hadronisers/GenericHadroniser.h"
#include "CepGen/Event/Event.h"
#include <thread>
#include <math.h>
#include <gsl/gsl_monte_miser.h>
#define COORD(s,i,j) ((s)->xi[(i)*(s)->dim + (j)])
-namespace CepGen
+namespace cepgen
{
Integrator::Integrator( unsigned int ndim, double integrand( double*, size_t, void* ), Parameters* params ) :
ps_bin_( 0 ), input_params_( params ),
function_( new gsl_monte_function{ integrand, ndim, (void*)input_params_ } ),
rng_( gsl_rng_alloc( input_params_->integrator.rng_engine ), gsl_rng_free ),
grid_( new GridParameters ), r_boxes_( 0 )
{
//--- initialise the random number generator
unsigned long seed = ( input_params_->integrator.rng_seed > 0 )
? input_params_->integrator.rng_seed
: time( nullptr ); // seed with time
gsl_rng_set( rng_.get(), seed );
//--- a bit of printout for debugging
CG_DEBUG( "Integrator:build" )
<< "Number of integration dimensions: " << function_->dim << ",\n\t"
<< "Number of function calls: " << input_params_->integrator.ncvg << ",\n\t"
<< "Random numbers generator: " << gsl_rng_name( rng_.get() ) << ".";
switch ( input_params_->integrator.type ) {
case Type::Vegas:
CG_DEBUG( "Integrator:build" ) << "Vegas parameters:\n\t"
<< "Number of iterations in Vegas: " << input_params_->integrator.vegas.iterations << ",\n\t"
<< "α-value: " << input_params_->integrator.vegas.alpha << ",\n\t"
<< "Verbosity: " << input_params_->integrator.vegas.verbose << ",\n\t"
<< "Grid interpolation mode: " << (Integrator::VegasMode)input_params_->integrator.vegas.mode << ".";
break;
case Type::MISER:
CG_DEBUG( "Integrator:build" ) << "MISER parameters:\n\t"
<< "Number of calls: " << input_params_->integrator.miser.min_calls << ", "
<< "per bisection: " << input_params_->integrator.miser.min_calls_per_bisection << ",\n\t"
<< "Estimate fraction: " << input_params_->integrator.miser.estimate_frac << ",\n\t"
<< "α-value: " << input_params_->integrator.miser.alpha << ",\n\t"
<< "Dither: " << input_params_->integrator.miser.dither << ".";
break;
case Type::plain:
break;
}
}
Integrator::~Integrator()
{}
//-----------------------------------------------------------------------------------------------
// cross section computation part
//-----------------------------------------------------------------------------------------------
int
Integrator::integrate( double& result, double& abserr )
{
int res = -1;
//--- integration bounds
std::vector<double> x_low( function_->dim, 0. ), x_up( function_->dim, 1. );
//--- launch integration
switch ( input_params_->integrator.type ) {
case Type::plain: {
std::unique_ptr<gsl_monte_plain_state,void(*)( gsl_monte_plain_state* )>
pln_state( gsl_monte_plain_alloc( function_->dim ), gsl_monte_plain_free );
res = gsl_monte_plain_integrate( function_.get(),
&x_low[0], &x_up[0],
function_->dim, input_params_->integrator.ncvg,
rng_.get(), pln_state.get(),
&result, &abserr );
} break;
case Type::Vegas: {
//----- warmup (prepare the grid)
res = warmupVegas( x_low, x_up, 25000 );
//----- integration
unsigned short it_chisq = 0;
do {
res = gsl_monte_vegas_integrate( function_.get(),
&x_low[0], &x_up[0],
function_->dim, 0.2 * input_params_->integrator.ncvg,
rng_.get(), veg_state_.get(),
&result, &abserr );
CG_LOG( "Integrator:integrate" )
<< "\t>> at call " << ( ++it_chisq ) << ": "
<< Form( "average = %10.6f "
"sigma = %10.6f chi2 = %4.3f.",
result, abserr,
gsl_monte_vegas_chisq( veg_state_.get() ) );
} while ( fabs( gsl_monte_vegas_chisq( veg_state_.get() )-1. )
> input_params_->integrator.vegas_chisq_cut-1. );
CG_DEBUG( "Integrator:integrate" )
<< "Vegas grid information:\n\t"
<< "ran for " << veg_state_->dim << " dimensions, and generated " << veg_state_->bins_max << " bins.\n\t"
<< "Integration volume: " << veg_state_->vol << ".";
r_boxes_ = std::pow( veg_state_->bins, function_->dim );
} break;
case Type::MISER: {
std::unique_ptr<gsl_monte_miser_state,void(*)( gsl_monte_miser_state* )>
mis_state( gsl_monte_miser_alloc( function_->dim ), gsl_monte_miser_free );
gsl_monte_miser_params_set( mis_state.get(), &input_params_->integrator.miser );
res = gsl_monte_miser_integrate( function_.get(),
&x_low[0], &x_up[0],
function_->dim, input_params_->integrator.ncvg,
rng_.get(), mis_state.get(),
&result, &abserr );
} break;
}
input_params_->integrator.result = result;
input_params_->integrator.err_result = abserr;
if ( input_params_->hadroniser() )
input_params_->hadroniser()->setCrossSection( result, abserr );
return res;
}
int
Integrator::warmupVegas( std::vector<double>& x_low, std::vector<double>& x_up, unsigned int ncall )
{
// start by preparing the grid/state
veg_state_.reset( gsl_monte_vegas_alloc( function_->dim ) );
gsl_monte_vegas_params_set( veg_state_.get(), &input_params_->integrator.vegas );
// then perform a first integration with the given calls count
double result = 0., abserr = 0.;
int res = gsl_monte_vegas_integrate( function_.get(),
&x_low[0], &x_up[0],
function_->dim, ncall,
rng_.get(), veg_state_.get(),
&result, &abserr );
// ensure the operation was successful
if ( res != GSL_SUCCESS )
CG_ERROR( "Integrator:vegas" )
<< "Failed to warm-up the Vegas grid.\n\t"
<< "GSL error: " << gsl_strerror( res ) << ".";
CG_INFO( "Integrator:vegas" )
<< "Finished the Vegas warm-up.";
return res;
}
//-----------------------------------------------------------------------------------------------
// events generation part
//-----------------------------------------------------------------------------------------------
void
Integrator::generateOne( std::function<void( const Event&, unsigned long )> callback )
{
if ( !grid_->gen_prepared )
computeGenerationParameters();
std::vector<double> x( function_->dim, 0. );
//--- correction cycles
if ( ps_bin_ != 0 ) {
bool has_correction = false;
while ( !correctionCycle( x, has_correction ) ) {}
if ( has_correction ) {
storeEvent( x, callback );
return;
}
}
double weight = 0.;
//--- normal generation cycle
while ( true ) {
double y = -1.;
//----- select a and reject if fmax is too small
while ( true ) {
// ...
ps_bin_ = uniform() * grid_->max;
y = uniform() * grid_->f_max_global;
grid_->num[ps_bin_] += 1;
if ( y <= grid_->f_max[ps_bin_] )
break;
}
// shoot a point x in this bin
std::vector<unsigned short> grid_n = grid_->n_map.at( ps_bin_ );
for ( unsigned int i = 0; i < function_->dim; ++i )
x[i] = ( uniform() + grid_n[i] ) * GridParameters::inv_mbin_;
// get weight for selected x value
weight = eval( x );
if ( weight <= 0. )
continue;
if ( weight > y )
break;
}
if ( weight <= grid_->f_max[ps_bin_] )
ps_bin_ = 0;
// init correction cycle if weight is higher than fmax or ffmax
else if ( weight <= grid_->f_max_global ) {
grid_->f_max_old = grid_->f_max[ps_bin_];
grid_->f_max[ps_bin_] = weight;
grid_->f_max_diff = weight-grid_->f_max_old;
grid_->correc = ( grid_->num[ps_bin_]-1. ) * grid_->f_max_diff / grid_->f_max_global - 1.;
}
else {
grid_->f_max_old = grid_->f_max[ps_bin_];
grid_->f_max[ps_bin_] = weight;
grid_->f_max_diff = weight-grid_->f_max_old;
grid_->f_max_global = weight;
grid_->correc = ( grid_->num[ps_bin_] - 1. ) * grid_->f_max_diff / grid_->f_max_global * weight / grid_->f_max_global - 1.;
}
CG_DEBUG("Integrator::generateOne")
<< "Correction " << grid_->correc << " will be applied for phase space bin " << ps_bin_ << ".";
// return with an accepted event
if ( weight > 0. )
storeEvent( x, callback );
}
void
Integrator::generate( unsigned long num_events, std::function<void( const Event&, unsigned long )> callback, const Timer* tmr )
{
if ( num_events < 1 )
num_events = input_params_->generation.maxgen;
try {
while ( input_params_->generation.ngen < num_events )
generateOne( callback );
} catch ( const Exception& e ) { throw; }
}
bool
Integrator::correctionCycle( std::vector<double>& x, bool& has_correction )
{
CG_DEBUG_LOOP( "Integrator:correction" )
<< "Correction cycles are started.\n\t"
<< "bin = " << ps_bin_ << "\t"
<< "correc = " << grid_->correc << "\t"
<< "corre2 = " << grid_->correc2 << ".";
if ( grid_->correc >= 1. )
grid_->correc -= 1.;
if ( uniform() < grid_->correc ) {
grid_->correc = -1.;
std::vector<double> xtmp( function_->dim );
// Select x values in phase space bin
const std::vector<unsigned short> grid_n = grid_->n_map.at( ps_bin_ );
for ( unsigned int k = 0; k < function_->dim; ++k )
xtmp[k] = ( uniform() + grid_n[k] ) * GridParameters::inv_mbin_;
const double weight = eval( xtmp );
// Parameter for correction of correction
if ( weight > grid_->f_max[ps_bin_] ) {
grid_->f_max2 = std::max( grid_->f_max2, weight );
grid_->correc += 1.;
grid_->correc2 -= 1.;
}
// Accept event
if ( weight >= grid_->f_max_diff*uniform() + grid_->f_max_old ) {
x = xtmp;
has_correction = true;
return true;
}
return false;
}
// Correction if too big weight is found while correction
// (All your bases are belong to us...)
if ( grid_->f_max2 > grid_->f_max[ps_bin_] ) {
grid_->f_max_old = grid_->f_max[ps_bin_];
grid_->f_max[ps_bin_] = grid_->f_max2;
grid_->f_max_diff = grid_->f_max2-grid_->f_max_old;
grid_->correc = ( grid_->num[ps_bin_]-1. ) * grid_->f_max_diff / grid_->f_max_global;
if ( grid_->f_max2 >= grid_->f_max_global ) {
grid_->correc *= grid_->f_max2 / grid_->f_max_global;
grid_->f_max_global = grid_->f_max2;
}
grid_->correc -= grid_->correc2;
grid_->correc2 = 0.;
grid_->f_max2 = 0.;
return false;
}
return true;
}
bool
Integrator::storeEvent( const std::vector<double>& x, std::function<void( const Event&, unsigned long )> callback )
{
const double weight = eval( x );
if ( weight <= 0. )
return false;
{
if ( input_params_->generation.ngen % input_params_->generation.gen_print_every == 0 ) {
CG_INFO( "Integrator:store" )
<< "Generated events: " << input_params_->generation.ngen;
input_params_->process()->last_event->dump();
}
input_params_->generation.ngen += 1;
if ( callback )
callback( *input_params_->process()->last_event, input_params_->generation.ngen );
}
return true;
}
//-----------------------------------------------------------------------------------------------
// initial preparation run before the generation of unweighted events
//-----------------------------------------------------------------------------------------------
void
Integrator::computeGenerationParameters()
{
input_params_->generation.ngen = 0;
input_params_->setStorage( false );
if ( input_params_->generation.treat
&& input_params_->integrator.type != Type::Vegas ) {
CG_INFO( "Integrator:setGen" )
<< "Treat switched on without a proper Vegas grid; running a warm-up beforehand.";
std::vector<double> x_low( function_->dim, 0. ), x_up( function_->dim, 1. );
int res = warmupVegas( x_low, x_up, 25000 );
if ( res != GSL_SUCCESS ) {
CG_ERROR( "Integrator::setGen" )
<< "Failed to perform a Vegas warm-up.\n\t"
<< "Disabling treat...";
input_params_->generation.treat = false;
}
}
CG_INFO( "Integrator:setGen" )
<< "Preparing the grid (" << input_params_->generation.num_points << " points/bin) "
<< "for the generation of unweighted events.";
grid_->max = pow( GridParameters::mbin_, function_->dim );
const double inv_num_points = 1./input_params_->generation.num_points;
if ( function_->dim > GridParameters::max_dimensions_ )
throw CG_FATAL( "Integrator:setGen" )
<< "Number of dimensions to integrate exceeds the maximum number, "
<< GridParameters::max_dimensions_ << ".";
grid_->f_max = std::vector<double>( grid_->max, 0. );
grid_->num.reserve( grid_->max );
std::vector<double> x( function_->dim, 0. );
std::vector<unsigned short> n( function_->dim, 0 );;
// ...
double sum = 0., sum2 = 0., sum2p = 0.;
//--- main loop
for ( unsigned int i = 0; i < grid_->max; ++i ) {
unsigned int jj = i;
for ( unsigned int j = 0; j < function_->dim; ++j ) {
unsigned int tmp = jj*GridParameters::inv_mbin_;
n[j] = jj-tmp*GridParameters::mbin_;
jj = tmp;
}
grid_->n_map[i] = n;
if ( CG_EXCEPT_MATCH( "Integrator:setGen", debugInsideLoop ) ) {
std::ostringstream os;
for ( const auto& ni : n )
os << ni << " ";
CG_DEBUG_LOOP( "Integrator:setGen" )
<< "n-vector for bin " << i << ": " << os.str();
}
double fsum = 0., fsum2 = 0.;
for ( unsigned int j = 0; j < input_params_->generation.num_points; ++j ) {
for ( unsigned int k = 0; k < function_->dim; ++k )
x[k] = ( uniform()+n[k] ) * GridParameters::inv_mbin_;
const double weight = eval( x );
grid_->f_max[i] = std::max( grid_->f_max[i], weight );
fsum += weight;
fsum2 += weight*weight;
}
const double av = fsum*inv_num_points, av2 = fsum2*inv_num_points, sig2 = av2-av*av;
sum += av;
sum2 += av2;
sum2p += sig2;
grid_->f_max_global = std::max( grid_->f_max_global, grid_->f_max[i] );
// per-bin debugging loop
if ( CG_EXCEPT_MATCH( "Integrator:setGen", debugInsideLoop ) ) {
const double sig = sqrt( sig2 );
const double eff = ( grid_->f_max[i] != 0. )
? grid_->f_max[i]/av
: 1.e4;
std::ostringstream os;
for ( unsigned int j = 0; j < function_->dim; ++j )
os << ( j != 0 ? ", " : "" ) << n[j];
CG_DEBUG_LOOP( "Integrator:setGen" )
<< "In iteration #" << i << ":\n\t"
<< "av = " << av << "\n\t"
<< "sig = " << sig << "\n\t"
<< "fmax = " << grid_->f_max[i] << "\n\t"
<< "eff = " << eff << "\n\t"
<< "n = (" << os.str() << ")";
}
} // end of main loop
const double inv_max = 1./grid_->max;
sum *= inv_max;
sum2 *= inv_max;
sum2p *= inv_max;
const double sig = sqrt( sum2-sum*sum ), sigp = sqrt( sum2p );
double eff1 = 0.;
for ( unsigned int i = 0; i < grid_->max; ++i )
eff1 += sum/grid_->max*grid_->f_max[i];
const double eff2 = sum/grid_->f_max_global;
CG_DEBUG( "Integrator:setGen" )
<< "Average function value = sum = " << sum << "\n\t"
<< "Average squared function value = sum2 = " << sum2 << "\n\t"
<< "Overall standard deviation = sig = " << sig << "\n\t"
<< "Average standard deviation = sigp = " << sigp << "\n\t"
<< "Maximum function value = f_max = " << grid_->f_max_global << "\n\t"
<< "Average inefficiency = eff1 = " << eff1 << "\n\t"
<< "Overall inefficiency = eff2 = " << eff2;
grid_->gen_prepared = true;
input_params_->setStorage( true );
CG_INFO( "Integrator:setGen" ) << "Grid prepared! Now launching the production.";
}
//------------------------------------------------------------------------------------------------
// helper / alias methods
//------------------------------------------------------------------------------------------------
unsigned short
Integrator::dimensions() const
{
if ( !function_ )
return 0;
return function_->dim;
}
double
Integrator::eval( const std::vector<double>& x )
{
if ( input_params_->generation.treat ) {
double w = r_boxes_;
std::vector<double> x_new( x.size() );
for ( unsigned short j = 0; j < function_->dim; ++j ) {
const double z = x[j]*veg_state_->bins;
const unsigned int k = z;
const double y = z-k;
const double bin_width = ( k == 0. ? COORD( veg_state_, 1, j ) : COORD( veg_state_, k+1, j )-COORD( veg_state_, k, j ) );
x_new[j] = COORD( veg_state_, k+1, j )-bin_width*( 1.-y );
w *= bin_width;
}
return w*function_->f( (double*)&x_new[0], function_->dim, (void*)input_params_ );
}
return function_->f( (double*)&x[0], function_->dim, (void*)input_params_ );
}
double
Integrator::uniform() const
{
return gsl_rng_uniform( rng_.get() );
}
//------------------------------------------------------------------------------------------------
std::ostream&
operator<<( std::ostream& os, const Integrator::Type& type )
{
switch ( type ) {
case Integrator::Type::plain:
return os << "plain";
case Integrator::Type::Vegas:
return os << "Vegas";
case Integrator::Type::MISER:
return os << "MISER";
}
return os;
}
std::ostream&
operator<<( std::ostream& os, const Integrator::VegasMode& mode )
{
switch ( mode ) {
case Integrator::VegasMode::importance:
return os << "importance";
case Integrator::VegasMode::importanceOnly:
return os << "importance-only";
case Integrator::VegasMode::stratified:
return os << "stratified";
}
return os;
}
}
diff --git a/CepGen/Core/Integrator.h b/CepGen/Core/Integrator.h
index 630e0c5..5a30fe7 100644
--- a/CepGen/Core/Integrator.h
+++ b/CepGen/Core/Integrator.h
@@ -1,98 +1,98 @@
#ifndef CepGen_Core_Integrator_h
#define CepGen_Core_Integrator_h
#include <vector>
#include <memory>
#include <functional>
#include <string.h>
#include <gsl/gsl_monte.h>
#include <gsl/gsl_monte_vegas.h>
#include <gsl/gsl_rng.h>
-namespace CepGen
+namespace cepgen
{
class Parameters;
class Event;
class GridParameters;
class Timer;
/// Monte-Carlo integrator instance
class Integrator
{
public:
enum class Type {
plain = 0,
Vegas = 1, ///< VEGAS algorithm \cite Lepage:1977sw developed by G.P. Lepage
MISER = 2
};
enum class VegasMode { importance = 1, importanceOnly = 0, stratified = -1 };
/**
* Book the memory slots and structures for the integrator
* \note Three integration algorithms are currently supported:
* * the plain algorithm randomly sampling points in the phase space
* * the Vegas algorithm developed by P. Lepage, as documented in \cite Lepage:1977sw
* * the MISER algorithm developed by W.H. Press and G.R. Farrar, as documented in \cite Press:1989vk.
* \param[in] ndim Number of dimensions on which the function will be integrated
* \param[in] integrand Function to be integrated
* \param[inout] params Run parameters to define the phase space on which this integration is performed (embedded in an Parameters object)
*/
Integrator( unsigned int ndim, double integrand(double*,size_t,void*), Parameters* params );
/// Class destructor
~Integrator();
/**
* Algorithm to perform the n-dimensional Monte Carlo integration of a given function.
* \author This C++ implementation: GSL
* \param[out] result_ The cross section as integrated for the given phase space restrictions
* \param[out] abserr_ The error associated to the computed cross section
* \return 0 if the integration was performed successfully
*/
int integrate( double& result_, double& abserr_ );
/// Dimensional size of the phase space
unsigned short dimensions() const;
void generateOne( std::function<void( const Event&, unsigned long )> callback = nullptr );
void generate( unsigned long num_events = 0, std::function<void( const Event&, unsigned long )> callback = nullptr, const Timer* tmr = nullptr );
private:
/**
* Store the event characterized by its _ndim-dimensional point in the phase
* space to the output file
* \brief Store the event in the output file
* \param[in] x The d-dimensional point in the phase space defining the unique event to store
* \return A boolean stating whether or not the event could be saved
*/
bool storeEvent( const std::vector<double>& x, std::function<void( const Event&, unsigned long )> callback = nullptr );
/// Start the correction cycle on the grid
/// \param x Point in the phase space considered
/// \param has_correction Correction cycle started?
bool correctionCycle( std::vector<double>& x, bool& has_correction );
int warmupVegas( std::vector<double>& x_low, std::vector<double>& x_up, unsigned int ncall );
/**
* Set all the generation mode variables and align them to the integration grid set while computing the cross-section
* \brief Prepare the class for events generation
*/
void computeGenerationParameters();
double uniform() const;
double eval( const std::vector<double>& x );
/// Selected bin at which the function will be evaluated
int ps_bin_;
/// List of parameters to specify the integration range and the physics determining the phase space
Parameters* input_params_;
/// GSL structure storing the function to be integrated by this integrator instance (along with its parameters)
std::unique_ptr<gsl_monte_function> function_;
std::unique_ptr<gsl_rng,void(*)( gsl_rng* )> rng_;
std::unique_ptr<GridParameters> grid_;
struct gsl_monte_vegas_deleter
{
void operator()( gsl_monte_vegas_state* state ) {
gsl_monte_vegas_free( state );
}
};
std::unique_ptr<gsl_monte_vegas_state,gsl_monte_vegas_deleter> veg_state_;
double r_boxes_;
};
std::ostream& operator<<( std::ostream&, const Integrator::Type& );
std::ostream& operator<<( std::ostream&, const Integrator::VegasMode& );
}
#endif
diff --git a/CepGen/Core/Logger.h b/CepGen/Core/Logger.h
index 60add32..a9ebacf 100644
--- a/CepGen/Core/Logger.h
+++ b/CepGen/Core/Logger.h
@@ -1,83 +1,83 @@
#ifndef CepGen_Core_Logger_h
#define CepGen_Core_Logger_h
#include <iostream>
#include <vector>
#include <regex>
-namespace CepGen
+namespace cepgen
{
/// General purposes logger
/// \author Laurent Forthomme <laurent.forthomme@cern.ch>
/// \date 15 Oct 2015
class Logger
{
public:
/// Logging threshold for the output stream
enum class Level { nothing = 0, error, warning, information, debug, debugInsideLoop };
private:
/// Initialize a logging object
Logger( std::ostream* os = &std::cout ) :
level( Level::information ), output( os ) {}
#if !defined(__CINT__) && !defined(__CLING__)
std::vector<std::regex> allowed_exc_;
#endif
public:
/// Retrieve the running instance of the logger
static Logger& get( std::ostream* os = &std::cout ) {
static Logger log( os );
return log;
}
/// Add a new rule to display exceptions/messages
/// \param[in] rule Regex rule to handle
void addExceptionRule( const std::string& rule ) {
#if !defined(__CINT__) && !defined(__CLING__)
allowed_exc_.emplace_back( rule );
#endif
}
/// \brief Is the module set to be displayed/logged?
/// \param[in] tmpl Module name to probe
/// \param[in] lev Upper verbosity level
bool passExceptionRule( const std::string& tmpl, const Level& lev ) const {
#if !defined(__CINT__) && !defined(__CLING__)
if ( level >= lev )
return true;
if ( allowed_exc_.size() == 0 )
return false;
for ( const auto& rule : allowed_exc_ )
if ( std::regex_match( tmpl, rule ) )
return true;
#endif
return false;
}
/// Redirect the logger to a given output stream
friend std::ostream& operator<<( std::ostream& os, const Logger::Level& lvl ) {
switch ( lvl ) {
case Logger::Level::nothing:
return os << "None";
case Logger::Level::error:
return os << "Errors";
case Logger::Level::warning:
return os << "Warnings";
case Logger::Level::information:
return os << "Infos";
case Logger::Level::debug:
return os << "Debug";
case Logger::Level::debugInsideLoop:
return os << "Debug (in loops)";
}
return os;
}
/// Logging threshold for the output stream
Level level;
/// Output stream to use for all logging operations
std::ostream* output;
};
}
#endif
diff --git a/CepGen/Core/Parameters.cpp b/CepGen/Core/Parameters.cpp
index b1bca39..63dc486 100644
--- a/CepGen/Core/Parameters.cpp
+++ b/CepGen/Core/Parameters.cpp
@@ -1,257 +1,257 @@
#include "CepGen/Parameters.h"
#include "CepGen/Core/ParametersList.h"
#include "CepGen/Core/Exception.h"
#include "CepGen/Core/TamingFunction.h"
#include "CepGen/Physics/PDG.h"
#include "CepGen/Processes/GenericProcess.h"
#include "CepGen/Hadronisers/GenericHadroniser.h"
#include "CepGen/StructureFunctions/StructureFunctions.h"
#include <iomanip>
-namespace CepGen
+namespace cepgen
{
Parameters::Parameters() :
general( new ParametersList ),
taming_functions( new TamingFunctionsCollection ),
store_( false ), total_gen_time_( 0. ), num_gen_events_( 0 )
{}
Parameters::Parameters( Parameters& param ) :
general( param.general ),
kinematics( param.kinematics ), integrator( param.integrator ), generation( param.generation ),
taming_functions( param.taming_functions ),
process_( std::move( param.process_ ) ),
hadroniser_( std::move( param.hadroniser_ ) ),
store_( false ), total_gen_time_( param.total_gen_time_ ), num_gen_events_( param.num_gen_events_ )
{}
Parameters::Parameters( const Parameters& param ) :
general( param.general ),
kinematics( param.kinematics ), integrator( param.integrator ), generation( param.generation ),
taming_functions( param.taming_functions ),
store_( false ), total_gen_time_( param.total_gen_time_ ), num_gen_events_( param.num_gen_events_ )
{}
Parameters::~Parameters() // required for unique_ptr initialisation!
{}
void
Parameters::setThetaRange( float thetamin, float thetamax )
{
kinematics.cuts.central.eta_single = {
Particle::thetaToEta( thetamax ),
Particle::thetaToEta( thetamin )
};
CG_DEBUG( "Parameters" )
<< "eta in range: " << kinematics.cuts.central.eta_single
<< " => theta(min) = " << thetamin << ", theta(max) = " << thetamax << ".";
}
void
Parameters::clearRunStatistics()
{
total_gen_time_ = 0.;
num_gen_events_ = 0;
}
void
Parameters::addGenerationTime( double gen_time )
{
total_gen_time_ += gen_time;
num_gen_events_++;
}
process::GenericProcess*
Parameters::process()
{
return process_.get();
}
std::string
Parameters::processName() const
{
if ( !process_ )
return "no process";
return process_->name();
}
void
Parameters::setProcess( std::unique_ptr<process::GenericProcess> proc )
{
process_ = std::move( proc );
}
void
Parameters::setProcess( process::GenericProcess* proc )
{
if ( !proc )
throw CG_FATAL( "Parameters" )
<< "Trying to clone an invalid process!";
process_.reset( proc );
}
hadroniser::GenericHadroniser*
Parameters::hadroniser()
{
return hadroniser_.get();
}
std::string
Parameters::hadroniserName() const
{
if ( !hadroniser_ )
return "";
return hadroniser_->name();
}
void
Parameters::setHadroniser( hadroniser::GenericHadroniser* hadr )
{
hadroniser_.reset( hadr );
}
std::ostream&
operator<<( std::ostream& os, const Parameters* p )
{
const bool pretty = true;
const int wb = 90, wt = 40;
os
<< "Parameters dump" << std::left << "\n\n"
<< std::setfill('_') << std::setw( wb+3 ) << "_/¯¯RUN¯INFORMATION¯¯\\_" << std::setfill( ' ' ) << "\n"
<< std::right << std::setw( wb ) << std::left << std::endl
<< std::setw( wt ) << "Process to generate";
if ( p->process_ ) {
os << ( pretty ? boldify( p->process_->name().c_str() ) : p->process_->name() ) << "\n"
<< std::setw( wt ) << "" << p->process_->description();
}
else
os << ( pretty ? boldify( "no process!" ) : "no process!" );
os
<< "\n"
<< std::setw( wt ) << "Events generation? "
<< ( pretty ? yesno( p->generation.enabled ) : std::to_string( p->generation.enabled ) ) << "\n"
<< std::setw( wt ) << "Number of events to generate"
<< ( pretty ? boldify( p->generation.maxgen ) : std::to_string( p->generation.maxgen ) ) << "\n";
if ( p->generation.num_threads > 1 )
os
<< std::setw( wt ) << "Number of threads" << p->generation.num_threads << "\n";
os
<< std::setw( wt ) << "Number of points to try per bin" << p->generation.num_points << "\n"
<< std::setw( wt ) << "Integrand treatment"
<< ( pretty ? yesno( p->generation.treat ) : std::to_string( p->generation.treat ) ) << "\n"
<< std::setw( wt ) << "Verbosity level " << Logger::get().level << "\n";
if ( p->hadroniser_ ) {
os
<< "\n"
<< std::setfill( '-' ) << std::setw( wb+6 )
<< ( pretty ? boldify( " Hadronisation algorithm " ) : "Hadronisation algorithm" ) << std::setfill( ' ' ) << "\n\n"
<< std::setw( wt ) << "Name"
<< ( pretty ? boldify( p->hadroniser_->name().c_str() ) : p->hadroniser_->name() ) << "\n";
}
os
<< "\n"
<< std::setfill( '-' ) << std::setw( wb+6 )
<< ( pretty ? boldify( " Integration parameters " ) : "Integration parameters" ) << std::setfill( ' ' ) << "\n\n";
std::ostringstream int_algo; int_algo << p->integrator.type;
os
<< std::setw( wt ) << "Integration algorithm"
<< ( pretty ? boldify( int_algo.str().c_str() ) : int_algo.str() ) << "\n"
<< std::setw( wt ) << "Number of function calls" << p->integrator.ncvg << "\n"
<< std::setw( wt ) << "Random number generator seed" << p->integrator.rng_seed << "\n";
if ( p->integrator.rng_engine )
os
<< std::setw( wt ) << "Random number generator engine"
<< p->integrator.rng_engine->name << "\n";
std::ostringstream proc_mode; proc_mode << p->kinematics.mode;
os
<< "\n"
<< std::setfill('_') << std::setw( wb+3 )
<< "_/¯¯EVENTS¯KINEMATICS¯¯\\_" << std::setfill( ' ' ) << "\n\n"
<< std::setw( wt ) << "Incoming particles"
<< p->kinematics.incoming_beams.first << ",\n" << std::setw( wt ) << ""
<< p->kinematics.incoming_beams.second << "\n";
if ( p->kinematics.mode != KinematicsMode::invalid )
os << std::setw( wt ) << "Subprocess mode" << ( pretty ? boldify( proc_mode.str().c_str() ) : proc_mode.str() ) << "\n";
if ( p->kinematics.mode != KinematicsMode::ElasticElastic )
os << std::setw( wt ) << "Structure functions" << *p->kinematics.structure_functions << "\n";
os
<< "\n"
<< std::setfill( '-' ) << std::setw( wb+6 ) << ( pretty ? boldify( " Incoming partons " ) : "Incoming partons" ) << std::setfill( ' ' ) << "\n\n";
for ( const auto& lim : p->kinematics.cuts.initial.list() ) // map(particles class, limits)
if ( lim.second.valid() )
os << std::setw( wt ) << lim.first << lim.second << "\n";
os
<< "\n"
<< std::setfill( '-' ) << std::setw( wb+6 ) << ( pretty ? boldify( " Outgoing central system " ) : "Outgoing central system" ) << std::setfill( ' ' ) << "\n\n";
for ( const auto& lim : p->kinematics.cuts.central.list() )
if ( lim.second.valid() )
os << std::setw( wt ) << lim.first << lim.second << "\n";
if ( p->kinematics.cuts.central_particles.size() > 0 ) {
os << std::setw( wt ) << ( pretty ? boldify( ">>> per-particle cuts:" ) : ">>> per-particle cuts:" ) << "\n";
for ( const auto& part_per_lim : p->kinematics.cuts.central_particles ) {
os << " * all single " << std::setw( wt-3 ) << part_per_lim.first << "\n";
for ( const auto& lim : part_per_lim.second.list() )
if ( lim.second.valid() )
os << " - " << std::setw( wt-5 ) << lim.first << lim.second << "\n";
}
}
os << "\n";
os << std::setfill( '-' ) << std::setw( wb+6 ) << ( pretty ? boldify( " Proton / remnants " ) : "Proton / remnants" ) << std::setfill( ' ' ) << "\n\n";
for ( const auto& lim : p->kinematics.cuts.remnants.list() )
os << std::setw( wt ) << lim.first << lim.second << "\n";
return os;
}
std::ostream&
operator<<( std::ostream& os, const Parameters& p )
{
return os << &p;
}
//-----------------------------------------------------------------------------------------------
Parameters::Integration::Integration() :
type( Integrator::Type::Vegas ), ncvg( 500000 ),
rng_seed( 0 ), rng_engine( (gsl_rng_type*)gsl_rng_mt19937 ),
vegas_chisq_cut( 1.5 ),
result( -1. ), err_result( -1. )
{
const size_t ndof = 10;
{
std::shared_ptr<gsl_monte_vegas_state> tmp_state( gsl_monte_vegas_alloc( ndof ), gsl_monte_vegas_free );
gsl_monte_vegas_params_get( tmp_state.get(), &vegas );
}
{
std::shared_ptr<gsl_monte_miser_state> tmp_state( gsl_monte_miser_alloc( ndof ), gsl_monte_miser_free );
gsl_monte_miser_params_get( tmp_state.get(), &miser );
}
}
Parameters::Integration::Integration( const Integration& rhs ) :
type( rhs.type ), ncvg( rhs.ncvg ),
rng_seed( rhs.rng_seed ), rng_engine( rhs.rng_engine ),
vegas( rhs.vegas ), vegas_chisq_cut( rhs.vegas_chisq_cut ),
miser( rhs.miser ),
result( -1. ), err_result( -1. )
{}
Parameters::Integration::~Integration()
{
//if ( vegas.ostream && vegas.ostream != stdout && vegas.ostream != stderr )
// fclose( vegas.ostream );
}
//-----------------------------------------------------------------------------------------------
Parameters::Generation::Generation() :
enabled( false ), maxgen( 0 ),
symmetrise( false ), treat( false ), ngen( 0 ), gen_print_every( 10000 ),
num_threads( 2 ), num_points( 100 )
{}
}
diff --git a/CepGen/Core/ParametersList.cpp b/CepGen/Core/ParametersList.cpp
index f94cc67..63b5c67 100644
--- a/CepGen/Core/ParametersList.cpp
+++ b/CepGen/Core/ParametersList.cpp
@@ -1,298 +1,298 @@
#include "CepGen/Core/ParametersList.h"
#include "CepGen/Core/Exception.h"
-namespace CepGen
+namespace cepgen
{
ParametersList&
ParametersList::operator+=( const ParametersList& oth )
{
param_values_.insert( oth.param_values_.begin(), oth.param_values_.end() );
int_values_.insert( oth.int_values_.begin(), oth.int_values_.end() );
dbl_values_.insert( oth.dbl_values_.begin(), oth.dbl_values_.end() );
str_values_.insert( oth.str_values_.begin(), oth.str_values_.end() );
vec_param_values_.insert( oth.vec_param_values_.begin(), oth.vec_param_values_.end() );
vec_int_values_.insert( oth.vec_int_values_.begin(), oth.vec_int_values_.end() );
vec_dbl_values_.insert( oth.vec_dbl_values_.begin(), oth.vec_dbl_values_.end() );
vec_str_values_.insert( oth.vec_str_values_.begin(), oth.vec_str_values_.end() );
return *this;
}
std::ostream&
operator<<( std::ostream& os, const ParametersList& params )
{
for ( const auto& kv : params.int_values_ )
os << "\n" << kv.first << ": int(" << kv.second << ")";
for ( const auto& kv : params.dbl_values_ )
os << "\n" << kv.first << ": double(" << kv.second << ")";
for ( const auto& kv : params.str_values_ )
os << "\n" << kv.first << ": string(" << kv.second << ")";
for ( const auto& kv : params.param_values_ )
os << "\n" << kv.first << ": param({" << kv.second << "\n})";
for ( const auto& kv : params.vec_int_values_ ) {
os << "\n" << kv.first << ": vint(";
bool first = true;
for ( const auto& v : kv.second ) {
os << ( first ? "" : ", " ) << v;
first = false;
}
os << ")";
}
for ( const auto& kv : params.vec_dbl_values_ ) {
os << "\n" << kv.first << ": vdouble(";
bool first = true;
for ( const auto& v : kv.second ) {
os << ( first ? "" : ", " ) << v;
first = false;
}
os << ")";
}
for ( const auto& kv : params.vec_str_values_ ) {
os << "\n" << kv.first << ": vstring(";
bool first = true;
for ( const auto& v : kv.second ) {
os << ( first ? "" : ", " ) << v;
first = false;
}
os << ")";
}
return os;
}
//------------------------------------------------------------------
// default template (placeholders)
//------------------------------------------------------------------
template<typename T> T
ParametersList::get( std::string key, T def ) const
{
throw CG_FATAL( "ParametersList" ) << "Invalid type retrieved for key=" << key << "!";
}
template<typename T> T&
ParametersList::operator[]( std::string key )
{
throw CG_FATAL( "ParametersList" ) << "Invalid type retrieved for key=" << key << "!";
}
template<typename T> void
ParametersList::set( std::string key, const T& value )
{
throw CG_FATAL( "ParametersList" ) << "Invalid type to be set for key=" << key << "!";
}
//------------------------------------------------------------------
// sub-parameters-type attributes
//------------------------------------------------------------------
template<> ParametersList
ParametersList::get<ParametersList>( std::string key, ParametersList def ) const
{
for ( const auto& kv : param_values_ )
if ( kv.first.compare( key ) == 0 )
return kv.second;
CG_DEBUG( "ParametersList" ) << "Failed to retrieve parameter with key=" << key << ".";
return def;
}
template<> ParametersList&
ParametersList::operator[]<ParametersList>( std::string key )
{
for ( auto& kv : param_values_ )
if ( kv.first.compare( key ) == 0 )
return kv.second;
return param_values_[key];
}
template<> void
ParametersList::set<ParametersList>( std::string key, const ParametersList& value )
{
param_values_[key] = value;
}
template<> std::vector<ParametersList>
ParametersList::get<std::vector<ParametersList> >( std::string key, std::vector<ParametersList> def ) const
{
for ( const auto& kv : vec_param_values_ )
if ( kv.first.compare( key ) == 0 )
return kv.second;
CG_DEBUG( "ParametersList" ) << "Failed to retrieve parameter with key=" << key << ".";
return def;
}
template<> std::vector<ParametersList>&
ParametersList::operator[]<std::vector<ParametersList> >( std::string key )
{
for ( auto& kv : vec_param_values_ )
if ( kv.first.compare( key ) == 0 )
return kv.second;
return vec_param_values_[key];
}
template<> void
ParametersList::set<std::vector<ParametersList> >( std::string key, const std::vector<ParametersList>& value )
{
vec_param_values_[key] = value;
}
//------------------------------------------------------------------
// integer-type attributes
//------------------------------------------------------------------
template<> int
ParametersList::get<int>( std::string key, int def ) const
{
for ( const auto& kv : int_values_ )
if ( kv.first.compare( key ) == 0 )
return kv.second;
CG_DEBUG( "ParametersList" ) << "Failed to retrieve parameter with key=" << key << ".";
return def;
}
template<> int&
ParametersList::operator[]<int>( std::string key )
{
for ( auto& kv : int_values_ )
if ( kv.first.compare( key ) == 0 )
return kv.second;
return int_values_[key];
}
template<> void
ParametersList::set<int>( std::string key, const int& value )
{
int_values_[key] = value;
}
template<> std::vector<int>
ParametersList::get<std::vector<int> >( std::string key, std::vector<int> def ) const
{
for ( const auto& kv : vec_int_values_ )
if ( kv.first.compare( key ) == 0 )
return kv.second;
CG_DEBUG( "ParametersList" ) << "Failed to retrieve parameter with key=" << key << ".";
return def;
}
template<> std::vector<int>&
ParametersList::operator[]<std::vector<int> >( std::string key )
{
for ( auto& kv : vec_int_values_ )
if ( kv.first.compare( key ) == 0 )
return kv.second;
return vec_int_values_[key];
}
template<> void
ParametersList::set<std::vector<int> >( std::string key, const std::vector<int>& value )
{
vec_int_values_[key] = value;
}
//------------------------------------------------------------------
// floating point-type attributes
//------------------------------------------------------------------
template<> double
ParametersList::get<double>( std::string key, double def ) const
{
for ( const auto& kv : dbl_values_ )
if ( kv.first.compare( key ) == 0 )
return kv.second;
CG_DEBUG( "ParametersList" ) << "Failed to retrieve parameter with key=" << key << ".";
return def;
}
template<> double&
ParametersList::operator[]<double>( std::string key )
{
for ( auto& kv : dbl_values_ )
if ( kv.first.compare( key ) == 0 )
return kv.second;
return dbl_values_[key];
}
template<> void
ParametersList::set<double>( std::string key, const double& value )
{
dbl_values_[key] = value;
}
template<> std::vector<double>
ParametersList::get<std::vector<double> >( std::string key, std::vector<double> def ) const
{
for ( const auto& kv : vec_dbl_values_ )
if ( kv.first.compare( key ) == 0 )
return kv.second;
CG_DEBUG( "ParametersList" ) << "Failed to retrieve parameter with key=" << key << ".";
return def;
}
template<> std::vector<double>&
ParametersList::operator[]<std::vector<double> >( std::string key )
{
for ( auto& kv : vec_dbl_values_ )
if ( kv.first.compare( key ) == 0 )
return kv.second;
return vec_dbl_values_[key];
}
template<> void
ParametersList::set<std::vector<double> >( std::string key, const std::vector<double>& value )
{
vec_dbl_values_[key] = value;
}
//------------------------------------------------------------------
// string-type attributes
//------------------------------------------------------------------
template<> std::string
ParametersList::get<std::string>( std::string key, std::string def ) const
{
for ( const auto& kv : str_values_ )
if ( kv.first.compare( key ) == 0 )
return kv.second;
CG_DEBUG( "ParametersList" ) << "Failed to retrieve parameter with key=" << key << ".";
return def;
}
template<> std::string&
ParametersList::operator[]<std::string>( std::string key )
{
for ( auto& kv : str_values_ )
if ( kv.first.compare( key ) == 0 )
return kv.second;
return str_values_[key];
}
template<> void
ParametersList::set<std::string>( std::string key, const std::string& value )
{
str_values_[key] = value;
}
template<> std::vector<std::string>
ParametersList::get<std::vector<std::string> >( std::string key, std::vector<std::string> def ) const
{
for ( const auto& kv : vec_str_values_ )
if ( kv.first.compare( key ) == 0 )
return kv.second;
CG_DEBUG( "ParametersList" ) << "Failed to retrieve parameter with key=" << key << ".";
return def;
}
template<> std::vector<std::string>&
ParametersList::operator[]<std::vector<std::string> >( std::string key )
{
for ( auto& kv : vec_str_values_ )
if ( kv.first.compare( key ) == 0 )
return kv.second;
return vec_str_values_[key];
}
template<> void
ParametersList::set<std::vector<std::string> >( std::string key, const std::vector<std::string>& value )
{
vec_str_values_[key] = value;
}
}
diff --git a/CepGen/Core/ParametersList.h b/CepGen/Core/ParametersList.h
index 5abb45e..dd1d4d8 100644
--- a/CepGen/Core/ParametersList.h
+++ b/CepGen/Core/ParametersList.h
@@ -1,98 +1,98 @@
#ifndef CepGen_Core_ParametersList_h
#define CepGen_Core_ParametersList_h
#include <vector>
#include <map>
#include <unordered_map>
#include <string>
-namespace CepGen
+namespace cepgen
{
/// Parameters container
class ParametersList
{
private:
template<typename T> struct default_arg
{
static T get() { return T(); }
};
public:
ParametersList() = default;
~ParametersList() = default; // required for unique_ptr initialisation!
/// Get a parameter value
template<typename T> T get( std::string key, T def = default_arg<T>::get() ) const;
/// Reference to a parameter value
template<typename T> T& operator[]( std::string key );
/// Set a parameter value
template<typename T> void set( std::string key, const T& value );
/// Concatenate two parameters containers
ParametersList& operator+=( const ParametersList& oth );
/// Human-readable version of a parameters container
friend std::ostream& operator<<( std::ostream& os, const ParametersList& );
private:
std::map<std::string,ParametersList> param_values_;
std::unordered_map<std::string,int> int_values_;
std::unordered_map<std::string,double> dbl_values_;
std::unordered_map<std::string,std::string> str_values_;
std::unordered_map<std::string,std::vector<ParametersList> > vec_param_values_;
std::unordered_map<std::string,std::vector<int> > vec_int_values_;
std::unordered_map<std::string,std::vector<double> > vec_dbl_values_;
std::unordered_map<std::string,std::vector<std::string> > vec_str_values_;
};
/// Get an integer parameter value
template<> int ParametersList::get<int>( std::string key, int def ) const;
/// Reference to an integer parameter value
template<> int& ParametersList::operator[]<int>( std::string key );
/// Set an integer parameter value
template<> void ParametersList::set<int>( std::string key, const int& value );
/// Get a vector of integers parameter value
template<> std::vector<int> ParametersList::get<std::vector<int> >( std::string key, std::vector<int> def ) const;
/// Reference to a vector of integers parameter value
template<> std::vector<int>& ParametersList::operator[]<std::vector<int> >( std::string key );
/// Set a vector of integers parameter value
template<> void ParametersList::set<std::vector<int> >( std::string key, const std::vector<int>& value );
/// Get a double floating point parameter value
template<> double ParametersList::get<double>( std::string key, double def ) const;
/// Reference to a double floating point parameter value
template<> double& ParametersList::operator[]<double>( std::string key );
/// Set a double floating point parameter value
template<> void ParametersList::set<double>( std::string key, const double& value );
/// Get a vector of double floating point parameter value
template<> std::vector<double> ParametersList::get<std::vector<double> >( std::string key, std::vector<double> def ) const;
/// Reference to a vector of double floating point parameter value
template<> std::vector<double>& ParametersList::operator[]<std::vector<double> >( std::string key );
/// Set a vector of double floating point parameter value
template<> void ParametersList::set<std::vector<double> >( std::string key, const std::vector<double>& value );
/// Get a string parameter value
template<> std::string ParametersList::get<std::string>( std::string key, std::string def ) const;
/// Reference to a string parameter value
template<> std::string& ParametersList::operator[]<std::string>( std::string key );
/// Set a string parameter value
template<> void ParametersList::set<std::string>( std::string key, const std::string& value );
/// Get a vector of strings parameter value
template<> std::vector<std::string> ParametersList::get<std::vector<std::string> >( std::string key, std::vector<std::string> def ) const;
/// Reference to a vector of strings parameter value
template<> std::vector<std::string>& ParametersList::operator[]<std::vector<std::string> >( std::string key );
/// Set a vector of strings parameter value
template<> void ParametersList::set<std::vector<std::string> >( std::string key, const std::vector<std::string>& value );
/// Get a parameters list parameter value
template<> ParametersList ParametersList::get<ParametersList>( std::string key, ParametersList def ) const;
/// Reference to a parameters list parameter value
template<> ParametersList& ParametersList::operator[]<ParametersList>( std::string key );
/// Set a parameters list parameter value
template<> void ParametersList::set<ParametersList>( std::string key, const ParametersList& value );
/// Get a vector of parameters list parameter value
template<> std::vector<ParametersList> ParametersList::get<std::vector<ParametersList> >( std::string key, std::vector<ParametersList> def ) const;
/// Reference to a vector of parameters list parameter value
template<> std::vector<ParametersList>& ParametersList::operator[]<std::vector<ParametersList> >( std::string key );
/// Set a vector of parameters list parameter value
template<> void ParametersList::set<std::vector<ParametersList> >( std::string key, const std::vector<ParametersList>& value );
}
#endif
diff --git a/CepGen/Core/TamingFunction.h b/CepGen/Core/TamingFunction.h
index d383d25..0868bbd 100644
--- a/CepGen/Core/TamingFunction.h
+++ b/CepGen/Core/TamingFunction.h
@@ -1,46 +1,46 @@
#ifndef CepGen_Core_TamingFunction_h
#define CepGen_Core_TamingFunction_h
#include "CepGen/Core/Functional.h"
#include <unordered_map>
-namespace CepGen
+namespace cepgen
{
/// A collection of expression/variable with the associated functional
struct TamingFunction
{
TamingFunction() {}
TamingFunction( const std::string& var, const std::string& expr ) :
variable( var ), expression( expr ), function( expr, { { variable } } ) {}
std::string variable, expression;
Functional<1> function;
};
/// A collection of taming functions evaluator with helper classes
class TamingFunctionsCollection : public std::unordered_map<std::string,TamingFunction>
{
public:
/// Insert a new variable/expression into the collection
void add( const std::string& var, const std::string& expr ) {
emplace( std::make_pair( var, TamingFunction( var, expr ) ) );
}
/// Does the collection handle a taming function for a given variable?
bool has( const std::string& var ) const {
return ( find( var ) != end() );
}
/// Evaluate the taming function for a given variable at a given value
double eval( const std::string& var, double x ) const {
const auto& it = find( var );
if ( it == end() )
return 1.;
return it->second.function.eval( x );
}
/// Dump a full list of taming functions handled
void dump( std::ostream& os = *Logger::get().output ) const {
os << "List of taming functions:\n";
for ( const auto& it : *this )
os << ">> \"" << it.second.expression << "\" applied on variable \"" << it.first << "\"\n";
}
};
}
#endif
diff --git a/CepGen/Core/Timer.h b/CepGen/Core/Timer.h
index 9b29d68..3321852 100644
--- a/CepGen/Core/Timer.h
+++ b/CepGen/Core/Timer.h
@@ -1,35 +1,35 @@
#ifndef CepGen_Core_Timer_h
#define CepGen_Core_Timer_h
#include <chrono>
-namespace CepGen
+namespace cepgen
{
/**
* A generic timer to extract the processing time between two steps in this software's flow
* \author Laurent Forthomme <laurent.forthomme@cern.ch>
*/
class Timer
{
public:
inline Timer() { reset(); }
/**
* Get the time elapsed since the last @a reset call (or class construction)
* \return Elapsed time (since the last reset), in seconds
*/
inline double elapsed() const {
auto end = std::chrono::high_resolution_clock::now();
return std::chrono::duration<double>( end-beg_ ).count();
}
/// Reset the clock counter
inline void reset() {
beg_ = std::chrono::high_resolution_clock::now();
}
private:
/// Timestamp marking the beginning of the counter
std::chrono::time_point<std::chrono::high_resolution_clock> beg_;
};
}
#endif
diff --git a/CepGen/Core/Version.cpp b/CepGen/Core/Version.cpp
index 669b74b..868096f 100644
--- a/CepGen/Core/Version.cpp
+++ b/CepGen/Core/Version.cpp
@@ -1,12 +1,12 @@
#include "CepGen/Version.h"
#include "CepGen/Core/utils.h"
-namespace CepGen
+namespace cepgen
{
const std::string version()
{
return Form( "%02u.%02u.%02u", ( cepgen_version >> 16 ) & 0xff,
( cepgen_version >> 8 ) & 0xff,
cepgen_version & 0xff );
}
}
diff --git a/CepGen/Core/utils.cpp b/CepGen/Core/utils.cpp
index 793183f..1e1296c 100644
--- a/CepGen/Core/utils.cpp
+++ b/CepGen/Core/utils.cpp
@@ -1,41 +1,41 @@
#include "CepGen/Core/utils.h"
#include <math.h>
#include <stdarg.h> // For va_start, etc.
-namespace CepGen
+namespace cepgen
{
std::string
Form( const std::string fmt, ... )
{
int size = ( (int)fmt.size() ) * 2 + 50;
std::string str;
va_list ap;
while ( true ) {
//--- maximum two passes on a POSIX system...
str.resize( size );
va_start( ap, fmt );
int n = vsnprintf( (char*)str.data(), size, fmt.c_str(), ap );
va_end( ap );
//--- check if everything worked
if ( n > -1 && n < size ) {
str.resize( n );
return str;
}
size = ( n > -1 ) ? n+1 : size*2;
}
return str;
}
size_t
replace_all( std::string& str, const std::string& from, const std::string& to )
{
size_t count = 0, pos = 0;
while ( ( pos = str.find( from, pos ) ) != std::string::npos ) {
str.replace( pos, from.length(), to );
pos += to.length();
++count;
}
return count;
}
}
diff --git a/CepGen/Core/utils.h b/CepGen/Core/utils.h
index dd7678d..4728216 100644
--- a/CepGen/Core/utils.h
+++ b/CepGen/Core/utils.h
@@ -1,38 +1,38 @@
#ifndef CepGen_Core_utils_h
#define CepGen_Core_utils_h
#include <string>
-namespace CepGen
+namespace cepgen
{
/// Add a closing "s" when needed
inline const char* s( unsigned short num ) { return ( num > 1 ) ? "s" : ""; }
/// Format a string using a printf style format descriptor.
std::string Form( const std::string fmt, ... );
/// Human-readable boolean printout
inline const char* yesno( const bool& test ) { return ( test ) ? "\033[32;1myes\033[0m" : "\033[31;1mno\033[0m"; }
//inline const char* boldify( const char* str ) { const std::string out = std::string( "\033[33;1m" ) + std::string( str ) + std::string( "\033[0m" ); return out.c_str(); }
/// Boldify a string for TTY-type output streams
inline std::string boldify( const std::string& str ) { return Form( "\033[1m%s\033[0m", str.c_str() ); }
/// Boldify a string for TTY-type output streams
inline std::string boldify( const char* str ) { return boldify( std::string( str ) ); }
/// Boldify a double floating point number for TTY-type output streams
inline std::string boldify( const double& dbl ) { return boldify( Form("%.2f", dbl ) ); }
/// Boldify an integer for TTY-type output streams
inline std::string boldify( const int& i ) { return boldify( Form("% d", i ) ); }
/// Boldify an unsigned integer for TTY-type output streams
inline std::string boldify( const unsigned int& ui ) { return boldify( Form("%d", ui ) ); }
/// Boldify an unsigned long integer for TTY-type output streams
inline std::string boldify( const unsigned long& ui ) { return boldify( Form("%lu", ui ) ); }
/// TTY-type enumeration of colours
enum class Colour { gray = 30, red = 31, green = 32, yellow = 33, blue = 34, purple = 35 };
/// Colourise a string for TTY-type output streams
inline std::string colourise( const std::string& str, const Colour& col ) { return Form( "\033[%d%s\033[0m", (int)col, str.c_str() ); }
/// Replace all occurences of a text by another
size_t replace_all( std::string& str, const std::string& from, const std::string& to );
}
/// Provide a random number generated along a uniform distribution between 0 and 1
#define drand() static_cast<double>( rand()/RAND_MAX )
#endif
diff --git a/CepGen/Event/Event.cpp b/CepGen/Event/Event.cpp
index bce4c2a..abd89e7 100644
--- a/CepGen/Event/Event.cpp
+++ b/CepGen/Event/Event.cpp
@@ -1,339 +1,339 @@
#include "CepGen/Event/Event.h"
#include "CepGen/Physics/PDG.h"
#include "CepGen/Physics/HeavyIon.h"
#include "CepGen/Core/Exception.h"
#include "CepGen/Core/utils.h"
#include <algorithm>
#include <math.h>
-namespace CepGen
+namespace cepgen
{
Event::Event() :
num_hadronisation_trials( 0 ),
time_generation( -1. ), time_total( -1. )
{}
Event::Event( const Event& rhs ) :
num_hadronisation_trials( rhs.num_hadronisation_trials ),
time_generation( rhs.time_generation ), time_total( rhs.time_total ),
particles_( rhs.particles_ ),
evtcontent_( rhs.evtcontent_ )
{}
void
Event::clear()
{
particles_.clear();
time_generation = -1.;
time_total = -1.;
}
void
Event::freeze()
{
//--- store a snapshot of the primordial event block
if ( particles_.count( Particle::CentralSystem ) > 0 )
evtcontent_.cs = particles_[Particle::CentralSystem].size();
if ( particles_.count( Particle::OutgoingBeam1 ) > 0 )
evtcontent_.op1 = particles_[Particle::OutgoingBeam1].size();
if ( particles_.count( Particle::OutgoingBeam2 ) > 0 )
evtcontent_.op2 = particles_[Particle::OutgoingBeam2].size();
}
void
Event::restore()
{
//--- remove all particles after the primordial event block
if ( particles_.count( Particle::CentralSystem ) > 0 )
particles_[Particle::CentralSystem].resize( evtcontent_.cs );
if ( particles_.count( Particle::OutgoingBeam1 ) > 0 )
particles_[Particle::OutgoingBeam1].resize( evtcontent_.op1 );
if ( particles_.count( Particle::OutgoingBeam2 ) > 0 )
particles_[Particle::OutgoingBeam2].resize( evtcontent_.op2 );
}
double
Event::cmEnergy() const
{
return CMEnergy( getOneByRole( Particle::IncomingBeam1 ), getOneByRole( Particle::IncomingBeam2 ) );
}
Particles&
Event::getByRole( Particle::Role role )
{
//--- retrieve all particles with a given role
return particles_[role];
}
const Particles&
Event::getByRole( Particle::Role role ) const
{
if ( particles_.count( role ) == 0 )
throw CG_FATAL( "Event" ) << "Failed to retrieve a particle with " << role << " role.";
//--- retrieve all particles with a given role
return particles_.at( role );
}
ParticlesIds
Event::getIdsByRole( Particle::Role role ) const
{
ParticlesIds out;
//--- retrieve all particles ids with a given role
if ( particles_.count( role ) == 0 )
return out;
for ( const auto& part : particles_.at( role ) )
out.insert( part.id() );
return out;
}
Particle&
Event::getOneByRole( Particle::Role role )
{
//--- retrieve the first particle a the given role
Particles& parts_by_role = getByRole( role );
if ( parts_by_role.size() == 0 )
throw CG_FATAL( "Event" ) << "No particle retrieved with " << role << " role.";
if ( parts_by_role.size() > 1 )
throw CG_FATAL( "Event" ) << "More than one particle with " << role << " role: "
<< parts_by_role.size() << " particles.";
return *parts_by_role.begin();
}
const Particle&
Event::getOneByRole( Particle::Role role ) const
{
if ( particles_.count( role ) == 0 )
throw CG_FATAL( "Event" ) << "Failed to retrieve a particle with " << role << " role.";
//--- retrieve the first particle a the given role
const Particles& parts_by_role = particles_.at( role );
if ( parts_by_role.size() == 0 )
throw CG_FATAL( "Event" ) << "No particle retrieved with " << role << " role.";
if ( parts_by_role.size() > 1 )
throw CG_FATAL( "Event" ) << "More than one particle with " << role << " role: "
<< parts_by_role.size() << " particles";
return *parts_by_role.begin();
}
Particle&
Event::operator[]( int id )
{
for ( auto& role_part : particles_ )
for ( auto& part : role_part.second )
if ( part.id() == id )
return part;
throw CG_FATAL( "Event" ) << "Failed to retrieve the particle with id=" << id << ".";
}
const Particle&
Event::at( int id ) const
{
for ( const auto& role_part : particles_ )
for ( const auto& part : role_part.second )
if ( part.id() == id )
return part;
throw CG_FATAL( "Event" ) << "Failed to retrieve the particle with id=" << id << ".";
}
Particles
Event::getByIds( const ParticlesIds& ids ) const
{
Particles out;
for ( const auto& id : ids )
out.emplace_back( at( id ) );
return out;
}
Particles
Event::mothers( const Particle& part )
{
return getByIds( part.mothers() );
}
Particles
Event::daughters( const Particle& part )
{
return getByIds( part.daughters() );
}
ParticleRoles
Event::roles() const
{
ParticleRoles out;
ParticlesMap::const_iterator it, end = particles_.end();
for ( it = particles_.begin(); it != end; it = particles_.upper_bound( it->first ) ) {
out.emplace_back( it->first );
}
return out;
}
Particle&
Event::addParticle( Particle& part, bool replace )
{
CG_DEBUG_LOOP( "Event" ) << "Particle with PDGid = " << part.integerPdgId() << " has role " << part.role();
if ( part.role() <= 0 )
throw CG_FATAL( "Event" ) << "Trying to add a particle with role=" << (int)part.role() << ".";
//--- retrieve the list of particles with the same role
Particles& part_with_same_role = getByRole( part.role() );
//--- specify the id
if ( part_with_same_role.empty() && part.id() < 0 ) part.setId( numParticles() ); // set the id if previously invalid/inexistent
if ( !part_with_same_role.empty() ) {
if ( replace ) part.setId( part_with_same_role[0].id() ); // set the previous id if replacing a particle
else part.setId( numParticles() );
}
//--- add the particle to the collection
if ( replace ) part_with_same_role = Particles( 1, part ); // generate a vector containing only this particle
else part_with_same_role.emplace_back( part );
return part_with_same_role.back();
}
Particle&
Event::addParticle( Particle::Role role, bool replace )
{
Particle np( role, PDG::invalid );
return addParticle( np, replace );
}
size_t
Event::numParticles() const
{
size_t out = 0;
for ( const auto& role_part : particles_ )
out += role_part.second.size();
return out;
}
const Particles
Event::particles() const
{
Particles out;
for ( const auto& role_part : particles_ )
out.insert( out.end(), role_part.second.begin(), role_part.second.end() );
std::sort( out.begin(), out.end() );
return out;
}
const Particles
Event::stableParticles() const
{
Particles out;
for ( const auto& role_part : particles_ )
for ( const auto& part : role_part.second )
if ( (short)part.status() > 0 )
out.emplace_back( part );
std::sort( out.begin(), out.end() );
return out;
}
void
Event::checkKinematics() const
{
// check the kinematics through parentage
for ( const auto& part : particles() ) {
ParticlesIds daughters = part.daughters();
if ( daughters.empty() )
continue;
Particle::Momentum ptot;
for ( const auto& daugh : daughters ) {
const Particle& d = at( daugh );
const ParticlesIds mothers = d.mothers();
ptot += d.momentum();
if ( mothers.size() < 2 )
continue;
for ( const auto& moth : mothers )
if ( moth != part.id() )
ptot -= at( moth ).momentum();
}
const double mass_diff = ( ptot-part.momentum() ).mass();
if ( fabs( mass_diff ) > minimal_precision_ ) {
dump();
throw CG_FATAL( "Event" ) << "Error in momentum balance for particle " << part.id() << ": mdiff = " << mass_diff << ".";
}
}
}
void
Event::dump( std::ostream& out, bool stable ) const
{
const Particles parts = ( stable ) ? stableParticles() : particles();
std::ostringstream os;
Particle::Momentum p_total;
for ( const auto& part : parts ) {
const ParticlesIds mothers = part.mothers();
{
std::ostringstream oss_pdg;
if ( part.pdgId() == PDG::invalid && mothers.size() > 0 ) {
for ( unsigned short i = 0; i < mothers.size(); ++i )
oss_pdg << ( i > 0 ? "/" : "" ) << at( *std::next( mothers.begin(), i ) ).pdgId();
os << Form( "\n %2d\t\t%-10s", part.id(), oss_pdg.str().c_str() );
}
else {
if ( (HeavyIon)part.pdgId() )
oss_pdg << (HeavyIon)part.pdgId();
else
oss_pdg << part.pdgId();
os << Form( "\n %2d\t%-+7d %-10s", part.id(), part.integerPdgId(), oss_pdg.str().c_str() );
}
}
os << "\t";
if ( part.charge() != 999. )
os << Form( "%-.2f\t", part.charge() );
else
os << "\t";
{ std::ostringstream oss; oss << part.role(); os << Form( "%-8s %6d\t", oss.str().c_str(), part.status() ); }
if ( !mothers.empty() ) {
std::ostringstream oss;
unsigned short i = 0;
for ( const auto& moth : mothers ) {
oss << ( i > 0 ? "+" : "" ) << moth;
++i;
}
os << Form( "%6s ", oss.str().c_str() );
}
else os << " ";
const Particle::Momentum mom = part.momentum();
os << Form( "% 9.6e % 9.6e % 9.6e % 9.6e % 12.5f", mom.px(), mom.py(), mom.pz(), part.energy(), part.mass() );
// discard non-primary, decayed particles
if ( part.status() >= Particle::Status::Undefined ) {
const int sign = ( part.status() == Particle::Status::Undefined )
? -1
: +1;
p_total += sign*mom;
}
}
//--- set a threshold to the computation precision
p_total.truncate();
//
CG_INFO( "Event" )
<< Form( "Dump of event content:\n"
" Id\tPDG id\tName\t\tCharge\tRole\t Status\tMother\tpx py pz E \t M \n"
" --\t------\t----\t\t------\t----\t ------\t------\t----GeV/c--- ----GeV/c--- ----GeV/c--- ----GeV/c---\t --GeV/c²--"
"%s\n"
" ----------------------------------------------------------------------------------------------------------------------------------\n"
"\t\t\t\t\t\t\tBalance% 9.6e % 9.6e % 9.6e % 9.6e", os.str().c_str(), p_total.px(), p_total.py(), p_total.pz(), p_total.energy() );
}
//------------------------------------------------------------------------------------------------
Event::NumParticles::NumParticles() :
cs( 0 ), op1( 0 ), op2( 0 )
{}
Event::NumParticles::NumParticles( const NumParticles& np ) :
cs( np.cs ), op1( np.op1 ), op2( np.op2 )
{}
}
diff --git a/CepGen/Event/Event.h b/CepGen/Event/Event.h
index 599b592..3a2185c 100644
--- a/CepGen/Event/Event.h
+++ b/CepGen/Event/Event.h
@@ -1,119 +1,119 @@
#ifndef CepGen_Event_Event_h
#define CepGen_Event_Event_h
#include "CepGen/Event/Particle.h"
#include "CepGen/Core/Logger.h"
-namespace CepGen
+namespace cepgen
{
/**
* Class containing all the information on the in- and outgoing particles' kinematics
* \brief Kinematic information on the particles in the event
*/
class Event {
public:
Event();
Event( const Event& );
/// Empty the whole event content
void clear();
/// Initialize an "empty" event collection
void freeze();
/// Restore the event to its "empty" state
void restore();
/// Dump all the known information on every Particle object contained in this Event container in the output stream
/// \param[out] os Output stream where to dump the information
/// \param[in] stable_ Do we only show the stable particles in this event?
void dump( std::ostream& os = *Logger::get().output, bool stable_ = false ) const;
/// Incoming beams centre-of-mass energy, in GeV
double cmEnergy() const;
//----- particles adders
/// \brief Set the information on one particle in the process
/// \param[in] part The Particle object to insert or modify in the event
/// \param[in] replace Do we replace the particle if already present in the event or do we append another particle with the same role ?
Particle& addParticle( Particle& part, bool replace = false );
/// \brief Create a new particle in the event, with no kinematic information but the role it has to play in the process
/// \param[in] role The role the particle will play in the process
/// \param[in] replace Do we replace the particle if already present in the event or do we append another particle with the same role ?
Particle& addParticle( Particle::Role role, bool replace = false );
//----- particles retrievers
/// Number of particles in the event
size_t numParticles() const;
/// Vector of all particles in the event
const Particles particles() const;
/// Vector of all stable particles in the event
const Particles stableParticles() const;
/** Get a list of Particle objects corresponding to a certain role in the process kinematics
* \param[in] role The role the particles have to play in the process
* \return A vector of references to the requested Particle objects
*/
Particles& getByRole( Particle::Role role );
/// Get a list of constant Particle objects corresponding to a certain role in the process kinematics
const Particles& getByRole( Particle::Role role ) const;
/// Get a list of particle identifiers in Event corresponding to a certain role in the process kinematics
ParticlesIds getIdsByRole( Particle::Role role ) const;
/** \brief Get the first Particle object in the particles list whose role corresponds to the given argument
* \param[in] role The role the particle has to play in the event
* \return A Particle object corresponding to the first particle with the role
*/
Particle& getOneByRole( Particle::Role role );
const Particle& getOneByRole( Particle::Role role ) const;
/** \brief Get the reference to the Particle object corresponding to a unique identifier in the event
* \param[in] id The unique identifier to this particle in the event
* \return A reference to the requested Particle object
*/
Particle& operator[]( int id );
/** \brief Get a const Particle object using its unique identifier
* \param[in] id Unique identifier of the particle in the event
* \return Constant object to be retrieved
*/
const Particle& at( int id ) const;
/** \brief Get references to the Particle objects corresponding to the unique identifiers in the event
* \param[in] ids_ The unique identifiers to the particles to be selected in the event
* \return A vector of references to the requested Particle objects
*/
Particles getByIds( const ParticlesIds& ids_ ) const;
/** \brief Get the list of mother particles of any given Particle object in this event
* \param[in] part The reference to the Particle object from which we want to extract the mother particles
* \return A list of parenting Particle object
*/
//----- general particles information retriever
Particles mothers( const Particle& part );
/// Get a vector containing all the daughters from a particle
/// \param[in] part The particle for which the daughter particles have to be retrieved
/// \return Vector of Particle objects containing all the daughters' kinematic information
Particles daughters( const Particle& part );
/// Get a list of roles for the given event (really process-dependant for the central system)
/// \return Vector of integers corresponding to all the roles the particles can play in the event
ParticleRoles roles() const;
/// Number of trials before the event was "correctly" hadronised
unsigned short num_hadronisation_trials;
/// Time needed to generate the event at parton level (in seconds)
float time_generation;
/// Time needed to generate the hadronised (if needed) event (in seconds)
float time_total;
private:
static constexpr double minimal_precision_ = 1.e-10;
/// Check if the event kinematics is properly defined
void checkKinematics() const;
/// List of particles in the event, mapped to their role in the process
ParticlesMap particles_;
/// Last particle in an "empty" event
struct NumParticles {
NumParticles();
NumParticles( const NumParticles& np );
unsigned short cs, op1, op2;
};
NumParticles evtcontent_;
};
}
#endif
diff --git a/CepGen/Event/Momentum.cpp b/CepGen/Event/Momentum.cpp
index b009b38..6be02f9 100644
--- a/CepGen/Event/Momentum.cpp
+++ b/CepGen/Event/Momentum.cpp
@@ -1,379 +1,379 @@
#include "CepGen/Event/Particle.h"
#include "CepGen/Core/Exception.h"
#include "CepGen/Core/utils.h"
#include <math.h>
#include <iomanip>
-namespace CepGen
+namespace cepgen
{
using Momentum = Particle::Momentum;
//----- Particle momentum methods
Momentum::Momentum() :
px_( 0. ), py_( 0. ), pz_( 0. ), p_( 0. ), energy_( 0. )
{}
Momentum::Momentum( double x, double y, double z, double t ) :
px_( x ), py_( y ), pz_( z ), energy_( t )
{
computeP();
}
Momentum::Momentum( double* p ) :
px_( p[0] ), py_( p[1] ), pz_( p[2] ), energy_( p[3] )
{
computeP();
}
//--- static constructors
Momentum
Momentum::fromPtEtaPhi( double pt, double eta, double phi, double e )
{
const double px = pt*cos( phi ),
py = pt*sin( phi ),
pz = pt*sinh( eta );
return Momentum( px, py, pz, e );
}
Momentum
Momentum::fromPThetaPhi( double p, double theta, double phi, double e )
{
const double px = p*sin( theta )*cos( phi ),
py = p*sin( theta )*sin( phi ),
pz = p*cos( theta );
return Momentum( px, py, pz, e );
}
Momentum
Momentum::fromPxPyPzE( double px, double py, double pz, double e )
{
return Momentum( px, py, pz, e );
}
Momentum
Momentum::fromPxPyYM( double px, double py, double rap, double m )
{
const double pt = std::hypot( px, py ), et = std::hypot( pt, m );
return Momentum( px, py, et*sinh( rap ), et*cosh( rap ) );
}
//--- arithmetic operators
Momentum&
Momentum::operator+=( const Momentum& mom )
{
px_ += mom.px_;
py_ += mom.py_;
pz_ += mom.pz_;
energy_ += mom.energy_;
computeP();
return *this;
}
Momentum&
Momentum::operator-=( const Momentum& mom )
{
px_ -= mom.px_;
py_ -= mom.py_;
pz_ -= mom.pz_;
energy_ -= mom.energy_;
computeP();
return *this;
}
bool
Momentum::operator==( const Momentum& mom ) const
{
return ( px_ == mom.px_
&& py_ == mom.py_
&& pz_ == mom.pz_
&& energy_ == mom.energy_ );
}
double
Momentum::threeProduct( const Momentum& mom ) const
{
CG_DEBUG_LOOP( "Momentum" )
<< " (" << px_ << ", " << py_ << ", " << pz_ << ")\n\t"
<< "* (" << mom.px_ << ", " << mom.py_ << ", " << mom.pz_ << ")\n\t"
<< "= " << px_*mom.px_+py_*mom.py_+pz_*mom.pz_;
return px_*mom.px_+py_*mom.py_+pz_*mom.pz_;
}
double
Momentum::fourProduct( const Momentum& mom ) const
{
CG_DEBUG_LOOP( "Momentum" )
<< " (" << px_ << ", " << py_ << ", " << pz_ << ", " << energy_ << ")\n\t"
<< "* (" << mom.px_ << ", " << mom.py_ << ", " << mom.pz_ << ", " << mom.energy_ << ")\n\t"
<< "= " << energy_*mom.energy_-threeProduct(mom);
return energy_*mom.energy_-threeProduct(mom);
}
double
Momentum::crossProduct( const Momentum& mom ) const
{
return px_*mom.py_-py_*mom.px_;
}
double
Momentum::operator*=( const Momentum& mom )
{
return threeProduct( mom );
}
Momentum&
Momentum::operator*=( double c )
{
px_ *= c;
py_ *= c;
pz_ *= c;
energy_ *= c;
computeP();
return *this;
}
Momentum
operator*( const Momentum& mom, double c )
{
Momentum out = mom;
out *= c;
return out;
}
Momentum
operator*( double c, const Momentum& mom )
{
Momentum out = mom;
out *= c;
return out;
}
Momentum
operator+( const Momentum& mom1, const Momentum& mom2 )
{
Momentum out = mom1;
out += mom2;
return out;
}
Momentum
operator-( const Momentum& mom1, const Momentum& mom2 )
{
Momentum out = mom1;
out -= mom2;
return out;
}
Momentum
operator-( const Momentum& mom )
{
return Momentum()-mom;
}
double
operator*( const Momentum& mom1, const Momentum& mom2 )
{
Momentum tmp = mom1;
return tmp.threeProduct( mom2 );
}
//--- various setters
void
Momentum::setMass2( double m2 )
{
energy_ = sqrt( p2()+m2 );
}
void
Momentum::setP( double px, double py, double pz, double e )
{
setP( px, py, pz );
setEnergy( e );
}
void
Momentum::setP( double px, double py, double pz )
{
px_ = px;
py_ = py;
pz_ = pz;
computeP();
}
void
Momentum::computeP()
{
p_ = std::hypot( pt(), pz_ );
}
void
Momentum::truncate( double tolerance )
{
if ( px_ <= tolerance )
px_ = 0.;
if ( py_ <= tolerance )
py_ = 0.;
if ( pz_ <= tolerance )
pz_ = 0.;
if ( energy_ <= tolerance )
energy_ = 0.;
computeP();
}
//--- various getters
double
Momentum::operator[]( unsigned int i ) const
{
switch ( i ) {
case 0: return px_;
case 1: return py_;
case 2: return pz_;
case 3: return energy_;
default:
throw CG_FATAL( "Momentum" ) << "Failed to retrieve the component " << i << "!";
}
}
double&
Momentum::operator[]( const unsigned int i )
{
switch ( i ) {
case 0: return px_;
case 1: return py_;
case 2: return pz_;
case 3: return energy_;
default:
throw CG_FATAL( "Momentum" ) << "Failed to retrieve the component " << i << "!";
}
}
const std::vector<double>
Momentum::pVector() const
{
return std::vector<double>{ px(), py(), pz(), energy(), mass() };
}
double
Momentum::mass() const
{
if ( mass2() >= 0. )
return sqrt( mass2() );
return -sqrt( -mass2() );
}
double
Momentum::theta() const
{
return atan2( pt(), pz() );
}
double
Momentum::phi() const
{
return atan2( py(), px() );
}
double
Momentum::pt() const
{
return std::hypot( px_, py_ );
}
double
Momentum::pt2() const
{
return px_*px_+py_*py_;
}
double
Momentum::eta() const
{
const int sign = ( pz()/fabs( pz() ) );
return ( pt() != 0. )
? log( ( p()+fabs( pz() ) )/pt() )*sign
: 9999.*sign;
}
double
Momentum::rapidity() const
{
const int sign = ( pz()/fabs( pz() ) );
return ( energy() >= 0. )
? log( ( energy()+pz() )/( energy()-pz() ) )*0.5
: 999.*sign;
}
//--- boosts/rotations
Momentum&
Momentum::betaGammaBoost( double gamma, double betagamma )
{
if ( gamma == 1. && betagamma == 0. ) return *this; // trivial case
const double pz = pz_, e = energy_;
pz_ = gamma*pz+betagamma*e;
energy_ = gamma*e +betagamma*pz;
computeP();
return *this;
}
Momentum&
Momentum::lorentzBoost( const Momentum& p )
{
//--- do not boost on a system at rest
if ( p.p() == 0. )
return *this;
const double m = p.mass();
const double pf4 = fourProduct( p )/m;
const double fn = ( pf4+energy_ )/( p.energy_+m );
*this -= p*fn;
energy_ = pf4;
return *this;
}
Momentum&
Momentum::rotatePhi( double phi, double sign )
{
const double px = px_*cos( phi )+py_*sin( phi )*sign,
py =-px_*sin( phi )+py_*cos( phi )*sign;
px_ = px;
py_ = py;
return *this;
}
Momentum&
Momentum::rotateThetaPhi( double theta, double phi )
{
double rotmtx[3][3], mom[3]; //FIXME check this! cos(phi)->-sin(phi) & sin(phi)->cos(phi) --> phi->phi+pi/2 ?
rotmtx[0][0] = -sin( phi ); rotmtx[0][1] = -cos( theta )*cos( phi ); rotmtx[0][2] = sin( theta )*cos( phi );
rotmtx[1][0] = cos( phi ); rotmtx[1][1] = -cos( theta )*sin( phi ); rotmtx[1][2] = sin( theta )*sin( phi );
rotmtx[2][0] = 0.; rotmtx[2][1] = sin( theta ); rotmtx[2][2] = cos( theta );
for ( unsigned short i = 0; i < 3; ++i ) {
mom[i] = 0.;
for ( unsigned short j = 0; j < 3; ++j )
mom[i] += rotmtx[i][j]*operator[]( j );
}
setP( mom[0], mom[1], mom[2] );
return *this;
}
//--- printout
std::ostream&
operator<<( std::ostream& os, const Momentum& mom )
{
return os << "(E|p) = (" << std::fixed
<< std::setw( 9 ) << mom.energy_ << "|"
<< std::setw( 9 ) << mom.px_ << " "
<< std::setw( 9 ) << mom.py_ << " "
<< std::setw( 9 ) << mom.pz_ << ")";
}
}
diff --git a/CepGen/Event/Particle.cpp b/CepGen/Event/Particle.cpp
index 69e0fa4..2ef94e3 100644
--- a/CepGen/Event/Particle.cpp
+++ b/CepGen/Event/Particle.cpp
@@ -1,264 +1,264 @@
#include "CepGen/Event/Particle.h"
#include "CepGen/Physics/PDG.h"
#include "CepGen/Core/Exception.h"
#include "CepGen/Core/utils.h"
#include "CepGen/Physics/Constants.h"
-namespace CepGen
+namespace cepgen
{
Particle::Particle() :
id_( -1 ), charge_sign_( 1 ),
mass_( -1. ), helicity_( 0. ),
role_( UnknownRole ), status_( Status::Undefined ), pdg_id_( PDG::invalid )
{}
Particle::Particle( Role role, PDG pdgId, Status st ) :
id_( -1 ), charge_sign_( 1 ),
mass_( -1. ), helicity_( 0. ),
role_( role ), status_( st ), pdg_id_( pdgId )
{
if ( pdg_id_ != PDG::invalid )
computeMass();
}
Particle::Particle( const Particle& part ) :
id_( part.id_ ), charge_sign_( part.charge_sign_ ),
momentum_( part.momentum_ ), mass_( part.mass_ ), helicity_( part.helicity_ ),
role_( part.role_ ), status_( part.status_ ),
mothers_( part.mothers_ ), daughters_( part.daughters_ ),
pdg_id_( part.pdg_id_ )
{}
bool
Particle::operator<( const Particle& rhs ) const
{
return id_ >= 0
&& rhs.id_ > 0
&& id_ < rhs.id_;
}
double
Particle::thetaToEta( double theta )
{
return -log( tan( 0.5*theta*M_PI/180. ) );
}
double
Particle::etaToTheta( double eta )
{
return 2.*atan( exp( -eta ) )*180.*M_1_PI;
}
bool
Particle::valid()
{
if ( pdg_id_ == PDG::invalid )
return false;
if ( momentum_.p() == 0. && mass_ == 0. )
return false;
return true;
}
void
Particle::computeMass( bool off_shell )
{
if ( !off_shell && pdg_id_ != PDG::invalid ) { // retrieve the mass from the on-shell particle's properties
- mass_ = part::mass( pdg_id_ );
+ mass_ = particleproperties::mass( pdg_id_ );
}
else if ( momentum_.energy() >= 0. ) {
mass_ = sqrt( energy2() - momentum_.p2() );
}
//--- finish by setting the energy accordingly
if ( momentum_.energy() < 0. ) { // invalid energy
momentum_.setEnergy( sqrt( momentum_.p2() + mass2() ) );
}
}
void
Particle::setMass( double m )
{
if ( m >= 0. )
mass_ = m;
else
computeMass();
}
void
Particle::addMother( Particle& part )
{
mothers_.insert( part.id() );
CG_DEBUG_LOOP( "Particle" )
<< "Particle " << id() << " (pdgId=" << part.integerPdgId() << ") "
<< "is the new mother of " << id_ << " (pdgId=" << (int)pdg_id_ << ").";
part.addDaughter( *this );
}
void
Particle::addDaughter( Particle& part )
{
const auto ret = daughters_.insert( part.id() );
if ( CG_EXCEPT_MATCH( "Particle", debugInsideLoop ) ) {
std::ostringstream os;
for ( const auto& daugh : daughters_ )
os << Form( "\n\t * id=%d", daugh );
CG_DEBUG_LOOP( "Particle" )
<< "Particle " << role_ << " (pdgId=" << (int)pdg_id_ << ") "
<< "has now " << daughters_.size() << " daughter(s):"
<< os.str();
}
if ( ret.second ) {
CG_DEBUG_LOOP( "Particle" )
<< "Particle " << part.role() << " (pdgId=" << part.integerPdgId() << ") "
<< "is a new daughter of " << role_ << " (pdgId=" << (int)pdg_id_ << "%4d).";
if ( part.mothers().find( id_ ) == part.mothers().end() )
part.addMother( *this );
}
}
void
Particle::setMomentum( const Momentum& mom, bool offshell )
{
momentum_ = mom;
if ( !offshell && mom.mass() > 0. )
mass_ = momentum_.mass();
else
computeMass();
}
void
Particle::setMomentum( double px, double py, double pz, double e )
{
momentum_.setP( px, py, pz );
setEnergy( e );
if ( fabs( e-momentum_.energy() ) > 1.e-6 ) // more than 1 eV difference
CG_ERROR( Form( "Energy difference: %.5e", e-momentum_.energy() ) );
}
double
Particle::energy() const
{
return ( momentum_.energy() < 0.
? std::hypot( mass_, momentum_.p() )
: momentum_.energy() );
}
void
Particle::setEnergy( double e )
{
if ( e < 0. && mass_ >= 0. )
e = std::hypot( mass_, momentum_.p() );
momentum_.setEnergy( e );
}
void
Particle::setPdgId( short pdg )
{
pdg_id_ = (PDG)abs( pdg );
switch ( pdg_id_ ) {
case PDG::electron: case PDG::muon: case PDG::tau:
charge_sign_ = -pdg/abs( pdg ); break;
default:
charge_sign_ = pdg/abs( pdg ); break;
}
}
void
Particle::setPdgId( const PDG& pdg, short ch )
{
pdg_id_ = pdg;
switch ( pdg_id_ ) {
case PDG::electron: case PDG::muon: case PDG::tau:
charge_sign_ = -ch; break;
default:
charge_sign_ = ch; break;
}
}
int
Particle::integerPdgId() const
{
- const float ch = part::charge( pdg_id_ );
+ const float ch = particleproperties::charge( pdg_id_ );
if ( ch == 0 )
return static_cast<int>( pdg_id_ );
return static_cast<int>( pdg_id_ ) * charge_sign_ * ( ch/fabs( ch ) );
}
void
Particle::dump() const
{
std::ostringstream osm, osd;
if ( !primary() ) {
osm << ": mother(s): ";
unsigned short i = 0;
for ( const auto& moth : mothers_ ) {
osm << ( i > 0 ? ", " : "" ) << moth;
++i;
}
}
const ParticlesIds daughters_list = daughters();
if ( daughters_list.size() > 0 ) {
osd << ": id = ";
unsigned short i = 0;
for ( const auto& daugh : daughters_list ) {
osm << ( i > 0 ? ", " : "" ) << daugh;
++i;
}
}
CG_INFO( "Particle" )
<< "Dumping a particle with id=" << id_ << ", role=" << role_ << ", status=" << (int)status_ << "\n\t"
<< "Particle id: " << integerPdgId() << " (" << pdg_id_ << "), mass = " << mass_ << " GeV\n\t"
<< "Momentum: " << momentum_ << " GeV\t" << "(|P| = p = " << momentum_.p() << " GeV)\n\t"
<< " p⟂ = " << momentum_.pt() << " GeV, eta = " << momentum_.eta() << ", phi = " << momentum_.phi() << "\n\t"
<< "Primary? " << yesno( primary() ) << osm.str() << "\n\t"
<< numDaughters() << " daughter(s)" << osd.str();
}
double
Particle::etaToY( double eta_, double m_, double pt_ )
{
const double m2 = m_*m_, mt = std::hypot( m_, pt_ );
return asinh( sqrt( ( ( mt*mt-m2 )*cosh( 2.*eta_ )+m2 )/ mt*mt - 1. )*M_SQRT1_2 );
}
std::ostream&
operator<<( std::ostream& os, const Particle::Role& rl )
{
switch ( rl ) {
case Particle::UnknownRole: return os << "unknown";
case Particle::IncomingBeam1: return os << "i.beam 1";
case Particle::IncomingBeam2: return os << "i.beam 2";
case Particle::OutgoingBeam1: return os << "o.beam 1";
case Particle::OutgoingBeam2: return os << "o.beam 2";
case Particle::Parton1: return os << "parton 1";
case Particle::Parton2: return os << "parton 2";
case Particle::Parton3: return os << "parton 3";
case Particle::Intermediate: return os << "hard pr.";
case Particle::CentralSystem: return os << "central";
}
return os;
}
double
CMEnergy( const Particle& p1, const Particle& p2 )
{
if ( p1.mass()*p2.mass() < 0.
|| p1.energy()*p2.energy() < 0. )
return 0.;
return sqrt( p1.mass2()+p2.mass2() + 2.*p1.energy()*p2.energy() - 2.*( p1.momentum()*p2.momentum() ) );
}
double
CMEnergy( const Particle::Momentum& m1, const Particle::Momentum& m2 )
{
if ( m1.mass()*m2.mass() < 0.
|| m1.energy()*m2.energy() < 0. )
return 0.;
return sqrt( m1.mass2()+m2.mass2() + 2.*m1.energy()*m2.energy() - 2.*( m1*m2 ) );
}
}
diff --git a/CepGen/Event/Particle.h b/CepGen/Event/Particle.h
index 298206a..2992b54 100644
--- a/CepGen/Event/Particle.h
+++ b/CepGen/Event/Particle.h
@@ -1,346 +1,346 @@
#ifndef CepGen_Event_Particle_h
#define CepGen_Event_Particle_h
#include "CepGen/Physics/ParticleProperties.h"
#include <set>
#include <map>
#include <vector>
-namespace CepGen
+namespace cepgen
{
/// A set of integer-type particle identifiers
typedef std::set<int> ParticlesIds;
/// Kinematic information for one particle
class Particle {
public:
/// Internal status code for a particle
enum class Status {
PrimordialIncoming = -9,
DebugResonance = -5,
Resonance = -4,
Fragmented = -3,
Propagator = -2,
Incoming = -1,
Undefined = 0,
FinalState = 1,
Undecayed = 2, Unfragmented = 3
};
/// Role of the particle in the process
enum Role {
UnknownRole = -1,
IncomingBeam1 = 1, IncomingBeam2 = 2,
OutgoingBeam1 = 3, OutgoingBeam2 = 5,
CentralSystem = 6,
Intermediate = 4,
Parton1 = 41, Parton2 = 42, Parton3 = 43
};
/**
* Container for a particle's 4-momentum, along with useful methods to ease the development of any matrix element level generator
* \brief 4-momentum for a particle
* \date Dec 2015
* \author Laurent Forthomme <laurent.forthomme@cern.ch>
*/
class Momentum {
public:
/// Build a 4-momentum at rest with an invalid energy (no mass information known)
Momentum();
/// Build a 4-momentum using its 3-momentum coordinates and its energy
Momentum( double x, double y, double z, double t = -1. );
/// Build a 4-momentum using its 3-momentum coordinates and its energy
Momentum( double* p );
// --- static definitions
/// Build a 3-momentum from its three pseudo-cylindric coordinates
static Momentum fromPtEtaPhi( double pt, double eta, double phi, double e = -1. );
/// Build a 4-momentum from its scalar momentum, and its polar and azimuthal angles
static Momentum fromPThetaPhi( double p, double theta, double phi, double e = -1. );
/// Build a 4-momentum from its four momentum and energy coordinates
static Momentum fromPxPyPzE( double px, double py, double pz, double e );
/// Build a 4-momentum from its transverse momentum, rapidity and mass
static Momentum fromPxPyYM( double px, double py, double rap, double m );
// --- vector and scalar operators
/// Scalar product of the 3-momentum with another 3-momentum
double threeProduct( const Momentum& ) const;
/// Scalar product of the 4-momentum with another 4-momentum
double fourProduct( const Momentum& ) const;
/// Vector product of the 3-momentum with another 3-momentum
double crossProduct( const Momentum& ) const;
/// Add a 4-momentum through a 4-vector sum
Momentum& operator+=( const Momentum& );
/// Subtract a 4-momentum through a 4-vector sum
Momentum& operator-=( const Momentum& );
/// Scalar product of the 3-momentum with another 3-momentum
double operator*=( const Momentum& );
/// Multiply all 4-momentum coordinates by a scalar
Momentum& operator*=( double c );
/// Equality operator
bool operator==( const Momentum& ) const;
/// Human-readable format for a particle's momentum
friend std::ostream& operator<<( std::ostream& os, const Particle::Momentum& mom );
Momentum& betaGammaBoost( double gamma, double betagamma );
/// Forward Lorentz boost
Momentum& lorentzBoost( const Particle::Momentum& p );
// --- setters and getters
/// Set all the components of the 4-momentum (in GeV)
void setP( double px, double py, double pz, double e );
/// Set all the components of the 3-momentum (in GeV)
void setP( double px, double py, double pz );
/// Set the energy (in GeV)
inline void setEnergy( double e ) { energy_ = e; }
/// Compute the energy from the mass
inline void setMass( double m ) { setMass2( m*m ); }
/// Compute the energy from the mass
void setMass2( double m2 );
/// Get one component of the 4-momentum (in GeV)
double operator[]( const unsigned int i ) const;
/// Get one component of the 4-momentum (in GeV)
double& operator[]( const unsigned int i );
/// Momentum along the \f$x\f$-axis (in GeV)
inline double px() const { return px_; }
/// Momentum along the \f$y\f$-axis (in GeV)
inline double py() const { return py_; }
/// Longitudinal momentum (in GeV)
inline double pz() const { return pz_; }
/// Transverse momentum (in GeV)
double pt() const;
/// Squared transverse momentum (in GeV\f${}^2\f$)
double pt2() const;
/// 4-vector of double precision floats (in GeV)
const std::vector<double> pVector() const;
/// 3-momentum norm (in GeV)
inline double p() const { return p_; }
/// Squared 3-momentum norm (in GeV\f${}^2\f$)
inline double p2() const { return p_*p_; }
/// Energy (in GeV)
inline double energy() const { return energy_; }
/// Squared energy (in GeV\f${}^2\f$)
inline double energy2() const { return energy_*energy_; }
/// Squared mass (in GeV\f${}^2\f$) as computed from its energy and momentum
inline double mass2() const { return energy2()-p2(); }
/// Mass (in GeV) as computed from its energy and momentum
/// \note Returns \f$-\sqrt{|E^2-\mathbf{p}^2|}<0\f$ if \f$\mathbf{p}^2>E^2\f$
double mass() const;
/// Polar angle (angle with respect to the longitudinal direction)
double theta() const;
/// Azimutal angle (angle in the transverse plane)
double phi() const;
/// Pseudo-rapidity
double eta() const;
/// Rapidity
double rapidity() const;
void truncate( double tolerance = 1.e-10 );
/// Rotate the transverse components by an angle phi (and reflect the y coordinate)
Momentum& rotatePhi( double phi, double sign );
/// Rotate the particle's momentum by a polar/azimuthal angle
Momentum& rotateThetaPhi( double theta_, double phi_ );
/// Apply a \f$ z\rightarrow -z\f$ transformation
inline Momentum& mirrorZ() { pz_ = -pz_; return *this; }
private:
/// Compute the 3-momentum's norm
void computeP();
/// Momentum along the \f$x\f$-axis
double px_;
/// Momentum along the \f$y\f$-axis
double py_;
/// Momentum along the \f$z\f$-axis
double pz_;
/// 3-momentum's norm (in GeV/c)
double p_;
/// Energy (in GeV)
double energy_;
};
/// Human-readable format for a particle's PDG code
friend std::ostream& operator<<( std::ostream& os, const PDG& pc );
/// Human-readable format for a particle's role in the event
friend std::ostream& operator<<( std::ostream& os, const Particle::Role& rl );
/// Compute the 4-vector sum of two 4-momenta
friend Particle::Momentum operator+( const Particle::Momentum& mom1, const Particle::Momentum& mom2 );
/// Compute the 4-vector difference of two 4-momenta
friend Particle::Momentum operator-( const Particle::Momentum& mom1, const Particle::Momentum& mom2 );
/// Compute the inverse per-coordinate 4-vector
friend Particle::Momentum operator-( const Particle::Momentum& mom );
/// Scalar product of two 3-momenta
friend double operator*( const Particle::Momentum& mom1, const Particle::Momentum& mom2 );
/// Multiply all components of a 4-momentum by a scalar
friend Particle::Momentum operator*( const Particle::Momentum& mom, double c );
/// Multiply all components of a 4-momentum by a scalar
friend Particle::Momentum operator*( double c, const Particle::Momentum& mom );
//----- static getters
/// Convert a polar angle to a pseudo-rapidity
static double thetaToEta( double theta );
/// Convert a pseudo-rapidity to a polar angle
static double etaToTheta( double eta );
/// Convert a pseudo-rapidity to a rapidity
static double etaToY( double eta_, double m_, double pt_ );
Particle();
/// Build using the role of the particle in the process and its PDG id
/// \param[in] pdgId PDG identifier
/// \param[in] role Role of the particle in the process
/// \param[in] st Current status
Particle( Role role, PDG pdgId, Status st = Status::Undefined );
/// Copy constructor
Particle( const Particle& );
inline ~Particle() {}
/// Comparison operator (from unique identifier)
bool operator<( const Particle& rhs ) const;
/// Comparison operator (from their reference's unique identifier)
//bool operator<( Particle *rhs ) const { return ( id < rhs->id ); }
// --- general particle properties
/// Unique identifier (in a Event object context)
int id() const { return id_; }
//void setId( int id ) { id_ = id; }
/// Set the particle unique identifier in an event
void setId( int id ) { id_ = id; }
/// Electric charge (given as a float number, for the quarks and bound states)
- float charge() const { return charge_sign_ * part::charge( pdg_id_ ); }
+ float charge() const { return charge_sign_ * particleproperties::charge( pdg_id_ ); }
/// Set the electric charge sign (+-1 for charged or 0 for neutral particles)
void setChargeSign( int sign ) { charge_sign_ = sign; }
/// Role in the considered process
Role role() const { return role_; }
/// Set the particle role in the process
void setRole( const Role& role ) { role_ = role; }
/**
* Codes 1-10 correspond to currently existing partons/particles, and larger codes contain partons/particles which no longer exist, or other kinds of event information
* \brief Particle status
*/
Status status() const { return status_; }
/// Set the particle decay/stability status
void setStatus( Status status ) { status_ = status; }
/// Set the PDG identifier (along with the particle's electric charge)
/// \param[in] pdg PDG identifier
/// \param[in] ch Electric charge (0, 1, or -1)
void setPdgId( const PDG& pdg, short ch = 0 );
/// Set the PDG identifier (along with the particle's electric charge)
/// \param[in] pdg_id PDG identifier (incl. electric charge in e)
void setPdgId( short pdg_id );
/// Retrieve the objectified PDG identifier
inline PDG pdgId() const { return pdg_id_; }
/// Retrieve the integer value of the PDG identifier
int integerPdgId() const;
/// Particle's helicity
float helicity() const { return helicity_; }
/// Set the helicity of the particle
void setHelicity( float heli ) { helicity_ = heli; }
/// Particle mass in GeV/c\f${}^2\f$
/// \return Particle's mass
inline double mass() const { return mass_; };
/// Compute the particle mass
/// \param[in] off_shell Allow the particle to be produced off-shell?
/// \note This method ensures that the kinematics is properly set (the mass is set according to the energy and the momentum in priority)
void computeMass( bool off_shell = false );
/// Set the particle mass, in GeV/c\f${}^2\f$
/// \param m Mass in GeV/c\f${}^2\f$
/// \note This method ensures that the kinematics is properly set (the mass is set according to the energy and the momentum in priority)
void setMass( double m = -1. );
/// Particle squared mass, in GeV\f${}^2\f$/c\f${}^4\f$
inline double mass2() const { return mass_*mass_; };
/// Retrieve the momentum object associated with this particle
inline Momentum& momentum() { return momentum_; }
/// Retrieve the momentum object associated with this particle
inline Momentum momentum() const { return momentum_; }
/// Associate a momentum object to this particle
void setMomentum( const Momentum& mom, bool offshell = false );
/**
* \brief Set the 3- or 4-momentum associated to the particle
* \param[in] px Momentum along the \f$x\f$-axis, in GeV/c
* \param[in] py Momentum along the \f$y\f$-axis, in GeV/c
* \param[in] pz Momentum along the \f$z\f$-axis, in GeV/c
* \param[in] e Energy, in GeV
*/
void setMomentum( double px, double py, double pz, double e = -1. );
/// Set the 4-momentum associated to the particle
/// \param[in] p 4-momentum
inline void setMomentum( double p[4] ) { setMomentum( p[0], p[1], p[2], p[3] ); }
/// Set the particle's energy
/// \param[in] e Energy, in GeV
void setEnergy( double e = -1. );
/// Get the particle's energy, in GeV
double energy() const;
/// Get the particle's squared energy, in GeV\f${}^2\f$
inline double energy2() const { return energy()*energy(); };
/// Is this particle a valid particle which can be used for kinematic computations?
bool valid();
// --- particle relations
/// Is this particle a primary particle?
inline bool primary() const { return mothers_.empty(); }
/// Set the mother particle
/// \param[in] part A Particle object containing all the information on the mother particle
void addMother( Particle& part );
/// Get the unique identifier to the mother particle from which this particle arises
/// \return An integer representing the unique identifier to the mother of this particle in the event
inline ParticlesIds mothers() const { return mothers_; }
/**
* \brief Add a decay product
* \param[in] part The Particle object in which this particle will desintegrate or convert
* \return A boolean stating if the particle has been added to the daughters list or if it was already present before
*/
void addDaughter( Particle& part );
/// Gets the number of daughter particles
inline unsigned int numDaughters() const { return daughters_.size(); };
/// Get an identifiers list all daughter particles
/// \return An integer vector containing all the daughters' unique identifier in the event
inline ParticlesIds daughters() const { return daughters_; }
// --- global particle information extraction
/// Dump all the information on this particle into the standard output stream
void dump() const;
private:
/// Unique identifier in an event
int id_;
/// Electric charge (+-1 or 0)
short charge_sign_;
/// Momentum properties handler
Momentum momentum_;
/// Mass, in GeV/c\f${}^2\f$
double mass_;
/// Helicity
float helicity_;
/// Role in the process
Role role_;
/// Decay/stability status
Status status_;
/// List of mother particles
ParticlesIds mothers_;
/// List of daughter particles
ParticlesIds daughters_;
/// PDG id
PDG pdg_id_;
};
/// Compute the centre of mass energy of two particles (incoming or outgoing states)
double CMEnergy( const Particle& p1, const Particle& p2 );
/// Compute the centre of mass energy of two particles (incoming or outgoing states)
double CMEnergy( const Particle::Momentum& m1, const Particle::Momentum& m2 );
//bool operator<( const Particle& a, const Particle& b ) { return a.id<b.id; }
// --- particle containers
/// List of Particle objects
typedef std::vector<Particle> Particles;
/// List of particles' roles
typedef std::vector<Particle::Role> ParticleRoles;
/// Map between a particle's role and its associated Particle object
typedef std::map<Particle::Role,Particles> ParticlesMap;
}
#endif
diff --git a/CepGen/Generator.h b/CepGen/Generator.h
index b2afd73..00149e1 100644
--- a/CepGen/Generator.h
+++ b/CepGen/Generator.h
@@ -1,122 +1,122 @@
#ifndef CepGen_Generator_h
#define CepGen_Generator_h
#include <sstream>
#include <memory>
#include <functional>
////////////////////////////////////////////////////////////////////////////////
/**
* \mainpage Foreword
* This Monte Carlo generator was developed as a modern version of the LPAIR code introduced
* in the early 1990s by J. Vermaseren *et al*\cite Baranov:1991yq\cite Vermaseren:1982cz. This latter allows to
* compute the cross-section and to generate events for the \f$\gamma\gamma\to\ell^{+}\ell^{-}\f$
* process in the scope of high energy physics.
*
* Soon after the integration of its matrix element, it was extended as a tool to compute and
* generate events for any generic 2\f$\rightarrow\f$ 3 central exclusive process.
* To do so, the main operation performed here is the integration of the matrix element (given as a
* subset of a GenericProcess object) over the full available phase space.
*
*/
////////////////////////////////////////////////////////////////////////////////
/// Common namespace for this Monte Carlo generator
-namespace CepGen
+namespace cepgen
{
namespace integrand
{
/**
* Function to be integrated. It returns the value of the weight for one point
* of the full phase space (or "event"). This weights includes the matrix element
* of the process considered, along with all the kinematic factors, and the cut
* restrictions imposed on this phase space. \f$x\f$ is therefore an array of random
* numbers defined inside its boundaries (as normalised so that \f$\forall i<\mathrm{ndim}\f$,
* \f$0<x_i<1\f$.
*/
double eval( double*, size_t, void* );
}
class Event;
class Integrator;
class Parameters;
////////////////////////////////////////////////////////////////////////////////
/**
* This object represents the core of this Monte Carlo generator, with its
* capability to generate the events (using the embedded Vegas object) and to
* study the phase space in term of the variation of resulting cross section
* while scanning the various parameters (point \f${\bf x}\f$ in the
* multi-dimensional phase space).
*
* The phase space is constrained using the Parameters object given as an
* argument to the constructor, and the differential cross-sections for each
* value of the array \f${\bf x}\f$ are computed in the \a f-function defined
* outside (but populated inside) this object.
*
* This f-function embeds a GenericProcess-inherited object which defines all the
* methods to compute this differential cross-section as well as the in- and outgoing
* kinematics associated to each particle.
*
* \author Laurent Forthomme <laurent.forthomme@cern.ch>
* \date Feb 2013
* \brief Core of the Monte-Carlo generator
*
*/
class Generator {
public:
/// Core of the Monte Carlo integrator and events generator
Generator();
/// Core of the Monte Carlo integrator and events generator
/// \param[in] ip List of input parameters defining the phase space on which to perform the integration
Generator( Parameters *ip );
~Generator();
/// Dump this program's header into the standard output stream
void printHeader();
/// Feed the generator with a Parameters object
void setParameters( Parameters& ip );
/// Remove all references to a previous generation/run
void clearRun();
/**
* Compute the cross section for the run parameters defined by this object.
* This returns the cross section as well as the absolute error computed along.
* \brief Compute the cross-section for the given process
* \param[out] xsec The computed cross-section, in pb
* \param[out] err The absolute integration error on the computed cross-section, in pb
*/
void computeXsection( double& xsec, double& err );
/// Integrate the functional over the whole phase space
void integrate();
/// Last cross section computed by the generator
double crossSection() const { return result_; }
/// Last error on the cross section computed by the generator
double crossSectionError() const { return result_error_; }
//void terminate();
/// Generate one single event given the phase space computed by Vegas in the integration step
/// \return A pointer to the Event object generated in this run
std::shared_ptr<Event> generateOneEvent();
/// Launch the generation of events
void generate( std::function<void( const Event&, unsigned long )> callback = {} );
/// Number of dimensions on which the integration is performed
size_t numDimensions() const;
/// Compute one single point from the total phase space
/// \param[in] x the n-dimensional point to compute
/// \return the function value for the given point
double computePoint( double* x );
/// Physical Parameters used in the events generation and cross-section computation
std::unique_ptr<Parameters> parameters;
private:
/// Vegas instance which will integrate the function
std::unique_ptr<Integrator> integrator_;
/// Cross section value computed at the last integration
double result_;
/// Error on the cross section as computed in the last integration
double result_error_;
};
}
#endif
diff --git a/CepGen/Hadronisers/GenericHadroniser.cpp b/CepGen/Hadronisers/GenericHadroniser.cpp
index 8b297ec..4b578ae 100644
--- a/CepGen/Hadronisers/GenericHadroniser.cpp
+++ b/CepGen/Hadronisers/GenericHadroniser.cpp
@@ -1,53 +1,53 @@
#include "CepGen/Hadronisers/GenericHadroniser.h"
#include "CepGen/Core/Exception.h"
#include "CepGen/Core/ParametersList.h"
-namespace CepGen
+namespace cepgen
{
namespace hadroniser
{
GenericHadroniser::GenericHadroniser( const char* name, const ParametersList& plist ) :
name_( name ),
seed_ ( plist.get<int>( "seed", -1ll ) ),
max_trials_( plist.get<int>( "maxTrials", 1 ) )
{
CG_DEBUG( "Hadroniser:init" )
<< "\"" << name_ << "\"-type hadroniser built with:\n\t"
<< "* seed = " << seed_ << "\n\t"
<< "* maximum trials: " << max_trials_;
}
void
GenericHadroniser::readStrings( const std::vector<std::string>& params ) {
if ( params.empty() )
return;
std::ostringstream os;
for ( const auto& p : params ) {
readString( p );
os << "\n\t '" << p << "'";
}
CG_DEBUG( "Hadroniser:configure" )
<< "Feeding \"" << name_ << "\" hadroniser with:"
<< os.str();
}
std::string
GenericHadroniser::name() const
{
return name_;
}
}
std::ostream&
operator<<( std::ostream& os, const hadroniser::GenericHadroniser& hadr )
{
return os << hadr.name().c_str();
}
std::ostream&
operator<<( std::ostream& os, const hadroniser::GenericHadroniser* hadr )
{
return os << hadr->name().c_str();
}
}
diff --git a/CepGen/Hadronisers/GenericHadroniser.h b/CepGen/Hadronisers/GenericHadroniser.h
index 082fe9c..bfdfaa4 100644
--- a/CepGen/Hadronisers/GenericHadroniser.h
+++ b/CepGen/Hadronisers/GenericHadroniser.h
@@ -1,70 +1,70 @@
#ifndef CepGen_Hadronisers_GenericHadroniser_h
#define CepGen_Hadronisers_GenericHadroniser_h
#include <vector>
#include <memory>
#include <iostream>
-namespace CepGen
+namespace cepgen
{
class Event;
class Particle;
class Parameters;
class ParametersList;
/// Location for all hadronisers to be run downstream to the events generation
namespace hadroniser
{
/**
* \brief Class template to define any hadroniser as a general object with defined methods
* \author Laurent Forthomme <laurent.forthomme@cern.ch>
* \date January 2014
*/
class GenericHadroniser
{
public:
/// Write out all hadroniser attributes in output stream
friend std::ostream& operator<<( std::ostream& os, const GenericHadroniser& hadr );
/// Write out all hadroniser attributes in output stream
friend std::ostream& operator<<( std::ostream& os, const GenericHadroniser* hadr );
/// Default constructor for an undefined hadroniser
explicit GenericHadroniser( const char* name, const ParametersList& );
virtual ~GenericHadroniser() {}
/// Parse a configuration string
virtual void readString( const char* ) {}
/// Parse a configuration string
virtual void readString( const std::string& param ) { readString( param.c_str() ); }
/// Parse a list of configuration strings
virtual void readStrings( const std::vector<std::string>& params );
/// Initialise the event hadroniser before its running
virtual void init() = 0;
/** \brief Hadronise a full event
* \param[inout] ev Event to hadronise
* \param[inout] weight Event weight after hadronisation
* \param[in] full Perform the full state hadronisation (incl. remnants fragmentation)
* \return Boolean stating whether or not the hadronisation occured successfully
*/
virtual bool run( Event& ev, double& weight, bool full ) = 0;
/// Specify the process cross section, in pb
virtual void setCrossSection( double xsec, double xsec_err ) {}
/// \brief Specify a random numbers generator seed for the hadroniser
/// \param[in] seed A RNG seed
void setSeed( long long seed ) { seed_ = seed; }
/// Return a human-readable name for this hadroniser
std::string name() const;
protected:
/// Name of the hadroniser
std::string name_;
/// Random numbers generator seed for the hadroniser
long long seed_;
/// Maximal number of trials for the hadronisation of the proton(s) remnants
unsigned short max_trials_;
};
}
}
#endif
diff --git a/CepGen/Hadronisers/Pythia8Hadroniser.cpp b/CepGen/Hadronisers/Pythia8Hadroniser.cpp
index b188eda..9a025ae 100644
--- a/CepGen/Hadronisers/Pythia8Hadroniser.cpp
+++ b/CepGen/Hadronisers/Pythia8Hadroniser.cpp
@@ -1,464 +1,464 @@
#include "CepGen/Hadronisers/Pythia8Hadroniser.h"
#include "CepGen/Parameters.h"
#include "CepGen/Physics/Kinematics.h"
#include "CepGen/Physics/Constants.h"
#include "CepGen/Physics/PDG.h"
#include "CepGen/Core/ParametersList.h"
#include "CepGen/Core/Exception.h"
#include "CepGen/Core/utils.h"
#include "CepGen/Event/Event.h"
#include "CepGen/Event/Particle.h"
#include "CepGen/Version.h"
-namespace CepGen
+namespace cepgen
{
namespace hadroniser
{
#ifdef PYTHIA8
Pythia8::Vec4
momToVec4( const Particle::Momentum& mom )
{
return Pythia8::Vec4( mom.px(), mom.py(), mom.pz(), mom.energy() );
}
#endif
Pythia8Hadroniser::Pythia8Hadroniser( const Parameters& params, const ParametersList& plist ) :
GenericHadroniser( "pythia8", plist ),
#ifdef PYTHIA8
pythia_( new Pythia8::Pythia ), lhaevt_( new LHAEvent( &params ) ),
#endif
full_evt_( false ), offset_( 0 ), first_evt_( true ), params_( &params )
{
#ifdef PYTHIA8
pythia_->setLHAupPtr( (Pythia8::LHAup*)lhaevt_.get() );
pythia_->settings.parm( "Beams:idA", (short)params.kinematics.incoming_beams.first.pdg );
pythia_->settings.parm( "Beams:idB", (short)params.kinematics.incoming_beams.second.pdg );
// specify we will be using a LHA input
pythia_->settings.mode( "Beams:frameType", 5 );
pythia_->settings.parm( "Beams:eCM", params.kinematics.sqrtS() );
#endif
for ( const auto& pdgid : params.kinematics.minimum_final_state )
min_ids_.emplace_back( (unsigned short)pdgid );
}
Pythia8Hadroniser::~Pythia8Hadroniser()
{
#ifdef PYTHIA8
pythia_->settings.writeFile( "last_pythia_config.cmd", false );
#endif
}
void
Pythia8Hadroniser::readString( const char* param )
{
#ifdef PYTHIA8
if ( !pythia_->readString( param ) )
throw CG_FATAL( "Pythia8Hadroniser" ) << "The Pythia8 core failed to parse the following setting:\n\t" << param;
#endif
}
void
Pythia8Hadroniser::init()
{
#ifdef PYTHIA8
if ( pythia_->settings.flag( "ProcessLevel:all" ) != full_evt_ )
pythia_->settings.flag( "ProcessLevel:all", full_evt_ );
if ( seed_ == -1ll )
pythia_->settings.flag( "Random:setSeed", false );
else {
pythia_->settings.flag( "Random:setSeed", true );
pythia_->settings.mode( "Random:seed", seed_ );
}
switch ( params_->kinematics.mode ) {
case KinematicsMode::ElasticElastic: {
pythia_->settings.mode( "BeamRemnants:unresolvedHadron", 3 );
} break;
case KinematicsMode::InelasticElastic: {
pythia_->settings.mode( "BeamRemnants:unresolvedHadron", 2 );
} break;
case KinematicsMode::ElasticInelastic: {
pythia_->settings.mode( "BeamRemnants:unresolvedHadron", 1 );
} break;
case KinematicsMode::InelasticInelastic: default: {
pythia_->settings.mode( "BeamRemnants:unresolvedHadron", 0 );
} break;
}
if ( !pythia_->init() )
throw CG_FATAL( "Pythia8Hadroniser" )
<< "Failed to initialise the Pythia8 core!\n\t"
<< "See the message above for more details.";
#else
throw CG_FATAL( "Pythia8Hadroniser" )
<< "Pythia8 is not linked to this instance!";
#endif
}
void
Pythia8Hadroniser::setCrossSection( double xsec, double xsec_err )
{
#ifdef PYTHIA8
lhaevt_->setCrossSection( 0, xsec, xsec_err );
#endif
}
bool
Pythia8Hadroniser::run( Event& ev, double& weight, bool full )
{
//--- initialise the event weight before running any decay algorithm
weight = 1.;
#ifdef PYTHIA8
if ( !full && !pythia_->settings.flag( "ProcessLevel:resonanceDecays" ) )
return true;
//--- switch full <-> partial event
if ( full != full_evt_ ) {
full_evt_ = full;
init();
}
//===========================================================================================
// convert our event into a custom LHA format
//===========================================================================================
lhaevt_->feedEvent( ev, full, params_->kinematics.mode );
//if ( full ) lhaevt_->listEvent();
//===========================================================================================
// launch the hadronisation / resonances decays, and update the event accordingly
//===========================================================================================
ev.num_hadronisation_trials = 0;
while ( true ) {
if ( ev.num_hadronisation_trials++ > max_trials_ )
return false;
//--- run the hadronisation/fragmentation algorithm
if ( pythia_->next() ) {
//--- hadronisation successful
if ( first_evt_ && full ) {
offset_ = 0;
for ( unsigned short i = 1; i < pythia_->event.size(); ++i )
if ( pythia_->event[i].status() == -12 ) // skip the incoming particles
offset_++;
first_evt_ = false;
}
break;
}
}
//===========================================================================================
// update the event content with Pythia's output
//===========================================================================================
updateEvent( ev, weight, full );
return true;
#else
throw CG_FATAL( "Pythia8Hadroniser" ) << "Pythia8 is not linked to this instance!";
#endif
}
#ifdef PYTHIA8
Particle&
Pythia8Hadroniser::addParticle( Event& ev, const Pythia8::Particle& py_part, const Pythia8::Vec4& mom, unsigned short role ) const
{
Particle& op = ev.addParticle( (Particle::Role)role );
op.setPdgId( static_cast<PDG>( abs( py_part.id() ) ), py_part.charge() );
op.setStatus( py_part.isFinal()
? Particle::Status::FinalState
: Particle::Status::Propagator );
op.setMomentum( Particle::Momentum( mom.px(), mom.py(), mom.pz(), mom.e() ) );
op.setMass( mom.mCalc() );
lhaevt_->addCorresp( py_part.index()-offset_, op.id() );
return op;
}
void
Pythia8Hadroniser::updateEvent( Event& ev, double& weight, bool full ) const
{
for ( unsigned short i = 1+offset_; i < pythia_->event.size(); ++i ) {
const Pythia8::Particle& p = pythia_->event[i];
const unsigned short cg_id = lhaevt_->cepgenId( i-offset_ );
if ( cg_id != LHAEvent::invalid_id ) {
//----- particle already in the event
Particle& cg_part = ev[cg_id];
//--- fragmentation result
if ( cg_part.role() == Particle::OutgoingBeam1
|| cg_part.role() == Particle::OutgoingBeam2 ) {
cg_part.setStatus( Particle::Status::Fragmented );
continue;
}
//--- particle is not what we expect
if ( p.idAbs() != abs( cg_part.integerPdgId() ) ) {
CG_INFO( "Pythia8Hadroniser:update" ) << "LHAEVT event content:";
lhaevt_->listEvent();
CG_INFO( "Pythia8Hadroniser:update" ) << "Pythia event content:";
pythia_->event.list();
CG_INFO( "Pythia8Hadroniser:update" ) << "CepGen event content:";
ev.dump();
CG_INFO( "Pythia8Hadroniser:update" ) << "Correspondence:";
lhaevt_->dumpCorresp();
throw CG_FATAL( "Pythia8Hadroniser:update" )
<< "Event list corruption detected for (Pythia/CepGen) particle " << i << "/" << cg_id << ":\n\t"
<< "should be " << abs( p.id() ) << ", "
<< "got " << cg_part.integerPdgId() << "!";
}
//--- resonance decayed; apply branching ratio for this decay
if ( p.particleDataEntry().sizeChannels() > 0 ) {
weight *= p.particleDataEntry().pickChannel().bRatio();
cg_part.setStatus( Particle::Status::Resonance );
}
}
else {
//----- new particle to be added
const unsigned short role = findRole( ev, p );
switch ( (Particle::Role)role ) {
default: break;
case Particle::OutgoingBeam1: {
ev.getByRole( Particle::OutgoingBeam1 )[0].setStatus( Particle::Status::Fragmented );
if ( abs( p.status() ) != 61 )
break;
} // no break!
case Particle::OutgoingBeam2: {
ev.getByRole( Particle::OutgoingBeam2 )[0].setStatus( Particle::Status::Fragmented );
if ( abs( p.status() ) != 61 )
break;
} // no break!
}
// found the role ; now we can add the particle
Particle& cg_part = addParticle( ev, p, p.p(), role );
for ( const auto& moth_id : p.motherList() ) {
if ( moth_id <= offset_ )
continue;
const unsigned short moth_cg_id = lhaevt_->cepgenId( moth_id-offset_ );
if ( moth_cg_id != LHAEvent::invalid_id )
cg_part.addMother( ev[moth_cg_id] );
else
cg_part.addMother( addParticle( ev, pythia_->event[moth_id], p.p(), role ) );
if ( !p.isFinal() ) {
if ( p.isResonance() || p.daughterList().size() > 0 )
cg_part.setStatus( Particle::Status::Resonance );
else
cg_part.setStatus( Particle::Status::Undefined );
}
}
}
}
}
unsigned short
Pythia8Hadroniser::findRole( const Event& ev, const Pythia8::Particle& p ) const
{
for ( const auto& par_id : p.motherList() ) {
if ( par_id == 1 && offset_ > 0 )
return (unsigned short)Particle::OutgoingBeam1;
if ( par_id == 2 && offset_ > 0 )
return (unsigned short)Particle::OutgoingBeam2;
const unsigned short par_cg_id = lhaevt_->cepgenId( par_id-offset_ );
if ( par_cg_id != LHAEvent::invalid_id )
return (unsigned short)ev.at( par_cg_id ).role();
return findRole( ev, pythia_->event[par_id] );
}
return (unsigned short)Particle::UnknownRole;
}
#endif
}
//================================================================================================
// Custom LHA event definition
//================================================================================================
#ifdef PYTHIA8
- const double LHAEvent::mp_ = part::mass( PDG::proton );
+ const double LHAEvent::mp_ = particleproperties::mass( PDG::proton );
const double LHAEvent::mp2_ = LHAEvent::mp_*LHAEvent::mp_;
LHAEvent::LHAEvent( const Parameters* params ) :
LHAup( 3 ), params_( params )
{
addProcess( 0, 1., 1., 1.e3 );
if ( params_ ) {
setBeamA( (short)params_->kinematics.incoming_beams.first.pdg, params_->kinematics.incoming_beams.first.pz );
setBeamB( (short)params_->kinematics.incoming_beams.second.pdg, params_->kinematics.incoming_beams.second.pz );
}
}
void
LHAEvent::setCrossSection( int id, double xsec, double xsec_err )
{
setXSec( id, xsec );
setXErr( id, xsec_err );
//listInit();
}
void
LHAEvent::feedEvent( const Event& ev, bool full, const KinematicsMode& mode )
{
const double scale = ev.getOneByRole( Particle::Intermediate ).mass();
setProcess( 0, 1., scale, constants::alphaEM, constants::alphaQCD );
const Particle& part1 = ev.getOneByRole( Particle::Parton1 ), &part2 = ev.getOneByRole( Particle::Parton2 );
const Particle& op1 = ev.getOneByRole( Particle::OutgoingBeam1 ), &op2 = ev.getOneByRole( Particle::OutgoingBeam2 );
const double q2_1 = -part1.momentum().mass2(), q2_2 = -part2.momentum().mass2();
const double x1 = q2_1/( q2_1+op1.mass2()-mp2_ ), x2 = q2_2/( q2_2+op2.mass2()-mp2_ );
unsigned short quark1_id = 0, quark2_id = 0;
unsigned short quark1_pdgid = part1.integerPdgId(), quark2_pdgid = part2.integerPdgId();
const Pythia8::Vec4 mom_part1( hadroniser::momToVec4( part1.momentum() ) ), mom_part2( hadroniser::momToVec4( part2.momentum() ) );
if ( !full ) {
//=============================================================================================
// incoming partons
//=============================================================================================
addCorresp( sizePart(), part1.id() );
addParticle( quark1_pdgid, -2, quark1_id, 0, 0, 0, mom_part1.px(), mom_part1.py(), mom_part1.pz(), mom_part1.e(), mom_part1.mCalc(), 0., 0. );
addCorresp( sizePart(), part2.id() );
addParticle( quark2_pdgid, -2, quark2_id, 0, 0, 0, mom_part2.px(), mom_part2.py(), mom_part2.pz(), mom_part2.e(), mom_part2.mCalc(), 0., 0. );
}
else { // full event content (with collinear partons)
const bool inel1 = ( mode == KinematicsMode::InelasticElastic || mode == KinematicsMode::InelasticInelastic );
const bool inel2 = ( mode == KinematicsMode::ElasticInelastic || mode == KinematicsMode::InelasticInelastic );
Pythia8::Vec4 mom_iq1 = mom_part1, mom_iq2 = mom_part2;
unsigned short colour_index = 501, quark1_colour = 0, quark2_colour = 0;
//FIXME select quark flavours accordingly
if ( inel1 ) {
quark1_pdgid = 2;
quark1_colour = colour_index++;
mom_iq1 = hadroniser::momToVec4( x1*ev.getOneByRole( Particle::IncomingBeam1 ).momentum() );
}
if ( inel2 ) {
quark2_pdgid = 2;
quark2_colour = colour_index++;
mom_iq2 = hadroniser::momToVec4( x2*ev.getOneByRole( Particle::IncomingBeam2 ).momentum() );
}
//--- flavour / x value of hard-process initiators
setIdX( part1.integerPdgId(), part2.integerPdgId(), x1, x2 );
//===========================================================================================
// incoming valence quarks
//===========================================================================================
quark1_id = sizePart();
addCorresp( quark1_id, op1.id() );
addParticle( quark1_pdgid, -1, 0, 0, quark1_colour, 0, mom_iq1.px(), mom_iq1.py(), mom_iq1.pz(), mom_iq1.e(), mom_iq1.mCalc(), 0., 1. );
quark2_id = sizePart();
addCorresp( quark2_id, op2.id() );
addParticle( quark2_pdgid, -1, 0, 0, quark2_colour, 0, mom_iq2.px(), mom_iq2.py(), mom_iq2.pz(), mom_iq2.e(), mom_iq2.mCalc(), 0., 1. );
//===========================================================================================
// outgoing valence quarks
//===========================================================================================
if ( inel1 ) {
const Pythia8::Vec4 mom_oq1 = mom_iq1-mom_part1;
addParticle( quark1_pdgid, 1, quark1_id, quark2_id, quark1_colour, 0, mom_oq1.px(), mom_oq1.py(), mom_oq1.pz(), mom_oq1.e(), mom_oq1.mCalc(), 0., 1. );
}
if ( inel2 ) {
const Pythia8::Vec4 mom_oq2 = mom_iq2-mom_part2;
addParticle( quark2_pdgid, 1, quark1_id, quark2_id, quark2_colour, 0, mom_oq2.px(), mom_oq2.py(), mom_oq2.pz(), mom_oq2.e(), mom_oq2.mCalc(), 0., 1. );
}
}
//=============================================================================================
// central system
//=============================================================================================
for ( const auto& p : ev.getByRole( Particle::CentralSystem ) ) {
const auto mothers = p.mothers();
unsigned short moth1_id = 1, moth2_id = 2;
if ( !full ) {
moth1_id = moth2_id = 0;
if ( mothers.size() > 0 ) {
const unsigned short moth1_cg_id = *mothers.begin();
moth1_id = pythiaId( moth1_cg_id );
if ( moth1_id == invalid_id ) {
const Particle& moth = ev.at( moth1_cg_id );
if ( moth.mothers().size() > 0 )
moth1_id = pythiaId( *moth.mothers().begin() );
if ( moth.mothers().size() > 1 )
moth2_id = pythiaId( *moth.mothers().rbegin() );
}
if ( mothers.size() > 1 ) {
const unsigned short moth2_cg_id = *mothers.rbegin();
moth2_id = pythiaId( moth2_cg_id );
if ( moth2_id == invalid_id ) {
const Particle& moth = ev.at( moth2_cg_id );
moth.dump();
moth2_id = pythiaId( *moth.mothers().rbegin() );
}
}
}
}
const Pythia8::Vec4 mom_part( p.momentum().px(), p.momentum().py(), p.momentum().pz(), p.momentum().energy() );
addCorresp( sizePart(), p.id() );
addParticle( p.integerPdgId(), 1, moth1_id, moth2_id, 0, 0, mom_part.px(), mom_part.py(), mom_part.pz(), mom_part.e(), mom_part.mCalc(), 0., 0., 0. );
}
setPdf( quark1_pdgid, quark2_pdgid, x1, x2, scale, 0., 0., false );
}
bool
LHAEvent::setInit()
{
return true;
}
bool
LHAEvent::setEvent( int )
{
return true;
}
void
LHAEvent::setProcess( int id, double xsec, double q2_scale, double alpha_qed, double alpha_qcd )
{
LHAup::setProcess( id, xsec, q2_scale, alpha_qed, alpha_qcd );
py_cg_corresp_.clear();
}
unsigned short
LHAEvent::cepgenId( unsigned short py_id ) const
{
for ( const auto& py_cg : py_cg_corresp_ )
if ( py_cg.first == py_id )
return py_cg.second;
return invalid_id;
}
unsigned short
LHAEvent::pythiaId( unsigned short cg_id ) const
{
for ( const auto& py_cg : py_cg_corresp_ )
if ( py_cg.second == cg_id )
return py_cg.first;
return invalid_id;
}
void
LHAEvent::addCorresp( unsigned short py_id, unsigned short cg_id )
{
py_cg_corresp_.emplace_back( py_id, cg_id );
}
void
LHAEvent::dumpCorresp() const
{
std::ostringstream oss;
oss << "List of Pythia <-> CepGen particle ids correspondance";
for ( const auto& py_cg : py_cg_corresp_ )
oss << "\n\t" << py_cg.first << " <-> " << py_cg.second;
CG_INFO( "LHAEvent:dump" ) << oss.str();
}
#endif
}
diff --git a/CepGen/Hadronisers/Pythia8Hadroniser.h b/CepGen/Hadronisers/Pythia8Hadroniser.h
index d4dea88..23eb371 100644
--- a/CepGen/Hadronisers/Pythia8Hadroniser.h
+++ b/CepGen/Hadronisers/Pythia8Hadroniser.h
@@ -1,84 +1,84 @@
#ifndef CepGen_Hadronisers_Pythia8Hadroniser_h
#define CepGen_Hadronisers_Pythia8Hadroniser_h
#include "CepGen/Hadronisers/GenericHadroniser.h"
#ifdef PYTHIA8
#include <Pythia8/Pythia.h>
#include <memory>
#endif
#include <unordered_map>
#include <vector>
-namespace CepGen
+namespace cepgen
{
class Particle;
class ParametersList;
enum class KinematicsMode;
#ifdef PYTHIA8
class LHAEvent : public Pythia8::LHAup
{
public:
explicit LHAEvent( const Parameters* );
void feedEvent( const Event& ev, bool full, const KinematicsMode& );
bool setInit() override;
bool setEvent( int ) override;
void setCrossSection( int id, double xsec, double xsec_err );
void setProcess( int id, double xsec, double q2_scale, double alpha_qed, double alpha_qcd );
unsigned short cepgenId( unsigned short py_id ) const;
unsigned short pythiaId( unsigned short cg_id ) const;
void addCorresp( unsigned short py_id, unsigned short cg_id );
void dumpCorresp() const;
static constexpr unsigned short invalid_id = 999;
private:
static const double mp_, mp2_;
std::vector<std::pair<unsigned short, unsigned short> > py_cg_corresp_;
const Parameters* params_;
};
#endif
namespace hadroniser
{
/**
* Full interface to the Pythia8 hadronisation algorithm. It can be used in a single particle decay mode as well as a full event hadronisation using the string model, as in Jetset.
* \brief Pythia8 hadronisation algorithm
*/
class Pythia8Hadroniser : public GenericHadroniser
{
public:
explicit Pythia8Hadroniser( const Parameters&, const ParametersList& );
~Pythia8Hadroniser();
void readString( const char* param ) override;
void init() override;
bool run( Event& ev, double& weight, bool full ) override;
void setCrossSection( double xsec, double xsec_err ) override;
bool fullEvent() const { return full_evt_; }
void setFullEvent( bool full = true ) { full_evt_ = full; }
private:
static constexpr unsigned short invalid_idx_ = 999;
std::vector<unsigned short> min_ids_;
std::unordered_map<short,short> py_cg_corresp_;
#ifdef PYTHIA8
unsigned short findRole( const Event& ev, const Pythia8::Particle& p ) const;
void updateEvent( Event& ev, double& weight, bool full ) const;
Particle& addParticle( Event& ev, const Pythia8::Particle&, const Pythia8::Vec4& mom, unsigned short ) const;
/// A Pythia8 core to be wrapped
std::unique_ptr<Pythia8::Pythia> pythia_;
std::unique_ptr<LHAEvent> lhaevt_;
#endif
bool full_evt_;
unsigned short offset_;
bool first_evt_;
const Parameters* params_; // not owning
};
}
}
#endif
diff --git a/CepGen/IO/ExportHandler.h b/CepGen/IO/ExportHandler.h
index 20e9422..4c00b31 100644
--- a/CepGen/IO/ExportHandler.h
+++ b/CepGen/IO/ExportHandler.h
@@ -1,59 +1,59 @@
#ifndef CepGen_Export_ExportHandler_h
#define CepGen_Export_ExportHandler_h
#include <iostream>
-namespace CepGen
+namespace cepgen
{
class Event;
class Parameters;
/// Location for all output generators
namespace output
{
/**
* \brief Output format handler for events export
* \author Laurent Forthomme <laurent.forthomme@cern.ch>
* \date Sep 2016
*/
class ExportHandler
{
public:
/// All types of output available for export
enum OutputType {
HepMC, ///< HepMC ASCII format
LHE ///< LHEF format
};
/// Human-readable output name
friend std::ostream& operator<<( std::ostream& os, const OutputType& type ) {
switch ( type ) {
case HepMC: return os << "HepMC ASCII";
case LHE: return os << "LHEF";
}
return os;
}
public:
/// \brief Class constructor
/// \param[in] type Requested output type
explicit ExportHandler( const OutputType& type ) :
type_( type ), event_num_( 0. ) {}
virtual ~ExportHandler() {}
/// Initialise the handler and its inner parameterisation
virtual void initialise( const Parameters& ) = 0;
/// Set the process cross section and its associated error
virtual void setCrossSection( double xsec, double err_xsec ) {}
/// Set the event number
void setEventNumber( const unsigned int& ev_id ) { event_num_ = ev_id; }
/// Writer operator
virtual void operator<<( const Event& ) = 0;
protected:
/// Type of output requested
OutputType type_;
/// Event index
unsigned int event_num_;
};
}
}
#endif
diff --git a/CepGen/IO/GridHandler.h b/CepGen/IO/GridHandler.h
index 7b2f64d..525bfb8 100644
--- a/CepGen/IO/GridHandler.h
+++ b/CepGen/IO/GridHandler.h
@@ -1,318 +1,318 @@
#ifndef CepGen_IO_GridHandler_h
#define CepGen_IO_GridHandler_h
#include <gsl/gsl_version.h>
#ifdef GSL_MAJOR_VERSION
# if GSL_MAJOR_VERSION > 2 || ( GSL_MAJOR_VERSION == 2 && GSL_MINOR_VERSION >= 1 )
# include <gsl/gsl_interp2d.h>
# include <gsl/gsl_spline2d.h>
# define GOOD_GSL 1
# endif
#endif
#include <gsl/gsl_interp.h>
#include <gsl/gsl_spline.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_math.h>
#include "CepGen/Core/Exception.h"
#include <vector>
#include <map>
-namespace CepGen
+namespace cepgen
{
namespace sf { class Parameterisation; }
/// Interpolation type for the grid coordinates
enum struct GridType { linear, logarithmic, square };
/// \brief A generic class for D-dimensional grid interpolation
/// \param D Number of variables in the grid (dimension)
/// \param N Number of values handled per point
template <size_t D,size_t N=1>
class GridHandler
{
public:
typedef std::vector<double> coord_t; ///< Coordinates container
typedef std::array<double,N> values_t; ///< Value(s) at a given coordinate
public:
/// Build a grid interpolator from a grid type
explicit GridHandler( const GridType& grid_type ) :
grid_type_( grid_type ), accel_{}
{
for ( size_t i = 0; i < D; ++i )
accel_.emplace_back( gsl_interp_accel_alloc(), gsl_interp_accel_free );
}
~GridHandler() {}
/// Interpolate a point to a given coordinate
values_t eval( coord_t in_coords ) const {
values_t out;
coord_t coord = in_coords;
switch ( grid_type_ ) {
case GridType::logarithmic: {
for ( auto& c : coord )
c = log10( c );
} break;
case GridType::square: {
for ( auto& c : coord )
c *= c;
} break;
default: break;
}
//--- dimension of the vector space coordinate to evaluate
switch ( D ) {
case 1: {
for ( size_t i = 0; i < N; ++i ) {
int res = gsl_spline_eval_e( splines_1d_.at( i ).get(), coord.at( 0 ), accel_.at( 0 ).get(), &out[i] );
if ( res != GSL_SUCCESS ) {
out[i] = 0.;
CG_WARNING( "GridHandler" )
<< "Failed to evaluate the grid value (N=" << i << ") "
<< "for x = " << in_coords.at( 0 ) << ". "
<< "GSL error: " << gsl_strerror( res );
}
}
} break;
case 2: {
#ifdef GOOD_GSL
const double x = coord.at( 0 ), y = coord.at( 1 );
for ( size_t i = 0; i < N; ++i ) {
int res = gsl_spline2d_eval_e( splines_2d_.at( i ).get(), x, y, accel_.at( 0 ).get(), accel_.at( 1 ).get(), &out[i] );
if ( res != GSL_SUCCESS ) {
out[i] = 0.;
CG_WARNING( "GridHandler" )
<< "Failed to evaluate the grid value (N=" << i << ") "
<< "for x = " << in_coords.at( 0 ) << " / y = " << in_coords.at( 1 ) << ". "
<< "GSL error: " << gsl_strerror( res );
}
}
#else
//--- retrieve the indices of the bin in the set
coord_t before, after;
findIndices( coord, before, after );
//--- find boundaries values
const gridpoint_t& ext_11 = values_raw_.at( { before[0], before[1] } ),
&ext_12 = values_raw_.at( { before[0], after[1] } ),
&ext_21 = values_raw_.at( { after[0], before[1] } ),
&ext_22 = values_raw_.at( { after[0], after[1] } );
//--- now that we have the boundaries, we may interpolate
coord_t c_d( D );
for ( size_t i = 0; i < D; ++i )
c_d[i] = ( after[i] != before[i] )
? ( coord.at( i )-before[i] )/( after[i]-before[i] )
: 0.;
const gridpoint_t ext_1 = ext_11*( 1.-c_d[0] ) + ext_21*c_d[0];
const gridpoint_t ext_2 = ext_12*( 1.-c_d[0] ) + ext_22*c_d[0];
out = ext_1*( 1.-c_d[1] )+ext_2*c_d[1];
#endif
} break;
case 3: {
//--- retrieve the indices of the bin in the set
coord_t before, after;
findIndices( coord, before, after );
//--- find boundaries values
const gridpoint_t& ext_111 = values_raw_.at( { before[0], before[1], before[2] } ),
&ext_112 = values_raw_.at( { before[0], before[1], after[2] } ),
&ext_121 = values_raw_.at( { before[0], after[1], before[2] } ),
&ext_122 = values_raw_.at( { before[0], after[1], after[2] } ),
&ext_211 = values_raw_.at( { after[0], before[1], before[2] } ),
&ext_212 = values_raw_.at( { after[0], before[1], after[2] } ),
&ext_221 = values_raw_.at( { after[0], after[1], before[2] } ),
&ext_222 = values_raw_.at( { after[0], after[1], after[2] } );
//--- now that we have the boundaries, we may interpolate
coord_t c_d( D );
for ( size_t i = 0; i < D; ++i )
c_d[i] = ( after[i] != before[i] )
? ( coord.at( i )-before[i] )/( after[i]-before[i] )
: 0.;
const gridpoint_t ext_11 = ext_111*( 1.-c_d[0] ) + ext_211*c_d[0];
const gridpoint_t ext_12 = ext_112*( 1.-c_d[0] ) + ext_212*c_d[0];
const gridpoint_t ext_21 = ext_121*( 1.-c_d[0] ) + ext_221*c_d[0];
const gridpoint_t ext_22 = ext_122*( 1.-c_d[0] ) + ext_222*c_d[0];
const gridpoint_t ext_1 = ext_11*( 1.-c_d[1] ) + ext_21*c_d[1];
const gridpoint_t ext_2 = ext_12*( 1.-c_d[1] ) + ext_22*c_d[1];
out = ext_1*( 1.-c_d[2] )+ext_2*c_d[2];
} break;
default:
throw CG_FATAL( "GridHandler" ) << "Unsupported number of dimensions: " << N << ".\n\t"
<< "Please contact the developers to add such a new feature.";
}
return out;
}
/// Insert a new value in the grid
void insert( coord_t coord, values_t value ) {
auto mod_coord = coord;
if ( grid_type_ != GridType::linear )
for ( auto& c : mod_coord )
switch ( grid_type_ ) {
case GridType::logarithmic:
c = log10( c ); break;
case GridType::square:
c *= c; break;
default: break;
}
values_raw_[mod_coord] = value;
}
/// Return the list of values handled in the grid
std::map<coord_t,values_t> values() const { return values_raw_; }
/// Initialise the grid and all useful interpolators/accelerators
void init() {
if ( values_raw_.empty() )
CG_ERROR( "GridHandler" ) << "Empty grid.";
gsl_set_error_handler_off();
//--- start by building grid coordinates from raw values
for ( auto& c : coords_ )
c.clear();
for ( const auto& val : values_raw_ ) {
unsigned short i = 0;
for ( const auto& c : val.first ) {
if ( std::find( coords_.at( i ).begin(), coords_.at( i ).end(), c ) == coords_.at( i ).end() )
coords_.at( i ).emplace_back( c );
++i;
}
}
for ( auto& c : coords_ )
std::sort( c.begin(), c.end() );
{ //--- debugging of the grid coordinates
std::ostringstream os;
unsigned short i = 0;
for ( const auto& cs : coords_ ) {
os << "\n>> coordinate " << (i++) << " has " << cs.size() << " member" << ( cs.size() > 1 ? "s" : "" ) << ":";
unsigned short j = 0;
for ( const auto& val : cs )
os << ( j++ % 20 == 0 ? "\n " : " " ) << val;
}
CG_DEBUG( "GridHandler" ) << "Grid dump:" << os.str();
}
//--- particularise by dimension
switch ( D ) {
case 1: { //--- x |-> (f1,...)
const gsl_interp_type* type = gsl_interp_cspline;
//const gsl_interp_type* type = gsl_interp_steffen;
#ifdef GOOD_GSL
const unsigned short min_size = gsl_interp_type_min_size( type );
#else
const unsigned short min_size = type->min_size;
#endif
if ( min_size >= values_raw_.size() )
throw CG_FATAL( "GridHandler" ) << "Not enough points for \"" << type->name << "\" type of interpolation.\n\t"
<< "Minimum required: " << min_size << ", got " << values_raw_.size() << "!";
for ( size_t i = 0; i < N; ++i ) {
values_[i].reset( new double[values_raw_.size()] );
splines_1d_.emplace_back( gsl_spline_alloc( type, values_raw_.size() ), gsl_spline_free );
}
std::vector<double> x_vec;
unsigned short i = 0;
for ( const auto& vals : values_raw_ ) {
x_vec.emplace_back( vals.first.at( 0 ) );
unsigned short j = 0;
for ( const auto& val : vals.second )
values_[j++].get()[i++] = val;
}
for ( unsigned short i = 0; i < splines_1d_.size(); ++i )
gsl_spline_init( splines_1d_.at( i ).get(), &x_vec[0], values_[i].get(), values_raw_.size() );
} break;
case 2: { //--- (x,y) |-> (f1,...)
#ifdef GOOD_GSL
const gsl_interp2d_type* type = gsl_interp2d_bilinear;
splines_2d_.clear();
for ( size_t i = 0; i < N; ++i ) {
values_[i].reset( new double[coords_.at( 0 ).size() * coords_.at( 1 ).size()] );
splines_2d_.emplace_back( gsl_spline2d_alloc( type, coords_.at( 0 ).size(), coords_.at( 1 ).size() ), gsl_spline2d_free );
}
// second loop over all points to populate the grid
for ( const auto& val : values_raw_ ) {
double val_x = val.first.at( 0 ), val_y = val.first.at( 1 );
// retrieve the index of the bin in the set
const unsigned short id_x = std::distance( coords_.at( 0 ).begin(), std::lower_bound( coords_.at( 0 ).begin(), coords_.at( 0 ).end(), val_x ) );
const unsigned short id_y = std::distance( coords_.at( 1 ).begin(), std::lower_bound( coords_.at( 1 ).begin(), coords_.at( 1 ).end(), val_y ) );
for ( unsigned short i = 0; i < splines_2d_.size(); ++i )
gsl_spline2d_set( splines_2d_.at( i ).get(), values_[i].get(), id_x, id_y, val.second[i] );
}
// initialise splines objects
const coord_t& x_vec = coords_.at( 0 ), &y_vec = coords_.at( 1 );
for ( unsigned short i = 0; i < splines_2d_.size(); ++i )
gsl_spline2d_init( splines_2d_.at( i ).get(), &x_vec[0], &y_vec[0], values_[i].get(), x_vec.size(), y_vec.size() );
#else
CG_WARNING( "GridHandler" )
<< "GSL version ≥ 2.1 is required for spline bilinear interpolation.\n\t"
<< "Version " << GSL_VERSION << " is installed on this system!\n\t"
<< "Will use a simple bilinear approximation instead.";
#endif
} break;
}
}
/// Grid boundaries (collection of pair(min,max))
std::array<std::pair<double,double>,D> boundaries() const {
std::array<std::pair<double,double>,D> out;
unsigned short i = 0;
for ( const auto& c : coords_ ) {
const auto& min = std::min_element( c.begin(), c.end() ), max = std::max_element( c.begin(), c.end() );
out[i++] = {
( min != c.end() ) ? *min : std::numeric_limits<double>::infinity(),
( max != c.end() ) ? *max : std::numeric_limits<double>::infinity() };
}
return out;
}
protected:
/// Type of interpolation for the grid members
GridType grid_type_;
/// List of coordinates and associated value(s) in the grid
std::map<coord_t,values_t> values_raw_;
/// GSL grid interpolation accelerator
std::vector<std::unique_ptr<gsl_interp_accel,void(*)( gsl_interp_accel* )> > accel_;
/// Collection of splines for linear interpolations
std::vector<std::unique_ptr<gsl_spline,void(*)( gsl_spline* )> > splines_1d_;
#ifdef GOOD_GSL
/// Collection of splines for bilinear interpolations
std::vector<std::unique_ptr<gsl_spline2d,void(*)( gsl_spline2d* )> > splines_2d_;
#endif
/// Collection of coordinates building up the grid
std::array<coord_t,D> coords_;
/// Collection of values for all points in the grid
std::array<std::unique_ptr<double[]>,N> values_;
private:
/// Retrieve lower and upper grid indices for a given coordinate
void findIndices( const coord_t& coord, coord_t& min, coord_t& max ) const {
min.reserve( D );
max.reserve( D );
for ( size_t i = 0; i < D; ++i ) {
const auto& c = coords_.at( i );
if ( coord.at( i ) < c.front() )
min[i] = max[i] = c.front();
else if ( coord.at( i ) > c.back() )
min[i] = max[i] = c.back();
else {
auto it_coord = std::lower_bound( c.begin(), c.end(), coord.at( i ) );
min[i] = *it_coord;
max[i] = ( it_coord != c.end() ) ? *( it_coord++ ) : *it_coord;
}
}
}
/// A single value in grid coordinates
struct gridpoint_t : values_t
{
gridpoint_t() : values_t() {}
gridpoint_t( const values_t& arr ) : values_t( arr ) {}
gridpoint_t operator*( double c ) const {
gridpoint_t out = *this;
for ( auto& a : out )
a *= c;
return out;
}
gridpoint_t operator+( const gridpoint_t& rhs ) const {
gridpoint_t out = *this;
for ( size_t i = 0; i < out.size(); ++i )
out[i] += rhs[i];
return out;
}
};
};
}
#endif
diff --git a/CepGen/IO/HepMCHandler.cpp b/CepGen/IO/HepMCHandler.cpp
index c9d7990..48438dc 100644
--- a/CepGen/IO/HepMCHandler.cpp
+++ b/CepGen/IO/HepMCHandler.cpp
@@ -1,133 +1,133 @@
#include "CepGen/IO/HepMCHandler.h"
#include "CepGen/Parameters.h"
#include "CepGen/Core/Exception.h"
#include "CepGen/Event/Event.h"
#include "CepGen/Physics/Constants.h"
#ifdef LIBHEPMC
# include "HepMC/GenVertex.h"
# include "HepMC/GenParticle.h"
#endif
-namespace CepGen
+namespace cepgen
{
namespace output
{
HepMCHandler::HepMCHandler( const char* filename, const ExportHandler::OutputType& type ) :
ExportHandler( type )
#ifdef LIBHEPMC
# ifdef HEPMC_VERSION3
, output_( new HepMC::WriterAscii( filename ) ),
# else
, output_( new HepMC::IO_GenEvent( filename ) ),
# endif
event_( new HepMC::GenEvent() )
#endif
{}
void
HepMCHandler::operator<<( const Event& evt )
{
fillEvent( evt );
#ifdef LIBHEPMC
# ifdef HEPMC_VERSION3
output_->write_event( *event_ );
# else
output_->write_event( event_.get() );
# endif
#endif
}
void
HepMCHandler::setCrossSection( double xsect, double xsect_err )
{
#ifdef LIBHEPMC
# ifdef HEPMC_VERSION3
xs_->set_cross_section( xsect, xsect_err );
event_->add_attribute( "AlphaQCD", HepMC::make_shared<HepMC::DoubleAttribute>( constants::alphaQCD ) );
event_->add_attribute( "AlphaEM", HepMC::make_shared<HepMC::DoubleAttribute>( constants::alphaEM ) );
# else
xs_.set_cross_section( xsect, xsect_err );
event_->set_alphaQCD( constants::alphaQCD );
event_->set_alphaQED( constants::alphaEM );
# endif
#endif
}
void
HepMCHandler::fillEvent( const Event& evt )
{
#ifdef LIBHEPMC
event_->clear();
// general information
event_->set_cross_section( xs_ );
event_->set_event_number( event_num_ );
event_->weights().push_back( 1. ); // unweighted events
// filling the particles content
const HepMC::FourVector origin( 0., 0., 0., 0. );
Particles part_vec = evt.particles();
int cm_id = 0, idx = 1;
# ifdef HEPMC_VERSION3
HepMC::GenVertexPtr v1 = HepMC::make_shared<HepMC::GenVertex>( origin ),
v2 = HepMC::make_shared<HepMC::GenVertex>( origin ),
vcm = HepMC::make_shared<HepMC::GenVertex>( origin );
# else
HepMC::GenVertex* v1 = new HepMC::GenVertex( origin ),
*v2 = new HepMC::GenVertex( origin ),
*vcm = new HepMC::GenVertex( origin );
# endif
for ( unsigned int i = 0; i < part_vec.size(); ++i ) {
const Particle part_orig = part_vec.at( i );
HepMC::FourVector pmom( part_orig.momentum().px(),
part_orig.momentum().py(),
part_orig.momentum().pz(),
part_orig.energy() );
# ifdef HEPMC_VERSION3
HepMC::GenParticlePtr part = HepMC::make_shared<HepMC::GenParticle>( pmom, part_orig.integerPdgId(), (int)part_orig.status() );
# else
HepMC::GenParticle* part = new HepMC::GenParticle( pmom, part_orig.integerPdgId(), (int)part_orig.status() );
part->suggest_barcode( idx++ );
# endif
const ParticlesIds moth = part_orig.mothers();
switch ( part_orig.role() ) {
case Particle::IncomingBeam1: { v1->add_particle_in( part ); } break;
case Particle::IncomingBeam2: { v2->add_particle_in( part ); } break;
case Particle::OutgoingBeam1: { v1->add_particle_out( part ); } break;
case Particle::OutgoingBeam2: { v2->add_particle_out( part ); } break;
case Particle::Parton1: { v1->add_particle_out( part ); vcm->add_particle_in( part ); } break;
case Particle::Parton2: { v2->add_particle_out( part ); vcm->add_particle_in( part ); } break;
case Particle::Parton3: { v2->add_particle_out( part ); vcm->add_particle_in( part ); } break;
case Particle::Intermediate: { cm_id = i; continue; } break;
case Particle::CentralSystem:
default: {
if ( moth.size() == 0 ) continue;
if ( *moth.begin() == cm_id ) vcm->add_particle_out( part );
else
throw CG_FATAL( "HepMCHandler:fillEvent" )
<< "Other particle requested! Not yet implemented!";
} break;
}
idx++;
}
event_->add_vertex( v1 );
event_->add_vertex( v2 );
event_->add_vertex( vcm );
# ifndef HEPMC_VERSION3
event_->set_beam_particles( *v1->particles_in_const_begin(), *v2->particles_in_const_begin() );
event_->set_signal_process_vertex( *v1->vertices_begin() );
event_->set_beam_particles( *v1->particles_in_const_begin(), *v2->particles_in_const_end() );
# endif
#endif
event_num_++;
}
}
}
diff --git a/CepGen/IO/HepMCHandler.h b/CepGen/IO/HepMCHandler.h
index 0d739a6..0b31543 100644
--- a/CepGen/IO/HepMCHandler.h
+++ b/CepGen/IO/HepMCHandler.h
@@ -1,66 +1,66 @@
#ifndef CepGen_IO_HepMCHandler_h
#define CepGen_IO_HepMCHandler_h
#include "CepGen/IO/ExportHandler.h"
#ifdef LIBHEPMC
# include "HepMC/Version.h"
# ifndef HEPMC_VERSION_CODE // HepMC v2
# include "HepMC/IO_GenEvent.h"
# include "HepMC/SimpleVector.h"
# else // HepMC v3+
# define HEPMC_VERSION3
# include "HepMC/WriterAscii.h"
# include "HepMC/FourVector.h"
# endif
# include "HepMC/GenEvent.h"
#endif
#include <memory>
-namespace CepGen
+namespace cepgen
{
namespace output
{
/**
* \brief Handler for the HepMC file output
* \author Laurent Forthomme <laurent.forthomme@cern.ch>
* \date Sep 2016
*/
class HepMCHandler : public ExportHandler
{
public:
/// Class constructor
/// \param[in] filename Output file path
/// \param[in] type Output type
HepMCHandler( const char* filename, const ExportHandler::OutputType& type = ExportHandler::HepMC );
void initialise( const Parameters& params ) override {}
/// Writer operator
void operator<<( const Event& ) override;
void setCrossSection( double, double ) override;
private:
/// Clear the associated HepMC event content
void clearEvent();
/// Populate the associated HepMC event with a Event object
void fillEvent( const Event& );
#ifdef LIBHEPMC
# ifdef HEPMC_VERSION3
/// Writer object (from HepMC v3+)
std::unique_ptr<HepMC::WriterAscii> output_;
/// Generator cross section and error
HepMC::GenCrossSectionPtr xs_;
# else
/// Writer object (from HepMC v<3)
std::unique_ptr<HepMC::IO_GenEvent> output_;
/// Generator cross section and error
HepMC::GenCrossSection xs_;
# endif
/// Associated HepMC event
std::shared_ptr<HepMC::GenEvent> event_;
#endif
};
}
}
#endif
diff --git a/CepGen/IO/LHEFHandler.cpp b/CepGen/IO/LHEFHandler.cpp
index 19f44e3..b29dea8 100644
--- a/CepGen/IO/LHEFHandler.cpp
+++ b/CepGen/IO/LHEFHandler.cpp
@@ -1,252 +1,252 @@
#include "CepGen/IO/LHEFHandler.h"
#include "CepGen/StructureFunctions/StructureFunctions.h"
#include "CepGen/Event/Event.h"
#include "CepGen/Physics/Constants.h"
#include "CepGen/Parameters.h"
#include "CepGen/Version.h"
-namespace CepGen
+namespace cepgen
{
namespace output
{
LHEFHandler::LHEFHandler( const char* filename ) :
ExportHandler( ExportHandler::LHE )
#if defined ( HEPMC_LHEF )
, lhe_output_( new LHEF::Writer( filename ) )
#elif defined ( PYTHIA_LHEF )
, pythia_( new Pythia8::Pythia ), lhaevt_( new LHAevent )
#endif
{
#if defined ( PYTHIA_LHEF )
lhaevt_->openLHEF( filename );
#endif
}
LHEFHandler::~LHEFHandler()
{
#if defined ( PYTHIA_LHEF )
if ( lhaevt_ )
lhaevt_->closeLHEF( false ); // we do not want to rewrite the init block
#endif
}
void
LHEFHandler::initialise( const Parameters& params )
{
std::ostringstream oss_init;
oss_init
<< "<!--\n"
<< " ***** Sample generated with CepGen v" << version() << " *****\n"
<< " * process: " << params.processName() << " (" << params.kinematics.mode << ")\n";
if ( params.kinematics.mode != KinematicsMode::ElasticElastic ) {
oss_init
<< " * structure functions: " << params.kinematics.structure_functions->type << "\n";
if ( !params.hadroniserName().empty() )
oss_init
<< " * hadroniser: " << params.hadroniserName() << "\n";
}
oss_init
<< " *--- incoming state\n";
if ( params.kinematics.cuts.initial.q2.valid() )
oss_init
<< " * Q2 range (GeV2): "
<< params.kinematics.cuts.initial.q2.min() << ", "
<< params.kinematics.cuts.initial.q2.max() << "\n";
if ( params.kinematics.mode != KinematicsMode::ElasticElastic
&& params.kinematics.cuts.remnants.mass_single.valid() )
oss_init
<< " * remnants mass range (GeV/c2): "
<< params.kinematics.cuts.remnants.mass_single.min() << ", "
<< params.kinematics.cuts.remnants.mass_single.max() << "\n";
oss_init
<< " *--- central system\n";
if ( params.kinematics.cuts.central.pt_single.valid() )
oss_init
<< " * single particle pt (GeV/c): "
<< params.kinematics.cuts.central.pt_single.min() << ", "
<< params.kinematics.cuts.central.pt_single.max() << "\n";
if ( params.kinematics.cuts.central.energy_single.valid() )
oss_init
<< " * single particle energy (GeV): "
<< params.kinematics.cuts.central.energy_single.min() << ", "
<< params.kinematics.cuts.central.energy_single.max() << "\n";
if ( params.kinematics.cuts.central.eta_single.valid() )
oss_init
<< " * single particle eta: "
<< params.kinematics.cuts.central.eta_single.min() << ", "
<< params.kinematics.cuts.central.eta_single.max() << "\n";
if ( params.kinematics.cuts.central.pt_sum.valid() )
oss_init
<< " * total pt (GeV/c): "
<< params.kinematics.cuts.central.mass_sum.min() << ", "
<< params.kinematics.cuts.central.mass_sum.max() << "\n";
if ( params.kinematics.cuts.central.mass_sum.valid() )
oss_init
<< " * total invariant mass (GeV/c2): "
<< params.kinematics.cuts.central.mass_sum.min() << ", "
<< params.kinematics.cuts.central.mass_sum.max() << "\n";
oss_init
<< " **************************************************\n"
<< "-->";
#if defined ( HEPMC_LHEF )
lhe_output_->headerBlock() << oss_init.str();
//params.dump( lhe_output_->initComments(), false );
LHEF::HEPRUP run = lhe_output_->heprup;
run.IDBMUP = { (int)params.kinematics.incoming_beams.first.pdg, (int)params.kinematics.incoming_beams.second.pdg };
run.EBMUP = { (double)params.kinematics.incoming_beams.first.pz, (double)params.kinematics.incoming_beams.second.pz };
run.NPRUP = 1;
run.resize();
run.XSECUP[0] = params.integrator.result;
run.XERRUP[0] = params.integrator.err_result;
run.XMAXUP[0] = 1.;
run.LPRUP[0] = 1;
lhe_output_->heprup = run;
lhe_output_->init();
#elif defined ( PYTHIA_LHEF )
oss_init << std::endl; // LHEF is usually not beautifully parsed as a standard XML...
lhaevt_->addComments( oss_init.str() );
lhaevt_->initialise( params );
pythia_->settings.mode( "Beams:frameType", 5 );
pythia_->settings.mode( "Next:numberCount", 0 ); // remove some of the Pythia output
pythia_->settings.flag( "ProcessLevel:all", false ); // we do not want Pythia to interfere...
pythia_->setLHAupPtr( lhaevt_.get() );
pythia_->init();
lhaevt_->initLHEF();
#endif
}
void
LHEFHandler::operator<<( const Event& ev )
{
#if defined ( HEPMC_LHEF )
LHEF::HEPEUP out;
out.heprup = &lhe_output_->heprup;
out.XWGTUP = 1.;
out.XPDWUP = std::pair<double,double>( 0., 0. );
out.SCALUP = 0.;
out.AQEDUP = constants::alphaEM;
out.AQCDUP = constants::alphaQCD;
out.NUP = ev.numParticles();
out.resize();
for ( unsigned short ip = 0; ip < ev.numParticles(); ++ip ) {
const Particle part = ev.at( ip );
out.IDUP[ip] = part.integerPdgId(); // PDG id
out.ISTUP[ip] = (short)part.status(); // status code
out.MOTHUP[ip] = std::pair<int,int>( ( part.mothers().size() > 0 ) ? *part.mothers().begin()+1 : 0, ( part.mothers().size() > 1 ) ? *part.mothers().rbegin()+1 : 0 ); // mothers
out.ICOLUP[ip] = std::pair<int,int>( 0, 0 );
out.PUP[ip] = std::vector<double>( { { part.momentum().px(), part.momentum().py(), part.momentum().pz(), part.energy(), part.mass() } } ); // momentum
out.VTIMUP[ip] = 0.; // invariant lifetime
out.SPINUP[ip] = 0.;
}
lhe_output_->eventComments() << "haha";
lhe_output_->hepeup = out;
lhe_output_->writeEvent();
#elif defined ( PYTHIA_LHEF )
lhaevt_->feedEvent( 0, ev );
pythia_->next();
lhaevt_->eventLHEF();
#endif
}
void
LHEFHandler::setCrossSection( double xsect, double xsect_err )
{
#if defined ( PYTHIA_LHEF )
lhaevt_->setCrossSection( 0, xsect, xsect_err );
#endif
}
//---------------------------------------------------------------------------------------------
// Define LHA event record if one uses Pythia to store the LHE
//---------------------------------------------------------------------------------------------
#if defined ( PYTHIA_LHEF )
LHEFHandler::LHAevent::LHAevent() : LHAup( 3 )
{}
void
LHEFHandler::LHAevent::initialise( const Parameters& params )
{
setBeamA( (short)params.kinematics.incoming_beams.first.pdg, params.kinematics.incoming_beams.first.pz );
setBeamB( (short)params.kinematics.incoming_beams.second.pdg, params.kinematics.incoming_beams.second.pz );
addProcess( 0, params.integrator.result, params.integrator.err_result, 100. );
}
void
LHEFHandler::LHAevent::addComments( const std::string& comments )
{
osLHEF << comments;
}
void
LHEFHandler::LHAevent::setCrossSection( unsigned short proc_id, double xsect, double xsect_err )
{
setXSec( proc_id, xsect );
setXErr( proc_id, xsect_err );
}
void
LHEFHandler::LHAevent::feedEvent( unsigned short proc_id, const Event& ev, bool full_event )
{
const double scale = ev.getOneByRole( Particle::Intermediate ).mass();
setProcess( proc_id, 1., scale, constants::alphaEM, constants::alphaQCD );
const Particle& ip1 = ev.getOneByRole( Particle::IncomingBeam1 ), &ip2 = ev.getOneByRole( Particle::IncomingBeam2 );
const Particles& op1 = ev.getByRole( Particle::OutgoingBeam1 ), &op2 = ev.getByRole( Particle::OutgoingBeam2 );
const double q2_1 = -( ip1.momentum()-op1[0].momentum() ).mass2(), q2_2 = -( ip2.momentum()-op2[0].momentum() ).mass2();
const double x1 = q2_1/( q2_1+op1[0].mass2()-ip1.mass2() ), x2 = q2_2/( q2_2+op2[0].mass2()-ip2.mass2() );
setIdX( ip1.integerPdgId(), ip2.integerPdgId(), x1, x2 );
short parton1_pdgid = 0, parton2_pdgid = 0;
for ( const auto& part : ev.particles() ) {
short pdg_id = part.integerPdgId(), status = 0, moth1 = 0, moth2 = 0;
switch ( part.role() ) {
case Particle::Parton1:
case Particle::Parton2: {
if ( part.role() == Particle::Parton1 )
parton1_pdgid = part.integerPdgId();
if ( part.role() == Particle::Parton2 )
parton2_pdgid = part.integerPdgId();
if ( !full_event )
continue;
status = -2; // conserving xbj/Q2
} break;
case Particle::Intermediate: {
if ( !full_event )
continue;
status = 2;
if ( pdg_id == 0 )
pdg_id = ev.at( *part.mothers().begin() ).integerPdgId();
} break;
case Particle::IncomingBeam1:
case Particle::IncomingBeam2: {
if ( !full_event )
continue;
status = -9;
} break;
case Particle::OutgoingBeam1:
case Particle::OutgoingBeam2:
case Particle::CentralSystem: {
status = (short)part.status();
if ( status != 1 )
continue;
} break;
default: break;
}
if ( full_event ) {
const auto& mothers = part.mothers();
if ( mothers.size() > 0 )
moth1 = *mothers.begin()+1;
if ( mothers.size() > 1 )
moth2 = *mothers.rbegin()+1;
}
const Particle::Momentum& mom = part.momentum();
addParticle( pdg_id, status, moth1, moth2, 0, 0, mom.px(), mom.py(), mom.pz(), mom.energy(), mom.mass(), 0. ,0., 0. );
}
setPdf( parton1_pdgid, parton2_pdgid, x1, x2, scale, 0., 0., true );
}
#endif
}
}
diff --git a/CepGen/IO/LHEFHandler.h b/CepGen/IO/LHEFHandler.h
index 5acf548..f542276 100644
--- a/CepGen/IO/LHEFHandler.h
+++ b/CepGen/IO/LHEFHandler.h
@@ -1,70 +1,70 @@
#ifndef CepGen_Export_LHEFHandler_h
#define CepGen_Export_LHEFHandler_h
#include "CepGen/IO/ExportHandler.h"
#include "CepGen/IO/HepMCHandler.h"
#ifndef LIBHEPMC
# ifndef PYTHIA8
# pragma message( "HepMC/Pythia8 are not linked to this instance!" )
# endif
#else
# ifndef HEPMC_VERSION3
# ifdef PYTHIA8
# include "Pythia8/Pythia.h"
# define PYTHIA_LHEF 1
# else
# pragma message( "HepMC v3 or Pythia8 are required for the LHEF export!" )
# endif
# else
# include "HepMC/LHEF.h"
# define HEPMC_LHEF 1
# endif
#endif
-namespace CepGen
+namespace cepgen
{
class Event;
namespace output
{
/**
* \brief Handler for the LHE file output
* \author Laurent Forthomme <laurent.forthomme@cern.ch>
* \date Sep 2016
*/
class LHEFHandler : public ExportHandler
{
public:
/// Class constructor
/// \param[in] filename Output file path
explicit LHEFHandler( const char* filename );
~LHEFHandler() override;
void initialise( const Parameters& ) override;
/// Writer operator
void operator<<( const Event& ) override;
void setCrossSection( double, double ) override;
private:
#if defined ( HEPMC_LHEF )
/// Writer object (from HepMC)
std::unique_ptr<LHEF::Writer> lhe_output_;
LHEF::HEPRUP run_;
#elif defined ( PYTHIA_LHEF )
std::unique_ptr<Pythia8::Pythia> pythia_;
struct LHAevent : Pythia8::LHAup
{
explicit LHAevent();
void initialise( const Parameters& );
void setCrossSection( unsigned short, double, double );
void feedEvent( unsigned short proc_id, const Event& ev, bool full_event = false );
bool setInit() override { return true; }
bool setEvent( int ) override { return true; }
void addComments( const std::string& );
};
std::unique_ptr<LHAevent> lhaevt_;
#endif
};
}
}
#endif
diff --git a/CepGen/Parameters.h b/CepGen/Parameters.h
index a9c0e4c..13d5f18 100644
--- a/CepGen/Parameters.h
+++ b/CepGen/Parameters.h
@@ -1,147 +1,147 @@
#ifndef CepGen_Parameters_h
#define CepGen_Parameters_h
#include "CepGen/Core/Integrator.h"
#include "CepGen/Physics/Kinematics.h"
#include <memory>
#include <gsl/gsl_monte_vegas.h>
#include <gsl/gsl_monte_miser.h>
-namespace CepGen
+namespace cepgen
{
class Event;
class TamingFunctionsCollection;
class ParametersList;
namespace process { class GenericProcess; }
namespace hadroniser { class GenericHadroniser; }
/// List of parameters used to start and run the simulation job
class Parameters
{
public:
Parameters();
/// Copy constructor (transfers ownership to the process/hadroniser!)
Parameters( Parameters& );
/// Const copy constructor (all but the process and the hadroniser)
Parameters( const Parameters& );
~Parameters(); // required for unique_ptr initialisation!
/// Set the polar angle range for the produced leptons
/// \param[in] thetamin The minimal value of \f$\theta\f$ for the outgoing leptons
/// \param[in] thetamax The maximal value of \f$\theta\f$ for the outgoing leptons
void setThetaRange( float thetamin, float thetamax );
/// Dump the input parameters in the terminal
friend std::ostream& operator<<( std::ostream& os, const Parameters* );
friend std::ostream& operator<<( std::ostream& os, const Parameters& );
std::shared_ptr<ParametersList> general;
//----- process to compute
/// Process for which the cross-section will be computed and the events will be generated
process::GenericProcess* process();
/// Name of the process considered
std::string processName() const;
/// Set the process to study
void setProcess( std::unique_ptr<process::GenericProcess> proc );
/// Set the process to study
void setProcess( process::GenericProcess* proc );
//----- events kinematics
/// Events kinematics for phase space definition
Kinematics kinematics;
//----- VEGAS
/// Collection of integrator parameters
struct Integration
{
Integration();
Integration( const Integration& );
~Integration();
Integrator::Type type;
/// Number of function calls to be computed for each point
unsigned int ncvg; // ??
/// Random number generator seed
long rng_seed;
/// Random number generator engine
gsl_rng_type* rng_engine;
gsl_monte_vegas_params vegas;
double vegas_chisq_cut;
gsl_monte_miser_params miser;
double result, err_result;
};
/// Integrator parameters
Integration integrator;
//----- events generation
/// Collection of events generation parameters
struct Generation
{
Generation();
/// Are we generating events ? (true) or are we only computing the cross-section ? (false)
bool enabled;
/// Maximal number of events to generate in this run
unsigned int maxgen;
/// Do we want the events to be symmetrised with respect to the \f$z\f$-axis ?
bool symmetrise;
/// Is the integrand to be smoothed for events generation?
bool treat;
/// Number of events already generated in this run
unsigned int ngen;
/// Frequency at which the events are displayed to the end-user
unsigned int gen_print_every;
/// Number of threads to perform the integration
unsigned int num_threads;
/// Number of points to "shoot" in each integration bin by the algorithm
unsigned int num_points;
};
/// Events generation parameters
Generation generation;
/// Specify if the generated events are to be stored
void setStorage( bool store ) { store_ = store; }
/// Are the events generated in this run to be stored in the output file ?
bool storage() const { return store_; }
//----- hadronisation algorithm
/// Hadronisation algorithm to use for the proton(s) fragmentation
hadroniser::GenericHadroniser* hadroniser();
/// Name of the hadroniser (if applicable)
std::string hadroniserName() const;
/// Set the hadronisation algorithm
void setHadroniser( hadroniser::GenericHadroniser* hadr );
//----- taming functions
/// Functionals to be used to account for rescattering corrections (implemented within the process)
std::shared_ptr<TamingFunctionsCollection> taming_functions;
//----- run statistics
/// Reset the total generation time and the number of events generated for this run
void clearRunStatistics();
/// Add a new timing into the total generation time
/// \param[in] gen_time Time to add (in seconds)
void addGenerationTime( double gen_time );
/// Return the total generation time for this run (in seconds)
inline double totalGenerationTime() const { return total_gen_time_; }
/// Total number of events already generated in this run
inline unsigned int numGeneratedEvents() const { return num_gen_events_; }
private:
std::unique_ptr<process::GenericProcess> process_;
std::unique_ptr<hadroniser::GenericHadroniser> hadroniser_;
bool store_;
/// Total generation time (in seconds)
double total_gen_time_;
/// Number of events already generated
unsigned int num_gen_events_;
};
}
#endif
diff --git a/CepGen/Physics/BreitWigner.h b/CepGen/Physics/BreitWigner.h
index f3f0302..342ad71 100644
--- a/CepGen/Physics/BreitWigner.h
+++ b/CepGen/Physics/BreitWigner.h
@@ -1,44 +1,44 @@
#ifndef CepGen_Physics_BreitWigner_h
#define CepGen_Physics_BreitWigner_h
#include <math.h>
-namespace CepGen
+namespace cepgen
{
/// A Breit-Wigner/Cauchy distribution generator
class BreitWigner
{
public:
BreitWigner( double mean = 0., double gamma = 0., double emin = -1., double emax = -1. ) :
mean_( mean ), gamma_( gamma ), emin_( emin ), emax_( emax ) {}
/// Copy constructor
BreitWigner( const BreitWigner& oth ) :
mean_( oth.mean_ ), gamma_( oth.gamma_ ), emin_( oth.emin_ ), emax_( oth.emax_ ) {}
/// Minimal energy to consider
double min() const { return emin_; }
/// Maximal energy to consider
double max() const { return emax_; }
/// Shoot a value according to parameterisation
inline double operator()( double x ) const {
const double val = mean_+0.5*gamma_*tan( ( 2.*x-1. )*M_PI_2 );
if ( emin_ >= 0. && val < emin_ )
return -1.;
if ( emax_ >= 0. && val > emax_ )
return -1.;
return val;
}
private:
/// Mean of distribution
double mean_;
/// Width of distribution
double gamma_;
/// Minimal value
double emin_;
/// Maximal value
double emax_;
};
}
#endif
diff --git a/CepGen/Physics/Constants.h b/CepGen/Physics/Constants.h
index 5182da7..e118af8 100644
--- a/CepGen/Physics/Constants.h
+++ b/CepGen/Physics/Constants.h
@@ -1,21 +1,21 @@
#ifndef CepGen_Physics_Constants_h
#define CepGen_Physics_Constants_h
#include <math.h>
-namespace CepGen
+namespace cepgen
{
/// List of physical constants useful that may be used for the matrix element definition
namespace constants
{
/// Electromagnetic coupling constant \f$\alpha_{\rm em}=\frac{e^2}{4\pi\epsilon_0\hbar c}\f$
constexpr double alphaEM = 1./137.035;
/// Strong coupling constant \f$\alpha_{\rm QCD}\f$
constexpr double alphaQCD = 0.1184; // at the Z pole
/// Conversion factor between GeV\f${}^2\f$ and barn
constexpr double GeV2toBarn = 0.389351824e9; // 1.e4*(197.3271**2);
constexpr double sconstb = 2.1868465e10; // 1.1868465e10;
}
}
#endif
diff --git a/CepGen/Physics/Cuts.cpp b/CepGen/Physics/Cuts.cpp
index abb5a07..8841214 100644
--- a/CepGen/Physics/Cuts.cpp
+++ b/CepGen/Physics/Cuts.cpp
@@ -1,42 +1,42 @@
#include "CepGen/Physics/Cuts.h"
-namespace CepGen
+namespace cepgen
{
std::vector<std::pair<std::string,Limits> >
Cuts::list() const
{
std::vector<std::pair<std::string,Limits> > out;
if ( pt_single.valid() )
out.emplace_back( "Single central pt (GeV/c)", pt_single );
if ( eta_single.valid() )
out.emplace_back( "Single central eta", eta_single );
if ( rapidity_single.valid() )
out.emplace_back( "Single central rapidity", rapidity_single );
if ( energy_single.valid() )
out.emplace_back( "Single central energy (GeV)", energy_single );
if ( mass_single.valid() )
out.emplace_back( "Single particle mass (GeV/c²)", mass_single );
if ( pt_sum.valid() )
out.emplace_back( "Central system pt (GeV/c)", pt_sum );
if ( eta_sum.valid() )
out.emplace_back( "Central system eta", eta_sum );
if ( energy_sum.valid() )
out.emplace_back( "Central system energy", energy_sum );
if ( mass_sum.valid() )
out.emplace_back( "Central system mass", mass_sum );
if ( pt_diff.valid() )
out.emplace_back( "Central system Δpt (GeV/c)", pt_diff );
if ( phi_pt_diff.valid() )
out.emplace_back( "Central system Δɸ", phi_pt_diff );
if ( rapidity_diff.valid() )
out.emplace_back( "Central system ΔY", rapidity_diff );
if ( q2.valid() )
out.emplace_back( "Virtuality range (GeV²)", q2 );
if ( qt.valid() )
out.emplace_back( "Transverse virtuality range (GeV)", qt );
if ( phi_qt.valid() )
out.emplace_back( "Partons Δɸ range", phi_qt );
return out;
}
}
diff --git a/CepGen/Physics/Cuts.h b/CepGen/Physics/Cuts.h
index 6c8e1e7..bdd978c 100644
--- a/CepGen/Physics/Cuts.h
+++ b/CepGen/Physics/Cuts.h
@@ -1,32 +1,32 @@
#ifndef CepGen_Physics_Cuts_h
#define CepGen_Physics_Cuts_h
#include "CepGen/Physics/Limits.h"
#include <vector>
-namespace CepGen
+namespace cepgen
{
/// Constraints to be applied on the events kinematics
struct Cuts
{
Limits pt_single; ///< single particle transverse momentum
Limits eta_single; ///< single particle pseudo-rapidity
Limits rapidity_single; ///< single particle rapidity
Limits energy_single; ///< single particle energy
Limits mass_single; ///< single particle mass
Limits pt_sum; ///< multiparticle system transverse momentum
Limits eta_sum; ///< multiparticle system pseudo-rapidity
Limits energy_sum; ///< multiparticle system energy
Limits mass_sum; ///< multiparticle system invariant mass
Limits pt_diff; ///< transverse momentum balance between the central particles
Limits phi_pt_diff; ///< azimuthal angles difference between the central particles
Limits rapidity_diff; ///< rapidity balance between the central particles
Limits q2; ///< parton virtuality
Limits qt; ///< parton transverse virtuality
Limits phi_qt; ///< parton azimuthal angle difference
/// A collection of name -> limits
std::vector<std::pair<std::string,Limits> > list() const;
};
}
#endif
diff --git a/CepGen/Physics/FormFactors.cpp b/CepGen/Physics/FormFactors.cpp
index 34689b7..a1e1123 100644
--- a/CepGen/Physics/FormFactors.cpp
+++ b/CepGen/Physics/FormFactors.cpp
@@ -1,55 +1,55 @@
#include "CepGen/Physics/FormFactors.h"
#include "CepGen/Core/Exception.h"
#include "CepGen/Physics/ParticleProperties.h"
#include "CepGen/Physics/PDG.h"
#include "CepGen/StructureFunctions/SuriYennie.h"
-namespace CepGen
+namespace cepgen
{
- const double FormFactors::mp_ = part::mass( PDG::proton );
+ const double FormFactors::mp_ = particleproperties::mass( PDG::proton );
const double FormFactors::mp2_ = FormFactors::mp_*FormFactors::mp_;
FormFactors
FormFactors::trivial()
{
return FormFactors( 1.0, 1.0 );
}
FormFactors
FormFactors::protonElastic( double q2 )
{
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( double q2, double mi2, double mf2, sf::Parameterisation& sf )
{
const double xbj = q2 / ( q2 + mf2 - mi2 );
switch ( sf.type ) {
case sf::Type::ElasticProton:
CG_WARNING( "FormFactors" ) << "Elastic proton form factors requested! Check your process definition!";
return FormFactors::protonElastic( q2 );
case sf::Type::SuriYennie: {
sf::SuriYennie suriyennie, sy = (sf::SuriYennie)suriyennie( xbj, q2 );
return FormFactors( sy.F2 * xbj * sqrt( mi2 ) / q2, sy.FM ); //FIXME
} break;
default: {
sf = sf( xbj, q2 );
sf.computeFL( xbj, q2 );
return FormFactors( sf.F2 * xbj / q2, -2.*sf.F1( xbj, q2 ) / q2 );
} break;
}
}
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/Physics/FormFactors.h b/CepGen/Physics/FormFactors.h
index 2c317e6..7f3e09d 100644
--- a/CepGen/Physics/FormFactors.h
+++ b/CepGen/Physics/FormFactors.h
@@ -1,38 +1,38 @@
#ifndef CepGen_Physics_FormFactors_h
#define CepGen_Physics_FormFactors_h
#include <math.h>
#include <array>
#include "CepGen/Core/utils.h"
#include "CepGen/Physics/Constants.h"
-namespace CepGen
+namespace cepgen
{
namespace sf { class Parameterisation; }
/// Form factors collection (electric and magnetic parts)
class FormFactors
{
public:
/// Initialise a collection of electric/magnetic form factors
FormFactors( double fe = 0., double fm = 0. ) : FE( fe ), FM( fm ) {}
/// Trivial, spin-0 form factors (e.g. pion)
static FormFactors trivial();
/// Elastic proton form factors
static FormFactors protonElastic( double q2 );
/// Generate the form factors according to the proton structure functions set
static FormFactors protonInelastic( double q2, double mi2, double mf2, sf::Parameterisation& );
/// Electric form factor
double FE;
/// Magnetic form factor
double FM;
/// Dumping operator for standard output streams
friend std::ostream& operator<<( std::ostream&, const FormFactors& );
private:
static const double mp_, mp2_;
};
}
#endif
diff --git a/CepGen/Physics/GluonGrid.cpp b/CepGen/Physics/GluonGrid.cpp
index cedb60b..300215e 100644
--- a/CepGen/Physics/GluonGrid.cpp
+++ b/CepGen/Physics/GluonGrid.cpp
@@ -1,54 +1,54 @@
#include "CepGen/Physics/GluonGrid.h"
#include "CepGen/Core/Exception.h"
#include <fstream>
#include <set>
namespace kmr
{
GluonGrid&
GluonGrid::get( const char* filename )
{
Parameters p;
p.grid_path = filename;
static GluonGrid instance( p );
return instance;
}
GluonGrid::GluonGrid( const Parameters& param ) :
- CepGen::GridHandler<3,1>( CepGen::GridType::linear ),
+ cepgen::GridHandler<3,1>( cepgen::GridType::linear ),
params( param )
{
std::set<double> kt2_vals, x_vals, mu2_vals;
{ // file readout part
std::ifstream file( params.grid_path, std::ios::in );
if ( !file.is_open() )
throw CG_FATAL( "GluonGrid" ) << "Impossible to load grid file \"" << params.grid_path << "\"!";
std::string x_tmp, kt2_tmp, mu2_tmp, fg_tmp;
while ( file >> x_tmp >> kt2_tmp >> mu2_tmp >> fg_tmp ) {
const double x = stod( x_tmp ), kt2 = stod( kt2_tmp ), mu2 = stod( mu2_tmp ), fg = stod( fg_tmp );
x_vals.insert( x );
kt2_vals.insert( kt2 );
mu2_vals.insert( mu2 );
insert( { x, kt2, mu2 }, { fg } );
}
file.close();
}
init();
CG_INFO( "GluonGrid" )
<< "KMR grid evaluator built!\n\t"
<< " kt² in range [" << *kt2_vals.begin() << ":" << *kt2_vals.rbegin() << "]\n\t"
<< " x in range [" << *x_vals.begin() << ":" << *x_vals.rbegin() << "]\n\t"
<< " µ² in range [" << *mu2_vals.begin() << ":" << *mu2_vals.rbegin() << "].";
}
double
GluonGrid::operator()( double x, double kt2, double mu2 ) const
{
- return CepGen::GridHandler<3,1>::eval( { x, kt2, mu2 } ).at( 0 );
+ return cepgen::GridHandler<3,1>::eval( { x, kt2, mu2 } ).at( 0 );
}
}
diff --git a/CepGen/Physics/GluonGrid.h b/CepGen/Physics/GluonGrid.h
index a432e26..41c8fcc 100644
--- a/CepGen/Physics/GluonGrid.h
+++ b/CepGen/Physics/GluonGrid.h
@@ -1,41 +1,41 @@
#ifndef CepGen_Physics_GluonGrid_h
#define CepGen_Physics_GluonGrid_h
#include "CepGen/IO/GridHandler.h"
#define DEFAULT_KMR_GRID_PATH "gluon_mmht2014nlo_Watt.dat"
/// Kimber-Martin-Ryskin unintegrated gluon densities
namespace kmr
{
/// A KMR unintegrated gluon densities grid interpolator
- class GluonGrid : private CepGen::GridHandler<3,1>
+ class GluonGrid : private cepgen::GridHandler<3,1>
{
public:
struct Parameters {
Parameters() : grid_path( DEFAULT_KMR_GRID_PATH ) {}
/// Location of the grid to be interpolated
std::string grid_path;
};
public:
/// Retrieve the grid interpolator (singleton)
static GluonGrid& get( const char* path = DEFAULT_KMR_GRID_PATH );
/// Compute the gluon flux
double operator()( double x, double kt2, double mu2 ) const;
/// Grid parameterisation object
Parameters params;
public:
GluonGrid( const GluonGrid& ) = delete;
void operator=( const GridHandler& ) = delete;
private:
explicit GluonGrid( const Parameters& = Parameters() );
};
}
#undef DEFAULT_KMR_GRID_PATH
#endif
diff --git a/CepGen/Physics/HeavyIon.cpp b/CepGen/Physics/HeavyIon.cpp
index 2477e74..331ef94 100644
--- a/CepGen/Physics/HeavyIon.cpp
+++ b/CepGen/Physics/HeavyIon.cpp
@@ -1,46 +1,46 @@
#include "CepGen/Physics/HeavyIon.h"
#include <sstream>
-namespace CepGen
+namespace cepgen
{
HeavyIon::HeavyIon( const PDG& pdg ) :
A( (unsigned int)pdg % 1000 ),
Z( (Element)( (unsigned int)pdg/1000000 == 0 ? 0
: ( (unsigned int)pdg/1000 ) % 1000 ) )
{}
HeavyIon::operator PDG() const
{
// Pythia8 convention/10-1e10+1e6
return (PDG)( 1000000+1000*(unsigned short)Z+A );
}
std::ostream&
operator<<( std::ostream& os, const HeavyIon& hi )
{
std::ostringstream oss; oss << hi.Z;
if ( oss.str().empty() )
return os << "HI{Z=" << (unsigned short)hi.Z << ", A=" << hi.A << "}";
return os << hi.A << oss.str();
}
std::ostream&
operator<<( std::ostream& os, const Element& elem )
{
switch ( elem ) {
case Element::invalid:
return os;
case Element::H: return os << "H";
case Element::C: return os << "C";
case Element::O: return os << "O";
case Element::Al: return os << "Al";
case Element::Cu: return os << "Cu";
case Element::Xe: return os << "Xe";
case Element::Au: return os << "Au";
case Element::Pb: return os << "Pb";
case Element::U: return os << "U";
}
return os;
}
}
diff --git a/CepGen/Physics/HeavyIon.h b/CepGen/Physics/HeavyIon.h
index e2b996c..4de418f 100644
--- a/CepGen/Physics/HeavyIon.h
+++ b/CepGen/Physics/HeavyIon.h
@@ -1,44 +1,44 @@
#ifndef CepGen_Physics_HeavyIon_h
#define CepGen_Physics_HeavyIon_h
#include <ostream>
-namespace CepGen
+namespace cepgen
{
enum class PDG;
/// Enumeration of chemical elements
enum class Element
{
invalid = 0,
H = 1, C = 6, O = 8,
Al = 13, Cu = 29,
Xe = 54, Au = 79, Pb = 82,
U = 92
};
std::ostream& operator<<( std::ostream& os, const Element& elem );
/// Heavy ion container (Z+A)
struct HeavyIon
{
/// General constructor from mass and atomic number
HeavyIon( unsigned short a, const Element& z ) : A( a ), Z( z ) {}
/// Build from a custom PDG id
HeavyIon( const PDG& pdg );
/// Simple proton
static inline HeavyIon proton() { return HeavyIon( 1, Element::H ); }
/// Convert the HI into a custom PDG id
operator PDG() const;
/// Check the validity of the heavy ion
inline operator bool() const {
return Z > Element::invalid && A > 1; // skip the proton
}
/// Human-readable expression of the ion
friend std::ostream& operator<<( std::ostream& os, const HeavyIon& hi );
/// Mass number
unsigned short A;
/// Atomic number
Element Z;
};
}
#endif
diff --git a/CepGen/Physics/KTFlux.cpp b/CepGen/Physics/KTFlux.cpp
index fcfef07..1f5376a 100644
--- a/CepGen/Physics/KTFlux.cpp
+++ b/CepGen/Physics/KTFlux.cpp
@@ -1,103 +1,103 @@
#include "CepGen/Physics/KTFlux.h"
#include "CepGen/Physics/FormFactors.h"
#include "CepGen/Physics/ParticleProperties.h"
#include "CepGen/Physics/HeavyIon.h"
#include "CepGen/Physics/GluonGrid.h"
#include "CepGen/StructureFunctions/StructureFunctions.h"
#include "CepGen/Core/Exception.h"
-namespace CepGen
+namespace cepgen
{
const double KTFluxParameters::kMinKTFlux = 1.e-20;
- const double KTFluxParameters::kMP = part::mass( PDG::proton );
+ const double KTFluxParameters::kMP = particleproperties::mass( PDG::proton );
const double KTFluxParameters::kMP2 = KTFluxParameters::kMP*KTFluxParameters::kMP;
double
ktFlux( const KTFlux& type, double x, double kt2, sf::Parameterisation& sf, double mx )
{
double flux = 0.;
const double mp2 = KTFluxParameters::kMP2;
switch ( type ) {
case KTFlux::P_Photon_Elastic: {
const double x2 = x*x;
const double q2min = x2*mp2/( 1.-x ), q2 = q2min + kt2/( 1.-x );
// electromagnetic form factors
const auto& ff = FormFactors::protonElastic( q2 );
const double ela1 = ( 1.-x )*( 1.-q2min/q2 );
//const double ela3 = 1.-( q2-kt2 )/q2;
flux = constants::alphaEM*M_1_PI*( 1.-x )/q2*( ela1*ff.FE + 0.5*x2*ff.FM );
} break;
case KTFlux::P_Photon_Inelastic_Budnev: {
const double mx2 = mx*mx, x2 = x*x;
const double q2min = ( x*( mx2-mp2 ) + x2*mp2 )/( 1.-x ), q2 = q2min + kt2/( 1.-x );
const double xbj = q2 / ( q2+mx2-mp2 );
// structure functions
auto& str_fun = sf( xbj, q2 );
str_fun.computeFL( xbj, q2 );
const double f_D = str_fun.F2/( q2+mx2-mp2 )* ( 1.-x )*( 1.-q2min/q2 );
const double f_C = str_fun.F1( xbj, q2 ) * 2./q2;
flux = constants::alphaEM*M_1_PI*( 1.-x )/q2*( f_D+0.5*x2*f_C );
} break;
case KTFlux::P_Gluon_KMR: {
flux = kmr::GluonGrid::get()( log10( x ), log10( kt2 ), 2.*log10( mx ) );
} break;
default:
throw CG_FATAL( "GenericKTProcess:flux" ) << "Invalid flux type: " << type;
}
if ( flux < KTFluxParameters::kMinKTFlux )
return 0.;
return flux;
}
double
ktFlux( const KTFlux& type, double x, double kt2, const HeavyIon& hi )
{
double flux = 0.;
switch ( type ) {
case KTFlux::HI_Photon_Elastic: {
const double r_a = 1.1*std::pow( hi.A, 1./3 ), a0 = 0.7, m_a = hi.A*KTFluxParameters::kMP;
const double q2_ela = ( kt2+x*x*m_a*m_a )/( 1.-x ), cons = sqrt( q2_ela )/0.1973;
const double tau = cons*r_a, tau1 = cons*a0;
// "Realistic nuclear form-factor" as used in STARLIGHT
const double ff1 = 3.*( sin( tau )-tau*cos( tau ) )/pow( tau+1.e-10, 3 );
const double ff2 = 1./( 1.+tau1*tau1 );
const double ela1 = pow( kt2/( kt2+x*x*m_a*m_a ), 2 );
const double ela2 = pow( ff1*ff2, 2 )/*, ela3 = 1.-( q2_ela-kt2 )/q2_ela*/;
const unsigned int z = (unsigned short)hi.Z;
flux = constants::alphaEM*M_1_PI*z*z*ela1*ela2/q2_ela;
} break;
default:
throw CG_FATAL("GenericKTProcess:flux") << "Invalid flux type: " << type;
}
if ( flux < KTFluxParameters::kMinKTFlux )
return 0.;
return flux;
}
std::ostream&
operator<<( std::ostream& os, const KTFlux& type )
{
switch ( type ) {
case KTFlux::P_Photon_Elastic:
return os << "elastic photon from proton";
case KTFlux::P_Photon_Inelastic:
return os << "inelastic photon from proton";
case KTFlux::P_Photon_Inelastic_Budnev:
return os << "inelastic photon from proton (Budnev)";
case KTFlux::P_Gluon_KMR:
return os << "elastic gluon from proton (KMR)";
case KTFlux::HI_Photon_Elastic:
return os << "elastic photon from HI";
case KTFlux::invalid: default:
return os << "unrecognized flux (" << (int)type << ")";
}
}
}
diff --git a/CepGen/Physics/KTFlux.h b/CepGen/Physics/KTFlux.h
index d58f312..be632b1 100644
--- a/CepGen/Physics/KTFlux.h
+++ b/CepGen/Physics/KTFlux.h
@@ -1,45 +1,45 @@
#ifndef CepGen_Physics_KTFlux_h
#define CepGen_Physics_KTFlux_h
#include "CepGen/Physics/PDG.h"
#include <ostream>
-namespace CepGen
+namespace cepgen
{
namespace sf { class Parameterisation; }
class HeavyIon;
/// Collection of fundamental constants for kT fluxes definition
struct KTFluxParameters
{
static const double kMinKTFlux; ///< Minimal value taken for a kT-factorised flux
static const double kMP; ///< Proton mass, un GeV/c\f${}^2\f$
static const double kMP2; ///< Squared proton mass
};
/// Type of incoming partons fluxes
enum class KTFlux
{
invalid = -1,
P_Photon_Elastic = 0,
P_Photon_Inelastic = 1,
P_Photon_Inelastic_Budnev = 11,
P_Gluon_KMR = 20,
HI_Photon_Elastic = 100
};
/// Human version of the flux name
std::ostream& operator<<( std::ostream&, const KTFlux& );
/// \brief Compute the flux for a given parton x/kT
/// \param[in] type Flux modelling
/// \param[in] x Parton momentum fraction
/// \param[in] kt2 Transverse 2-momentum \f$\mathbf{q}_{\mathrm{T}}^2\f$ of the incoming parton
/// \param[in] sf Structure functions evaluator
/// \param[in] mx Outgoing diffractive proton mass
double ktFlux( const KTFlux& type, double x, double kt2, sf::Parameterisation& sf, double mx = KTFluxParameters::kMP );
/// \brief Compute the flux (from heavy ion) for a given parton x/kT
/// \param[in] type Flux modelling
/// \param[in] x Parton momentum fraction
/// \param[in] kt2 Transverse 2-momentum \f$\mathbf{q}_{\mathrm{T}}^2\f$ of the incoming parton
/// \param[in] hi Heavy ion properties
double ktFlux( const KTFlux& type, double x, double kt2, const HeavyIon& hi );
}
#endif
diff --git a/CepGen/Physics/Kinematics.cpp b/CepGen/Physics/Kinematics.cpp
index eff9d09..cb60c99 100644
--- a/CepGen/Physics/Kinematics.cpp
+++ b/CepGen/Physics/Kinematics.cpp
@@ -1,88 +1,88 @@
#include "CepGen/Physics/Kinematics.h"
#include "CepGen/Physics/PDG.h"
#include "CepGen/Physics/KTFlux.h"
#include "CepGen/Core/Exception.h"
#include "CepGen/Core/utils.h"
#include "CepGen/StructureFunctions/SuriYennie.h"
#include "CepGen/Event/Particle.h"
-namespace CepGen
+namespace cepgen
{
Kinematics::Kinematics() :
incoming_beams( { { 6500., PDG::proton, KTFlux::invalid }, { 6500., PDG::proton, KTFlux::invalid } } ),
mode( KinematicsMode::invalid ), structure_functions( new sf::SuriYennie )
{}
Kinematics::~Kinematics()
{}
void
Kinematics::setSqrtS( double sqrts )
{
incoming_beams.first.pz = incoming_beams.second.pz = 0.5 * sqrts;
}
double
Kinematics::sqrtS() const
{
return incoming_beams.first.pz + incoming_beams.second.pz;
}
//--------------------------------------------------------------------
// User-friendly display of the kinematics mode
//--------------------------------------------------------------------
std::ostream&
operator<<( std::ostream& os, const KinematicsMode& pm )
{
switch ( pm ) {
case KinematicsMode::invalid:
return os << "invalid";
case KinematicsMode::ElectronElectron:
return os << "electron/electron";
case KinematicsMode::ElectronProton:
return os << "electron/proton";
case KinematicsMode::ProtonElectron:
return os << "proton/electron";
case KinematicsMode::ElasticElastic:
return os << "elastic/elastic";
case KinematicsMode::InelasticElastic:
return os << "inelastic/elastic";
case KinematicsMode::ElasticInelastic:
return os << "elastic/inelastic";
case KinematicsMode::InelasticInelastic:
return os << "inelastic/inelastic";
}
return os;
}
//--------------------------------------------------------------------
// User-friendly display of incoming particles
//--------------------------------------------------------------------
std::ostream&
operator<<( std::ostream& os, const Kinematics::Beam& beam )
{
if ( (HeavyIon)beam.pdg )
os << (HeavyIon)beam.pdg;
else
os << beam.pdg;
os << " (" << beam.pz << " GeV/c)";
if ( beam.kt_flux != KTFlux::invalid )
os << " [unint.flux: " << beam.kt_flux << "]";
return os;
}
//--------------------------------------------------------------------
// List of kinematics limits
//--------------------------------------------------------------------
Kinematics::CutsList::CutsList()
{
initial.q2 = { 0., 1.e5 };
central.pt_single.min() = 0.;
remnants.mass_single = { 1.07, 320. };
}
}
diff --git a/CepGen/Physics/Kinematics.h b/CepGen/Physics/Kinematics.h
index 794c377..7d9dfb9 100644
--- a/CepGen/Physics/Kinematics.h
+++ b/CepGen/Physics/Kinematics.h
@@ -1,79 +1,79 @@
#ifndef CepGen_Physics_Kinematics_h
#define CepGen_Physics_Kinematics_h
#include "CepGen/Core/Hasher.h"
#include "CepGen/Physics/Cuts.h"
#include "CepGen/Physics/HeavyIon.h"
#include <ostream>
#include <vector>
#include <unordered_map>
#include <memory>
-namespace CepGen
+namespace cepgen
{
enum class PDG;
enum class KTFlux;
namespace sf { class Parameterisation; }
/// Type of kinematics to consider for the process
enum class KinematicsMode
{
invalid = -1,
ElectronProton = 0, ///< electron-proton elastic case
ElasticElastic = 1, ///< proton-proton elastic case
ElasticInelastic = 2, ///< proton-proton single-dissociative (or inelastic-elastic) case
InelasticElastic = 3, ///< proton-proton single-dissociative (or elastic-inelastic) case
InelasticInelastic = 4, ///< proton-proton double-dissociative case
ProtonElectron,
ElectronElectron
};
/// Human-readable format of a process mode (elastic/dissociative parts)
std::ostream& operator<<( std::ostream&, const KinematicsMode& );
/// List of kinematic constraints to apply on the process phase space.
class Kinematics
{
public:
Kinematics();
~Kinematics();
/// Incoming beams characteristics
struct Beam
{
double pz; ///< Incoming particle momentum, in GeV/c
PDG pdg; ///< PDG identifier for the beam
KTFlux kt_flux; ///< Type of kT-factorised flux to be considered (if any)
};
friend std::ostream& operator<<( std::ostream&, const Beam& );
/// Beam/primary particle's kinematics
std::pair<Beam,Beam> incoming_beams;
/// Set the incoming particles' momenta (if the collision is symmetric)
void setSqrtS( double sqrts );
/// Process centre of mass energy
double sqrtS() const;
/// Minimum list of central particles required
std::vector<PDG> minimum_final_state;
/// Type of kinematics to consider for the phase space
KinematicsMode mode;
/// Type of structure functions to consider
std::shared_ptr<sf::Parameterisation> structure_functions;
/// A collection of cuts to apply on the physical phase space
struct CutsList
{
CutsList();
/// Cuts on the initial particles kinematics
Cuts initial;
/// Cuts on the central system produced
Cuts central;
std::unordered_map<PDG,Cuts,EnumHash<PDG> > central_particles;
/// Cuts on the beam remnants system
Cuts remnants;
};
CutsList cuts;
std::string kmr_grid_path;
};
}
#endif
diff --git a/CepGen/Physics/Limits.cpp b/CepGen/Physics/Limits.cpp
index 39f7b9b..dd6cb04 100644
--- a/CepGen/Physics/Limits.cpp
+++ b/CepGen/Physics/Limits.cpp
@@ -1,98 +1,98 @@
#include "CepGen/Physics/Limits.h"
#include "CepGen/Core/Exception.h"
#include "CepGen/Core/utils.h"
-namespace CepGen
+namespace cepgen
{
Limits::Limits( double min, double max ) :
std::pair<double,double>( min, max )
{}
Limits::Limits( const Limits& rhs ) :
std::pair<double,double>( rhs.first, rhs.second )
{}
void
Limits::in( double low, double up )
{
first = low;
second = up;
}
double
Limits::range() const
{
if ( !hasMin() || !hasMax() )
return 0.;
return second-first;
}
bool
Limits::hasMin() const
{
return first != kInvalid;
}
bool
Limits::hasMax() const
{
return second != kInvalid;
}
bool
Limits::passes( double val ) const
{
if ( hasMin() && val < min() )
return false;
if ( hasMax() && val > max() )
return false;
return true;
}
bool
Limits::valid() const
{
return hasMin() || hasMax();
}
void
Limits::save( bool& on, double& lmin, double& lmax ) const
{
on = false; lmin = lmax = 0.;
if ( !valid() )
return;
on = true;
if ( hasMin() )
lmin = min();
if ( hasMax() )
lmax = max();
if ( lmin == lmax )
on = false;
}
double
Limits::x( double v ) const
{
if ( v < 0. || v > 1. )
CG_ERROR( "Limits:shoot" )
<< "x must be comprised between 0 and 1; x value = " << v << ".";
if ( !valid() )
return kInvalid;
return first + ( second-first ) * v;
}
std::ostream&
operator<<( std::ostream& os, const Limits& lim )
{
if ( !lim.hasMin() && !lim.hasMax() )
return os << "no cuts";
if ( !lim.hasMin() )
return os << Form( "≤ %g", lim.max() );
if ( !lim.hasMax() )
return os << Form( "≥ %g", lim.min() );
return os << Form( "%g → %g", lim.min(), lim.max() );
}
}
diff --git a/CepGen/Physics/Limits.h b/CepGen/Physics/Limits.h
index 21f3563..bd874e9 100644
--- a/CepGen/Physics/Limits.h
+++ b/CepGen/Physics/Limits.h
@@ -1,51 +1,51 @@
#ifndef CepGen_Physics_Limits_h
#define CepGen_Physics_Limits_h
#include <utility>
#include <ostream>
-namespace CepGen
+namespace cepgen
{
/// Validity interval for a variable
class Limits : private std::pair<double,double>
{
public:
/// Define lower and upper limits on a quantity
Limits( double min = kInvalid, double max = kInvalid );
Limits( const Limits& );
/// Lower limit to apply on the variable
double min() const { return first; }
/// Lower limit to apply on the variable
double& min() { return first; }
/// Upper limit to apply on the variable
double max() const { return second; }
/// Upper limit to apply on the variable
double& max() { return second; }
/// Export the limits into external variables
void save( bool& on, double& lmin, double& lmax ) const;
/// Find the [0,1] value scaled between minimum and maximum
double x( double v ) const;
/// Specify the lower and upper limits on the variable
void in( double low, double up );
/// Full variable range allowed
double range() const;
/// Have a lower limit?
bool hasMin() const;
/// Have an upper limit?
bool hasMax() const;
/// Check if the value is inside limits' boundaries
bool passes( double val ) const;
/// Is there a lower and upper limit?
bool valid() const;
/// Human-readable expression of the limits
friend std::ostream& operator<<( std::ostream&, const Limits& );
private:
static constexpr double kInvalid = -999.999;
};
}
#endif
diff --git a/CepGen/Physics/PDG.h b/CepGen/Physics/PDG.h
index 47889bf..547c2cf 100644
--- a/CepGen/Physics/PDG.h
+++ b/CepGen/Physics/PDG.h
@@ -1,38 +1,38 @@
#ifndef CepGen_Physics_PDG_h
#define CepGen_Physics_PDG_h
#include <iostream>
-namespace CepGen
+namespace cepgen
{
/** Unique identifier for a particle type. From \cite Beringer:1900zz :
* `The Monte Carlo particle numbering scheme [...] is intended to facilitate interfacing between event generators, detector simulators, and analysis packages used in particle physics.`
* \brief PDG ids of all known particles
*/
enum class PDG
{
invalid = 0,
//--- fundamental particles
down = 1, up = 2, strange = 3, charm = 4, bottom = 5, top = 6,
electron = 11, electronNeutrino = 12,
muon = 13, muonNeutrino = 14,
tau = 15, tauNeutrino = 16,
gluon = 21, photon = 22, Z = 23, W = 24,
//--- composite particles
piPlus = 211, piZero = 111,
KPlus = 321, DPlus = 411,
rho770_0 = 113, rho1450_0 = 100113, rho1700_0 = 30113,
eta = 221, omega782 = 223,
h1380_1 = 10333,
Jpsi= 443,
phi1680 = 100333,
Upsilon1S = 553, Upsilon2S = 100553, Upsilon3S = 200553,
proton = 2212, neutron = 2112,
pomeron = 990, reggeon = 110,
diffractiveProton = 9902210
};
std::ostream& operator<<( std::ostream& os, const PDG& pc );
}
#endif
diff --git a/CepGen/Physics/ParticleProperties.cpp b/CepGen/Physics/ParticleProperties.cpp
index fd4a1a7..8ca74b1 100644
--- a/CepGen/Physics/ParticleProperties.cpp
+++ b/CepGen/Physics/ParticleProperties.cpp
@@ -1,153 +1,153 @@
#include "CepGen/Physics/ParticleProperties.h"
#include "CepGen/Physics/PDG.h"
#include "CepGen/Core/Exception.h"
-namespace CepGen
+namespace cepgen
{
- namespace part
+ namespace particleproperties
{
double
mass( const PDG& pdg_id )
{
switch ( pdg_id ) {
case PDG::electron: return 0.510998928e-3;
case PDG::muon: return 0.1056583715;
case PDG::tau: return 1.77682;
case PDG::down: return 0.0048;
case PDG::up: return 0.0023;
case PDG::strange: return 0.095;
case PDG::charm: return 1.29;
case PDG::bottom: return 4.18;
case PDG::top: return 172.44;
case PDG::electronNeutrino:
case PDG::muonNeutrino:
case PDG::tauNeutrino: return 0.;
case PDG::gluon:
case PDG::photon:
case PDG::pomeron: return 0.;
case PDG::Z: return 91.1876;
case PDG::W: return 80.385;
case PDG::piPlus: return 0.13957018;
case PDG::piZero: return 0.1349766;
case PDG::KPlus: return 0.49368;
case PDG::DPlus: return 1.86962;
case PDG::Jpsi: return 3.0969;
case PDG::proton: return 0.938272046;
case PDG::neutron: return 0.939565346;
case PDG::Upsilon1S: return 9.46030;
case PDG::Upsilon2S: return 10.02326;
case PDG::Upsilon3S: return 10.3552;
case PDG::rho770_0: return 0.77526;
case PDG::rho1450_0: return 1.465;
case PDG::rho1700_0: return 1.720;
case PDG::h1380_1: return 1.38619;
case PDG::eta: return 0.547862;
case PDG::invalid:
default:
return -1.;
}
}
double
charge( const PDG& pdg_id )
{
switch ( pdg_id ) {
case PDG::proton: case PDG::diffractiveProton:
return +1.;
case PDG::electron: case PDG::muon: case PDG::tau:
return -1.;
case PDG::down: case PDG::strange: case PDG::bottom:
return -1./3;
case PDG::up: case PDG::charm: case PDG::top:
return +2./3;
case PDG::W:
return +1.;
case PDG::piPlus: case PDG::KPlus: case PDG::DPlus:
return +1.;
default:
return 0.;
}
}
double
charge( int id )
{
const short sign = id / abs( id );
return sign * charge( (PDG)abs( id ) );
}
unsigned short
colours( const PDG& pdg_id )
{
switch ( pdg_id ) {
case PDG::top: return 3;
default: return 1;
}
}
double
width( const PDG& pdg_id )
{
switch ( pdg_id ) {
case PDG::Jpsi: return 92.9e-6; //FIXME
case PDG::Z: return 2.4952;
case PDG::W: return 2.085;
case PDG::Upsilon1S: return 54.02e-6;
case PDG::Upsilon2S: return 31.98e-6;
case PDG::Upsilon3S: return 20.32e-6;
case PDG::rho770_0: return 0.150; // PDG
case PDG::rho1450_0: return 0.400; // PDG
case PDG::rho1700_0: return 0.250; // PDG
default:
CG_WARNING( "ParticleProperties:width" )
<< "Particle " << pdg_id << " has no registered width.";
return -1.;
}
}
}
std::ostream&
operator<<( std::ostream& os, const PDG& pc )
{
switch ( pc ) {
case PDG::electron: return os << "e± ";
case PDG::electronNeutrino: return os << "ν_e ";
case PDG::muon: return os << "µ± ";
case PDG::muonNeutrino: return os << "ν_µ ";
case PDG::tau: return os << "τ± ";
case PDG::tauNeutrino: return os << "ν_τ ";
case PDG::gluon: return os << "gluon";
case PDG::photon: return os << "ɣ ";
case PDG::Z: return os << "Z";
case PDG::W: return os << "W± ";
case PDG::piPlus: return os << "π± ";
case PDG::piZero: return os << "π⁰\t";
case PDG::KPlus: return os << "K± ";
case PDG::DPlus: return os << "D± ";
case PDG::rho770_0: return os << "ρ(770)₀ ";
case PDG::rho1450_0: return os << "ρ(1450)₀ ";
case PDG::rho1700_0: return os << "ρ(1700)₀ ";
case PDG::h1380_1: return os << "h(1380)₁ ";
case PDG::eta: return os << "η meson";
case PDG::omega782: return os << "ω(782) ";
case PDG::Jpsi: return os << "J/ψ ";
case PDG::phi1680: return os << "ɸ(1680) ";
case PDG::Upsilon1S: return os << "Υ(1S) ";
case PDG::Upsilon2S: return os << "Υ(2S) ";
case PDG::Upsilon3S: return os << "Υ(3S) ";;
case PDG::proton: return os << "proton";
case PDG::diffractiveProton:return os << "diffr.proton";
case PDG::neutron: return os << "neutron";
case PDG::pomeron: return os << "IP";
case PDG::reggeon: return os << "IR";
case PDG::down: return os << "d";
case PDG::up: return os << "u";
case PDG::strange: return os << "s";
case PDG::charm: return os << "c";
case PDG::bottom: return os << "b";
case PDG::top: return os << "t";
case PDG::invalid: return os << "[...]";
}
return os;
}
}
diff --git a/CepGen/Physics/ParticleProperties.h b/CepGen/Physics/ParticleProperties.h
index 5c3ac96..2a1d6c0 100644
--- a/CepGen/Physics/ParticleProperties.h
+++ b/CepGen/Physics/ParticleProperties.h
@@ -1,33 +1,33 @@
#ifndef CepGen_Physics_ParticleProperties_h
#define CepGen_Physics_ParticleProperties_h
-namespace CepGen
+namespace cepgen
{
enum class PDG;
/// All useful properties about particles
- namespace part
+ namespace particleproperties
{
/** \brief Mass of a particle, in GeV/c\f${}^2\f$
* \param pdg_id PDG identifier
*/
double mass( const PDG& pdg_id );
/** \brief Electric charge of a particle, in \f$e\f$
* \param[in] pdg_id PDG id
*/
double charge( const PDG& pdg_id );
/** \brief Electric charge of a particle, in \f$e\f$
* \param[in] id integer PDG id
*/
double charge( int id );
/** \brief Colour factor for a given particle
* \param[in] pdg_id PDG id
*/
unsigned short colours( const PDG& pdg_id );
/** \brief Total decay width of an unstable particle, in GeV
* \param[in] pdg_id PDG id
*/
double width( const PDG& pdg_id );
}
}
#endif
diff --git a/CepGen/Processes/Fortran/KTStructures.h b/CepGen/Processes/Fortran/KTStructures.h
index 39f2732..3f98cb0 100644
--- a/CepGen/Processes/Fortran/KTStructures.h
+++ b/CepGen/Processes/Fortran/KTStructures.h
@@ -1,76 +1,76 @@
#ifndef CepGen_Processes_Fortran_KTStructures_h
#define CepGen_Processes_Fortran_KTStructures_h
-namespace CepGen
+namespace cepgen
{
/// Collection of common blocks for Fortran kT-processes
namespace ktblock
{
/// General physics constants
struct Constants {
double m_p; ///< Proton mass
double units; ///< Conversion factor GeV\f${}^2\to\f$ barn
double pi; ///< \f$\pi\f$
double alpha_em; ///< Electromagnetic coupling constant
};
/// Generic run parameters
struct Parameters {
int icontri; ///< Kinematics mode
int iflux1; ///< Type of kT-factorised flux for first incoming parton
int iflux2; ///< Type of kT-factorised flux for second incoming parton
int imethod; ///< Computation method for matrix element
int sfmod; ///< Structure functions modelling
int pdg_l; ///< Central system PDG id
int a_nuc1; ///< First beam mass number
int z_nuc1; ///< First beam atomic number
int a_nuc2; ///< Second beam mass number
int z_nuc2; ///< Second beam atomic number
double inp1; ///< First beam momentum, in GeV/c
double inp2; ///< Second beam momentum, in GeV/c
};
/// Kinematics properties of the kT-factorised process
struct KTKinematics {
double q1t; ///< Transverse momentum of the first incoming parton
double q2t; ///< Transverse momentum of the second incoming parton
double phiq1t; ///< Azimutal angle of the first incoming parton
double phiq2t; ///< Azimutal angle of the second incoming parton
double y1; ///< First incoming parton rapidity
double y2; ///< Second incoming parton rapidity
double ptdiff; ///< Central system pT balance
double phiptdiff; ///< Central system azimutal angle difference
double m_x; ///< Invariant mass for the first diffractive state
double m_y; ///< Invariant mass for the second diffractive state
};
/// Phase space cuts for event kinematics
struct Cuts {
int ipt; ///< Switch for cut on single particle transverse momentum
int iene; ///< Switch for cut on single particle energy
int ieta; ///< Switch for cut on single particle pseudo-rapidity
int iinvm; ///< Switch for cut on central system invariant mass
int iptsum; ///< Switch for cut on central system transverse momentum
int idely; ///< Switch for cut on rapididty difference
double pt_min; ///< Minimal single particle transverse momentum
double pt_max; ///< Maximal single particle transverse momentum
double ene_min; ///< Minimal single particle energy
double ene_max; ///< Maximal single particle energy
double eta_min; ///< Minimal single particle pseudo-rapidity
double eta_max; ///< Maximal single particle pseudo-rapidity
double invm_min; ///< Minimal central system invariant mass
double invm_max; ///< Maximal central system invariant mass
double ptsum_min; ///< Minimal central system transverse momentum
double ptsum_max; ///< Maximal central system transverse momentum
double dely_min; ///< Minimal rapidity difference for central system
double dely_max; ///< Maximal rapidity difference for central system
};
/// Single event kinematics
struct Event {
int nout; ///< Number of particles in central system
int pdg[10]; ///< PDG ids of all particles in central system
double pc[10][4]; ///< 4-momenta of all particles in central system
double px[4]; ///< 4-momentum of first outgoing proton state
double py[4]; ///< 4-momentum of second outgoing proton state
};
}
}
#endif
diff --git a/CepGen/Processes/FortranKTProcess.cpp b/CepGen/Processes/FortranKTProcess.cpp
index fc14e33..5542eff 100644
--- a/CepGen/Processes/FortranKTProcess.cpp
+++ b/CepGen/Processes/FortranKTProcess.cpp
@@ -1,166 +1,166 @@
#include "CepGen/Processes/FortranKTProcess.h"
#include "CepGen/Processes/Fortran/KTStructures.h"
#include "CepGen/Core/ParametersList.h"
#include "CepGen/StructureFunctions/StructureFunctions.h"
#include "CepGen/Event/Event.h"
#include "CepGen/Physics/KTFlux.h"
#include "CepGen/Physics/Constants.h"
#include "CepGen/Physics/PDG.h"
extern "C"
{
- extern CepGen::ktblock::Constants constants_;
- extern CepGen::ktblock::Parameters params_;
- extern CepGen::ktblock::KTKinematics ktkin_;
- extern CepGen::ktblock::Cuts kincuts_;
- extern CepGen::ktblock::Event evtkin_;
+ extern cepgen::ktblock::Constants constants_;
+ extern cepgen::ktblock::Parameters params_;
+ extern cepgen::ktblock::KTKinematics ktkin_;
+ extern cepgen::ktblock::Cuts kincuts_;
+ extern cepgen::ktblock::Event evtkin_;
}
-namespace CepGen
+namespace cepgen
{
namespace process
{
FortranKTProcess::FortranKTProcess( const ParametersList& params, const char* name, const char* descr, std::function<void( double& )> func ) :
GenericKTProcess( params, name, descr, { { PDG::photon, PDG::photon } }, { PDG::muon, PDG::muon } ),
pair_( params.get<int>( "pair", 13 ) ),
method_( params.get<int>( "method", 1 ) ),
func_( func )
{
constants_.m_p = GenericProcess::mp_;
constants_.units = constants::GeV2toBarn;
constants_.pi = M_PI;
constants_.alpha_em = constants::alphaEM;
}
void
FortranKTProcess::preparePhaseSpace()
{
mom_ip1_ = event_->getOneByRole( Particle::IncomingBeam1 ).momentum();
mom_ip2_ = event_->getOneByRole( Particle::IncomingBeam2 ).momentum();
registerVariable( y1_, Mapping::linear, cuts_.cuts.central.rapidity_single, { -6., 6. }, "First central particle rapidity" );
registerVariable( y2_, Mapping::linear, cuts_.cuts.central.rapidity_single, { -6., 6. }, "Second central particle rapidity" );
registerVariable( pt_diff_, Mapping::linear, cuts_.cuts.central.pt_diff, { 0., 50. }, "Transverse momentum difference between central particles" );
registerVariable( phi_pt_diff_, Mapping::linear, cuts_.cuts.central.phi_pt_diff, { 0., 2.*M_PI }, "Central particles azimuthal angle difference" );
//===========================================================================================
// feed phase space cuts to the common block
//===========================================================================================
cuts_.cuts.central.pt_single.save( (bool&)kincuts_.ipt, kincuts_.pt_min, kincuts_.pt_max );
cuts_.cuts.central.energy_single.save( (bool&)kincuts_.iene, kincuts_.ene_min, kincuts_.ene_max );
cuts_.cuts.central.eta_single.save( (bool&)kincuts_.ieta, kincuts_.eta_min, kincuts_.eta_max );
cuts_.cuts.central.mass_sum.save( (bool&)kincuts_.iinvm, kincuts_.invm_min, kincuts_.invm_max );
cuts_.cuts.central.pt_sum.save( (bool&)kincuts_.iptsum, kincuts_.ptsum_min, kincuts_.ptsum_max );
cuts_.cuts.central.rapidity_diff.save( (bool&)kincuts_.idely, kincuts_.dely_min, kincuts_.dely_max );
//===========================================================================================
// feed run parameters to the common block
//===========================================================================================
params_.icontri = (int)cuts_.mode;
params_.imethod = method_;
params_.sfmod = (int)cuts_.structure_functions->type;
params_.pdg_l = pair_;
//-------------------------------------------------------------------------------------------
// incoming beams information
//-------------------------------------------------------------------------------------------
params_.inp1 = cuts_.incoming_beams.first.pz;
params_.inp2 = cuts_.incoming_beams.second.pz;
const HeavyIon in1 = (HeavyIon)cuts_.incoming_beams.first.pdg;
if ( in1 ) {
params_.a_nuc1 = in1.A;
params_.z_nuc1 = (unsigned short)in1.Z;
if ( params_.z_nuc1 > 1 ) {
event_->getOneByRole( Particle::IncomingBeam1 ).setPdgId( (PDG)in1 );
event_->getOneByRole( Particle::OutgoingBeam1 ).setPdgId( (PDG)in1 );
}
}
else
params_.a_nuc1 = params_.z_nuc1 = 1;
const HeavyIon in2 = (HeavyIon)cuts_.incoming_beams.second.pdg;
if ( in2 ) {
params_.a_nuc2 = in2.A;
params_.z_nuc2 = (unsigned short)in2.Z;
if ( params_.z_nuc2 > 1 ) {
event_->getOneByRole( Particle::IncomingBeam2 ).setPdgId( (PDG)in2 );
event_->getOneByRole( Particle::OutgoingBeam2 ).setPdgId( (PDG)in2 );
}
}
else
params_.a_nuc2 = params_.z_nuc2 = 1;
//-------------------------------------------------------------------------------------------
// intermediate partons information
//-------------------------------------------------------------------------------------------
params_.iflux1 = (int)cuts_.incoming_beams.first.kt_flux;
params_.iflux2 = (int)cuts_.incoming_beams.second.kt_flux;
if ( (KTFlux)params_.iflux1 == KTFlux::P_Gluon_KMR )
event_->getOneByRole( Particle::Parton1 ).setPdgId( PDG::gluon );
if ( (KTFlux)params_.iflux2 == KTFlux::P_Gluon_KMR )
event_->getOneByRole( Particle::Parton2 ).setPdgId( PDG::gluon );
}
double
FortranKTProcess::computeKTFactorisedMatrixElement()
{
ktkin_.q1t = qt1_;
ktkin_.q2t = qt2_;
ktkin_.phiq1t = phi_qt1_;
ktkin_.phiq2t = phi_qt2_;
ktkin_.y1 = y1_;
ktkin_.y2 = y2_;
ktkin_.ptdiff = pt_diff_;
ktkin_.phiptdiff = phi_pt_diff_;
ktkin_.m_x = MX_;
ktkin_.m_y = MY_;
//--- compute the event weight
double weight = 0.;
func_( weight );
return weight;
}
void
FortranKTProcess::fillCentralParticlesKinematics()
{
//===========================================================================================
// outgoing beam remnants
//===========================================================================================
PX_ = Particle::Momentum( evtkin_.px );
PY_ = Particle::Momentum( evtkin_.py );
// express these momenta per nucleon
PX_ *= 1./params_.a_nuc1;
PY_ *= 1./params_.a_nuc2;
//===========================================================================================
// intermediate partons
//===========================================================================================
const Particle::Momentum mom_par1 = mom_ip1_-PX_, mom_par2 = mom_ip2_-PY_;
event_->getOneByRole( Particle::Parton1 ).setMomentum( mom_par1 );
event_->getOneByRole( Particle::Parton2 ).setMomentum( mom_par2 );
event_->getOneByRole( Particle::Intermediate ).setMomentum( mom_par1+mom_par2 );
//===========================================================================================
// central system
//===========================================================================================
Particles& oc = event_->getByRole( Particle::CentralSystem );
for ( int i = 0; i < evtkin_.nout; ++i ) {
Particle& p = oc[i];
p.setPdgId( evtkin_.pdg[i] );
p.setStatus( Particle::Status::FinalState );
p.setMomentum( Particle::Momentum( evtkin_.pc[i] ) );
}
}
}
}
diff --git a/CepGen/Processes/FortranKTProcess.h b/CepGen/Processes/FortranKTProcess.h
index f00bd37..d4750d9 100644
--- a/CepGen/Processes/FortranKTProcess.h
+++ b/CepGen/Processes/FortranKTProcess.h
@@ -1,37 +1,37 @@
#ifndef CepGen_Processes_FortranKTProcess_h
#define CepGen_Processes_FortranKTProcess_h
#include "CepGen/Processes/GenericKTProcess.h"
#include <functional>
-namespace CepGen
+namespace cepgen
{
namespace process
{
/// Compute the matrix element for a generic \f$k_T\f$-factorised process defined in a Fortran subroutine
class FortranKTProcess : public GenericKTProcess
{
public:
FortranKTProcess( const ParametersList& params, const char* name, const char* descr, std::function<void(double&)> func );
ProcessPtr clone( const ParametersList& params ) const override { return ProcessPtr( new FortranKTProcess( *this ) ); }
private:
void preparePhaseSpace() override;
double computeKTFactorisedMatrixElement() override;
void fillCentralParticlesKinematics() override;
int pair_; ///< Outgoing particles type
int method_; ///< Computation method for the process
std::function<void(double&)> func_; ///< Subroutine to be called for weight computation
double y1_; ///< First outgoing particle rapidity
double y2_; ///< Second outgoing particle rapidity
double pt_diff_; ///< Transverse momentum balance between outgoing particles
double phi_pt_diff_; ///< Azimutal angle difference between outgoing particles
Particle::Momentum mom_ip1_; ///< First incoming beam momentum
Particle::Momentum mom_ip2_; ///< Second incoming beam momentum
};
}
}
#endif
diff --git a/CepGen/Processes/FortranProcesses.h b/CepGen/Processes/FortranProcesses.h
index 54e0db5..4c0ffe3 100644
--- a/CepGen/Processes/FortranProcesses.h
+++ b/CepGen/Processes/FortranProcesses.h
@@ -1,17 +1,17 @@
#ifndef CepGen_Processes_FortranProcesses_h
#define CepGen_Processes_FortranProcesses_h
#include "CepGen/Processes/FortranKTProcess.h"
#include "CepGen/Processes/ProcessesHandler.h"
#include "CepGen/Core/ParametersList.h"
#define DECLARE_FORTRAN_SUBROUTINE( method ) \
extern "C" { extern void method ## _( double& ); }
#define PROCESS_F77_NAME( name ) F77_ ## name
#define REGISTER_FORTRAN_PROCESS( name, method, description ) \
- struct PROCESS_F77_NAME( name ) : public CepGen::process::FortranKTProcess { \
- PROCESS_F77_NAME( name )() : CepGen::process::FortranKTProcess( CepGen::ParametersList(), STRINGIFY( name ), description, method ## _ ) {} }; \
+ struct PROCESS_F77_NAME( name ) : public cepgen::process::FortranKTProcess { \
+ PROCESS_F77_NAME( name )() : cepgen::process::FortranKTProcess( cepgen::ParametersList(), STRINGIFY( name ), description, method ## _ ) {} }; \
REGISTER_PROCESS( name, PROCESS_F77_NAME( name ) )
#endif
diff --git a/CepGen/Processes/GamGamLL.cpp b/CepGen/Processes/GamGamLL.cpp
index 5edfe56..b15d91a 100644
--- a/CepGen/Processes/GamGamLL.cpp
+++ b/CepGen/Processes/GamGamLL.cpp
@@ -1,1149 +1,1149 @@
#include "CepGen/Processes/GamGamLL.h"
#include "CepGen/Event/Event.h"
#include "CepGen/Core/Exception.h"
#include "CepGen/Physics/Constants.h"
#include "CepGen/Physics/FormFactors.h"
#include "CepGen/Physics/PDG.h"
#include "CepGen/Processes/ProcessesHandler.h"
-namespace CepGen
+namespace cepgen
{
namespace process
{
//---------------------------------------------------------------------------------------------
GamGamLL::Masses::Masses() :
MX2_( 0. ), MY2_( 0. ), Ml2_( 0. ),
w12_( 0. ), w31_( 0. ), dw31_( 0. ), w52_( 0. ), dw52_( 0. )
{}
//---------------------------------------------------------------------------------------------
GamGamLL::GamGamLL( const ParametersList& params ) :
GenericProcess( "lpair", "pp → p(*) ( ɣɣ → l⁺l¯ ) p(*)" ),
n_opt_( params.get<int>( "nopt", 0 ) ),
pair_( params.get<int>( "pair", 0 ) ),
ep1_( 0. ), ep2_( 0. ), p_cm_( 0. ),
ec4_( 0. ), pc4_( 0. ), mc4_( 0. ), w4_( 0. ),
p12_( 0. ), p1k2_( 0. ), p2k1_( 0. ),
p13_( 0. ), p14_( 0. ), p25_( 0. ),
q1dq_( 0. ), q1dq2_( 0. ),
s1_( 0. ), s2_( 0. ),
epsi_( 0. ),
g5_( 0. ), g6_( 0. ), a5_( 0. ), a6_( 0. ), bb_( 0. ),
gram_( 0. ),
dd1_( 0. ), dd2_( 0. ), dd3_( 0. ), dd4_( 0. ), dd5_( 0. ),
delta_( 0. ),
g4_( 0. ), sa1_( 0. ), sa2_( 0. ),
sl1_( 0. ),
cos_theta4_( 0. ), sin_theta4_( 0. ),
al4_( 0. ), be4_( 0. ), de3_( 0. ), de5_( 0. ),
pt4_( 0. ),
jacobian_( 0. )
{}
//---------------------------------------------------------------------------------------------
void
GamGamLL::addEventContent()
{
GenericProcess::setEventContent( {
{ Particle::IncomingBeam1, PDG::proton },
{ Particle::IncomingBeam2, PDG::proton },
{ Particle::Parton1, PDG::photon },
{ Particle::Parton2, PDG::photon }
}, {
{ Particle::OutgoingBeam1, { PDG::proton } },
{ Particle::OutgoingBeam2, { PDG::proton } },
{ Particle::CentralSystem, { (PDG)pair_, (PDG)pair_ } }
} );
}
unsigned int
GamGamLL::numDimensions() const
{
switch ( cuts_.mode ) {
case KinematicsMode::ElectronProton: default:
throw CG_FATAL( "GamGamLL" )
<< "Process mode " << cuts_.mode << " not (yet) supported! "
<< "Please contact the developers to consider an implementation.";
case KinematicsMode::ElasticElastic:
return 7;
case KinematicsMode::ElasticInelastic:
case KinematicsMode::InelasticElastic:
return 8;
case KinematicsMode::InelasticInelastic:
return 9;
}
}
//---------------------------------------------------------------------------------------------
void
GamGamLL::setKinematics( const Kinematics& kin )
{
GenericProcess::setKinematics( kin );
masses_.Ml2_ = event_->getByRole( Particle::CentralSystem )[0].mass2();
w_limits_ = cuts_.cuts.central.mass_single;
if ( !w_limits_.hasMax() )
w_limits_.max() = s_;
// The minimal energy for the central system is its outgoing leptons' mass energy (or wmin_ if specified)
if ( !w_limits_.hasMin() )
w_limits_.min() = 4.*masses_.Ml2_;
// The maximal energy for the central system is its CM energy with the outgoing particles' mass energy substracted (or wmax if specified)
w_limits_.max() = std::min( pow( sqs_-MX_-MY_, 2 ), w_limits_.max() );
CG_DEBUG_LOOP( "GamGamLL:setKinematics" )
<< "w limits = " << w_limits_ << "\n\t"
<< "wmax/wmin = " << w_limits_.max()/w_limits_.min();
q2_limits_ = cuts_.cuts.initial.q2;
mx_limits_ = cuts_.cuts.remnants.mass_single;
}
//---------------------------------------------------------------------------------------------
bool
GamGamLL::pickin()
{
CG_DEBUG_LOOP( "GamGamLL" )
<< "Optimised mode? " << n_opt_;
jacobian_ = 0.;
w4_ = mc4_*mc4_;
// sig1 = sigma and sig2 = sigma' in [1]
const double sig = mc4_+MY_;
double sig1 = sig*sig,
sig2 = sig1;
CG_DEBUG_LOOP( "GamGamLL" )
<< "mc4 = " << mc4_ << "\n\t"
<< "sig1 = " << sig1 << "\n\t"
<< "sig2 = " << sig2;
// Mass difference between the first outgoing particle
// and the first incoming particle
masses_.w31_ = masses_.MX2_-w1_;
// Mass difference between the second outgoing particle
// and the second incoming particle
masses_.w52_ = masses_.MY2_-w2_;
// Mass difference between the two incoming particles
masses_.w12_ = w1_-w2_;
// Mass difference between the central two-photons system
// and the second outgoing particle
const double d6 = w4_-masses_.MY2_;
CG_DEBUG_LOOP( "GamGamLL" )
<< "w1 = " << w1_ << "\n\t"
<< "w2 = " << w2_ << "\n\t"
<< "w3 = " << masses_.MX2_ << "\n\t"
<< "w4 = " << w4_ << "\n\t"
<< "w5 = " << masses_.MY2_;;
CG_DEBUG_LOOP( "GamGamLL" )
<< "w31 = " << masses_.w31_ << "\n\t"
<< "w52 = " << masses_.w52_ << "\n\t"
<< "w12 = " << masses_.w12_;;
const double ss = s_+masses_.w12_;
const double rl1 = ss*ss-4.*w1_*s_; // lambda(s, m1**2, m2**2)
if ( rl1 <= 0. ) {
CG_WARNING( "GamGamLL" ) << "rl1 = " << rl1 << " <= 0";
return false;
}
sl1_ = sqrt( rl1 );
s2_ = 0.;
double ds2 = 0.;
if ( n_opt_ == 0 ) {
const double smax = s_+masses_.MX2_-2.*MX_*sqs_;
map( x(2), Limits( sig1, smax ), s2_, ds2, "s2" );
sig1 = s2_; //FIXME!!!!!!!!!!!!!!!!!!!!
}
CG_DEBUG_LOOP( "GamGamLL" )
<< "s2 = " << s2_;
const double sp = s_+masses_.MX2_-sig1,
d3 = sig1-w2_;
const double rl2 = sp*sp-4.*s_*masses_.MX2_; // lambda(s, m3**2, sigma)
if ( rl2 <= 0. ) {
CG_DEBUG( "GamGamLL" ) << "rl2 = " << rl2 << " <= 0";
return false;
}
const double sl2 = sqrt( rl2 );
double t1_max = w1_+masses_.MX2_-( ss*sp+sl1_*sl2 )/( 2.*s_ ), // definition from eq. (A.4) in [1]
t1_min = ( masses_.w31_*d3+( d3-masses_.w31_ )*( d3*w1_-masses_.w31_*w2_ )/s_ )/t1_max; // definition from eq. (A.5) in [1]
// FIXME dropped in CDF version
if ( t1_max > -q2_limits_.min() ) {
CG_WARNING( "GamGamLL" ) << "t1max = " << t1_max << " > -q2min = " << ( -q2_limits_.min() );
return false;
}
if ( t1_min < -q2_limits_.max() && q2_limits_.hasMax() ) {
CG_DEBUG( "GamGamLL" ) << "t1min = " << t1_min << " < -q2max = " << -q2_limits_.max();
return false;
}
if ( t1_max < -q2_limits_.max() && q2_limits_.hasMax() )
t1_max = -q2_limits_.max();
if ( t1_min > -q2_limits_.min() && q2_limits_.hasMin() )
t1_min = -q2_limits_.min();
/////
// t1, the first photon propagator, is defined here
t1_ = 0.;
double dt1 = 0.;
map( x(0), Limits( t1_min, t1_max ), t1_, dt1, "t1" );
// changes wrt mapt1 : dx->-dx
dt1 *= -1.;
CG_DEBUG_LOOP( "GamGamLL" )
<< "Definition of t1 = " << t1_ << " according to\n\t"
<< "(t1min, t1max) = (" << t1_min << ", " << t1_max << ")";
dd4_ = w4_-t1_;
const double d8 = t1_-w2_, t13 = t1_-w1_-masses_.MX2_;
sa1_ = -pow( t1_-masses_.w31_, 2 )/4.+w1_*t1_;
if ( sa1_ >= 0. ) {
CG_WARNING( "GamGamLL" ) << "sa1_ = " << sa1_ << " >= 0";
return false;
}
const double sl3 = sqrt( -sa1_ );
// one computes splus and (s2x=s2max)
double splus, s2max;
if ( w1_ != 0. ) {
const double inv_w1 = 1./w1_;
const double sb = masses_.MX2_ + 0.5 * ( s_*( t1_-masses_.w31_ )+masses_.w12_*t13 )*inv_w1,
sd = sl1_*sl3*inv_w1,
se =( s_*( t1_*( s_+t13-w2_ )-w2_*masses_.w31_ )+masses_.MX2_*( masses_.w12_*d8+w2_*masses_.MX2_ ) )*inv_w1;
if ( fabs( ( sb-sd )/sd ) >= 1. ) {
splus = sb-sd;
s2max = se/splus;
}
else {
s2max = sb+sd;
splus = se/s2max;
}
}
else { // 3
s2max = ( s_*( t1_*( s_+d8-masses_.MX2_ )-w2_*masses_.MX2_ )+w2_*masses_.MX2_*( w2_+masses_.MX2_-t1_ ) )/( ss*t13 );
splus = sig2;
}
// 4
double s2x = s2max;
CG_DEBUG_LOOP( "GamGamLL" )
<< "s2x = s2max = " << s2x;
if ( n_opt_ < 0 ) { // 5
if ( splus > sig2 ) {
sig2 = splus;
CG_DEBUG_LOOP( "GamGamLL" )
<< "sig2 truncated to splus = " << splus;
}
if ( n_opt_ < -1 )
map( x(2), Limits( sig2, s2max ), s2_, ds2, "s2" );
else
mapla( t1_, w2_, x(2), sig2, s2max, s2_, ds2 ); // n_opt_==-1
s2x = s2_;
}
else if ( n_opt_ == 0 )
s2x = s2_; // 6
CG_DEBUG_LOOP( "GamGamLL" )
<< "s2x = " << s2x;
// 7
const double r1 = s2x-d8, r2 = s2x-d6;
const double rl4 = ( r1*r1-4.*w2_*s2x )*( r2*r2-4.*masses_.MY2_*s2x );
if ( rl4 <= 0. ) {
CG_DEBUG_LOOP( "GamGamLL" )
<< "rl4 = " << rl4 << " <= 0";
return false;
}
const double sl4 = sqrt( rl4 );
// t2max, t2min definitions from eq. (A.12) and (A.13) in [1]
const double t2_max = w2_+masses_.MY2_-( r1*r2+sl4 )/s2x * 0.5,
t2_min = ( masses_.w52_*dd4_+( dd4_-masses_.w52_ )*( dd4_*w2_-masses_.w52_*t1_ )/s2x )/t2_max;
// t2, the second photon propagator, is defined here
t2_ = 0.;
double dt2 = 0.;
map( x(1), Limits( t2_min, t2_max ), t2_, dt2, "t2" );
// changes wrt mapt2 : dx->-dx
dt2 *= -1.;
// \f$\delta_6=m_4^2-m_5^2\f$ as defined in Vermaseren's paper
const double tau = t1_-t2_,
r3 = dd4_-t2_,
r4 = masses_.w52_-t2_;
CG_DEBUG_LOOP( "GamGamLL" )
<< "r1 = " << r1 << "\n\t"
<< "r2 = " << r2 << "\n\t"
<< "r3 = " << r3 << "\n\t"
<< "r4 = " << r4;
const double b = r3*r4-2.*( t1_+w2_ )*t2_;
const double c = t2_*d6*d8+( d6-d8 )*( d6*w2_-d8*masses_.MY2_ );
const double t25 = t2_-w2_-masses_.MY2_;
sa2_ = -0.25 * r4*r4 + w2_*t2_;
if ( sa2_ >= 0. ) {
CG_WARNING( "GamGamLL" )
<< "sa2_ = " << sa2_ << " >= 0";
return false;
}
const double sl6 = 2.*sqrt( -sa2_ );
g4_ = -r3*r3/4.+t1_*t2_;
if ( g4_ >= 0. ) {
CG_WARNING( "GamGamLL" ) << "g4_ = " << g4_ << " >= 0";
return false;
}
const double sl7 = 2.*sqrt( -g4_ ),
sl5 = sl6*sl7;
double s2p, s2min;
if ( fabs( ( sl5-b )/sl5 ) >= 1. ) {
s2p = 0.5 * ( sl5-b )/t2_;
s2min = c/( t2_*s2p );
}
else { // 8
s2min = 0.5 * ( -sl5-b )/t2_;
s2p = c/( t2_*s2min );
}
// 9
if ( n_opt_ > 1 )
map( x( 2 ), Limits( s2min, s2max ), s2_, ds2, "s2" );
else if ( n_opt_ == 1 )
mapla( t1_, w2_, x( 2 ), s2min, s2max, s2_, ds2 );
const double ap = -0.25*pow( s2_+d8, 2 )+s2_*t1_;
CG_DEBUG_LOOP( "GamGamLL" )
<< "s2 = " << s2_ << ", s2max = " << s2max << ", splus = " << splus;
if ( w1_ != 0. )
dd1_ = -0.25 * ( s2_-s2max ) * ( s2_-splus ) * w1_; // 10
else
dd1_ = 0.25 * ( s2_-s2max ) * ss * t13;
// 11
dd2_ = -0.25 * t2_*( s2_-s2p )*( s2_-s2min );
CG_DEBUG_LOOP( "GamGamLL" )
<< "t2 = " << t2_ << "\n\t"
<< "s2 = " << s2_ << "\n\t"
<< "s2p = " << s2p << "\n\t"
<< "s2min = " << s2min << "\n\t"
<< "dd2 = " << dd2_;;
const double yy4 = cos( M_PI*x( 3 ) );
const double dd = dd1_*dd2_;
p12_ = 0.5 * ( s_-w1_-w2_ );
const double st = s2_-t1_-w2_;
const double delb = ( 2.*w2_*r3+r4*st )*( 4.*p12_*t1_-( t1_-masses_.w31_ )*st )/( 16.*ap );
if ( dd <= 0. ) {
CG_DEBUG_LOOP( "GamGamLL" )
<< std::scientific
<< "dd = " << dd << " <= 0\n\t"
<< "dd1 = " << dd1_ << "\t"
<< "dd2 = " << dd2_ << std::fixed;
return false;
}
delta_ = delb - yy4*st*sqrt( dd )/ ap * 0.5;
s1_ = t2_+w1_+( 2.*p12_*r3-4.*delta_ )/st;
if ( ap >= 0. ) {
CG_DEBUG_LOOP( "GamGamLL" )
<< "ap = " << ap << " >= 0";
return false;
}
jacobian_ = ds2 * dt1 * dt2 * 0.125 * M_PI*M_PI/( sl1_*sqrt( -ap ) );
CG_DEBUG_LOOP( "GamGamLL" )
<< "Jacobian = " << std::scientific << jacobian_ << std::fixed;
gram_ = ( 1.-yy4*yy4 )*dd/ap;
p13_ = -0.5 * t13;
p14_ = 0.5 * ( tau+s1_-masses_.MX2_ );
p25_ = -0.5 * t25;
p1k2_ = 0.5 * ( s1_-t2_-w1_ );
p2k1_ = 0.5 * st;
if ( w2_ != 0. ) {
const double inv_w2 = 1./w2_;
const double sbb = 0.5 * ( s_*( t2_-masses_.w52_ )-masses_.w12_*t25 )*inv_w2 + masses_.MY2_,
sdd = 0.5 * sl1_*sl6*inv_w2,
see = ( s_*( t2_*( s_+t25-w1_ )-w1_*masses_.w52_ )+masses_.MY2_*( w1_*masses_.MY2_-masses_.w12_*( t2_-w1_ ) ) )*inv_w2;
double s1m = 0., s1p = 0.;
if ( sbb/sdd >= 0. ) {
s1p = sbb+sdd;
s1m = see/s1p;
}
else {
s1m = sbb-sdd;
s1p = see/s1m;
} // 12
dd3_ = -0.25 * w2_*( s1p-s1_ )*( s1m-s1_ ); // 13
}
else { // 14
const double s1p = ( s_*( t2_*( s_-masses_.MY2_+t2_-w1_ )-w1_*masses_.MY2_ )+w1_*masses_.MY2_*( w1_+masses_.MY2_-t2_ ) )/( t25*( s_-masses_.w12_ ) );
dd3_ = -0.25 * t25*( s_-masses_.w12_ )*( s1p-s1_ );
}
// 15
//const double acc3 = (s1p-s1_)/(s1p+s1_);
const double ssb = t2_+0.5 * w1_-r3*( masses_.w31_-t1_ )/t1_,
ssd = sl3*sl7/t1_,
sse = ( t2_-w1_ )*( w4_-masses_.MX2_ )+( t2_-w4_+masses_.w31_ )*( ( t2_-w1_)*masses_.MX2_-(w4_-masses_.MX2_)*w1_)/t1_;
double s1pp, s1pm;
if ( ssb/ssd >= 0. ) {
s1pp = ssb+ssd;
s1pm = sse/s1pp;
}
else { // 16
s1pm = ssb-ssd;
s1pp = sse/s1pm;
}
// 17
dd4_ = -0.25 * t1_*( s1_-s1pp )*( s1_-s1pm );
//const double acc4 = ( s1_-s1pm )/( s1_+s1pm );
dd5_ = dd1_+dd3_+( ( p12_*( t1_-masses_.w31_ )*0.5-w1_*p2k1_ )*( p2k1_*( t2_-masses_.w52_ )-w2_*r3 )
-delta_*( 2.*p12_*p2k1_-w2_*( t1_-masses_.w31_ ) ) ) / p2k1_;
return true;
}
//---------------------------------------------------------------------------------------------
bool
GamGamLL::orient()
{
if ( !pickin() || jacobian_ == 0. ) {
CG_DEBUG_LOOP( "GamGamLL" )
<< "Pickin failed! Jacobian = " << jacobian_;
return false;
}
const double re = 0.5 / sqs_;
ep1_ = re*( s_+masses_.w12_ );
ep2_ = re*( s_-masses_.w12_ );
CG_DEBUG_LOOP( "GamGamLL" )
<< std::scientific
<< " re = " << re << "\n\t"
<< "w12_ = " << masses_.w12_
<< std::fixed;
CG_DEBUG_LOOP( "GamGamLL" )
<< "Incoming particles' energy = " << ep1_ << ", " << ep2_;
p_cm_ = re*sl1_;
de3_ = re*(s2_-masses_.MX2_+masses_.w12_);
de5_ = re*(s1_-masses_.MY2_-masses_.w12_);
// Final state energies
const double ep3 = ep1_-de3_,
ep5 = ep2_-de5_;
ec4_ = de3_+de5_;
if ( ec4_ < mc4_ ) {
CG_WARNING( "GamGamLL" )
<< "ec4_ = " << ec4_ << " < mc4_ = " << mc4_ << "\n\t"
<< "==> de3 = " << de3_ << ", de5 = " << de5_;
return false;
}
// What if the protons' momenta are not along the z-axis?
pc4_ = sqrt( ec4_*ec4_-mc4_*mc4_ );
if ( pc4_ == 0. ) {
CG_WARNING( "GamGamLL" ) << "pzc4 is null and should not be...";
return false;
}
const double pp3 = sqrt( ep3*ep3-masses_.MX2_ ), pt3 = sqrt( dd1_/s_ )/p_cm_,
pp5 = sqrt( ep5*ep5-masses_.MY2_ ), pt5 = sqrt( dd3_/s_ )/p_cm_;
CG_DEBUG_LOOP( "GamGamLL" )
<< "Central system's energy: E4 = " << ec4_ << "\n\t"
<< " momentum: p4 = " << pc4_ << "\n\t"
<< " invariant mass: m4 = " << mc4_ << "\n\t"
<< "Outgoing particles' energy: E3 = " << ep3 << "\n\t"
<< " E5 = " << ep5;
const double sin_theta3 = pt3/pp3,
sin_theta5 = pt5/pp5;
CG_DEBUG_LOOP( "GamGamLL" )
<< std::scientific
<< "sin_theta3 = " << sin_theta3 << "\n\t"
<< "sin_theta5 = " << sin_theta5
<< std::fixed;
if ( sin_theta3 > 1. ) {
CG_WARNING( "GamGamLL" )
<< "sin_theta3 = " << sin_theta3 << " > 1";
return false;
}
if ( sin_theta5 > 1. ) {
CG_WARNING( "GamGamLL" )
<< "sin_theta5 = " << sin_theta5 << " > 1";
return false;
}
double ct3 = sqrt( 1.-sin_theta3*sin_theta3 ),
ct5 = sqrt( 1.-sin_theta5*sin_theta5 );
if ( ep1_*ep3 < p13_ )
ct3 *= -1.;
if ( ep2_*ep5 > p25_ )
ct5 *= -1.;
CG_DEBUG_LOOP( "GamGamLL" )
<< "ct3 = " << ct3 << "\n\t"
<< "ct5 = " << ct5;
if ( dd5_ < 0. ) {
CG_WARNING( "GamGamLL" )
<< "dd5 = " << dd5_ << " < 0";
return false;
}
// Centre of mass system kinematics (theta4 and phi4)
pt4_ = sqrt( dd5_/s_ )/p_cm_;
sin_theta4_ = pt4_/pc4_;
if ( sin_theta4_ > 1. ) {
CG_WARNING( "GamGamLL" )
<< "st4 = " << sin_theta4_ << " > 1";
return false;
}
cos_theta4_ = sqrt( 1.-sin_theta4_*sin_theta4_ );
if ( ep1_*ec4_ < p14_ )
cos_theta4_ *= -1.;
al4_ = 1.-cos_theta4_;
be4_ = 1.+cos_theta4_;
if ( cos_theta4_ < 0. ) be4_ = sin_theta4_*sin_theta4_/al4_;
else al4_ = sin_theta4_*sin_theta4_/be4_;
CG_DEBUG_LOOP( "GamGamLL" )
<< "ct4 = " << cos_theta4_ << "\n\t"
<< "al4 = " << al4_ << ", be4 = " << be4_;
const double rr = sqrt( -gram_/s_ )/( p_cm_*pt4_ );
const double sin_phi3 = rr / pt3,
sin_phi5 = -rr / pt5;
if ( fabs( sin_phi3 ) > 1. ) {
CG_WARNING( "GamGamLL" )
<< "sin(phi_3) = " << sin_phi3 << " while it must be in [-1 ; 1]";
return false;
}
if ( fabs( sin_phi5 ) > 1. ) {
CG_WARNING( "GamGamLL" )
<< "sin(phi_5) = " << sin_phi5 << " while it must be in [-1 ; 1]";
return false;
}
const double cos_phi3 = -sqrt( 1.-sin_phi3*sin_phi3 ),
cos_phi5 = -sqrt( 1.-sin_phi5*sin_phi5 );
p3_lab_ = Particle::Momentum( pp3*sin_theta3*cos_phi3, pp3*sin_theta3*sin_phi3, pp3*ct3, ep3 );
p5_lab_ = Particle::Momentum( pp5*sin_theta5*cos_phi5, pp5*sin_theta5*sin_phi5, pp5*ct5, ep5 );
const double a1 = p3_lab_.px()-p5_lab_.px();
CG_DEBUG_LOOP( "GamGamLL" )
<< "Kinematic quantities\n\t"
<< "cos(theta3) = " << ct3 << "\t" << "sin(theta3) = " << sin_theta3 << "\n\t"
<< "cos( phi3 ) = " << cos_phi3 << "\t" << "sin( phi3 ) = " << sin_phi3 << "\n\t"
<< "cos(theta4) = " << cos_theta4_ << "\t" << "sin(theta4) = " << sin_theta4_ << "\n\t"
<< "cos(theta5) = " << ct5 << "\t" << "sin(theta5) = " << sin_theta5 << "\n\t"
<< "cos( phi5 ) = " << cos_phi5 << "\t" << "sin( phi5 ) = " << sin_phi5 << "\n\t"
<< "a1 = " << a1;
if ( fabs( pt4_+p3_lab_.px()+p5_lab_.px() ) < fabs( fabs( a1 )-pt4_ ) ) {
CG_DEBUG_LOOP( "GamGamLL" )
<< "|pt4+pt3*cos(phi3)+pt5*cos(phi5)| < | |a1|-pt4 |\n\t"
<< "pt4 = " << pt4_ << "\t"
<< "pt5 = " << pt5 << "\n\t"
<< "cos(phi3) = " << cos_phi3 << "\t"
<< "cos(phi5) = " << cos_phi5 << "\n\t"
<< "a1 = " << a1;
return true;
}
if ( a1 < 0. ) p5_lab_[0] = -p5_lab_.px();
else p3_lab_[0] = -p3_lab_.px();
return true;
}
//---------------------------------------------------------------------------------------------
double
GamGamLL::computeOutgoingPrimaryParticlesMasses( double x, double outmass, double lepmass, double& dw )
{
- const double mx0 = mp_+part::mass( PDG::piZero ); // 1.07
+ const double mx0 = mp_+particleproperties::mass( PDG::piZero ); // 1.07
const double wx2min = pow( std::max( mx0, mx_limits_.min() ), 2 ),
wx2max = pow( std::min( sqs_-outmass-2.*lepmass, mx_limits_.max() ), 2 );
double mx2 = 0., dmx2 = 0.;
map( x, Limits( wx2min, wx2max ), mx2, dmx2, "mx2" );
CG_DEBUG_LOOP( "GamGamLL" )
<< "mX^2 in range (" << wx2min << ", " << wx2max << "), x = " << x << "\n\t"
<< "mX^2 = " << mx2 << ", d(mX^2) = " << dmx2 << "\n\t"
<< "mX = " << sqrt( mx2 ) << ", d(mX) = " << sqrt( dmx2 );
dw = sqrt( dmx2 );
return sqrt( mx2 );
}
//---------------------------------------------------------------------------------------------
void
GamGamLL::beforeComputeWeight()
{
if ( !GenericProcess::is_point_set_ ) return;
const Particle& p1 = event_->getOneByRole( Particle::IncomingBeam1 ),
&p2 = event_->getOneByRole( Particle::IncomingBeam2 );
ep1_ = p1.energy();
ep2_ = p2.energy();
//std::cout << __PRETTY_FUNCTION__ << ":" << w_limits_ << "|" << q2_limits_ << "|" << mx_limits_ << std::endl;
switch ( cuts_.mode ) {
case KinematicsMode::ElectronProton: default:
CG_ERROR( "GamGamLL" ) << "Case not yet supported!"; break;
case KinematicsMode::ElasticElastic:
masses_.dw31_ = masses_.dw52_ = 0.; break;
case KinematicsMode::InelasticElastic: {
const double m = computeOutgoingPrimaryParticlesMasses( x( 7 ), p1.mass(), sqrt( masses_.Ml2_ ), masses_.dw31_ );
event_->getOneByRole( Particle::OutgoingBeam1 ).setMass( m );
- event_->getOneByRole( Particle::OutgoingBeam2 ).setMass( part::mass( p2.pdgId() ) );
+ event_->getOneByRole( Particle::OutgoingBeam2 ).setMass( particleproperties::mass( p2.pdgId() ) );
} break;
case KinematicsMode::ElasticInelastic: {
const double m = computeOutgoingPrimaryParticlesMasses( x( 7 ), p2.mass(), sqrt( masses_.Ml2_ ), masses_.dw52_ );
- event_->getOneByRole( Particle::OutgoingBeam1 ).setMass( part::mass( p1.pdgId() ) );
+ event_->getOneByRole( Particle::OutgoingBeam1 ).setMass( particleproperties::mass( p1.pdgId() ) );
event_->getOneByRole( Particle::OutgoingBeam2 ).setMass( m );
} break;
case KinematicsMode::InelasticInelastic: {
const double mx = computeOutgoingPrimaryParticlesMasses( x( 7 ), p2.mass(), sqrt( masses_.Ml2_ ), masses_.dw31_ );
event_->getOneByRole( Particle::OutgoingBeam1 ).setMass( mx );
const double my = computeOutgoingPrimaryParticlesMasses( x( 8 ), p1.mass(), sqrt( masses_.Ml2_ ), masses_.dw52_ );
event_->getOneByRole( Particle::OutgoingBeam2 ).setMass( my );
} break;
}
MX_ = event_->getOneByRole( Particle::OutgoingBeam1 ).mass();
MY_ = event_->getOneByRole( Particle::OutgoingBeam2 ).mass();
masses_.MX2_ = MX_*MX_;
masses_.MY2_ = MY_*MY_;
}
//---------------------------------------------------------------------------------------------
double
GamGamLL::computeWeight()
{
CG_DEBUG_LOOP( "GamGamLL" )
<< "sqrt(s) = " << sqs_ << " GeV\n\t"
<< "m(X1) = " << MX_ << " GeV\t"
<< "m(X2) = " << MY_ << " GeV";
// compute the two-photon energy for this point
w4_ = 0.;
double dw4 = 0.;
map( x( 4 ), w_limits_, w4_, dw4, "w4" );
mc4_ = sqrt( w4_ );
CG_DEBUG_LOOP( "GamGamLL" )
<< "Computed value for w4 = " << w4_ << " → mc4 = " << mc4_;
if ( !orient() )
return 0.;
if ( jacobian_ == 0. ) {
CG_WARNING( "GamGamLL" ) << "dj = " << jacobian_;
return 0.;
}
if ( t1_ > 0. ) {
CG_WARNING( "GamGamLL" ) << "t1 = " << t1_ << " > 0";
return 0.;
}
if ( t2_ > 0. ) {
CG_WARNING( "GamGamLL" ) << "t2 = " << t2_ << " > 0";
return 0.;
}
const double ecm6 = w4_ / ( 2.*mc4_ ),
pp6cm = sqrt( ecm6*ecm6-masses_.Ml2_ );
jacobian_ *= dw4*pp6cm/( mc4_*constants::sconstb*s_ );
// Let the most obscure part of this code begin...
const double e1mp1 = w1_ / ( ep1_+p_cm_ ),
e3mp3 = masses_.MX2_ / ( p3_lab_.energy()+p3_lab_.p() );
const double al3 = pow( sin( p3_lab_.theta() ), 2 )/( 1.+( p3_lab_.theta() ) );
// 2-photon system kinematics ?!
const double eg = ( w4_+t1_-t2_ )/( 2.*mc4_ );
double pg = sqrt( eg*eg-t1_ );
const double pgx = -p3_lab_.px()*cos_theta4_-sin_theta4_*( de3_-e1mp1 + e3mp3 + p3_lab_.p()*al3 ),
pgy = -p3_lab_.py(),
pgz = mc4_*de3_/( ec4_+pc4_ )-ec4_*de3_*al4_/mc4_-p3_lab_.px()*ec4_*sin_theta4_/mc4_+ec4_*cos_theta4_/mc4_*( p3_lab_.p()*al3+e3mp3-e1mp1 );
CG_DEBUG_LOOP( "GamGamLL" ) << "pg = " << Particle::Momentum( pgx, pgy, pgz );
const double pgp = sqrt( pgx*pgx + pgy*pgy ), // outgoing proton (3)'s transverse momentum
pgg = sqrt( pgp*pgp + pgz*pgz ); // outgoing proton (3)'s momentum
if ( pgg > pgp*0.9 && pgg > pg )
pg = pgg; //FIXME ???
// angles for the 2-photon system ?!
const double cpg = pgx/pgp, spg = pgy/pgp;
const double stg = pgp/pg;
const int theta_sign = ( pgz>0. ) ? 1 : -1;
const double ctg = theta_sign*sqrt( 1.-stg*stg );
double xx6 = x( 5 );
const double amap = 0.5 * ( w4_-t1_-t2_ ),
bmap = 0.5 * sqrt( ( pow( w4_-t1_-t2_, 2 )-4.*t1_*t2_ )*( 1.-4.*masses_.Ml2_/w4_ ) ),
ymap = ( amap+bmap )/( amap-bmap ),
beta = pow( ymap, 2.*xx6-1. );
xx6 = 0.5 * ( 1. + amap/bmap*( beta-1. )/( beta+1. ) );
xx6 = std::max( 0., std::min( xx6, 1. ) ); // xx6 in [0., 1.]
CG_DEBUG_LOOP( "GamGamLL" )
<< "amap = " << amap << "\n\t"
<< "bmap = " << bmap << "\n\t"
<< "ymap = " << ymap << "\n\t"
<< "beta = " << beta;
// 3D rotation of the first outgoing lepton wrt the CM system
const double theta6cm = acos( 1.-2.*xx6 );
// match the Jacobian
jacobian_ *= ( amap+bmap*cos( theta6cm ) );
jacobian_ *= ( amap-bmap*cos( theta6cm ) );
jacobian_ /= amap;
jacobian_ /= bmap;
jacobian_ *= log( ymap );
jacobian_ *= 0.5;
CG_DEBUG_LOOP( "GamGamLL" ) << "Jacobian = " << jacobian_;
CG_DEBUG_LOOP( "GamGamLL" )
<< "ctcm6 = " << cos( theta6cm ) << "\n\t"
<< "stcm6 = " << sin( theta6cm );
const double phi6cm = 2.*M_PI*x( 6 );
// First outgoing lepton's 3-momentum in the centre of mass system
Particle::Momentum p6cm = Particle::Momentum::fromPThetaPhi( pp6cm, theta6cm, phi6cm );
CG_DEBUG_LOOP( "GamGamLL" ) << "p3cm6 = " << p6cm;
const double h1 = stg*p6cm.pz()+ctg*p6cm.px();
const double pc6z = ctg*p6cm.pz()-stg*p6cm.px(), pc6x = cpg*h1-spg*p6cm.py();
const double qcx = 2.*pc6x, qcz = 2.*pc6z;
// qcy == QCY is never defined
const double el6 = ( ec4_*ecm6+pc4_*pc6z ) / mc4_,
h2 = ( ec4_*pc6z+pc4_*ecm6 ) / mc4_;
CG_DEBUG_LOOP( "GamGamLL" ) << "h1 = " << h1 << "\n\th2 = " << h2;
// first outgoing lepton's 3-momentum
const double p6x = cos_theta4_*pc6x+sin_theta4_*h2,
p6y = cpg*p6cm.py()+spg*h1,
p6z = cos_theta4_*h2-sin_theta4_*pc6x;
// first outgoing lepton's kinematics
p6_cm_ = Particle::Momentum( p6x, p6y, p6z, el6 );
CG_DEBUG_LOOP( "GamGamLL" ) << "p6(cm) = " << p6_cm_;
const double hq = ec4_*qcz/mc4_;
const Particle::Momentum qve(
cos_theta4_*qcx+sin_theta4_*hq,
2.*p6y,
cos_theta4_*hq-sin_theta4_*qcx,
pc4_*qcz/mc4_ // energy
);
// Available energy for the second lepton is the 2-photon system's energy with the first lepton's energy removed
const double el7 = ec4_-el6;
CG_DEBUG_LOOP( "GamGamLL" )
<< "Outgoing kinematics\n\t"
<< " first outgoing lepton: p = " << p6_cm_.p() << ", E = " << p6_cm_.energy() << "\n\t"
<< "second outgoing lepton: p = " << p7_cm_.p() << ", E = " << p7_cm_.energy();;
// Second outgoing lepton's 3-momentum
const double p7x = -p6x + pt4_,
p7y = -p6y,
p7z = -p6z + pc4_*cos_theta4_;
// second outgoing lepton's kinematics
p7_cm_ = Particle::Momentum( p7x, p7y, p7z, el7 );
//p6_cm_ = Particle::Momentum(pl6*st6*cp6, pl6*st6*sp6, pl6*ct6, el6);
//p7_cm_ = Particle::Momentum(pl7*st7*cp7, pl7*st7*sp7, pl7*ct7, el7);
q1dq_ = eg*( 2.*ecm6-mc4_ )-2.*pg*p6cm.pz();
q1dq2_ = ( w4_-t1_-t2_ ) * 0.5;
const double phi3 = p3_lab_.phi(), cos_phi3 = cos( phi3 ), sin_phi3 = sin( phi3 ),
phi5 = p5_lab_.phi(), cos_phi5 = cos( phi5 ), sin_phi5 = sin( phi5 );
bb_ = t1_*t2_+( w4_*pow( sin( theta6cm ), 2 ) + 4.*masses_.Ml2_*pow( cos( theta6cm ), 2 ) )*pg*pg;
const double c1 = p3_lab_.pt() * ( qve.px()*sin_phi3 - qve.py()*cos_phi3 ),
c2 = p3_lab_.pt() * ( qve.pz()*ep1_ - qve.energy() *p_cm_ ),
c3 = ( masses_.w31_*ep1_*ep1_ + 2.*w1_*de3_*ep1_ - w1_*de3_*de3_ + p3_lab_.pt2()*ep1_*ep1_ ) / ( p3_lab_.energy()*p_cm_ + p3_lab_.pz()*ep1_ );
const double b1 = p5_lab_.pt() * ( qve.px()*sin_phi5 - qve.py()*cos_phi5 ),
b2 = p5_lab_.pt() * ( qve.pz()*ep2_ + qve.energy() *p_cm_ ),
b3 = ( masses_.w52_*ep2_*ep2_ + 2.*w2_*de5_*ep2_ - w2_*de5_*de5_ + p5_lab_.pt2()*ep2_*ep2_ ) / ( ep2_*p5_lab_.pz() - p5_lab_.energy()*p_cm_ );
const double r12 = c2*sin_phi3 + qve.py()*c3,
r13 = -c2*cos_phi3 - qve.px()*c3;
const double r22 = b2*sin_phi5 + qve.py()*b3,
r23 = -b2*cos_phi5 - qve.px()*b3;
epsi_ = p12_*c1*b1 + r12*r22 + r13*r23;
g5_ = w1_*c1*c1 + r12*r12 + r13*r13;
g6_ = w2_*b1*b1 + r22*r22 + r23*r23;
const double pt3 = p3_lab_.pt(), pt5 = p5_lab_.pt();
a5_ = -( qve.px()*cos_phi3 + qve.py()*sin_phi3 )*pt3*p1k2_
-( ep1_*qve.energy()-p_cm_*qve.pz() )*( cos_phi3*cos_phi5 + sin_phi3*sin_phi5 )*pt3*pt5
+( de5_*qve.pz()+qve.energy()*( p_cm_+p5_lab_.pz() ) )*c3;
a6_ = -( qve.px()*cos_phi5 + qve.py()*sin_phi5 )*pt5*p2k1_
-( ep2_*qve.energy()+p_cm_*qve.pz() )*( cos_phi3*cos_phi5 + sin_phi3*sin_phi5 )*pt3*pt5
+( de3_*qve.pz()-qve.energy()*( p_cm_-p3_lab_.pz() ) )*b3;
CG_DEBUG_LOOP( "GamGamLL" )
<< "a5 = " << a5_ << "\n\t"
<< "a6 = " << a6_;
////////////////////////////////////////////////////////////////
// END of GAMGAMLL subroutine in the FORTRAN version
////////////////////////////////////////////////////////////////
const Particle::Momentum cm = event_->getOneByRole( Particle::IncomingBeam1 ).momentum()
+ event_->getOneByRole( Particle::IncomingBeam2 ).momentum();
////////////////////////////////////////////////////////////////
// INFO from f.f
////////////////////////////////////////////////////////////////
const double gamma = cm.energy() / sqs_, betgam = cm.pz() / sqs_;
//--- kinematics computation for both leptons
p6_cm_.betaGammaBoost( gamma, betgam );
p7_cm_.betaGammaBoost( gamma, betgam );
//--- cut on mass of final hadronic system (MX/Y)
if ( mx_limits_.valid() ) {
if ( ( cuts_.mode == KinematicsMode::InelasticElastic
|| cuts_.mode == KinematicsMode::InelasticInelastic )
&& !mx_limits_.passes( MX_ ) )
return 0.;
if ( ( cuts_.mode == KinematicsMode::ElasticInelastic
|| cuts_.mode == KinematicsMode::InelasticInelastic )
&& !mx_limits_.passes( MY_ ) )
return 0.;
}
//--- cut on the proton's Q2 (first photon propagator T1)
if ( !cuts_.cuts.initial.q2.passes( -t1_ ) )
return 0.;
//--- cuts on outgoing leptons' kinematics
if ( !cuts_.cuts.central.mass_sum.passes( ( p6_cm_+p7_cm_ ).mass() ) )
return 0.;
//----- cuts on the individual leptons
if ( cuts_.cuts.central.pt_single.valid() ) {
const Limits& pt_limits = cuts_.cuts.central.pt_single;
if ( !pt_limits.passes( p6_cm_.pt() ) || !pt_limits.passes( p7_cm_.pt() ) )
return 0.;
}
if ( cuts_.cuts.central.energy_single.valid() ) {
const Limits& energy_limits = cuts_.cuts.central.energy_single;
if ( !energy_limits.passes( p6_cm_.energy() ) || !energy_limits.passes( p7_cm_.energy() ) )
return 0.;
}
if ( cuts_.cuts.central.eta_single.valid() ) {
const Limits& eta_limits = cuts_.cuts.central.eta_single;
if ( !eta_limits.passes( p6_cm_.eta() ) || !eta_limits.passes( p7_cm_.eta() ) )
return 0.;
}
//--- compute the structure functions factors
switch ( cuts_.mode ) { // inherited from CDF version
case KinematicsMode::ElectronProton: default: jacobian_ *= periPP( 1, 2 ); break; // ep case
case KinematicsMode::ElasticElastic: jacobian_ *= periPP( 2, 2 ); break; // elastic case
case KinematicsMode::InelasticElastic: jacobian_ *= periPP( 3, 2 )*( masses_.dw31_*masses_.dw31_ ); break;
case KinematicsMode::ElasticInelastic: jacobian_ *= periPP( 3, 2 )*( masses_.dw52_*masses_.dw52_ ); break; // single-dissociative case
case KinematicsMode::InelasticInelastic: jacobian_ *= periPP( 3, 3 )*( masses_.dw31_*masses_.dw31_ )*( masses_.dw52_*masses_.dw52_ ); break; // double-dissociative case
}
//--- compute the event weight using the Jacobian
return constants::GeV2toBarn*jacobian_;
}
//---------------------------------------------------------------------------------------------
void
GamGamLL::fillKinematics( bool )
{
const Particle::Momentum cm = event_->getOneByRole( Particle::IncomingBeam1 ).momentum() + event_->getOneByRole( Particle::IncomingBeam2 ).momentum();
const double gamma = cm.energy()/sqs_, betgam = cm.pz()/sqs_;
Particle::Momentum plab_ip1 = Particle::Momentum( 0., 0., p_cm_, ep1_ ).betaGammaBoost( gamma, betgam );
Particle::Momentum plab_ip2 = Particle::Momentum( 0., 0., -p_cm_, ep2_ ).betaGammaBoost( gamma, betgam );
p3_lab_.betaGammaBoost( gamma, betgam );
p5_lab_.betaGammaBoost( gamma, betgam );
//----- parameterise a random rotation around z-axis
const int rany = ( rand() >= 0.5 * RAND_MAX ) ? 1 : -1,
ransign = ( rand() >= 0.5 * RAND_MAX ) ? 1 : -1;
const double ranphi = ( 0.5 * rand()/RAND_MAX )*2.*M_PI;
Particle::Momentum plab_ph1 = ( plab_ip1-p3_lab_ ).rotatePhi( ranphi, rany );
Particle::Momentum plab_ph2 = ( plab_ip2-p5_lab_ ).rotatePhi( ranphi, rany );
p3_lab_.rotatePhi( ranphi, rany );
p5_lab_.rotatePhi( ranphi, rany );
p6_cm_.rotatePhi( ranphi, rany );
p7_cm_.rotatePhi( ranphi, rany );
/*if ( symmetrise_ && rand() >= .5*RAND_MAX ) {
p6_cm_.mirrorZ();
p7_cm_.mirrorZ();
}*/
//----- incoming protons
event_->getOneByRole( Particle::IncomingBeam1 ).setMomentum( plab_ip1 );
event_->getOneByRole( Particle::IncomingBeam2 ).setMomentum( plab_ip2 );
//----- first outgoing proton
Particle& op1 = event_->getOneByRole( Particle::OutgoingBeam1 );
op1.setMomentum( p3_lab_ );
switch ( cuts_.mode ) {
case KinematicsMode::ElasticElastic:
case KinematicsMode::ElasticInelastic:
default:
op1.setStatus( Particle::Status::FinalState ); // stable proton
break;
case KinematicsMode::InelasticElastic:
case KinematicsMode::InelasticInelastic:
op1.setStatus( Particle::Status::Unfragmented ); // fragmenting remnants
op1.setMass( MX_ );
break;
}
//----- second outgoing proton
Particle& op2 = event_->getOneByRole( Particle::OutgoingBeam2 );
op2.setMomentum( p5_lab_ );
switch ( cuts_.mode ) {
case KinematicsMode::ElasticElastic:
case KinematicsMode::InelasticElastic:
default:
op2.setStatus( Particle::Status::FinalState ); // stable proton
break;
case KinematicsMode::ElasticInelastic:
case KinematicsMode::InelasticInelastic:
op2.setStatus( Particle::Status::Unfragmented ); // fragmenting remnants
op2.setMass( MY_ );
break;
}
//----- first incoming photon
Particle& ph1 = event_->getOneByRole( Particle::Parton1 );
ph1.setMomentum( plab_ph1 );
//----- second incoming photon
Particle& ph2 = event_->getOneByRole( Particle::Parton2 );
ph2.setMomentum( plab_ph2 );
Particles& central_system = event_->getByRole( Particle::CentralSystem );
//----- first outgoing lepton
Particle& ol1 = central_system[0];
ol1.setPdgId( ol1.pdgId(), ransign );
ol1.setMomentum( p6_cm_ );
ol1.setStatus( Particle::Status::FinalState );
//----- second outgoing lepton
Particle& ol2 = central_system[1];
ol2.setPdgId( ol2.pdgId(), -ransign );
ol2.setMomentum( p7_cm_ );
ol2.setStatus( Particle::Status::FinalState );
//----- intermediate two-lepton system
event_->getOneByRole( Particle::Intermediate ).setMomentum( p6_cm_+p7_cm_ );
}
//---------------------------------------------------------------------------------------------
double
GamGamLL::periPP( int nup_, int ndown_ )
{
CG_DEBUG_LOOP( "GamGamLL" )
<< " Nup = " << nup_ << "\n\t"
<< "Ndown = " << ndown_;
FormFactors fp1, fp2;
formFactors( -t1_, -t2_, fp1, fp2 );
CG_DEBUG_LOOP( "GamGamLL" )
<< "u1 = " << fp1.FM << "\n\t"
<< "u2 = " << fp1.FE << "\n\t"
<< "v1 = " << fp2.FM << "\n\t"
<< "v2 = " << fp2.FE;
const double qqq = q1dq_*q1dq_,
qdq = 4.*masses_.Ml2_-w4_;
const double t11 = 64. *( bb_*( qqq-g4_-qdq*( t1_+t2_+2.*masses_.Ml2_ ) )-2.*( t1_+2.*masses_.Ml2_ )*( t2_+2.*masses_.Ml2_ )*qqq ) * t1_*t2_, // magnetic-magnetic
t12 = 128.*( -bb_*( dd2_+g6_ )-2.*( t1_+2.*masses_.Ml2_ )*( sa2_*qqq+a6_*a6_ ) ) * t1_, // electric-magnetic
t21 = 128.*( -bb_*( dd4_+g5_ )-2.*( t2_+2.*masses_.Ml2_ )*( sa1_*qqq+a5_*a5_ ) ) * t2_, // magnetic-electric
t22 = 512.*( bb_*( delta_*delta_-gram_ )-pow( epsi_-delta_*( qdq+q1dq2_ ), 2 )-sa1_*a6_*a6_-sa2_*a5_*a5_-sa1_*sa2_*qqq ); // electric-electric
const double peripp = ( fp1.FM*fp2.FM*t11 + fp1.FE*fp2.FM*t21 + fp1.FM*fp2.FE*t12 + fp1.FE*fp2.FE*t22 ) / pow( 2.*t1_*t2_*bb_, 2 );
CG_DEBUG_LOOP( "GamGamLL" )
<< "t11 = " << t11 << "\t"
<< "t12 = " << t12 << "\n\t"
<< "t21 = " << t21 << "\t"
<< "t22 = " << t22 << "\n\t"
<< "=> PeriPP = " << peripp;
return peripp;
}
void
GamGamLL::map( double expo, const Limits& lim, double& out, double& dout, const std::string& var_name_ )
{
const double y = lim.max()/lim.min();
out = lim.min()*pow( y, expo );
dout = out*log( y );
CG_DEBUG_LOOP( "GamGamLL:map" )
<< "Mapping variable \"" << var_name_ << "\"\n\t"
<< "limits = " << lim << "\n\t"
<< "max/min = " << y << "\n\t"
<< "exponent = " << expo << "\n\t"
<< "output = " << out << "\n\t"
<< "d(output) = " << dout;
}
void
GamGamLL::mapla( double y, double z, int u, double xm, double xp, double& x, double& d )
{
const double xmb = xm-y-z, xpb = xp-y-z;
const double c = -4.*y*z;
const double alp = sqrt( xpb*xpb + c ), alm = sqrt( xmb*xmb + c );
const double am = xmb+alm, ap = xpb+alp;
const double yy = ap/am, zz = pow( yy, u );
x = y + z + ( am*zz - c / ( am*zz ) ) / 2.;
const double ax = sqrt( pow( x-y-z, 2 ) + c );
d = ax*log( yy );
}
void
GamGamLL::formFactors( double q1, double q2, FormFactors& fp1, FormFactors& fp2 ) const
{
const double mx2 = MX_*MX_, my2 = MY_*MY_;
switch ( cuts_.mode ) {
case KinematicsMode::ElectronElectron: default: {
fp1 = FormFactors::trivial(); // electron (trivial) form factor
fp2 = FormFactors::trivial(); // electron (trivial) form factor
} break;
case KinematicsMode::ProtonElectron: {
fp1 = FormFactors::protonElastic( -t1_ ); // proton elastic form factor
fp2 = FormFactors::trivial(); // electron (trivial) form factor
} break;
case KinematicsMode::ElectronProton: {
fp1 = FormFactors::trivial(); // electron (trivial) form factor
fp2 = FormFactors::protonElastic( -t2_ ); // proton elastic form factor
} break;
case KinematicsMode::ElasticElastic: {
fp1 = FormFactors::protonElastic( -t1_ ); // proton elastic form factor
fp2 = FormFactors::protonElastic( -t2_ ); // proton elastic form factor
} break;
case KinematicsMode::ElasticInelastic: {
fp1 = FormFactors::protonElastic( -t1_ );
fp2 = FormFactors::protonInelastic( -t2_, w2_, my2, *cuts_.structure_functions );
} break;
case KinematicsMode::InelasticElastic: {
fp1 = FormFactors::protonInelastic( -t1_, w1_, mx2, *cuts_.structure_functions );
fp2 = FormFactors::protonElastic( -t2_ );
} break;
case KinematicsMode::InelasticInelastic: {
fp1 = FormFactors::protonInelastic( -t1_, w1_, mx2, *cuts_.structure_functions );
fp2 = FormFactors::protonInelastic( -t2_, w2_, my2, *cuts_.structure_functions );
} break;
}
}
// register process and define aliases
REGISTER_PROCESS( lpair, GamGamLL )
REGISTER_PROCESS( gamgamll, GamGamLL )
}
}
diff --git a/CepGen/Processes/GamGamLL.h b/CepGen/Processes/GamGamLL.h
index 20d7d22..1db3cbd 100644
--- a/CepGen/Processes/GamGamLL.h
+++ b/CepGen/Processes/GamGamLL.h
@@ -1,221 +1,221 @@
#ifndef CepGen_Processes_GamGamLL_h
#define CepGen_Processes_GamGamLL_h
#include "CepGen/Processes/GenericProcess.h"
#include "CepGen/Core/ParametersList.h"
-namespace CepGen
+namespace cepgen
{
namespace process
{
/**
* Full class of methods and objects to compute the full analytic matrix element
* \cite Vermaseren:1982cz for the \f$\gamma\gamma\to\ell^{+}\ell^{-}\f$ process
* according to a set of kinematic constraints provided for the incoming and
* outgoing particles (the Kinematics object).
* The \a f function created by this Process child has its \a _ndim -dimensional
* coordinates mapped as :
* - 0 = \f$t_1\f$, first incoming photon's virtuality
* - 1 = \f$t_2\f$, second incoming photon's virtuality
* - 2 = \f$s_2\f$ mapping
* - 3 = yy4 = \f$\cos\left(\pi x_3\right)\f$ definition
* - 4 = \f$w_4\f$, the two-photon system's invariant mass
* - 5 = xx6 = \f$\frac{1}{2}\left(1-\cos\theta^{\rm CM}_6\right)\f$ definition (3D rotation of the first outgoing lepton with respect to the two-photon centre-of-mass system). If the \a nm_ optimisation flag is set this angle coefficient value becomes
* \f[\frac{1}{2}\left(\frac{a_{\rm map}}{b_{\rm map}}\frac{\beta-1}{\beta+1}+1\right)\f]
* with \f$a_{\rm map}=\frac{1}{2}\left(w_4-t_1-t_2\right)\f$, \f$b_{\rm map}=\frac{1}{2}\sqrt{\left(\left(w_4-t_1-t_2\right)^2-4t_1t_2\right)\left(1-4\frac{w_6}{w_4}\right)}\f$, and \f$\beta=\left(\frac{a_{\rm map}+b_{\rm map}}{a_{\rm map}-b_{\rm map}}\right)^{2x_5-1}\f$
* and the Jacobian element is scaled by a factor \f$\frac{1}{2}\frac{\left(a_{\rm map}^2-b_{\rm map}^2\cos^2\theta^{\rm CM}_6\right)}{a_{\rm map}b_{\rm map}}\log\left(\frac{a_{\rm map}+b_{\rm map}}{a_{\rm map}-b_{\rm map}}\right)\f$
* - 6 = _phicm6_, or \f$\phi_6^{\rm CM}\f$ the rotation angle of the dilepton system in the centre-of-mass
* system
* - 7 = \f$x_q\f$, \f$w_X\f$ mappings, as used in the single- and double-dissociative
* cases only
* \brief Compute the matrix element for a CE \f$\gamma\gamma\to\ell^{+}\ell^{-}\f$
* process
*/
class GamGamLL : public GenericProcess
{
public:
/// \brief Class constructor: set the mandatory parameters before integration and events generation
/// \param[in] params General process parameters (nopt = Optimisation, legacy from LPAIR)
explicit GamGamLL( const ParametersList& params = ParametersList() );
ProcessPtr clone( const ParametersList& params ) const override { return ProcessPtr( new GamGamLL( params ) ); }
void addEventContent() override;
void beforeComputeWeight() override;
double computeWeight() override;
unsigned int numDimensions() const override;
void setKinematics( const Kinematics& cuts ) override;
void fillKinematics( bool ) override;
/// Compute the ougoing proton remnant mass
/// \param[in] x A random number (between 0 and 1)
/// \param[in] outmass The maximal outgoing particles' invariant mass
/// \param[in] lepmass The outgoing leptons' mass
/// \param[out] dw The size of the integration bin
/// \return Mass of the outgoing proton remnant
double computeOutgoingPrimaryParticlesMasses( double x, double outmass, double lepmass, double& dw );
/// Set all the kinematic variables for the outgoing proton remnants, and prepare the hadronisation
/// \param[in] part Particle to "prepare" for the hadronisation to be performed
void prepareHadronisation( Particle *part );
private:
/**
* Calculate energies and momenta of the
* 1st, 2nd (resp. the "proton-like" and the "electron-like" incoming particles),
* 3rd (the "proton-like" outgoing particle),
* 4th (the two-photons central system), and
* 5th (the "electron-like" outgoing particle) particles in the overall centre-of-mass frame.
* \brief Energies/momenta computation for the various particles, in the CM system
* \return Success state of the operation
*/
bool orient();
/**
* Compute the expression of the matrix element squared for the \f$\gamma\gamma\rightarrow\ell^{+}\ell^{-}\f$ process.
* It returns the value of the convolution of the form factor or structure functions with the central two-photons matrix element squared.
* \brief Computes the matrix element squared for the requested process
* \return Full matrix element for the two-photon production of a pair of spin\f$-\frac{1}{2}-\f$point particles.
* It is noted as \f[
* M = \frac{1}{4bt_1 t_2}\sum_{i=1}^2\sum_{j=1}^2 u_i v_j t_{ij} = \frac{1}{4}\frac{u_1 v_1 t_{11}+u_2 v_1 t_{21}+u_1 v_2 t_{12}+u_2 v_2 t_{22}}{t_1 t_2 b}
* \f] where \f$b\f$ = \a bb_ is defined in \a ComputeWeight as : \f[
* b = t_1 t_2+\left(w_{\gamma\gamma}\sin^2{\theta^{\rm CM}_6}+4m_\ell\cos^2{\theta^{\rm CM}_6}\right) p_g^2
* \f]
*/
double periPP( int, int );
/**
* Describe the kinematics of the process \f$p_1+p_2\to p_3+p_4+p_5\f$ in terms of Lorentz-invariant variables.
* These variables (along with others) will then be fed into the \a PeriPP method (thus are essential for the evaluation of the full matrix element).
* \return Success state of the operation
*/
bool pickin();
/// Internal switch for the optimised code version (LPAIR legacy ; unimplemented here)
int n_opt_;
int pair_;
Limits w_limits_;
Limits q2_limits_;
Limits mx_limits_;
struct Masses
{
Masses();
/// squared mass of the first proton-like outgoing particle
double MX2_;
/// squared mass of the second proton-like outgoing particle
double MY2_;
/// squared mass of the outgoing leptons
double Ml2_;
/// \f$\delta_2=m_1^2-m_2^2\f$ as defined in Vermaseren's paper
/// \cite Vermaseren:1982cz for the full definition of this quantity
double w12_;
/// \f$\delta_1=m_3^2-m_1^2\f$ as defined in Vermaseren's paper
/// \cite Vermaseren:1982cz for the full definition of this quantity
double w31_;
double dw31_;
/// \f$\delta_4=m_5^2-m_2^2\f$ as defined in Vermaseren's paper
/// \cite Vermaseren:1982cz for the full definition of this quantity
double w52_;
double dw52_;
};
Masses masses_;
/// energy of the first proton-like incoming particle
double ep1_;
/// energy of the second proton-like incoming particle
double ep2_;
double p_cm_;
/// energy of the two-photon central system
double ec4_;
/// 3-momentum norm of the two-photon central system
double pc4_;
/// mass of the two-photon central system
double mc4_;
/// squared mass of the two-photon central system
double w4_;
/// \f$p_{12} = \frac{1}{2}\left(s-m_{p_1}^2-m_{p_2}^2\right)\f$
double p12_;
double p1k2_, p2k1_;
/// \f$p_{13} = -\frac{1}{2}\left(t_1-m_{p_1}^2-m_{p_3}^2\right)\f$
double p13_;
double p14_, p25_;
double q1dq_, q1dq2_;
double s1_, s2_;
double epsi_;
double g5_, g6_;
double a5_, a6_;
double bb_;
double gram_;
double dd1_, dd2_, dd3_;
/// \f$\delta_5=m_4^2-t_1\f$ as defined in Vermaseren's paper
/// \cite Vermaseren:1982cz for the full definition of this quantity
double dd4_;
double dd5_;
/**
* Invariant used to tame divergences in the matrix element computation. It is defined as
* \f[\Delta = \left(p_1\cdot p_2\right)\left(q_1\cdot q_2\right)-\left(p_1\cdot q_2\right)\left(p_2\cdot q_1\right)\f]
* with \f$p_i, q_i\f$ the 4-momenta associated to the incoming proton-like particle and to the photon emitted from it.
*/
double delta_;
double g4_;
double sa1_, sa2_;
double sl1_;
/// cosine of the polar angle for the two-photons centre-of-mass system
double cos_theta4_;
/// sine of the polar angle for the two-photons centre-of-mass system
double sin_theta4_;
double al4_;
double be4_;
double de3_, de5_;
double pt4_;
/// Kinematics of the first incoming proton
Particle::Momentum p1_lab_;
/// Kinematics of the second incoming proton
Particle::Momentum p2_lab_;
/// Kinematics of the first outgoing proton
Particle::Momentum p3_lab_;
/// Kinematics of the two-photon system (in the two-proton CM)
Particle::Momentum p4_lab_;
/// Kinematics of the second outgoing proton
Particle::Momentum p5_lab_;
/// Kinematics of the first outgoing lepton (in the two-proton CM)
Particle::Momentum p6_cm_;
/// Kinematics of the second outgoing lepton (in the two-proton CM)
Particle::Momentum p7_cm_;
double jacobian_;
private:
/**
* Define modified variables of integration to avoid peaks integrations (see \cite Vermaseren:1982cz for details)
* Return a set of two modified variables of integration to maintain the stability of the integrant. These two new variables are :
* - \f$y_{out} = x_{min}\left(\frac{x_{max}}{x_{min}}\right)^{exp}\f$ the new variable
* - \f$\mathrm dy_{out} = x_{min}\left(\frac{x_{max}}{x_{min}}\right)^{exp}\log\frac{x_{min}}{x_{max}}\f$, the new variable's differential form
* \brief Redefine the variables of integration in order to avoid the strong peaking of the integrant
* \param[in] expo Exponant
* \param[in] lim Min/maximal value of the variable
* \param[out] out The new variable definition
* \param[out] dout The bin width the new variable definition
* \param[in] var_name The variable name
* \note This method overrides the set of `mapxx` subroutines in ILPAIR, with a slight difference according to the sign of the
* \f$\mathrm dy_{out}\f$ parameter :
* - left unchanged :
* > `mapw2`, `mapxq`, `mapwx`, `maps2`
* - opposite sign :
* > `mapt1`, `mapt2`
*/
void map( double expo, const Limits& lim, double& out, double& dout, const std::string& var_name = "" );
void mapla( double y, double z, int u, double xm, double xp, double& x, double& d );
/// Compute the electric/magnetic form factors for the two considered \f$Q^{2}\f$ momenta transfers
void formFactors( double q1, double q2, FormFactors& fp1, FormFactors& fp2 ) const;
};
}
}
#endif
diff --git a/CepGen/Processes/GenericKTProcess.cpp b/CepGen/Processes/GenericKTProcess.cpp
index 90fb99a..e8e50a8 100644
--- a/CepGen/Processes/GenericKTProcess.cpp
+++ b/CepGen/Processes/GenericKTProcess.cpp
@@ -1,370 +1,370 @@
#include "CepGen/Processes/GenericKTProcess.h"
#include "CepGen/Core/Exception.h"
#include "CepGen/Core/ParametersList.h"
#include "CepGen/Event/Event.h"
#include "CepGen/StructureFunctions/StructureFunctions.h"
#include "CepGen/StructureFunctions/SigmaRatio.h"
#include "CepGen/Physics/Constants.h"
#include "CepGen/Physics/KTFlux.h"
#include "CepGen/Physics/FormFactors.h"
#include "CepGen/Physics/PDG.h"
#include <iomanip>
-namespace CepGen
+namespace cepgen
{
namespace process
{
GenericKTProcess::GenericKTProcess( const ParametersList& params,
const std::string& name,
const std::string& description,
const std::array<PDG,2>& partons,
const std::vector<PDG>& central ) :
GenericProcess( name, description+" (kT-factorisation approach)" ),
num_dimensions_( 0 ), kt_jacobian_( 0. ),
qt1_( 0. ), phi_qt1_( 0. ), qt2_( 0. ), phi_qt2_( 0. ),
kIntermediateParts( partons ), kProducedParts( central )
{}
void
GenericKTProcess::addEventContent()
{
GenericProcess::setEventContent(
{ // incoming state
{ Particle::IncomingBeam1, PDG::proton },
{ Particle::IncomingBeam2, PDG::proton },
{ Particle::Parton1, kIntermediateParts[0] },
{ Particle::Parton2, kIntermediateParts[1] }
},
{ // outgoing state
{ Particle::OutgoingBeam1, { PDG::proton } },
{ Particle::OutgoingBeam2, { PDG::proton } },
{ Particle::CentralSystem, kProducedParts }
}
);
setExtraContent();
}
unsigned int
GenericKTProcess::numDimensions() const
{
return num_dimensions_;
}
void
GenericKTProcess::setKinematics( const Kinematics& kin )
{
cuts_ = kin;
const KTFlux flux1 = (KTFlux)cuts_.incoming_beams.first.kt_flux,
flux2 = (KTFlux)cuts_.incoming_beams.second.kt_flux;
if ( cuts_.mode == KinematicsMode::invalid ) {
bool el1 = ( flux1 == KTFlux::P_Photon_Elastic
|| flux1 == KTFlux::HI_Photon_Elastic
|| flux1 == KTFlux::P_Gluon_KMR );
bool el2 = ( flux2 == KTFlux::P_Photon_Elastic
|| flux2 == KTFlux::HI_Photon_Elastic
|| flux2 == KTFlux::P_Gluon_KMR );
if ( el1 && el2 )
cuts_.mode = KinematicsMode::ElasticElastic;
else if ( el1 )
cuts_.mode = KinematicsMode::ElasticInelastic;
else if ( el2 )
cuts_.mode = KinematicsMode::InelasticElastic;
else
cuts_.mode = KinematicsMode::InelasticInelastic;
}
else {
//==========================================================================================
// ensure the first incoming flux is compatible with the kinematics mode
//==========================================================================================
if ( ( cuts_.mode == KinematicsMode::ElasticElastic
|| cuts_.mode == KinematicsMode::ElasticInelastic )
&& ( flux1 != KTFlux::P_Photon_Elastic ) ) {
cuts_.incoming_beams.first.kt_flux = ( (HeavyIon)cuts_.incoming_beams.first.pdg )
? KTFlux::HI_Photon_Elastic
: KTFlux::P_Photon_Elastic;
CG_DEBUG( "GenericKTProcess:kinematics" )
<< "Set the kt flux for first incoming photon to \""
<< cuts_.incoming_beams.first.kt_flux << "\".";
}
else if ( flux1 != KTFlux::P_Photon_Inelastic
&& flux1 != KTFlux::P_Photon_Inelastic_Budnev ) {
if ( (HeavyIon)cuts_.incoming_beams.first.pdg )
throw CG_FATAL( "GenericKTProcess:kinematics" )
<< "Inelastic photon emission from HI not yet supported!";
cuts_.incoming_beams.first.kt_flux = KTFlux::P_Photon_Inelastic_Budnev;
CG_DEBUG( "GenericKTProcess:kinematics" )
<< "Set the kt flux for first incoming photon to \""
<< cuts_.incoming_beams.first.kt_flux << "\".";
}
//==========================================================================================
// ensure the second incoming flux is compatible with the kinematics mode
//==========================================================================================
if ( ( cuts_.mode == KinematicsMode::ElasticElastic
|| cuts_.mode == KinematicsMode::InelasticElastic )
&& ( flux2 != KTFlux::P_Photon_Elastic ) ) {
cuts_.incoming_beams.second.kt_flux = ( (HeavyIon)cuts_.incoming_beams.second.pdg )
? KTFlux::HI_Photon_Elastic
: KTFlux::P_Photon_Elastic;
CG_DEBUG( "GenericKTProcess:kinematics" )
<< "Set the kt flux for second incoming photon to \""
<< cuts_.incoming_beams.second.kt_flux << "\".";
}
else if ( flux2 != KTFlux::P_Photon_Inelastic
&& flux2 != KTFlux::P_Photon_Inelastic_Budnev ) {
if ( (HeavyIon)cuts_.incoming_beams.second.pdg )
throw CG_FATAL( "GenericKTProcess:kinematics" )
<< "Inelastic photon emission from HI not yet supported!";
cuts_.incoming_beams.second.kt_flux = KTFlux::P_Photon_Inelastic_Budnev;
CG_DEBUG( "GenericKTProcess:kinematics" )
<< "Set the kt flux for second incoming photon to \""
<< cuts_.incoming_beams.second.kt_flux << "\".";
}
}
//============================================================================================
// initialise the "constant" (wrt x) part of the Jacobian
//============================================================================================
kt_jacobian_ = 1.;
num_dimensions_ = 0;
mapped_variables_.clear();
//============================================================================================
// register the incoming partons' variables
//============================================================================================
registerVariable( qt1_, Mapping::logarithmic, cuts_.cuts.initial.qt, { 1.e-10, 500. }, "First incoming parton virtuality" );
registerVariable( qt2_, Mapping::logarithmic, cuts_.cuts.initial.qt, { 1.e-10, 500. }, "Second incoming parton virtuality" );
registerVariable( phi_qt1_, Mapping::linear, cuts_.cuts.initial.phi_qt, { 0., 2.*M_PI }, "First incoming parton azimuthal angle" );
registerVariable( phi_qt2_, Mapping::linear, cuts_.cuts.initial.phi_qt, { 0., 2.*M_PI }, "Second incoming parton azimuthal angle" );
//============================================================================================
// register all process-dependent variables
//============================================================================================
preparePhaseSpace();
//============================================================================================
// register the outgoing remnants' variables
//============================================================================================
MX_ = MY_ = event_->getOneByRole( Particle::IncomingBeam1 ).mass();
if ( cuts_.mode == KinematicsMode::InelasticElastic || cuts_.mode == KinematicsMode::InelasticInelastic )
registerVariable( MX_, Mapping::square, cuts_.cuts.remnants.mass_single, { 1.07, 1000. }, "Positive z proton remnant mass" );
if ( cuts_.mode == KinematicsMode::ElasticInelastic || cuts_.mode == KinematicsMode::InelasticInelastic )
registerVariable( MY_, Mapping::square, cuts_.cuts.remnants.mass_single, { 1.07, 1000. }, "Negative z proton remnant mass" );
prepareKinematics();
}
double
GenericKTProcess::computeWeight()
{
if ( mapped_variables_.size() == 0 )
throw CG_FATAL( "GenericKTProcess:weight" )
<< "No variables are mapped with this process!";
if ( kt_jacobian_ == 0. )
throw CG_FATAL( "GenericKTProcess:weight" )
<< "Point-independant component of the Jacobian for this "
<< "kt-factorised process is null.\n\t"
<< "Please check the validity of the phase space!";
//============================================================================================
// generate and initialise all variables, and auxiliary (x-dependent) part of the Jacobian
// for this phase space point.
//============================================================================================
const double aux_jacobian = generateVariables();
if ( aux_jacobian <= 0. )
return 0.;
//============================================================================================
// compute the integrand and combine together into a single weight for the phase space point.
//============================================================================================
const double integrand = computeKTFactorisedMatrixElement();
if ( integrand <= 0. )
return 0.;
const double weight = ( kt_jacobian_*aux_jacobian ) * integrand;
CG_DEBUG_LOOP( "GenericKTProcess:weight" )
<< "Jacobian: " << kt_jacobian_ << " * " << aux_jacobian
<< " = " << ( kt_jacobian_*aux_jacobian ) << ".\n\t"
<< "Integrand = " << integrand << "\n\t"
<< "dW = " << weight << ".";
return weight;
}
std::pair<double,double>
GenericKTProcess::incomingFluxes( double x1, double q1t2, double x2, double q2t2 ) const
{
//--- compute fluxes according to modelling specified in parameters card
std::pair<double,double> fluxes = {
ktFlux( (KTFlux)cuts_.incoming_beams.first.kt_flux, x1, q1t2, *cuts_.structure_functions, MX_ ),
ktFlux( (KTFlux)cuts_.incoming_beams.second.kt_flux, x2, q2t2, *cuts_.structure_functions, MY_ )
};
CG_DEBUG_LOOP( "GenericKTProcess:fluxes" )
<< "KT fluxes: " << fluxes.first << " / " << fluxes.second << ".";
return fluxes;
}
void
GenericKTProcess::registerVariable( double& out, const Mapping& type,
const Limits& in, Limits default_limits,
const char* description )
{
Limits lim = in;
out = 0.; // reset the variable
if ( !in.valid() ) {
CG_DEBUG( "GenericKTProcess:registerVariable" )
<< description << " could not be retrieved from the user configuration!\n\t"
<< "Setting it to the default value: " << default_limits << ".";
lim = default_limits;
}
if ( type == Mapping::logarithmic )
lim = {
std::max( log( lim.min() ), -10. ),
std::min( log( lim.max() ), +10. )
};
mapped_variables_.emplace_back( MappingVariable{ description, lim, out, type, num_dimensions_++ } );
switch ( type ) {
case Mapping::square:
kt_jacobian_ *= 2.*lim.range();
break;
default:
kt_jacobian_ *= lim.range();
break;
}
CG_DEBUG( "GenericKTProcess:registerVariable" )
<< description << " has been mapped to variable " << num_dimensions_ << ".\n\t"
<< "Allowed range for integration: " << lim << ".\n\t"
<< "Variable integration mode: " << type << ".";
}
void
GenericKTProcess::dumpVariables() const
{
std::ostringstream os;
for ( const auto& var : mapped_variables_ )
os << "\n\t(" << var.index << ") " << var.type << " mapping (" << var.description << ") in range " << var.limits;
CG_INFO( "GenericKTProcess:dumpVariables" )
<< "List of variables handled by this kt-factorised process:"
<< os.str();
}
double
GenericKTProcess::generateVariables() const
{
double jacobian = 1.;
for ( const auto& cut : mapped_variables_ ) {
if ( !cut.limits.valid() )
continue;
const double xv = x( cut.index ); // between 0 and 1
switch ( cut.type ) {
case Mapping::linear: {
cut.variable = cut.limits.x( xv );
} break;
case Mapping::logarithmic: {
cut.variable = exp( cut.limits.x( xv ) );
jacobian *= cut.variable;
} break;
case Mapping::square: {
cut.variable = cut.limits.x( xv );
jacobian *= cut.variable;
} break;
}
}
if ( CG_EXCEPT_MATCH( "KtProcess:vars", debugInsideLoop ) ) {
std::ostringstream oss;
for ( const auto& cut : mapped_variables_ ) {
oss << "variable " << cut.index
<< " in range " << std::left << std::setw( 20 ) << cut.limits << std::right
<< " has value " << cut.variable << "\n\t";
}
CG_DEBUG_LOOP( "KtProcess:vars" ) << oss.str();
}
return jacobian;
}
void
GenericKTProcess::fillKinematics( bool )
{
fillCentralParticlesKinematics(); // process-dependent!
fillPrimaryParticlesKinematics();
}
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 KinematicsMode::ElasticElastic:
op1.setStatus( Particle::Status::FinalState );
op2.setStatus( Particle::Status::FinalState );
break;
case KinematicsMode::ElasticInelastic:
op1.setStatus( Particle::Status::FinalState );
op2.setStatus( Particle::Status::Unfragmented ); op2.setMass( MY_ );
break;
case KinematicsMode::InelasticElastic:
op1.setStatus( Particle::Status::Unfragmented ); op1.setMass( MX_ );
op2.setStatus( Particle::Status::FinalState );
break;
case KinematicsMode::InelasticInelastic:
op1.setStatus( Particle::Status::Unfragmented ); op1.setMass( MX_ );
op2.setStatus( Particle::Status::Unfragmented ); op2.setMass( MY_ );
break;
default: {
throw CG_FATAL( "GenericKTProcess" )
<< "This kT factorisation process is intended for p-on-p collisions! Aborting.";
} break;
}
//============================================================================================
// incoming partons (photons, pomerons, ...)
//============================================================================================
Particle& g1 = event_->getOneByRole( Particle::Parton1 );
g1.setMomentum( event_->getOneByRole( Particle::IncomingBeam1 ).momentum()-PX_, true );
Particle& g2 = event_->getOneByRole( Particle::Parton2 );
g2.setMomentum( event_->getOneByRole( Particle::IncomingBeam2 ).momentum()-PY_, true );
//============================================================================================
// two-parton system
//============================================================================================
event_->getOneByRole( Particle::Intermediate ).setMomentum( g1.momentum()+g2.momentum() );
}
std::ostream&
operator<<( std::ostream& os, const GenericKTProcess::Mapping& type )
{
switch ( type ) {
case GenericKTProcess::Mapping::linear: return os << "linear";
case GenericKTProcess::Mapping::logarithmic: return os << "logarithmic";
case GenericKTProcess::Mapping::square: return os << "squared";
}
return os;
}
}
}
diff --git a/CepGen/Processes/GenericKTProcess.h b/CepGen/Processes/GenericKTProcess.h
index 2a99ddd..74b3a69 100644
--- a/CepGen/Processes/GenericKTProcess.h
+++ b/CepGen/Processes/GenericKTProcess.h
@@ -1,142 +1,142 @@
#ifndef CepGen_Processes_GenericKTProcess_h
#define CepGen_Processes_GenericKTProcess_h
#include "GenericProcess.h"
-namespace CepGen
+namespace cepgen
{
class ParametersList;
namespace process
{
/**
* A generic kT-factorisation process.
* \note
* - First 4 dimensions of the phase space are required for the
* incoming partons' virtualities (radial and azimuthal coordinates).
* - Last 0-2 dimensions may be used for the scattered diffractive
* system(s)' invariant mass definition.
* \brief Class template to define any kT-factorisation process
* \author Laurent Forthomme <laurent.forthomme@cern.ch>
* \date Apr 2016
*/
class GenericKTProcess : public GenericProcess
{
public:
/// Class constructor
/// \param[in] params Parameters list
/// \param[in] name Generic process name
/// \param[in] description Human-readable kT-factorised process name
/// \param[in] partons First and second incoming parton
/// \param[in] output Produced final state particles
GenericKTProcess( const ParametersList& params,
const std::string& name,
const std::string& description,
const std::array<PDG,2>& partons,
const std::vector<PDG>& output );
/// Populate the event content with the generated process' topology
void addEventContent() override;
/// Retrieve the total number of dimensions on which the integration is being performet
unsigned int numDimensions() const override;
/// Retrieve the event weight in the phase space
double computeWeight() override;
/// Populate the event content with the generated process' kinematics
void fillKinematics( bool ) override;
/// List all variables handled by this generic process
void dumpVariables() const;
protected:
/// Set the kinematics associated to the phase space definition
void setKinematics( const Kinematics& kin ) override;
/// Set the kinematics of the central system before any point computation
virtual void setExtraContent() {}
/// Prepare the central part of the Jacobian (only done once, as soon as the kinematics is set)
virtual void preparePhaseSpace() = 0;
/// kT-factorised matrix element (event weight)
/// \return Weight of the point in the phase space to the integral
virtual double computeKTFactorisedMatrixElement() = 0;
/// Compute the unintegrated photon fluxes (for inelastic distributions, interpolation on double logarithmic grid)
std::pair<double,double> incomingFluxes( double, double, double, double ) const;
/// Set the kinematics of the incoming and outgoing protons (or remnants)
void fillPrimaryParticlesKinematics();
/// Set the kinematics of the outgoing central system
virtual void fillCentralParticlesKinematics() = 0;
/// Type of mapping to apply on the variable
enum class Mapping
{
/// a linear \f${\rm d}x\f$ mapping
linear = 0,
/// a logarithmic \f$\frac{{\rm d}x}{x} = {\rm d}(\log x)\f$ mapping
logarithmic,
/// a square \f${\rm d}x^2=2x\cdot{\rm d}x\f$ mapping
square
};
friend std::ostream& operator<<( std::ostream&, const Mapping& );
/// Register a variable to be handled and populated whenever
/// a new phase space point weight is to be calculated.
/// \note To be run once per generation (before any point computation)
/// \param[out] out Reference to the variable to be mapped
/// \param[in] type Type of mapping to apply
/// \param[in] in Integration limits
/// \param[in] default_limits Limits to apply if none retrieved from the user configuration
/// \param[in] description Human-readable description of the variable
void registerVariable( double& out, const Mapping& type, const Limits& in, Limits default_limits, const char* description );
/// Generate and initialise all variables handled by this process
/// \return Phase space point-dependent component of the Jacobian weight of the point in the phase space for integration
/// \note To be run at each point computation (therefore, to be optimised!)
double generateVariables() const;
/// Number of dimensions on which to perform the integration
unsigned short num_dimensions_;
/// Phase space point-independant component of the Jacobian weight of the point in the phase space for integration
double kt_jacobian_;
/// Log-virtuality range of the intermediate parton
Limits log_qt_limits_;
/// Intermediate azimuthal angle range
Limits phi_qt_limits_;
/// Invariant mass range for the scattered excited system
Limits mx_limits_;
/// Virtuality of the first intermediate parton (photon, pomeron, ...)
double qt1_;
/// Azimuthal rotation of the first intermediate parton's transverse virtuality
double phi_qt1_;
/// Virtuality of the second intermediate parton (photon, pomeron, ...)
double qt2_;
/// Azimuthal rotation of the second intermediate parton's transverse virtuality
double phi_qt2_;
/// First outgoing proton
Particle::Momentum PX_;
/// Second outgoing proton
Particle::Momentum PY_;
/// Handler to a variable mapped by this process
struct MappingVariable
{
/// Human-readable description of the variable
std::string description;
/// Kinematic limits to apply on the variable
Limits limits;
/// Reference to the process variable to generate/map
double& variable;
/// Interpolation type
Mapping type;
/// Corresponding integration variable
unsigned short index;
};
/// Collection of variables to be mapped at the weight generation stage
std::vector<MappingVariable> mapped_variables_;
private:
/// First and second intermediate parton (photon, pomeron, ...)
std::array<PDG,2> kIntermediateParts;
/// Type of particles produced in the final state
std::vector<PDG> kProducedParts;
};
}
}
#endif
diff --git a/CepGen/Processes/GenericProcess.cpp b/CepGen/Processes/GenericProcess.cpp
index a003f82..a0d48b7 100644
--- a/CepGen/Processes/GenericProcess.cpp
+++ b/CepGen/Processes/GenericProcess.cpp
@@ -1,228 +1,228 @@
#include "CepGen/Processes/GenericProcess.h"
#include "CepGen/Core/Exception.h"
#include "CepGen/Event/Event.h"
#include "CepGen/Physics/ParticleProperties.h"
#include "CepGen/Physics/Constants.h"
#include "CepGen/Physics/FormFactors.h"
#include "CepGen/Physics/PDG.h"
-namespace CepGen
+namespace cepgen
{
namespace process
{
- const double GenericProcess::mp_ = part::mass( PDG::proton );
+ const double GenericProcess::mp_ = particleproperties::mass( PDG::proton );
const double GenericProcess::mp2_ = GenericProcess::mp_*GenericProcess::mp_;
GenericProcess::GenericProcess( const std::string& name, const std::string& description, bool has_event ) :
name_( name ), description_( description ),
first_run( true ),
s_( -1. ), sqs_( -1. ),
MX_( -1. ), MY_( -1. ), w1_( -1. ), w2_( -1. ),
t1_( -1. ), t2_( -1. ),
has_event_( has_event ), event_( new Event ),
is_point_set_( false )
{}
GenericProcess::GenericProcess( const GenericProcess& proc ) :
name_( proc.name_ ), description_( proc.description_ ),
first_run( proc.first_run ),
s_( proc.s_ ), sqs_( proc.sqs_ ),
MX_( proc.MX_ ), MY_( proc.MY_ ), w1_( proc.w1_ ), w2_( proc.w2_ ),
t1_( -1. ), t2_( -1. ), cuts_( proc.cuts_ ),
has_event_( proc.has_event_ ), event_( new Event( *proc.event_.get() ) ),
is_point_set_( false )
{}
GenericProcess&
GenericProcess::operator=( const GenericProcess& proc )
{
name_ = proc.name_; description_ = proc.description_;
first_run = proc.first_run;
s_ = proc.s_; sqs_ = proc.sqs_;
MX_ = proc.MX_; MY_ = proc.MY_; w1_ = proc.w1_; w2_ = proc.w2_;
cuts_ = proc.cuts_;
has_event_ = proc.has_event_; event_.reset( new Event( *proc.event_.get() ) );
is_point_set_ = false;
return *this;
}
void
GenericProcess::setPoint( const unsigned int ndim, double* x )
{
x_ = std::vector<double>( x, x+ndim );
is_point_set_ = true;
if ( CG_EXCEPT_MATCH( "Process:dumpPoint", debugInsideLoop ) )
dumpPoint();
}
double
GenericProcess::x( unsigned int idx ) const
{
if ( idx >= x_.size() )
return -1.;
return x_[idx];
}
void
GenericProcess::clearEvent()
{
event_->restore();
}
void
GenericProcess::setKinematics( const Kinematics& cuts )
{
cuts_ = cuts;
prepareKinematics();
}
void
GenericProcess::prepareKinematics()
{
if ( !isKinematicsDefined() )
throw CG_FATAL( "GenericProcess" ) << "Kinematics not properly defined for the process.";
// at some point introduce non head-on colliding beams?
Particle::Momentum p1( 0., 0., cuts_.incoming_beams.first.pz ), p2( 0., 0., -cuts_.incoming_beams.second.pz );
// on-shell beam particles
- p1.setMass( part::mass( cuts_.incoming_beams.first.pdg ) );
- p2.setMass( part::mass( cuts_.incoming_beams.second.pdg ) );
+ p1.setMass( particleproperties::mass( cuts_.incoming_beams.first.pdg ) );
+ p2.setMass( particleproperties::mass( cuts_.incoming_beams.second.pdg ) );
setIncomingKinematics( p1, p2 );
sqs_ = CMEnergy( p1, p2 );
s_ = sqs_*sqs_;
w1_ = p1.mass2();
w2_ = p2.mass2();
CG_DEBUG( "GenericProcess" ) << "Kinematics successfully prepared! sqrt(s) = " << sqs_ << ".";
}
void
GenericProcess::dumpPoint() const
{
std::ostringstream os;
for ( unsigned short i = 0; i < x_.size(); ++i ) {
os << Form( " x(%2d) = %8.6f\n\t", i, x_[i] );
}
CG_INFO( "GenericProcess" )
<< "Number of integration parameters: " << x_.size() << "\n\t"
<< os.str() << ".";
}
void
GenericProcess::setEventContent( const IncomingState& ini, const OutgoingState& fin )
{
if ( !has_event_ )
return;
event_->clear();
//----- add the particles in the event
//--- incoming state
for ( const auto& ip : ini ) {
Particle& p = event_->addParticle( ip.first );
- p.setPdgId( ip.second, part::charge( ip.second ) );
- p.setMass( part::mass( ip.second ) );
+ p.setPdgId( ip.second, particleproperties::charge( ip.second ) );
+ p.setMass( particleproperties::mass( ip.second ) );
if ( ip.first == Particle::IncomingBeam1
|| ip.first == Particle::IncomingBeam2 )
p.setStatus( Particle::Status::PrimordialIncoming );
if ( ip.first == Particle::Parton1
|| ip.first == Particle::Parton2 )
p.setStatus( Particle::Status::Incoming );
}
//--- central system (if not already there)
const auto& central_system = ini.find( Particle::CentralSystem );
if ( central_system == ini.end() ) {
Particle& p = event_->addParticle( Particle::Intermediate );
p.setPdgId( PDG::invalid );
p.setStatus( Particle::Status::Propagator );
}
//--- outgoing state
for ( const auto& opl : fin ) { // pair(role, list of PDGids)
for ( const auto& pdg : opl.second ) {
Particle& p = event_->addParticle( opl.first );
- p.setPdgId( pdg, part::charge( pdg ) );
- p.setMass( part::mass( pdg ) );
+ p.setPdgId( pdg, particleproperties::charge( pdg ) );
+ p.setMass( particleproperties::mass( pdg ) );
}
}
//----- define the particles parentage
const Particles parts = event_->particles();
for ( const auto& p : parts ) {
Particle& part = event_->operator[]( p.id() );
switch ( part.role() ) {
case Particle::OutgoingBeam1:
case Particle::Parton1:
part.addMother( event_->getOneByRole( Particle::IncomingBeam1 ) );
break;
case Particle::OutgoingBeam2:
case Particle::Parton2:
part.addMother( event_->getOneByRole( Particle::IncomingBeam2 ) );
break;
case Particle::Intermediate:
part.addMother( event_->getOneByRole( Particle::Parton1 ) );
part.addMother( event_->getOneByRole( Particle::Parton2 ) );
break;
case Particle::CentralSystem:
part.addMother( event_->getOneByRole( Particle::Intermediate ) );
break;
default: break;
}
}
//----- freeze the event as it is
event_->freeze();
last_event = event_;
}
void
GenericProcess::setIncomingKinematics( const Particle::Momentum& p1, const Particle::Momentum& p2 )
{
if ( !has_event_ )
return;
event_->getOneByRole( Particle::IncomingBeam1 ).setMomentum( p1 );
event_->getOneByRole( Particle::IncomingBeam2 ).setMomentum( p2 );
}
bool
GenericProcess::isKinematicsDefined()
{
if ( !has_event_ )
return true;
// check the incoming state
bool is_incoming_state_set =
( !event_->getByRole( Particle::IncomingBeam1 ).empty()
&& !event_->getByRole( Particle::IncomingBeam2 ).empty() );
// check the outgoing state
bool is_outgoing_state_set =
( !event_->getByRole( Particle::OutgoingBeam1 ).empty()
&& !event_->getByRole( Particle::OutgoingBeam2 ).empty()
&& !event_->getByRole( Particle::CentralSystem ).empty() );
// combine both states
return is_incoming_state_set && is_outgoing_state_set;
}
std::ostream&
operator<<( std::ostream& os, const GenericProcess& proc )
{
return os << proc.name().c_str();
}
std::ostream&
operator<<( std::ostream& os, const GenericProcess* proc )
{
return os << proc->name().c_str();
}
}
}
diff --git a/CepGen/Processes/GenericProcess.h b/CepGen/Processes/GenericProcess.h
index 135cf14..144f005 100644
--- a/CepGen/Processes/GenericProcess.h
+++ b/CepGen/Processes/GenericProcess.h
@@ -1,167 +1,167 @@
#ifndef CepGen_Processes_GenericProcess_h
#define CepGen_Processes_GenericProcess_h
#include "CepGen/Event/Particle.h"
#include "CepGen/Physics/Kinematics.h"
#include <vector>
#include <memory>
-namespace CepGen
+namespace cepgen
{
class Event;
class FormFactors;
class ParametersList;
/// Location for all physics processes to be generated
namespace process
{
/// \brief Class template to define any process to compute using this MC integrator/events generator
/// \author Laurent Forthomme <laurent.forthomme@cern.ch>
/// \date Jan 2014
class GenericProcess
{
public:
/// Default constructor for an undefined process
/// \param[in] name Process name
/// \param[in] description Human-readable description of the process
/// \param[in] has_event Do we generate the associated event structure?
GenericProcess( const std::string& name, const std::string& description = "<invalid process>", bool has_event = true );
/// Copy constructor for a user process
GenericProcess( const GenericProcess& );
virtual ~GenericProcess() = default;
/// Assignment operator
GenericProcess& operator=( const GenericProcess& );
/// Human-readable format dump of a GenericProcess object
friend std::ostream& operator<<( std::ostream& os, const GenericProcess& proc );
/// Human-readable format dump of a pointer to a GenericProcess object
friend std::ostream& operator<<( std::ostream& os, const GenericProcess* proc );
/// Generic map of particles with their role in the process
typedef std::map<Particle::Role,PDG> ParticlesRoleMap;
/// Pair of particle with their associated role in the process
typedef std::pair<Particle::Role,PDG> ParticleWithRole;
/// Map of all incoming state particles in the process
typedef ParticlesRoleMap IncomingState;
/// Map of all outgoing particles in the process
typedef std::map<Particle::Role,std::vector<PDG> > OutgoingState;
/// Copy all process attributes into a new object
virtual std::unique_ptr<GenericProcess> clone( const ParametersList& ) const = 0;
/// Restore the Event object to its initial state
void clearEvent();
/// Set the kinematics of the incoming state particles
void setIncomingKinematics( const Particle::Momentum& p1, const Particle::Momentum& p2 );
/// Compute the incoming state kinematics
void prepareKinematics();
public:
/// Set the incoming and outgoing state to be expected in the process
inline virtual void addEventContent() {}
/// Set the list of kinematic cuts to apply on the outgoing particles' final state
/// \param[in] cuts The Cuts object containing the kinematic parameters
virtual void setKinematics( const Kinematics& cuts );
/// Return the number of dimensions on which the integration has to be performed
/// \return Number of dimensions on which to integrate
virtual unsigned int numDimensions() const = 0;
/// Prepare the process for its integration over the whole phase space
inline virtual void beforeComputeWeight() {}
/// Compute the weight for this point in the phase-space
virtual double computeWeight() = 0;
/// Fill the Event object with the particles' kinematics
/// \param[in] symmetrise Symmetrise the event? (randomise the production of positively- and negatively-charged outgoing central particles)
virtual void fillKinematics( bool symmetrise = false ) = 0;
public:
/**
* Sets the phase space point to compute the weight associated to it.
* \brief Sets the phase space point to compute
* \param[in] ndim The number of dimensions of the point in the phase space
* \param[in] x[] The (\a ndim_)-dimensional point in the phase space on which the kinematics and the cross-section are computed
*/
void setPoint( const unsigned int ndim, double* x );
/// Dump the evaluated point's coordinates in the standard output stream
void dumpPoint() const;
/// Complete list of Particle with their role in the process for the point considered in the phase space, returned as an Event object.
/// \return Event object containing all the generated Particle objects
inline std::shared_ptr<Event> event() const { return event_; }
///Get the number of dimensions on which the integration is performed
inline const unsigned int ndim() const { return x_.size(); }
/// Get the value of a component of the d-dimensional point considered
double x( unsigned int idx ) const;
/// Name of the process considered
inline const std::string& name() const { return name_; }
/// Human-readable description of the process
inline const std::string& description() const { return description_; }
/// Does the process contain (and hold) an event?
bool hasEvent() const { return has_event_; }
/// Pointer to the last event produced in this run
std::shared_ptr<Event> last_event;
protected:
static const double mp_; ///< Proton mass, in GeV/c\f${}^2\f$
static const double mp2_; ///< Squared proton mass, in GeV\f${}^2\f$/c\f${}^4\f$
/// Set the incoming and outgoing states to be defined in this process (and prepare the Event object accordingly)
void setEventContent( const IncomingState& ini, const OutgoingState& fin );
// ---
/// Name of the process
std::string name_;
/// Process human-readable description
std::string description_;
public:
/// Is it the first time the process is computed?
bool first_run;
protected:
/// Array of double precision floats representing the point on which the weight in the cross-section is computed
std::vector<double> x_;
/// \f$s\f$, squared centre of mass energy of the incoming particles' system, in \f$\mathrm{GeV}^2\f$
double s_;
/// \f$\sqrt s\f$, centre of mass energy of the incoming particles' system (in GeV)
double sqs_;
/// Invariant mass of the first proton-like outgoing particle (or remnant)
double MX_;
/// Invariant mass of the second proton-like outgoing particle (or remnant)
double MY_;
/// \f$m_1^2\f$, squared mass of the first proton-like incoming particle
double w1_;
/// \f$m_2^2\f$, squared mass of the second proton-like incoming particle
double w2_;
/// Virtuality of the first incoming photon
double t1_;
/// Virtuality of the second incoming photon
double t2_;
/// Set of cuts to apply on the final phase space
Kinematics cuts_;
/// Does the process contain (and hold) an event?
bool has_event_;
/// Event object containing all the information on the in- and outgoing particles
std::shared_ptr<Event> event_;
/// Is the phase space point set?
bool is_point_set_;
private:
/**
* Is the system's kinematics well defined and compatible with the process ?
* This check is mandatory to perform the d-dimensional point's cross-section computation.
* \brief Is the system's kinematics well defined?
* \return A boolean stating if the input kinematics and the final states are well-defined
*/
bool isKinematicsDefined();
};
}
/// Helper typedef for a Process unique pointer
typedef std::unique_ptr<process::GenericProcess> ProcessPtr;
}
#endif
diff --git a/CepGen/Processes/PPtoFF.cpp b/CepGen/Processes/PPtoFF.cpp
index 671338f..627a63a 100644
--- a/CepGen/Processes/PPtoFF.cpp
+++ b/CepGen/Processes/PPtoFF.cpp
@@ -1,378 +1,378 @@
#include "CepGen/Processes/PPtoFF.h"
#include "CepGen/Event/Event.h"
#include "CepGen/Physics/Constants.h"
#include "CepGen/Physics/FormFactors.h"
#include "CepGen/Physics/PDG.h"
#include "CepGen/Core/Exception.h"
#include <iomanip>
#include "CepGen/Processes/ProcessesHandler.h"
-namespace CepGen
+namespace cepgen
{
namespace process
{
PPtoFF::PPtoFF( const ParametersList& params ) :
GenericKTProcess( params, "pptoff", "ɣɣ → f⁺f¯", { { PDG::photon, PDG::photon } }, { PDG::muon, PDG::muon } ),
pair_( params.get<int>( "pair", 0 ) ),
method_( params.get<int>( "method", 1 ) ),
y1_( 0. ), y2_( 0. ), pt_diff_( 0. ), phi_pt_diff_( 0. )
{}
void
PPtoFF::preparePhaseSpace()
{
registerVariable( y1_, Mapping::linear, cuts_.cuts.central.rapidity_single, { -6., 6. }, "First outgoing fermion rapidity" );
registerVariable( y2_, Mapping::linear, cuts_.cuts.central.rapidity_single, { -6., 6. }, "Second outgoing fermion rapidity" );
registerVariable( pt_diff_, Mapping::linear, cuts_.cuts.central.pt_diff, { 0., 50. }, "Fermions transverse momentum difference" );
registerVariable( phi_pt_diff_, Mapping::linear, cuts_.cuts.central.phi_pt_diff, { 0., 2.*M_PI }, "Fermions azimuthal angle difference" );
if ( (PDG)pair_ == PDG::invalid )
throw CG_FATAL( "PPtoFF:prepare" )
<< "Invalid fermion pair selected: " << pair_ << "!";
const PDG pdg_f = (PDG)pair_;
- mf_ = part::mass( pdg_f );
+ mf_ = particleproperties::mass( pdg_f );
mf2_ = mf_*mf_;
- qf_ = part::charge( pdg_f );
- colf_ = part::colours( pdg_f );
+ qf_ = particleproperties::charge( pdg_f );
+ colf_ = particleproperties::colours( pdg_f );
CG_DEBUG( "PPtoFF:prepare" )
<< "Produced particles (" << pdg_f << ") "
<< "with mass = " << mf_ << " GeV, "
<< "and charge = " << std::setprecision( 2 ) << qf_ << " e";
CG_DEBUG( "PPtoFF:mode" )
<< "matrix element computation method: " << method_ << ".";
}
double
PPtoFF::computeKTFactorisedMatrixElement()
{
//=================================================================
// matrix element computation
//=================================================================
//--- central partons
const Particle::Momentum q1t( qt1_*cos( phi_qt1_ ), qt1_*sin( phi_qt1_ ), 0. );
const Particle::Momentum q2t( qt2_*cos( phi_qt2_ ), qt2_*sin( phi_qt2_ ), 0. );
CG_DEBUG_LOOP( "PPtoFF" ) << "q(1/2)t = " << q1t << ", " << q2t << ".";
//--- two-parton system
const Particle::Momentum ptsum = q1t+q2t;
const Particle::Momentum ptdiff( pt_diff_*cos( phi_pt_diff_ ), pt_diff_*sin( phi_pt_diff_ ), 0. );
//--- outgoing fermions
const Particle::Momentum p1_cm = 0.5*( ptsum+ptdiff ), p2_cm = 0.5*( ptsum-ptdiff );
//=================================================================
// a window in single particle transverse momentum
//=================================================================
const Limits& pt_limits = cuts_.cuts.central.pt_single;
if ( !pt_limits.passes( p1_cm.pt() ) || !pt_limits.passes( p2_cm.pt() ) )
return 0.;
//=================================================================
// a window in transverse momentum difference
//=================================================================
if ( !cuts_.cuts.central.pt_diff.passes( fabs( p1_cm.pt()-p2_cm.pt() ) ) )
return 0.;
//=================================================================
// a window in rapidity distance
//=================================================================
if ( !cuts_.cuts.central.rapidity_diff.passes( fabs( y1_-y2_ ) ) )
return 0.;
//=================================================================
// auxiliary quantities
//=================================================================
// transverse mass for the two fermions
const double amt1 = std::hypot( p1_cm.pt(), mf_ ), amt2 = std::hypot( p2_cm.pt(), mf_ );
const double alpha1 = amt1/sqs_*exp( y1_ ), beta1 = amt1/sqs_*exp( -y1_ ),
alpha2 = amt2/sqs_*exp( y2_ ), beta2 = amt2/sqs_*exp( -y2_ );
CG_DEBUG_LOOP( "PPtoFF" )
<< "Sudakov parameters:\n\t"
<< " alpha(1/2) = " << alpha1 << ", " << alpha2 << "\n\t"
<< " beta(1/2) = " << beta1 << ", " << beta2 << ".";
const double x1 = alpha1+alpha2, x2 = beta1+beta2;
if ( x1 <= 0. || x1 > 1. || x2 <= 0. || x2 > 1. )
return 0.; // sanity check
//=================================================================
// additional conditions for energy-momentum conservation
//=================================================================
const double s1_eff = x1*s_-qt1_*qt1_, s2_eff = x2*s_-qt2_*qt2_;
const double invm = sqrt( amt1*amt1 + amt2*amt2 + 2.*amt1*amt2*cosh(y1_-y2_) - ptsum.pt2() );
CG_DEBUG_LOOP( "PPtoFF" )
<< "s(1/2)eff = " << s1_eff << ", " << s2_eff << " GeV²\n\t"
<< "central system's invariant mass = " << invm << " GeV.";
if ( ( cuts_.mode == KinematicsMode::ElasticInelastic
|| cuts_.mode == KinematicsMode::InelasticInelastic )
&& ( sqrt( s1_eff ) <= ( MY_+invm ) ) )
return 0.;
if ( ( cuts_.mode == KinematicsMode::InelasticElastic
|| cuts_.mode == KinematicsMode::InelasticInelastic )
&& ( sqrt( s2_eff ) <= ( MX_+invm ) ) )
return 0.;
//=================================================================
// four-momenta of the outgoing protons (or remnants)
//=================================================================
const Particle::Momentum& ak1 = event_->getOneByRole( Particle::IncomingBeam1 ).momentum(),
&ak2 = event_->getOneByRole( Particle::IncomingBeam2 ).momentum();
CG_DEBUG_LOOP( "PPtoFF" )
<< "incoming particles: p(1/2) = " << ak1 << ", " << ak2 << ".";
const double px_plus = ( 1.-x1 )*M_SQRT2*ak1.p(),
px_minus = ( MX_*MX_ + q1t.pt2() )*0.5/px_plus;
const double py_minus = ( 1.-x2 )*M_SQRT2*ak2.p(),
py_plus = ( MY_*MY_ + q2t.pt2() )*0.5/py_minus;
CG_DEBUG_LOOP( "PPtoFF" )
<< "px± = " << px_plus << ", " << px_minus << "\n\t"
<< "py± = " << py_plus << ", " << py_minus << ".";
PX_ = Particle::Momentum( -q1t.px(), -q1t.py(), ( px_plus-px_minus )*M_SQRT1_2, ( px_plus+px_minus )*M_SQRT1_2 );
PY_ = Particle::Momentum( -q2t.px(), -q2t.py(), ( py_plus-py_minus )*M_SQRT1_2, ( py_plus+py_minus )*M_SQRT1_2 );
CG_DEBUG_LOOP( "PPtoFF" )
<< "First remnant: " << PX_ << ", mass = " << PX_.mass() << "\n\t"
<< "Second remnant: " << PY_ << ", mass = " << PY_.mass() << ".";
if ( fabs( PX_.mass()-MX_ ) > 1.e-6 )
throw CG_FATAL( "PPtoFF" ) << "Invalid X system mass: " << PX_.mass() << "/" << MX_ << ".";
if ( fabs( PY_.mass()-MY_ ) > 1.e-6 )
throw CG_FATAL( "PPtoFF" ) << "Invalid Y system mass: " << PY_.mass() << "/" << MY_ << ".";
//=================================================================
// four-momenta of the outgoing l^+ and l^-
//=================================================================
const Particle::Momentum p1 = p1_cm + alpha1*ak1 + beta1*ak2;
const Particle::Momentum p2 = p2_cm + alpha2*ak1 + beta2*ak2;
CG_DEBUG_LOOP( "PPtoFF" )
<< "unboosted first fermion: " << p1 << ", mass = " << p1.mass() << "\n\t"
<< " second fermion: " << p2 << ", mass = " << p2.mass() << ".";
p_f1_ = Particle::Momentum::fromPxPyYM( p1_cm.px(), p1_cm.py(), y2_, mf_ );
p_f2_ = Particle::Momentum::fromPxPyYM( p2_cm.px(), p2_cm.py(), y1_, mf_ );
CG_DEBUG_LOOP( "PPtoFF" )
<< "First fermion: " << p_f1_ << ", mass = " << p_f1_.mass() << "\n\t"
<< "Second fermion: " << p_f2_ << ", mass = " << p_f2_.mass() << ".";
if ( fabs( p_f1_.mass()-mf_ ) > 1.e-4 )
throw CG_FATAL( "PPtoFF" ) << "Invalid fermion 1 mass: " << p_f1_.mass() << "/" << mf_ << ".";
if ( fabs( p_f2_.mass()-mf_ ) > 1.e-4 )
throw CG_FATAL( "PPtoFF" ) << "Invalid fermion 2 mass: " << p_f2_.mass() << "/" << mf_ << ".";
//=================================================================
// matrix elements
//=================================================================
double amat2 = 0.;
//=================================================================
// How matrix element is calculated
//=================================================================
if ( method_ == 0 ) {
//===============================================================
// Mendelstam variables
//===============================================================
//const double shat = s_*x1*x2; // approximation
const double shat = ( q1t+q2t ).mass2(); // exact formula
//const double mll = sqrt( shat );
const double that1 = ( q1t-p1 ).mass2(), that2 = ( q2t-p2 ).mass2();
const double uhat1 = ( q1t-p2 ).mass2(), uhat2 = ( q2t-p1 ).mass2();
const double that = 0.5*( that1+that2 ), uhat = 0.5*( uhat1+uhat2 );
amat2 = onShellME( shat, that, uhat );
CG_DEBUG_LOOP( "PPtoFF:onShell" )
<< "that(1/2) = " << that1 << " / " << that2 << "\n\t"
<< "uhat(1/2) = " << uhat1 << " / " << uhat2 << "\n\t"
<< "squared matrix element: " << amat2 << ".";
}
else if ( method_ == 1 ) {
const double t1abs = ( q1t.pt2() + x1*( MX_*MX_-mp2_ )+x1*x1*mp2_ )/( 1.-x1 ),
t2abs = ( q2t.pt2() + x2*( MY_*MY_-mp2_ )+x2*x2*mp2_ )/( 1.-x2 );
const double z1p = alpha1/x1, z1m = alpha2/x1,
z2p = beta1 /x2, z2m = beta2 /x2;
CG_DEBUG_LOOP( "PPtoFF:offShell" )
<< "z(1/2)p = " << z1p << ", " << z2p << "\n\t"
<< "z(1/2)m = " << z1m << ", " << z2m << ".";
amat2 = offShellME( t1abs, t2abs, z1m, z1p, z2m, z2p, q1t, q2t ) * pow( x1*x2*s_, 2 );
}
//============================================
// unintegrated photon distributions
//============================================
const std::pair<double,double> fluxes
= GenericKTProcess::incomingFluxes( x1, q1t.pt2(), x2, q2t.pt2() );
CG_DEBUG_LOOP( "PPtoFF" )
<< "Incoming photon fluxes for (x/kt2) = "
<< "(" << x1 << "/" << q1t.pt2() << "), "
<< "(" << x2 << "/" << q2t.pt2() << "):\n\t"
<< fluxes.first << ", " << fluxes.second << ".";
//=================================================================
// factor 2.*pi from integration over phi_sum
// factor 1/4 from jacobian of transformations
// factors 1/pi and 1/pi due to integration over
// d^2 kappa_1 d^2 kappa_2 instead d kappa_1^2 d kappa_2^2
//=================================================================
const double g_em = 4.*M_PI*constants::alphaEM*qf_*qf_;
const double aintegral = amat2 * colf_ * ( g_em*g_em )
* 1. / pow( 4.*M_PI*( x1*x2*s_ ), 2 )
* fluxes.first*M_1_PI * fluxes.second*M_1_PI * 0.25
* constants::GeV2toBarn;
//=================================================================
return aintegral*qt1_*qt2_*pt_diff_;
//=================================================================
}
void
PPtoFF::fillCentralParticlesKinematics()
{
// randomise the charge of the outgoing fermions
short sign = ( drand() > 0.5 ) ? +1 : -1;
//=================================================================
// first outgoing fermion
//=================================================================
Particle& of1 = event_->getByRole( Particle::CentralSystem )[0];
of1.setPdgId( of1.pdgId(), sign );
of1.setStatus( Particle::Status::FinalState );
of1.setMomentum( p_f1_ );
//=================================================================
// second outgoing fermion
//=================================================================
Particle& of2 = event_->getByRole( Particle::CentralSystem )[1];
of2.setPdgId( of2.pdgId(), -sign );
of2.setStatus( Particle::Status::FinalState );
of2.setMomentum( p_f2_ );
}
double
PPtoFF::onShellME( double shat, double that, double uhat ) const
{
CG_DEBUG_LOOP( "PPtoFF:onShell" )
<< "shat: " << shat << ", that: " << that << ", uhat: " << uhat << ".";
//=================================================================
// on-shell formula for M^2
//=================================================================
const double ml4 = mf2_*mf2_, ml8 = ml4*ml4;
const double term1 = 6. *ml8,
term2 = -3. *ml4 *that*that,
term3 = -14.*ml4 *that*uhat,
term4 = -3. *ml4 *uhat*uhat,
term5 = mf2_*that*that*that,
term6 = 7.* mf2_*that*that*uhat,
term7 = 7.* mf2_*that*uhat*uhat,
term8 = mf2_*uhat*uhat*uhat,
term9 = -that*that*that*uhat,
term10 = -that*uhat*uhat*uhat;
return -2.*( term1+term2+term3+term4+term5
+term6+term7+term8+term9+term10 )/( pow( ( mf2_-that )*( mf2_-uhat ), 2) );
}
double
PPtoFF::offShellME( double t1abs, double t2abs, double z1m, double z1p, double z2m, double z2p, const Particle::Momentum& q1, const Particle::Momentum& q2 ) const
{
//=================================================================
// Wolfgang's formulae
//=================================================================
const double z1 = z1p*z1m, z2 = z2p*z2m;
const double eps12 = mf2_+z1*t1abs, eps22 = mf2_+z2*t2abs;
const Particle::Momentum ak1 = ( z1m*p_f1_-z1p*p_f2_ ), ak2 = ( z2m*p_f1_-z2p*p_f2_ );
const Particle::Momentum ph_p1 = ak1+z1p*q2, ph_m1 = ak1-z1m*q2;
const Particle::Momentum ph_p2 = ak2+z2p*q1, ph_m2 = ak2-z2m*q1;
const Particle::Momentum phi1(
ph_p1.px()/( ph_p1.pt2()+eps12 )-ph_m1.px()/( ph_m1.pt2()+eps12 ),
ph_p1.py()/( ph_p1.pt2()+eps12 )-ph_m1.py()/( ph_m1.pt2()+eps12 ),
0.,
1./( ph_p1.pt2()+eps12 )-1./( ph_m1.pt2()+eps12 )
);
const Particle::Momentum phi2(
ph_p2.px()/( ph_p2.pt2()+eps22 )-ph_m2.px()/( ph_m2.pt2()+eps22 ),
ph_p2.py()/( ph_p2.pt2()+eps22 )-ph_m2.py()/( ph_m2.pt2()+eps22 ),
0.,
1./( ph_p2.pt2()+eps22 )-1./( ph_m2.pt2()+eps22 )
);
const double dot1 = phi1.threeProduct( q1 )/qt1_, cross1 = phi1.crossProduct( q1 )/qt1_;
const double dot2 = phi2.threeProduct( q2 )/qt2_, cross2 = phi2.crossProduct( q2 )/qt2_;
CG_DEBUG_LOOP( "PPtoFF:offShell" )
<< "phi1 = " << phi1 << "\n\t"
<< "phi2 = " << phi2 << "\n\t"
<< "(dot): " << dot1 << " / " << dot2 << "\n\t"
<< "(cross): " << cross1 << " / " << cross2 << ".";
//=================================================================
// six terms in Wolfgang's formula for
// off-shell gamma gamma --> l^+ l^-
//=================================================================
const unsigned short imat1 = 1, imat2 = 1;
const unsigned short itermLL = 1, itermTT = 1, itermLT = 1, itermtt = 1;
const double aux2_1 = itermLL * ( mf2_ + 4.*z1*z1*t1abs ) * phi1.energy2()
+itermTT * ( ( z1p*z1p + z1m*z1m )*( dot1*dot1 + cross1*cross1 ) )
+itermtt * ( cross1*cross1 - dot1*dot1 )
-itermLT * 4.*z1*( z1p-z1m ) * phi1.energy() * q1.threeProduct( phi1 );
const double aux2_2 = itermLL * ( mf2_ + 4.*z2*z2*t2abs ) * phi2.energy2()
+itermTT * ( ( z2p*z2p + z2m*z2m )*( dot2*dot2 + cross2*cross2 ) )
+itermtt * ( cross2*cross2 - dot2*dot2 )
-itermLT * 4.*z2*( z2p-z2m ) * phi2.energy() * q2.threeProduct( phi2 );
//=================================================================
// convention of matrix element as in our kt-factorization
// for heavy flavours
//=================================================================
const double amat2_1 = aux2_1*2.*z1*q1.pt2()/( q1.pt2()*q2.pt2() ),
amat2_2 = aux2_2*2.*z2*q2.pt2()/( q1.pt2()*q2.pt2() );
//=================================================================
// symmetrization
//=================================================================
CG_DEBUG_LOOP( "PPtoFF:offShell" )
<< "aux2(1/2) = " << aux2_1 << " / " << aux2_2 << "\n\t"
<< "amat2(1/2), amat2 = " << amat2_1 << " / " << amat2_2 << " / " << ( 0.5*( imat1*amat2_1 + imat2*amat2_2 ) ) << ".";
return 0.5*( imat1*amat2_1 + imat2*amat2_2 );
}
// register process and define aliases
REGISTER_PROCESS( pptoll, PPtoFF )
REGISTER_PROCESS( pptoff, PPtoFF )
}
}
diff --git a/CepGen/Processes/PPtoFF.h b/CepGen/Processes/PPtoFF.h
index d5e696c..6096b04 100644
--- a/CepGen/Processes/PPtoFF.h
+++ b/CepGen/Processes/PPtoFF.h
@@ -1,54 +1,54 @@
#ifndef CepGen_Processes_PPtoFF_h
#define CepGen_Processes_PPtoFF_h
#include "CepGen/Processes/GenericKTProcess.h"
#include "CepGen/Core/ParametersList.h"
-namespace CepGen
+namespace cepgen
{
namespace process
{
/// Compute the matrix element for a CE \f$\gamma\gamma\rightarrow f\bar f\f$ process using \f$k_T\f$-factorization approach
class PPtoFF : public GenericKTProcess
{
public:
PPtoFF( const ParametersList& params = ParametersList() );
ProcessPtr clone( const ParametersList& params ) const override { return ProcessPtr( new PPtoFF( params ) ); }
private:
void preparePhaseSpace() override;
/// \note IncQQbar in pptoll
double computeKTFactorisedMatrixElement() override;
void fillCentralParticlesKinematics() override;
/// Rapidity range for the outgoing fermions
double onShellME( double shat, double that, double uhat ) const;
double offShellME( double, double, double, double, double, double, const Particle::Momentum&, const Particle::Momentum& ) const;
/// PDG id of the fermion pair produced
int pair_;
int method_;
Limits rap_limits_;
/// Rapidity of the first outgoing fermion
double y1_;
/// Rapidity of the first outgoing fermion
double y2_;
/// Transverse momentum difference for the two outgoing fermions
double pt_diff_;
/// Azimuthal angle difference for the two outgoing fermions
double phi_pt_diff_;
double mf_, mf2_, qf_;
unsigned short colf_;
/// First outgoing fermion's momentum
Particle::Momentum p_f1_;
/// Second outgoing fermion's momentum
Particle::Momentum p_f2_;
};
}
}
#endif
diff --git a/CepGen/Processes/PPtoWW.cpp b/CepGen/Processes/PPtoWW.cpp
index 96eddfe..6fc9760 100644
--- a/CepGen/Processes/PPtoWW.cpp
+++ b/CepGen/Processes/PPtoWW.cpp
@@ -1,393 +1,393 @@
#include "CepGen/Processes/PPtoWW.h"
#include "CepGen/Event/Event.h"
#include "CepGen/Physics/Constants.h"
#include "CepGen/Physics/FormFactors.h"
#include "CepGen/Physics/PDG.h"
#include "CepGen/Core/Exception.h"
#include <assert.h>
#include "CepGen/Processes/ProcessesHandler.h"
-namespace CepGen
+namespace cepgen
{
namespace process
{
- const double PPtoWW::mw_ = part::mass( PDG::W );
+ const double PPtoWW::mw_ = particleproperties::mass( PDG::W );
const double PPtoWW::mw2_ = PPtoWW::mw_*PPtoWW::mw_;
PPtoWW::PPtoWW( const ParametersList& params ) :
GenericKTProcess( params, "pptoww", "ɣɣ → W⁺W¯", { { PDG::photon, PDG::photon } }, { PDG::W, PDG::W } ),
method_( params.get<int>( "method", 1 ) ),
pol_state_( (Polarisation)params.get<int>( "polarisationStates", 0 ) ),
y1_( 0. ), y2_( 0. ), pt_diff_( 0. ), phi_pt_diff_( 0. )
{}
void
PPtoWW::preparePhaseSpace()
{
registerVariable( y1_, Mapping::linear, cuts_.cuts.central.rapidity_single, { -6., 6. }, "First outgoing W rapidity" );
registerVariable( y2_, Mapping::linear, cuts_.cuts.central.rapidity_single, { -6., 6. }, "Second outgoing W rapidity" );
registerVariable( pt_diff_, Mapping::linear, cuts_.cuts.central.pt_diff, { 0., 500. }, "Ws transverse momentum difference" );
registerVariable( phi_pt_diff_, Mapping::linear, cuts_.cuts.central.phi_pt_diff, { 0., 2.*M_PI }, "Ws azimuthal angle difference" );
switch ( pol_state_ ) {
case Polarisation::LL: pol_w1_ = pol_w2_ = { 0 }; break;
case Polarisation::LT: pol_w1_ = { 0 }; pol_w2_ = { -1, 1 }; break;
case Polarisation::TL: pol_w1_ = { -1, 1 }; pol_w2_ = { 0 }; break;
case Polarisation::TT: pol_w1_ = pol_w2_ = { -1, 1 }; break;
default:
case Polarisation::full: pol_w1_ = pol_w2_ = { -1, 0, 1 }; break;
}
CG_DEBUG( "PPtoWW:mode" )
<< "matrix element computation method: " << method_ << ".";
}
double
PPtoWW::computeKTFactorisedMatrixElement()
{
//=================================================================
// matrix element computation
//=================================================================
//const double stild = s_/2.*(1+sqrt(1.-(4*pow(mp2_, 2))/s_*s_));
// Inner photons
const double q1tx = qt1_*cos( phi_qt1_ ), q1ty = qt1_*sin( phi_qt1_ ),
q2tx = qt2_*cos( phi_qt2_ ), q2ty = qt2_*sin( phi_qt2_ );
CG_DEBUG_LOOP( "PPtoWW:qt" )
<< "q1t(x/y) = " << q1tx << " / " << q1ty << "\n\t"
<< "q2t(x/y) = " << q2tx << " / " << q2ty << ".";
// Two-photon system
const double ptsumx = q1tx+q2tx,
ptsumy = q1ty+q2ty,
ptsum = sqrt( ptsumx*ptsumx+ptsumy*ptsumy );
const double ptdiffx = pt_diff_*cos( phi_pt_diff_ ),
ptdiffy = pt_diff_*sin( phi_pt_diff_ );
// Outgoing leptons
const double pt1x = ( ptsumx+ptdiffx )*0.5, pt1y = ( ptsumy+ptdiffy )*0.5, pt1 = std::hypot( pt1x, pt1y ),
pt2x = ( ptsumx-ptdiffx )*0.5, pt2y = ( ptsumy-ptdiffy )*0.5, pt2 = std::hypot( pt2x, pt2y );
if ( cuts_.cuts.central_particles.count( PDG::W ) > 0
&& cuts_.cuts.central_particles.at( PDG::W ).pt_single.valid() ) {
const Limits pt_limits = cuts_.cuts.central_particles.at( PDG::W ).pt_single;
if ( !pt_limits.passes( pt1 ) || !pt_limits.passes( pt2 ) )
return 0.;
}
// transverse mass for the two leptons
const double amt1 = sqrt( pt1*pt1+mw2_ ),
amt2 = sqrt( pt2*pt2+mw2_ );
//=================================================================
// a window in two-boson invariant mass
//=================================================================
const double invm = sqrt( amt1*amt1 + amt2*amt2 + 2.*amt1*amt2*cosh( y1_-y2_ ) - ptsum*ptsum );
if ( !cuts_.cuts.central.mass_sum.passes( invm ) )
return 0.;
//=================================================================
// a window in transverse momentum difference
//=================================================================
if ( !cuts_.cuts.central.pt_diff.passes( fabs( pt1-pt2 ) ) )
return 0.;
//=================================================================
// a window in rapidity distance
//=================================================================
if ( !cuts_.cuts.central.rapidity_diff.passes( fabs( y1_-y2_ ) ) )
return 0.;
//=================================================================
// auxiliary quantities
//=================================================================
const double alpha1 = amt1/sqs_*exp( y1_ ), beta1 = amt1/sqs_*exp( -y1_ ),
alpha2 = amt2/sqs_*exp( y2_ ), beta2 = amt2/sqs_*exp( -y2_ );
CG_DEBUG_LOOP( "PPtoWW:sudakov" )
<< "Sudakov parameters:\n\t"
<< " alpha1/2 = " << alpha1 << " / " << alpha2 << "\n\t"
<< " beta1/2 = " << beta1 << " / " << beta2 << ".";
const double q1t2 = q1tx*q1tx+q1ty*q1ty, q2t2 = q2tx*q2tx+q2ty*q2ty;
const double x1 = alpha1+alpha2, x2 = beta1+beta2;
const double z1p = alpha1/x1, z1m = alpha2/x1,
z2p = beta1 /x2, z2m = beta2 /x2;
CG_DEBUG_LOOP( "PPtoWW:zeta" )
<< "z(1/2)p = " << z1p << " / " << z2p << "\n\t"
<< "z(1/2)m = " << z1m << " / " << z2m << ".";
if ( x1 > 1. || x2 > 1. )
return 0.; // sanity check
// FIXME FIXME FIXME
const double ak10 = event_->getOneByRole( Particle::IncomingBeam1 ).energy(),
ak1z = event_->getOneByRole( Particle::IncomingBeam1 ).momentum().pz(),
ak20 = event_->getOneByRole( Particle::IncomingBeam2 ).energy(),
ak2z = event_->getOneByRole( Particle::IncomingBeam2 ).momentum().pz();
CG_DEBUG_LOOP( "PPtoWW:incoming" )
<< "incoming particles: p1: " << ak1z << " / " << ak10 << "\n\t"
<< " p2: " << ak2z << " / " << ak20 << ".";
//=================================================================
// additional conditions for energy-momentum conservation
//=================================================================
const double s1_eff = x1*s_-qt1_*qt1_, s2_eff = x2*s_-qt2_*qt2_;
CG_DEBUG_LOOP( "PPtoWW:central" )
<< "s(1/2)_eff = " << s1_eff << " / " << s2_eff << " GeV^2\n\t"
<< "diboson invariant mass = " << invm << " GeV";
if ( ( cuts_.mode == KinematicsMode::ElasticInelastic
|| cuts_.mode == KinematicsMode::InelasticInelastic )
&& ( sqrt( s1_eff ) <= ( MY_+invm ) ) )
return 0.;
if ( ( cuts_.mode == KinematicsMode::InelasticElastic
|| cuts_.mode == KinematicsMode::InelasticInelastic )
&& ( sqrt( s2_eff ) <= ( MX_+invm ) ) )
return 0.;
//const double qcaptx = pcaptx, qcapty = pcapty;
//=================================================================
// four-momenta of the outgoing protons (or remnants)
//=================================================================
const double px_plus = ( 1.-x1 )*fabs( ak1z )*M_SQRT2,
px_minus = ( MX_*MX_ + q1t2 )*0.5/px_plus;
const double py_minus = ( 1.-x2 )*fabs( ak2z )*M_SQRT2, // warning! sign of pz??
py_plus = ( MY_*MY_ + q2t2 )*0.5/py_minus;
CG_DEBUG_LOOP( "PPtoWW:pxy" )
<< "px± = " << px_plus << " / " << px_minus << "\n\t"
<< "py± = " << py_plus << " / " << py_minus << ".";
PX_ = Particle::Momentum( -q1tx, -q1ty, ( px_plus-px_minus )*M_SQRT1_2, ( px_plus+px_minus )*M_SQRT1_2 );
PY_ = Particle::Momentum( -q2tx, -q2ty, ( py_plus-py_minus )*M_SQRT1_2, ( py_plus+py_minus )*M_SQRT1_2 );
CG_DEBUG_LOOP( "PPtoWW:remnants" )
<< "First remnant: " << PX_ << ", mass = " << PX_.mass() << "\n\t"
<< "Second remnant: " << PY_ << ", mass = " << PY_.mass() << ".";
/*assert( fabs( PX_.mass()-MX_ ) < 1.e-6 );
assert( fabs( PY_.mass()-MY_ ) < 1.e-6 );*/
//=================================================================
// four-momenta squared of the virtual photons
//=================================================================
const double ww = 0.5 * ( 1.+sqrt( 1.-4.*mp2_/s_ ) );
// FIXME FIXME FIXME /////////////////////
const Particle::Momentum q1(
q1tx, q1ty,
+0.5 * x1*ww*sqs_*( 1.-q1t2/x1/x1/ww/ww/s_ ),
+0.5 * x1*ww*sqs_*( 1.+q1t2/x1/x1/ww/ww/s_ ) );
const Particle::Momentum q2(
q2tx, q2ty,
-0.5 * x2*ww*sqs_*( 1.-q2t2/x2/x2/ww/ww/s_ ),
+0.5 * x2*ww*sqs_*( 1.+q2t2/x2/x2/ww/ww/s_ ) );
//////////////////////////////////////////
CG_DEBUG_LOOP( "PPtoWW:partons" )
<< "First photon*: " << q1 << ", mass2 = " << q1.mass2() << "\n\t"
<< "Second photon*: " << q2 << ", mass2 = " << q2.mass2() << ".";
//const double q12 = q1.mass2(), q22 = q2.mass2();
//=================================================================
// four-momenta of the outgoing W^+ and W^-
//=================================================================
p_w1_ = Particle::Momentum( pt1x, pt1y, alpha1*ak1z + beta1*ak2z, alpha1*ak10 + beta1*ak20 );
p_w2_ = Particle::Momentum( pt2x, pt2y, alpha2*ak1z + beta2*ak2z, alpha2*ak10 + beta2*ak20 );
CG_DEBUG_LOOP( "PPtoWW:central" )
<< "First W: " << p_w1_ << ", mass = " << p_w1_.mass() << "\n\t"
<< "Second W: " << p_w2_ << ", mass = " << p_w2_.mass() << ".";
//assert( fabs( p_w1_.mass()-event_->getByRole( Particle::CentralSystem )[0].mass() ) < 1.e-6 );
//assert( fabs( p_w2_.mass()-event_->getByRole( Particle::CentralSystem )[1].mass() ) < 1.e-6 );
//=================================================================
// Mendelstam variables
//=================================================================
//const double shat = s_*x1*x2; // ishat = 1 (approximation)
const double shat = ( q1+q2 ).mass2(); // ishat = 2 (exact formula)
const double that1 = ( q1-p_w1_ ).mass2(), that2 = ( q2-p_w2_ ).mass2();
const double uhat1 = ( q1-p_w2_ ).mass2(), uhat2 = ( q2-p_w1_ ).mass2();
CG_DEBUG_LOOP( "PPtoWW" )
<< "that(1/2) = " << that1 << " / " << that2 << "\n\t"
<< "uhat(1/2) = " << uhat1 << " / " << uhat2 << ".";
//const double mll = sqrt( shat );
const double that = 0.5*( that1+that2 ), uhat = 0.5*( uhat1+uhat2 );
//=================================================================
// matrix elements
//=================================================================
double amat2 = 0.;
//=================================================================
// How matrix element is calculated
//=================================================================
CG_DEBUG_LOOP( "PPtoWW" )
<< "matrix element mode: " << method_ << ".";
//=================================================================
// matrix element for gamma gamma --> W^+ W^-
// (Denner+Dittmaier+Schuster)
// (work in collaboration with C. Royon)
//=================================================================
if ( method_ == 0 )
amat2 = onShellME( shat, that, uhat );
//=================================================================
// off-shell Nachtmann formulae
//=================================================================
else if ( method_ == 1 )
amat2 = offShellME( shat, that, uhat, phi_qt1_+phi_qt2_, phi_qt1_-phi_qt2_ );
if ( amat2 <= 0. )
return 0.;
//============================================
// unintegrated photon distributions
//============================================
const std::pair<double,double> fluxes
= GenericKTProcess::incomingFluxes( x1, q1t2, x2, q2t2 );
CG_DEBUG_LOOP( "PPtoWW:fluxes" )
<< "Incoming photon fluxes for (x/kt2) = "
<< "(" << x1 << "/" << q1t2 << "), "
<< "(" << x2 << "/" << q2t2 << "):\n\t"
<< fluxes.first << ", " << fluxes.second << ".";
//=================================================================
// factor 2.*pi from integration over phi_sum
// factor 1/4 from jacobian of transformations
// factors 1/pi and 1/pi due to integration over
// d^2 kappa_1 d^2 kappa_2 instead d kappa_1^2 d kappa_2^2
//=================================================================
const double aintegral = amat2 / ( 16.*M_PI*M_PI*( x1*x2*s_ )*( x1*x2*s_ ) )
* fluxes.first*M_1_PI * fluxes.second*M_1_PI * 0.25
* constants::GeV2toBarn;
/*const double aintegral = amat2 / ( 16.*M_PI*M_PI*x1*x1*x2*x2*s_*s_ )
* fluxes.first*M_1_PI * fluxes.second*M_1_PI
* constants::GeV2toBarn * 0.25;*/
//=================================================================
return aintegral*qt1_*qt2_*pt_diff_;
//=================================================================
}
void
PPtoWW::fillCentralParticlesKinematics()
{
// randomise the charge of the outgoing leptons
short sign = ( drand() > 0.5 ) ? +1 : -1;
//=================================================================
// first outgoing lepton
//=================================================================
Particle& ow1 = event_->getByRole( Particle::CentralSystem )[0];
ow1.setPdgId( ow1.pdgId(), sign );
ow1.setStatus( Particle::Status::Undecayed );
ow1.setMomentum( p_w1_ );
//=================================================================
// second outgoing lepton
//=================================================================
Particle& ow2 = event_->getByRole( Particle::CentralSystem )[1];
ow2.setPdgId( ow2.pdgId(), -sign );
ow2.setStatus( Particle::Status::Undecayed );
ow2.setMomentum( p_w2_ );
}
double
PPtoWW::onShellME( double shat, double that, double uhat )
{
const double mw4 = mw2_*mw2_;
const double term1 = 2.*shat * ( 2.*shat+3.*mw2_ ) / ( 3.*( mw2_-that )*( mw2_-uhat ) );
const double term2 = 2.*shat*shat * ( shat*shat + 3.*mw4 ) / ( 3.*pow( mw2_-that, 2 )*pow( mw2_-uhat, 2 ) );
const double auxil_gamgam = 1.-term1+term2;
const double beta = sqrt( 1.-4.*mw2_/shat );
return 3.*constants::alphaEM*constants::alphaEM*beta / ( 2.*shat ) * auxil_gamgam / ( beta/( 64.*M_PI*M_PI*shat ) );
}
double
PPtoWW::offShellME( double shat, double that, double uhat, double phi_sum, double phi_diff )
{
const double e2 = 4.*M_PI*constants::alphaEM;
double amat2_0 = 0., amat2_1 = 0., amat2_interf = 0.;
for ( const auto lam3 : pol_w1_ )
for ( const auto lam4 : pol_w2_ ) {
double ampli_pp = amplitudeWW( shat, that, uhat, +1, +1, lam3, lam4 );
double ampli_mm = amplitudeWW( shat, that, uhat, -1, -1, lam3, lam4 );
double ampli_pm = amplitudeWW( shat, that, uhat, +1, -1, lam3, lam4 );
double ampli_mp = amplitudeWW( shat, that, uhat, -1, +1, lam3, lam4 );
amat2_0 += ampli_pp*ampli_pp + ampli_mm*ampli_mm + 2.*cos( 2.*phi_diff )*ampli_pp*ampli_mm;
amat2_1 += ampli_pm*ampli_pm + ampli_mp*ampli_mp + 2.*cos( 2.*phi_sum )*ampli_pm*ampli_mp;
amat2_interf -= 2.*( cos( phi_sum+phi_diff )*( ampli_pp*ampli_pm+ampli_mm*ampli_mp )
+cos( phi_sum-phi_diff )*( ampli_pp*ampli_mp+ampli_mm*ampli_pm ) );
}
return e2*e2*( amat2_0+amat2_1+amat2_interf );
}
double
PPtoWW::amplitudeWW( double shat, double that, double uhat, short lam1, short lam2, short lam3, short lam4 )
{
//--- first compute some kinematic variables
const double cos_theta = ( that-uhat ) / shat / sqrt( 1.+1.e-10-4.*mw2_/shat ),
cos_theta2 = cos_theta*cos_theta;
const double sin_theta2 = 1.-cos_theta2,
sin_theta = sqrt( sin_theta2 );
const double beta = sqrt( 1.-4.*mw2_/shat ), beta2 = beta*beta;
const double inv_gamma = sqrt( 1.-beta2 ), gamma = 1./inv_gamma,
gamma2 = gamma*gamma, inv_gamma2 = inv_gamma*inv_gamma;
const double invA = 1./( 1.-beta2*cos_theta2 );
//--- per-helicity amplitude
// longitudinal-longitudinal
if ( lam3 == 0 && lam4 == 0 )
return invA*inv_gamma2*( ( gamma2+1. )*( 1.-lam1*lam2 )*sin_theta2 - ( 1.+lam1*lam2 ) );
// transverse-longitudinal
if ( lam4 == 0 )
return invA*( -M_SQRT2*inv_gamma*( lam1-lam2 )*( 1.+lam1*lam3*cos_theta )*sin_theta );
// longitudinal-transverse
if ( lam3 == 0 )
return invA*( -M_SQRT2*inv_gamma*( lam2-lam1 )*( 1.+lam2*lam4*cos_theta )*sin_theta );
// transverse-transverse
if ( lam3 != 0 && lam4 != 0 )
return -0.5*invA*( 2.*beta*( lam1+lam2 )*( lam3+lam4 )
-inv_gamma2*( 1.+lam3*lam4 )*( 2.*lam1*lam2+( 1.-lam1*lam2 ) * cos_theta2 )
+( 1.+lam1*lam2*lam3*lam4 )*( 3.+lam1*lam2 )
+2.*( lam1-lam2 )*( lam3-lam4 )*cos_theta
+( 1.-lam1*lam2 )*( 1.-lam3*lam4 )*cos_theta2 );
return 0.;
}
// register process and define aliases
REGISTER_PROCESS( pptoww, PPtoWW )
}
}
diff --git a/CepGen/Processes/PPtoWW.h b/CepGen/Processes/PPtoWW.h
index 49a10c1..03336ab 100644
--- a/CepGen/Processes/PPtoWW.h
+++ b/CepGen/Processes/PPtoWW.h
@@ -1,58 +1,58 @@
#ifndef CepGen_Processes_PPtoWW_h
#define CepGen_Processes_PPtoWW_h
#include "CepGen/Processes/GenericKTProcess.h"
#include "CepGen/Core/ParametersList.h"
-namespace CepGen
+namespace cepgen
{
namespace process
{
/// \brief Compute the matrix element for a CE \f$\gamma\gamma\rightarrow W^+W^-\f$ process using \f$k_T\f$-factorization approach
/// \note The full theoretical description of this process definition may be found in \cite Luszczak:2018ntp.
class PPtoWW : public GenericKTProcess
{
public:
PPtoWW( const ParametersList& params = ParametersList() );
ProcessPtr clone( const ParametersList& params ) const override { return ProcessPtr( new PPtoWW( params ) ); }
enum class Polarisation { full = 0, LL = 1, LT = 2, TL = 3, TT = 4 };
private:
static const double mw_, mw2_;
void preparePhaseSpace() override;
double computeKTFactorisedMatrixElement() override;
void fillCentralParticlesKinematics() override;
double amplitudeWW( double shat, double that, double uhat, short lam1, short lam2, short lam3, short lam4 );
double onShellME( double shat, double that, double uhat );
double offShellME( double shat, double that, double uhat, double phi_sum, double phi_diff );
int method_;
Polarisation pol_state_;
std::vector<short> pol_w1_, pol_w2_;
/// Rapidity range for the outgoing W bosons
Limits rap_limits_;
/// Rapidity of the first outgoing W boson
double y1_;
/// Rapidity of the first outgoing W boson
double y2_;
Limits ptdiff_limits_;
/// Transverse momentum difference for the two outgoing W bosons
double pt_diff_;
Limits phi_pt_diff_limits_;
/// Azimuthal angle difference for the two outgoing W bosons
double phi_pt_diff_;
/// First outgoing W boson's momentum
Particle::Momentum p_w1_;
/// Second outgoing W boson's momentum
Particle::Momentum p_w2_;
};
}
}
#endif
diff --git a/CepGen/Processes/ProcessesHandler.cpp b/CepGen/Processes/ProcessesHandler.cpp
index 312f2b8..36fe374 100644
--- a/CepGen/Processes/ProcessesHandler.cpp
+++ b/CepGen/Processes/ProcessesHandler.cpp
@@ -1,44 +1,44 @@
#include "CepGen/Core/Exception.h"
#include "CepGen/Core/utils.h"
#include "CepGen/Core/ParametersList.h"
#include "CepGen/Processes/PPtoFF.h"
#include "CepGen/Processes/ProcessesHandler.h"
#include <sstream>
-namespace CepGen
+namespace cepgen
{
ProcessesHandler&
ProcessesHandler::get()
{
static ProcessesHandler instance;
return instance;
}
void
ProcessesHandler::registerProcess( const std::string& name, const process::GenericProcess* proc )
{
map_[name].reset( proc );
CG_DEBUG( "ProcessesHandler" ) << "Process name \"" << name << "\" registered in database.";
}
void
ProcessesHandler::dump() const
{
std::ostringstream oss;
for ( const auto& p : map_ )
oss << " '" << p.first << "'";
CG_INFO( "ProcessesHandler:dump" )
<< "List of process(es) handled in the database:" << oss.str();
}
ProcessPtr
ProcessesHandler::build( const std::string& name, const ParametersList& params ) const
{
if ( map_.count( name ) == 0 )
throw CG_FATAL( "ProcessesHandler:build" )
<< "Failed to retrieve a process with name \"" << name << "\"!";
return map_.at( name )->clone( params );
}
}
diff --git a/CepGen/Processes/ProcessesHandler.h b/CepGen/Processes/ProcessesHandler.h
index f7c23b7..bcc409e 100644
--- a/CepGen/Processes/ProcessesHandler.h
+++ b/CepGen/Processes/ProcessesHandler.h
@@ -1,39 +1,39 @@
#ifndef CepGen_Processes_ProcessesHandler_h
#define CepGen_Processes_ProcessesHandler_h
#include "CepGen/Processes/GenericProcess.h"
#include <unordered_map>
#include <memory>
#define BUILDERNM( obj ) obj ## Builder
#define STRINGIFY( name ) #name
#define REGISTER_PROCESS( name, obj ) \
struct BUILDERNM( name ) { \
- BUILDERNM( name )() { CepGen::ProcessesHandler::get().registerProcess( STRINGIFY( name ), new obj ); } }; \
+ BUILDERNM( name )() { cepgen::ProcessesHandler::get().registerProcess( STRINGIFY( name ), new obj ); } }; \
static BUILDERNM( name ) g ## name;
-namespace CepGen
+namespace cepgen
{
class ParametersList;
//namespace process { class GenericProcess; }
class ProcessesHandler
{
public:
static ProcessesHandler& get();
~ProcessesHandler() = default;
- void registerProcess( const std::string& name, const CepGen::process::GenericProcess* );
+ void registerProcess( const std::string& name, const cepgen::process::GenericProcess* );
ProcessPtr build( const std::string& name, const ParametersList& ) const;
void dump() const;
private:
explicit ProcessesHandler() = default;
std::unordered_map<std::string, std::unique_ptr<const process::GenericProcess> > map_;
public:
ProcessesHandler( const ProcessesHandler& ) = delete;
void operator=( const ProcessesHandler& ) = delete;
};
}
#endif
diff --git a/CepGen/StructureFunctions/ALLM.cpp b/CepGen/StructureFunctions/ALLM.cpp
index 2334071..ea98836 100644
--- a/CepGen/StructureFunctions/ALLM.cpp
+++ b/CepGen/StructureFunctions/ALLM.cpp
@@ -1,165 +1,165 @@
#include "ALLM.h"
#include "CepGen/Physics/ParticleProperties.h"
#include <cmath>
-namespace CepGen
+namespace cepgen
{
namespace sf
{
ALLM::Parameters
ALLM::Parameters::allm91()
{
Parameters p;
p.pomeron = Trajectory( {
{ 0.26550, 0.04856, 1.04682 },
{ -0.04503, -0.36407, 8.17091 },
{ 0.49222, 0.52116, 3.5515 } } );
p.reggeon = Trajectory( {
{ 0.67639, 0.49027, 2.66275 },
{ 0.60408, 0.17353, 1.61812 },
{ 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;
p.type = Type::ALLM91;
return p;
}
ALLM::Parameters
ALLM::Parameters::allm97()
{
Parameters p;
p.pomeron = Trajectory( {
{ 0.28067, 0.22291, 2.1979 },
{ -0.0808, -0.44812, 1.1709 },
{ 0.36292, 1.8917, 1.8439 } } );
p.reggeon = Trajectory( {
{ 0.80107, 0.97307, 3.4924 },
{ 0.58400, 0.37888, 2.6063 },
{ 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;
p.type = Type::ALLM97;
return p;
}
ALLM::Parameters
ALLM::Parameters::hht_allm()
{
Parameters p;
p.pomeron = Trajectory( {
{ 0.412, 0.164, 17.7 },
{ -0.835, -0.446, 10.6 },
{ -45.8, 55.7, -0.031 } } );
p.reggeon = Trajectory( {
{ -1.04, 2.97, 0.163 },
{ 0.706, 0.185, -16.4 },
{ -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;
p.type = Type::Invalid;
return p;
}
ALLM::Parameters
ALLM::Parameters::hht_allm_ft()
{
Parameters p;
p.pomeron = Trajectory( {
{ 0.356, 0.171, 18.6 },
{ -0.075, -0.470, 9.2 },
{ -0.477, 54.0, 0.073 } } );
p.reggeon = Trajectory( {
{ -0.636, 3.37, -0.660 },
{ 0.882, 0.082, -8.5 },
{ 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;
p.type = Type::Invalid;
return p;
}
ALLM::Parameters
ALLM::Parameters::gd07p()
{
Parameters p;
p.pomeron = Trajectory( {
{ 0.339, 0.127, 1.16 },
{ -0.105, -0.495, 1.29 },
{ -1.42, 4.51, 0.551 } } );
p.reggeon = Trajectory( {
{ 0.838, 2.36, 1.77 },
{ 0.374, 0.998, 0.775 },
{ 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;
p.type = Type::GD07p;
return p;
}
ALLM::Parameters
ALLM::Parameters::gd11p()
{
Parameters p;
p.pomeron = Trajectory( {
{ 0.3638, 0.1211, 1.166 }, // c
{ -0.11895, -0.4783, 1.353 }, // a
{ 1.0833, 2.656, 1.771 } } ); // b
p.reggeon = Trajectory( {
{ 1.3633, 2.256, 2.209 },
{ 0.3425, 1.0603, 0.5164 },
{ -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;
p.type = Type::GD11p;
return p;
}
ALLM::ALLM( const ALLM::Parameters& param ) :
Parameterisation( param.type ), params_( param )
{}
ALLM&
ALLM::operator()( double xbj, double q2 )
{
const double W2_eff = q2*( 1.-xbj )/xbj;
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+params_.q02 )/ params_.lambda2 ), xlog2 = log( params_.q02/params_.lambda2 );
const double t = log( xlog1/xlog2 );
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 = 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 );
F2 = q2/( q2+params_.m02 ) * ( F2_Pom + F2_Reg );
return *this;
}
}
}
diff --git a/CepGen/StructureFunctions/ALLM.h b/CepGen/StructureFunctions/ALLM.h
index 2d5f253..a354c8e 100644
--- a/CepGen/StructureFunctions/ALLM.h
+++ b/CepGen/StructureFunctions/ALLM.h
@@ -1,62 +1,62 @@
#ifndef CepGen_StructureFunctions_ALLM_h
#define CepGen_StructureFunctions_ALLM_h
#include "CepGen/StructureFunctions/StructureFunctions.h"
#include "CepGen/StructureFunctions/SigmaRatio.h"
#include <vector>
-namespace CepGen
+namespace cepgen
{
namespace sf
{
/// \f$F_{2/L}\f$ parameterisation by Abramowicz, Levin, Levy, and Maor \cite Abramowicz:1991xz\cite Abramowicz:1997ms
class ALLM : public Parameterisation
{
public:
class Parameters
{
private:
struct Trajectory {
Trajectory() :
a( { 0., 0., 0. } ), b( { 0., 0., 0. } ), c( { 0., 0., 0. } ) {}
Trajectory( const std::vector<double>& c, const std::vector<double>& a, const std::vector<double>& b ) :
a( a ), b( b ), c( c ) {}
std::vector<double> a, b, c;
};
public:
Parameters() :
m02( 0. ), mp2( 0. ), mr2( 0. ), q02( 0. ), lambda2( 0. ) {}
/// Pre-HERA data fit (694 data points)
static Parameters allm91();
/// Fixed target and HERA photoproduction total cross sections (1356 points)
static Parameters allm97();
static Parameters hht_allm();
static Parameters hht_allm_ft();
static Parameters gd07p();
static Parameters gd11p();
Trajectory 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;
Type type;
};
explicit ALLM( const ALLM::Parameters& param = ALLM::Parameters::allm97() );
ALLM& operator()( double xbj, double q2 ) override;
private:
Parameters params_;
};
}
}
#endif
diff --git a/CepGen/StructureFunctions/BlockDurandHa.cpp b/CepGen/StructureFunctions/BlockDurandHa.cpp
index a9d0f79..eafb78f 100644
--- a/CepGen/StructureFunctions/BlockDurandHa.cpp
+++ b/CepGen/StructureFunctions/BlockDurandHa.cpp
@@ -1,53 +1,53 @@
#include "BlockDurandHa.h"
#include <cmath>
-namespace CepGen
+namespace cepgen
{
namespace sf
{
BlockDurandHa::Parameters
BlockDurandHa::Parameters::standard()
{
Parameters 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;
}
BlockDurandHa::BlockDurandHa( const Parameters& param ) :
Parameterisation( Type::BlockDurandHa ), params_( param )
{}
BlockDurandHa&
BlockDurandHa::operator()( double xbj, double q2 )
{
std::pair<double,double> nv = { xbj, q2 };
if ( nv == old_vals_ )
return *this;
old_vals_ = nv;
if ( q2 <= 0 ) {
F2 = 0.;
return *this;
}
const double tau = q2 / ( q2 + params_.mu2 );
const double xl = log1p( 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 );
F2 = D*pow( 1.-xbj, params_.n ) * ( C + A*xlx + B*xlx*xlx );
return *this;
}
}
}
diff --git a/CepGen/StructureFunctions/BlockDurandHa.h b/CepGen/StructureFunctions/BlockDurandHa.h
index 29e2921..105f31b 100644
--- a/CepGen/StructureFunctions/BlockDurandHa.h
+++ b/CepGen/StructureFunctions/BlockDurandHa.h
@@ -1,37 +1,37 @@
#ifndef CepGen_StructureFunctions_BlockDurandHa_h
#define CepGen_StructureFunctions_BlockDurandHa_h
#include "CepGen/StructureFunctions/StructureFunctions.h"
#include <array>
-namespace CepGen
+namespace cepgen
{
namespace sf
{
/// \f$F_2\f$ parameterisation from Block, Durand, and Ha \cite Block:2014kza
class BlockDurandHa : public Parameterisation
{
public:
struct Parameters
{
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 Parameters standard();
};
explicit BlockDurandHa( const Parameters& params = Parameters::standard() );
BlockDurandHa& operator()( double xbj, double q2 ) override;
private:
Parameters params_;
};
}
}
#endif
diff --git a/CepGen/StructureFunctions/CLAS.cpp b/CepGen/StructureFunctions/CLAS.cpp
index fb448d5..78d546e 100644
--- a/CepGen/StructureFunctions/CLAS.cpp
+++ b/CepGen/StructureFunctions/CLAS.cpp
@@ -1,220 +1,220 @@
#include "CepGen/StructureFunctions/CLAS.h"
#include "CepGen/Physics/PDG.h"
#include "CepGen/Physics/Constants.h"
#include "CepGen/Event/Particle.h"
#include "CepGen/Core/Exception.h"
-namespace CepGen
+namespace cepgen
{
namespace sf
{
CLAS::Parameters
CLAS::Parameters::standard_proton()
{
Parameters params;
params.mode = Parameters::proton;
params.mp = mp_;
- params.mpi0 = part::mass( PDG::piZero );
+ params.mpi0 = particleproperties::mass( PDG::piZero );
// SLAC fit parameters
params.c_slac = { { 0.25615, 2.1785, 0.89784, -6.7162, 3.7557, 1.6421, 0.37636 } };
// CLAS parameterisation
params.x = { { -0.599937, 4.76158, 0.411676 } };
params.b = { { 0.755311, 3.35065, 3.51024, 1.74470 } };
params.alpha = -0.174985;
params.beta = 0.00967019;
params.mu = -0.0352567;
params.mup = 3.51852;
Parameters::Resonance r0;
r0.amplitude = 1.04;
r0.mass = 1.22991;
r0.width = 0.106254;
r0.angular_momentum = 1;
params.resonances.emplace_back( r0 );
Parameters::Resonance r1;
r1.amplitude = 0.481327;
r1.mass = 1.51015;
r1.width = 0.0816620;
r1.angular_momentum = 2;
params.resonances.emplace_back( r1 );
Parameters::Resonance r2;
r2.amplitude = 0.655872;
r2.mass = 1.71762;
r2.width = 0.125520;
r2.angular_momentum = 3;
params.resonances.emplace_back( r2 );
Parameters::Resonance r3;
r3.amplitude = 0.747338;
r3.mass = 1.95381;
r3.width = 0.198915;
r3.angular_momentum = 2;
params.resonances.emplace_back( r3 );
return params;
}
CLAS::Parameters
CLAS::Parameters::standard_neutron()
{
Parameters params = standard_proton();
params.mode = Parameters::neutron;
params.c_slac = { { 0.0640, 0.2250, 4.1060, -7.0790, 3.0550, 1.6421, 0.37636 } };
return params;
}
CLAS::Parameters
CLAS::Parameters::standard_deuteron()
{
Parameters params = standard_proton();
params.mode = Parameters::deuteron;
params.c_slac = { { 0.47709, 2.1602, 3.6274, -10.470, 4.9272, 1.5121, 0.35115 } };
params.x = { { -0.21262, 6.9690, 0.40314 } };
params.b = { { 0.76111, 4.1470, 3.7119, 1.4218 } };
params.alpha = -0.24480;
params.beta = 0.014503;
params.resonances.clear();
Parameters::Resonance r0;
r0.amplitude = 0.74847;
r0.mass = 1.2400;
r0.width = 0.12115;
r0.angular_momentum = 1;
params.resonances.emplace_back( r0 );
Parameters::Resonance r1;
r1.amplitude = 0.011500;
r1.mass = 1.4772;
r1.width = 0.0069580;
r1.angular_momentum = 2;
params.resonances.emplace_back( r1 );
Parameters::Resonance r2;
r2.amplitude = 0.12662;
r2.mass = 1.5233;
r2.width = 0.084095;
r2.angular_momentum = 3;
params.resonances.emplace_back( r2 );
Parameters::Resonance r3;
r3.amplitude = 0.747338;
r3.mass = 1.95381;
r3.width = 0.198915;
r3.angular_momentum = 2;
params.resonances.emplace_back( r3 );
return params;
}
CLAS::CLAS( const Parameters& params ) :
Parameterisation( Type::CLAS ), params_( params )
{}
CLAS&
CLAS::operator()( double xbj, double q2 )
{
std::pair<double,double> nv = { xbj, q2 };
if ( nv == old_vals_ )
return *this;
old_vals_ = nv;
const double mp2 = params_.mp*params_.mp;
const double w2 = mp2 + q2*( 1.-xbj )/xbj;
const double w_min = params_.mp+params_.mpi0;
if ( sqrt( w2 ) < w_min ) {
F2 = 0.;
return *this;
}
F2 = f2slac( xbj, q2 );
std::pair<double,double> rb = resbkg( q2, sqrt( w2 ) );
F2 *= ( rb.first+rb.second );
return *this;
}
double
CLAS::f2slac( double xbj, double q2 ) const
{
if ( xbj >= 1. )
return 0.;
const double xsxb = ( q2+params_.c_slac[6] )/( q2+params_.c_slac[5]*xbj );
const double xs = xbj*xsxb;
double f2 = 0.;
for ( unsigned short i = 0; i < 5; ++i )
f2 += params_.c_slac[i]*pow( 1.-xs, i );
if ( params_.mode == Parameters::deuteron && xbj > 0. )
f2 /= ( 1.-exp( -7.70*( 1./xbj-1.+params_.mp*params_.mp/q2 ) ) );
return f2 * pow( 1.-xs, 3 ) / xsxb;
}
std::pair<double,double>
CLAS::resbkg( double q2, double w ) const
{
const double mp2 = params_.mp*params_.mp, mpi02 = params_.mpi0*params_.mpi0;
const double coef = 6.08974;
double wth = params_.mp+params_.mpi0;
if ( w < wth )
return std::make_pair( 0., 0. );
if ( w > 4. )
return std::make_pair( 1., 0. );
const double w2 = w*w;
double qs = pow( w2+mp2-mpi02, 2 )-4.*mp2*w2;
if ( qs <= 0. ) return std::make_pair( 1., 0. );
qs = 0.5 * sqrt( qs )/w;
const double omega = 0.5*( w2+q2-mp2 )/params_.mp;
const double xn = 0.5*q2/( params_.mp*omega );
const double bkg2 = ( w > params_.b[3] )
? exp( -params_.b[2]*( w2-params_.b[3]*params_.b[3] ) )
: 1.;
double f2bkg = ( params_.b[0] )*( 1.-exp( -params_.b[1]*( w-wth ) ) )
+ ( 1.-params_.b[0] )*( 1.-bkg2 );
f2bkg *= ( 1.+( 1.-f2bkg )*( params_.x[0]+params_.x[1]*pow( xn-params_.x[2], 2 ) ) );
double etab = 1., etad = 1.;
if ( params_.mode != Parameters::deuteron && q2 <= 2. && w <= 2.5 ) {
etab = 1.-2.5*q2*exp( -12.5*q2*q2-50.*( w-1.325 )*( w-1.325 ) );
etad = 1.+2.5*q2*exp( -12.5*q2*q2 );
}
f2bkg *= etab;
double f2resn = 0.;
for ( unsigned short i = 0; i < params_.resonances.size(); ++i ) {
const Parameters::Resonance& res = params_.resonances[i];
const double ai = ( i == 0 )
? etad * ( res.amplitude + q2*std::min( 0., params_.alpha+params_.beta*q2 ) )
: res.amplitude;
const double dmi = ( i == 2 )
? res.mass * ( 1.+params_.mu/( 1.+params_.mup*q2 ) )
: res.mass;
double qs0 = pow( dmi*dmi+mp2-mpi02, 2 )-4.*mp2*dmi*dmi;
if ( qs0 <= 0. )
break;
qs0 = 0.5*sqrt( qs0 )/dmi;
int ji = 2*res.angular_momentum;
const double dg = 0.5*res.width*pow( qs/qs0, ji+1 )*( 1.+pow( coef*qs0, ji ) )/( 1.+pow( coef*qs, ji ) );
f2resn += ai*dg/( ( w-dmi )*( w-dmi )+dg*dg );
}
f2resn *= 0.5*( 1.-params_.b[0] )*bkg2/params_.mp*M_1_PI;
return std::make_pair( f2bkg, f2resn );
}
}
}
diff --git a/CepGen/StructureFunctions/CLAS.h b/CepGen/StructureFunctions/CLAS.h
index ea89aae..2d58e38 100644
--- a/CepGen/StructureFunctions/CLAS.h
+++ b/CepGen/StructureFunctions/CLAS.h
@@ -1,69 +1,69 @@
#ifndef CepGen_StructureFunctions_CLAS_h
#define CepGen_StructureFunctions_CLAS_h
#include "CepGen/StructureFunctions/StructureFunctions.h"
#include <array>
#include <vector>
-namespace CepGen
+namespace cepgen
{
namespace sf
{
/// \brief CLAS parameterisation for nucleon data at \f$Q^2\f$ > 0.5 GeV\f${}^2\f$ and \f$x_{\rm Bj}\f$ > 0.15
/// \note This code was provided on 2016-04-13 by Silvano Simula and reflects the parameterisation used in \cite Osipenko:2003bu (CLAS) and described in \cite Ricco:1998yr.
class CLAS : public Parameterisation
{
public:
/// List of steering parameters for a physics case
struct Parameters
{
/// Standard parameterisation of a parton-from-neutron emission
static Parameters standard_neutron();
/// Standard parameterisation of a parton-from-proton emission
static Parameters standard_proton();
/// Standard parameterisation of a parton-from-deuteron emission
static Parameters standard_deuteron();
/// Physical properties associated to a resonance
struct Resonance
{
double amplitude, mass, width;
short angular_momentum;
};
enum { neutron = 0, proton = 1, deuteron = 2 } mode; ///< Nucleon type
double mp; ///< Proton mass
double mpi0; ///< Neutral pion mass
// SLAC fit parameters
std::array<double,7> c_slac;
// CLAS parameterisation
double alpha, beta, mu, mup;
std::array<double,3> x;
std::array<double,4> b;
std::vector<Resonance> resonances;
std::array<unsigned short,4> lr;
};
/// Standard parameterisation interpolator constructor (photon from proton)
explicit CLAS( const Parameters& params = Parameters::standard_proton() );
CLAS& operator()( double xbj, double q2 ) override;
private:
/// \brief Method to evaluate the background/resonance terms of
/// the modulating function for the nucleon
/// \note SLAC parameterisation
std::pair<double,double> resbkg( double q2, double w ) const;
/// \brief Method to evaluate the deep inelastic structure function
/// \f$F_{2}^{N}\f$ using the SLAC parameterisation
/// \param[in] q2 squared four-momentum transfer in GeV\f${}^2\f$
/// \param[in] xbj Bjorken scaling variable
/// \return \f$F_{2}^{N}\f$
double f2slac( double xbj, double q2 ) const;
Parameters params_;
};
}
}
#endif
diff --git a/CepGen/StructureFunctions/ChristyBosted.cpp b/CepGen/StructureFunctions/ChristyBosted.cpp
index 264b6f4..2c330f0 100644
--- a/CepGen/StructureFunctions/ChristyBosted.cpp
+++ b/CepGen/StructureFunctions/ChristyBosted.cpp
@@ -1,284 +1,284 @@
#include "CepGen/StructureFunctions/ChristyBosted.h"
#include "CepGen/Physics/PDG.h"
#include "CepGen/Event/Particle.h"
#include "CepGen/Core/Exception.h"
-namespace CepGen
+namespace cepgen
{
namespace sf
{
ChristyBosted::ChristyBosted( const Parameters& params ) :
Parameterisation( Type::ChristyBosted ), params_( params )
{}
double
ChristyBosted::resmod507( char sf, double w2, double q2 ) const
{
- const double mpi = part::mass( PDG::piZero ), mpi2 = mpi*mpi,
- meta = part::mass( PDG::eta ), meta2 = meta*meta;
+ const double mpi = particleproperties::mass( PDG::piZero ), mpi2 = mpi*mpi,
+ meta = particleproperties::mass( PDG::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 {
CG_ERROR( "ChristyBosted" ) << "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 Parameters::Resonance& 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;
//--- 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] );
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 Parameters::Resonance& 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;
//--- non-resonant background calculation
const double xpr = 1./( 1.+( w2-pow( mp_+mpi, 2 ) )/( q2+q20 ) );
if ( xpr > 1. ) return 0.; // FIXME
double sig_nr = 0.;
if ( sf == 'T' ) { // transverse
const double wdif = w - ( mp_ + mpi );
if ( wdif >= 0. ) {
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::Parameters
ChristyBosted::Parameters::standard()
{
Parameters params;
params.m0 = 4.2802;
params.continuum.transverse = { {
Continuum::Direction( 246.06, { { 0.067469, 1.3501, 0.12054, -0.0038495 } } ),
Continuum::Direction( -89.360, { { 0.20977, 1.5715, 0.090736, 0.010362 } } )
} };
params.continuum.longitudinal = { {
Continuum::Direction( 86.746, { { 0., 4.0294, 3.1285, 0.33403, 4.9623 } } )
} };
{ //--- P33(1232)
Resonance p33;
p33.br = Resonance::BR( 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)
Resonance s11_1535;
s11_1535.br = Resonance::BR( 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)
Resonance d13;
d13.br = Resonance::BR( 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)
Resonance f15;
f15.br = Resonance::BR( 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)
Resonance s11_1650;
s11_1650.br = Resonance::BR( 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
Resonance p11;
p11.br = Resonance::BR( 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)
Resonance f37;
f37.br = Resonance::BR( 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;
}
double
ChristyBosted::Parameters::Resonance::kr() const
{
return 0.5 * ( mass*mass-mp2_ ) / mp_;
}
double
ChristyBosted::Parameters::Resonance::ecmr( double m2 ) const
{
if ( mass == 0. ) return 0.;
return 0.5 * ( mass*mass+m2-mp2_ ) / mass;
}
ChristyBosted&
ChristyBosted::operator()( double xbj, double q2 )
{
std::pair<double,double> nv = { xbj, q2 };
if ( nv == old_vals_ )
return *this;
old_vals_ = nv;
const double w2 = mp2_ + q2*( 1.-xbj )/xbj;
- const double w_min = mp_+part::mass( PDG::piZero );
+ const double w_min = mp_+particleproperties::mass( PDG::piZero );
if ( sqrt( w2 ) < w_min ) {
F2 = 0.;
return *this;
}
//-----------------------------
// 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 );
const double sigL = resmod507( 'L', w2_eff, q2_eff );
F2 = prefac * q2_eff / ( 1+tau ) * ( sigT+sigL ) / constants::GeV2toBarn * 1.e6;
if ( q2 > q20 )
F2 *= q21/( q21 + delq2 );
if ( sigT != 0. )
Parameterisation::computeFL( q2_eff, xbj, sigL/sigT );
return *this;
}
}
}
diff --git a/CepGen/StructureFunctions/ChristyBosted.h b/CepGen/StructureFunctions/ChristyBosted.h
index 71ed675..582b0f8 100644
--- a/CepGen/StructureFunctions/ChristyBosted.h
+++ b/CepGen/StructureFunctions/ChristyBosted.h
@@ -1,85 +1,85 @@
#ifndef CepGen_StructureFunctions_ChristyBosted_h
#define CepGen_StructureFunctions_ChristyBosted_h
#include "CepGen/StructureFunctions/StructureFunctions.h"
#include "CepGen/Physics/Constants.h"
#include <array>
#include <vector>
-namespace CepGen
+namespace cepgen
{
namespace sf
{
/// \f$F_{2/L}\f$ parameterisation by Christy and Bosted \cite Bosted:2007xd
class ChristyBosted : public Parameterisation
{
public:
struct Parameters
{
static Parameters standard();
struct Resonance
{
/// Branching ratios container for resonance decay into single, double pion or eta states
struct BR
{
BR() : singlepi( 0. ), doublepi( 0. ), eta( 0. ) {}
BR( 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;
};
Resonance() : angular_momentum( 0. ), x0( 0. ), mass( 0. ), width( 0. ), A0_T( 0. ), A0_L( 0. ) {}
double kr() const;
double ecmr( double m2 ) const;
double kcmr() const { return ecmr( 0. ); }
double pcmr( double m2 ) const { return sqrt( std::max( 0., ecmr( m2 )*ecmr( m2 )-m2 ) ); }
BR 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 Continuum
{
struct Direction
{
Direction() : sig0( 0. ) {}
Direction( double sig0, const std::vector<double>& params ) : sig0( sig0 ), fit_parameters( params ) {}
double sig0;
std::vector<double> fit_parameters;
};
std::array<Direction,2> transverse;
std::array<Direction,1> longitudinal;
};
double m0;
std::vector<Resonance> resonances;
Continuum continuum;
};
explicit ChristyBosted( const Parameters& params = Parameters::standard() );
ChristyBosted& operator()( double xbj, double q2 ) override;
//--- already computed internally during F2 computation
void computeFL( double xbj, double q2, const sr::Parameterisation& ) override {}
void computeFL( double xbj, double q2, double r ) override {}
private:
double resmod507( char sf, double w2, double q2 ) const;
Parameters params_;
};
}
}
#endif
diff --git a/CepGen/StructureFunctions/FioreBrasse.cpp b/CepGen/StructureFunctions/FioreBrasse.cpp
index 937a0b5..625f1d9 100644
--- a/CepGen/StructureFunctions/FioreBrasse.cpp
+++ b/CepGen/StructureFunctions/FioreBrasse.cpp
@@ -1,97 +1,97 @@
#include "CepGen/StructureFunctions/FioreBrasse.h"
#include "CepGen/Core/Exception.h"
#include "CepGen/Core/utils.h"
#include "CepGen/Physics/PDG.h"
#include "CepGen/Physics/ParticleProperties.h"
#include "CepGen/Physics/Constants.h"
#include <complex>
-namespace CepGen
+namespace cepgen
{
namespace sf
{
FioreBrasse::Parameters
FioreBrasse::Parameters::standard()
{
Parameters p;
p.s0 = 1.14;
p.norm = 0.021;
p.resonances.emplace_back( Resonance{ -0.8377, 0.95, 0.1473, 1.0, 2.4617, 3./2. } ); // N*(1520)
p.resonances.emplace_back( Resonance{ -0.37, 0.95, 0.1471, 0.5399, 2.4617, 5./2. } ); // N*(1680)
p.resonances.emplace_back( Resonance{ 0.0038, 0.85, 0.1969, 4.2225, 1.5722, 3./2. } ); // Δ(1236)
p.resonances.emplace_back( Resonance{ 0.5645, 0.1126, 1.3086, 19.2694, 4.5259, 1. } ); // exotic
return p;
}
FioreBrasse::Parameters
FioreBrasse::Parameters::alternative()
{
Parameters p;
p.s0 = 1.2871;
p.norm = 0.0207;
p.resonances.emplace_back( Resonance{ -0.8070, 0.9632, 0.1387, 1.0, 2.6066, 3./2. } ); // N*(1520)
p.resonances.emplace_back( Resonance{ -0.3640, 0.9531, 0.1239, 0.6086, 2.6066, 5./2. } ); // N*(1680)
p.resonances.emplace_back( Resonance{ -0.0065, 0.8355, 0.2320, 4.7279, 1.4828, 3./2. } ); // Δ(1236)
p.resonances.emplace_back( Resonance{ 0.5484, 0.1373, 1.3139, 14.7267, 4.6041, 1. } ); // exotic
return p;
}
FioreBrasse::FioreBrasse( const Parameters& params ) :
Parameterisation( Type::FioreBrasse ), params( params )
{}
FioreBrasse&
FioreBrasse::operator()( double xbj, double q2 )
{
std::pair<double,double> nv = { xbj, q2 };
if ( nv == old_vals_ )
return *this;
old_vals_ = nv;
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_;
double ampli_res = 0., ampli_bg = 0., ampli_tot = 0.;
for ( unsigned short i = 0; i < 3; ++i ) { //FIXME 4??
const Parameters::Resonance& res = params.resonances[i];
const double sqrts0 = sqrt( params.s0 );
std::complex<double> alpha;
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( 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 Parameters::Resonance& 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 );
ampli_bg = res.a*formfactor*formfactor*std::imag( alpha )/denom;
}
ampli_tot = params.norm*( ampli_res+ampli_bg );
CG_DEBUG_LOOP( "FioreBrasse:amplitudes" )
<< "Amplitudes:\n\t"
<< " resonance part: " << ampli_res << ",\n\t"
<< " background part: " << ampli_bg << ",\n\t"
<< " total (with norm.): " << ampli_tot << ".";
F2 = prefactor*ampli_tot;
return *this;
}
}
}
diff --git a/CepGen/StructureFunctions/FioreBrasse.h b/CepGen/StructureFunctions/FioreBrasse.h
index 29e6d30..0c97854 100644
--- a/CepGen/StructureFunctions/FioreBrasse.h
+++ b/CepGen/StructureFunctions/FioreBrasse.h
@@ -1,38 +1,38 @@
#ifndef CepGen_StructureFunctions_FioreBrasse_h
#define CepGen_StructureFunctions_FioreBrasse_h
#include "CepGen/StructureFunctions/StructureFunctions.h"
#include <vector>
-namespace CepGen
+namespace cepgen
{
namespace sf
{
///\f${\cal W}_{1,2}\f$ structure functions parameterisation by Fiore et al \cite Fiore:2002re and Brasse et al \cite Brasse:1976bf
class FioreBrasse : public Parameterisation
{
public:
/// General parameters for this modelling
struct Parameters
{
static Parameters standard();
static Parameters alternative();
/// Description of a single resonance in the modelling
struct Resonance {
double alpha0, alpha1, alpha2, a, q02;
float spin;
};
/// All resonances considered in this modelling
std::vector<Resonance> resonances;
double s0, norm;
};
/// Fiore \cite Fiore:2002re and Brasse \cite Brasse:1976bf proton structure functions
explicit FioreBrasse( const Parameters& params = Parameters::standard() );
FioreBrasse& operator()( double xbj, double q2 ) override;
Parameters params;
};
}
}
#endif
diff --git a/CepGen/StructureFunctions/LHAPDF.cpp b/CepGen/StructureFunctions/LHAPDF.cpp
index 9290963..f52fd86 100644
--- a/CepGen/StructureFunctions/LHAPDF.cpp
+++ b/CepGen/StructureFunctions/LHAPDF.cpp
@@ -1,159 +1,159 @@
#include "CepGen/StructureFunctions/LHAPDF.h"
#include "CepGen/Core/Exception.h"
#include "CepGen/Core/utils.h"
-namespace CepGen
+namespace cepgen
{
namespace sf
{
constexpr std::array<short,6> LHAPDF::qtimes3_, LHAPDF::pdgid_;
LHAPDF::Parameters::Parameters() :
num_flavours( 4 ), pdf_set( "cteq6" ), pdf_code( 0l ), pdf_member( 0 ), mode( Mode::full )
{}
LHAPDF::LHAPDF( const Parameters& param ) :
Parameterisation( Type::LHAPDF ), params( param ), initialised_( false )
{}
LHAPDF::LHAPDF( const char* set, unsigned short member, const Parameters::Mode& mode ) :
Parameterisation( Type::LHAPDF ), initialised_( false )
{
params.pdf_set = set;
params.pdf_member = member;
params.mode = mode;
}
std::string
LHAPDF::description() const
{
std::ostringstream os;
os << "LHAPDF{" << params.pdf_set << ",m=" << params.pdf_member << ",mode=" << params.mode << "}";
return os.str();
}
void
LHAPDF::initialise()
{
if ( initialised_ )
return;
#ifdef LIBLHAPDF
std::string lhapdf_version, pdf_description, pdf_type;
# if defined LHAPDF_MAJOR_VERSION && LHAPDF_MAJOR_VERSION == 6
try {
//--- check if PDF code is set
if ( params.pdf_code != 0l ) {
auto pdf = ::LHAPDF::lookupPDF( params.pdf_code );
if ( pdf.second != 0 )
throw CG_FATAL( "LHAPDF" ) << "Failed to retrieve PDFset with id=" << params.pdf_code << "!";
if ( !params.pdf_set.empty() && params.pdf_set != pdf.first )
CG_WARNING( "LHAPDF" ) << "PDF set name changed from \"" << params.pdf_set << "\" to \"" << pdf.first << "\".";
params.pdf_set = pdf.first;
}
pdf_set_ = ::LHAPDF::PDFSet( params.pdf_set );
pdf_set_.mkPDFs<std::unique_ptr<::LHAPDF::PDF> >( pdfs_ );
lhapdf_version = ::LHAPDF::version();
pdf_description = pdf_set_.description();
pdf_type = pdfs_[params.pdf_member]->type();
} catch ( const ::LHAPDF::Exception& e ) {
throw CG_FATAL( "LHAPDF" )
<< "Caught LHAPDF exception:\n\t"
<< e.what();
}
# else
if ( params.pdf_code != 0l )
::LHAPDF::initPDFSet( (int)params.pdf_code, params.pdf_member );
else
::LHAPDF::initPDFSet( params.pdf_set, ::LHAPDF::LHGRID, params.pdf_member );
lhapdf_version = ::LHAPDF::getVersion();
pdf_description = ::LHAPDF::getDescription();
# endif
replace_all( pdf_description, ". ", ".\n " );
CG_INFO( "LHAPDF" ) << "LHAPDF structure functions evaluator successfully built.\n"
<< " * LHAPDF version: " << lhapdf_version << "\n"
<< " * number of flavours: " << params.num_flavours << "\n"
<< " * PDF set: " << params.pdf_set << "\n"
<< ( pdf_description.empty() ? "" : " "+pdf_description+"\n" )
<< " * PDF member: " << params.pdf_member << ( pdf_type.empty() ? "" : " ("+pdf_type+")" ) << "\n"
<< " * quarks mode: " << params.mode;
initialised_ = true;
#else
throw CG_FATAL( "LHAPDF" ) << "LHAPDF is not liked to this instance!";
#endif
}
LHAPDF&
LHAPDF::operator()( double xbj, double q2 )
{
#ifdef LIBLHAPDF
std::pair<double,double> nv = { xbj, q2 };
if ( nv == old_vals_ )
return *this;
old_vals_ = nv;
F2 = 0.;
if ( params.num_flavours == 0 || params.num_flavours > 6 )
return *this;
if ( !initialised_ )
initialise();
# if defined LHAPDF_MAJOR_VERSION && LHAPDF_MAJOR_VERSION >= 6
auto& member = *pdfs_[params.pdf_member];
if ( !member.inPhysicalRangeXQ2( xbj, q2 ) ) {
CG_WARNING( "LHAPDF" ) << "(x=" << xbj << ", Q²=" << q2 << " GeV²) "
<< "not in physical range for PDF member " << params.pdf_member << ":\n\t"
<< " min: (x=" << member.xMin() << ", Q²=" << member.q2Min() << "),\n\t"
<< " max: (x=" << member.xMax() << ", Q²=" << member.q2Max() << ").";
return *this;
}
# else
if ( q2 < ::LHAPDF::getQ2min( params.pdf_member ) || q2 > ::LHAPDF::getQ2max( params.pdf_member )
|| xbj < ::LHAPDF::getXmin( params.pdf_member ) || xbj > ::LHAPDF::getXmax( params.pdf_member ) ) {
CG_WARNING( "LHAPDF" ) << "(x=" << xbj << "/Q²=" << q2 << " GeV²) "
<< "not in physical range for PDF member " << params.pdf_member << ":\n"
<< " min: (x=" << ::LHAPDF::getXmin( params.pdf_member ) << "/Q²=" << ::LHAPDF::getQ2min( params.pdf_member ) << "),\n"
<< " max: (x=" << ::LHAPDF::getXmax( params.pdf_member ) << "/Q²=" << ::LHAPDF::getQ2max( params.pdf_member ) << ").";
return *this;
}
const double q = sqrt( q2 );
# endif
for ( int i = 0; i < params.num_flavours; ++i ) {
const double prefactor = 1./9.*qtimes3_[i]*qtimes3_[i];
# if defined LHAPDF_MAJOR_VERSION && LHAPDF_MAJOR_VERSION >= 6
if ( !pdfs_[params.pdf_member]->hasFlavor( pdgid_[i] ) )
throw CG_FATAL( "LHAPDF" ) << "Flavour " << pdgid_[i] << " is unsupported!";
const double xq = member.xfxQ2( pdgid_[i], xbj, q2 );
const double xqbar = member.xfxQ2( -pdgid_[i], xbj, q2 );
# else
const double xq = ::LHAPDF::xfx( xbj, q, pdgid_[i] );
const double xqbar = ::LHAPDF::xfx( xbj, q, -pdgid_[i] );
# endif
switch ( params.mode ) {
case Parameters::Mode::full:
F2 += prefactor*( xq+xqbar ); break;
case Parameters::Mode::valence:
F2 += prefactor*( xq-xqbar ); break;
case Parameters::Mode::sea:
F2 += prefactor*( 2.*xqbar ); break;
}
}
#else
throw CG_FATAL( "LHAPDF" ) << "LHAPDF is not liked to this instance!";
#endif
return *this;
}
}
std::ostream&
operator<<( std::ostream& os, const sf::LHAPDF::Parameters::Mode& mode )
{
switch ( mode ) {
case sf::LHAPDF::Parameters::Mode::full: return os << "all quarks";
case sf::LHAPDF::Parameters::Mode::valence: return os << "valence quarks";
case sf::LHAPDF::Parameters::Mode::sea: return os << "sea quarks";
}
return os;
}
}
diff --git a/CepGen/StructureFunctions/LHAPDF.h b/CepGen/StructureFunctions/LHAPDF.h
index be71ac1..f430d20 100644
--- a/CepGen/StructureFunctions/LHAPDF.h
+++ b/CepGen/StructureFunctions/LHAPDF.h
@@ -1,68 +1,68 @@
#ifndef CepGen_StructureFunctions_LHAPDF_h
#define CepGen_StructureFunctions_LHAPDF_h
#include "CepGen/StructureFunctions/StructureFunctions.h"
#ifdef LIBLHAPDF
#include "LHAPDF/LHAPDF.h"
#endif
#include <array>
-namespace CepGen
+namespace cepgen
{
namespace sf
{
/// Generic partonic level perturbative structure functions built from an external PDFs grid
class LHAPDF : public Parameterisation
{
public:
/// Model parameterisation
struct Parameters
{
/// Standard (usual CTEQ6) constructor
Parameters();
/// Number of quark flavours considered in the SF building
unsigned short num_flavours;
/// String-type PDF identifier (default)
std::string pdf_set;
/// Integer-type PDF identifier (if no string version is provided)
unsigned long pdf_code;
/// PDF set used
unsigned short pdf_member;
/// Quarks types
enum class Mode { full = 0, valence = 1, sea = 2 };
/// Quarks types considered in the SF building
Mode mode;
};
/// Build a calculator from its Parameters object
explicit LHAPDF( const Parameters& param = Parameters() );
/// Build a calculator from a set, its member, and the contributing quarks
explicit LHAPDF( const char* set, unsigned short member = 0, const Parameters::Mode& mode = Parameters::Mode::full );
LHAPDF& operator()( double xbj, double q2 ) override;
/// Parameterisation used in this SFs calculator
Parameters params;
private:
std::string description() const override;
void initialise();
bool initialised_;
#ifdef LIBLHAPDF
# if defined LHAPDF_MAJOR_VERSION && LHAPDF_MAJOR_VERSION >= 6
::LHAPDF::PDFSet pdf_set_;
std::vector<std::unique_ptr<::LHAPDF::PDF> > pdfs_;
# endif
#endif
static constexpr std::array<short,6> pdgid_ = { { 1, 2, 3, 4, 5, 6 } };
static constexpr std::array<short,6> qtimes3_ = { {
-1 /*d*/, 2 /*u*/,
-1 /*s*/, 2 /*c*/,
-1 /*b*/, 2 /*t*/
} };
};
}
std::ostream& operator<<( std::ostream& os, const sf::LHAPDF::Parameters::Mode& mode );
}
#endif
diff --git a/CepGen/StructureFunctions/MSTWGrid.cpp b/CepGen/StructureFunctions/MSTWGrid.cpp
index 29e50c0..5a256df 100644
--- a/CepGen/StructureFunctions/MSTWGrid.cpp
+++ b/CepGen/StructureFunctions/MSTWGrid.cpp
@@ -1,115 +1,115 @@
#include "CepGen/StructureFunctions/MSTWGrid.h"
#include "CepGen/Core/Exception.h"
#include "CepGen/Core/utils.h"
#include "CepGen/StructureFunctions/StructureFunctions.h"
#include <fstream>
namespace mstw
{
const unsigned int Grid::good_magic = 0x5754534d; // MSTW in ASCII
Grid&
Grid::get( const char* filename )
{
Parameters p;
p.grid_path = filename;
static Grid instance( p );
return instance;
}
Grid::Grid( const Parameters& param ) :
- CepGen::sf::Parameterisation( CepGen::sf::Type::MSTWgrid ),
- CepGen::GridHandler<2,2>( CepGen::GridType::logarithmic ),
+ cepgen::sf::Parameterisation( cepgen::sf::Type::MSTWgrid ),
+ cepgen::GridHandler<2,2>( cepgen::GridType::logarithmic ),
params( param )
{
{ // file readout part
std::ifstream file( params.grid_path, std::ios::binary | std::ios::in );
if ( !file.is_open() )
throw CG_FATAL( "Grid" ) << "Impossible to load grid file \"" << params.grid_path << "\"!";
file.read( reinterpret_cast<char*>( &header_ ), sizeof( header_t ) );
// first checks on the file header
if ( header_.magic != good_magic )
throw CG_FATAL( "Grid" ) << "Wrong magic number retrieved: " << header_.magic << ", expecting " << good_magic << ".";
if ( header_.nucleon != header_t::proton )
throw CG_FATAL( "Grid" ) << "Only proton structure function grids can be retrieved for this purpose!";
// retrieve all points and evaluate grid boundaries
sfval_t val;
while ( file.read( reinterpret_cast<char*>( &val ), sizeof( sfval_t ) ) )
insert( { val.xbj, val.q2 }, { val.f2, val.fl } );
file.close();
}
init();
const auto& bounds = boundaries();
CG_INFO( "Grid" )
<< "MSTW@" << header_.order << " grid evaluator built "
<< "for " << header_.nucleon << " structure functions (" << header_.cl << ")\n\t"
<< "xBj in range [" << pow( 10., bounds[0].first ) << ":" << pow( 10., bounds[0].second ) << "]\n\t"
<< " Q² in range [" << pow( 10., bounds[1].first ) << ":" << pow( 10., bounds[1].second ) << "].";
}
std::string
Grid::description() const
{
std::ostringstream os;
const auto& bounds = boundaries();
os << "MSTW grid{"
<< pow( 10., bounds[0].first ) << "<xbj<" << pow( 10., bounds[0].second ) << ","
<< pow( 10., bounds[1].first ) << "<Q²/GeV²<" << pow( 10., bounds[1].second ) << "}";
return os.str();
}
Grid&
Grid::operator()( double xbj, double q2 )
{
- const std::array<double,2> val = CepGen::GridHandler<2,2>::eval( { xbj, q2 } );
+ const std::array<double,2> val = cepgen::GridHandler<2,2>::eval( { xbj, q2 } );
F2 = val[0];
FL = val[1];
return *this;
}
std::ostream&
operator<<( std::ostream& os, const Grid::sfval_t& val )
{
- return os << CepGen::Form( "xbj = %.4f\tQ² = %.5e GeV²\tF₂ = % .6e\tFL = % .6e", val.xbj, val.q2, val.f2, val.fl );
+ return os << cepgen::Form( "xbj = %.4f\tQ² = %.5e GeV²\tF₂ = % .6e\tFL = % .6e", val.xbj, val.q2, val.f2, val.fl );
}
std::ostream&
operator<<( std::ostream& os, const Grid::header_t::order_t& order )
{
switch ( order ) {
case Grid::header_t::lo: return os << "LO";
case Grid::header_t::nlo: return os << "nLO";
case Grid::header_t::nnlo: return os << "nnLO";
}
return os;
}
std::ostream&
operator<<( std::ostream& os, const Grid::header_t::cl_t& cl )
{
switch ( cl ) {
case Grid::header_t::cl68: return os << "68% C.L.";
case Grid::header_t::cl95: return os << "95% C.L.";
}
return os;
}
std::ostream&
operator<<( std::ostream& os, const Grid::header_t::nucleon_t& nucl )
{
switch ( nucl ) {
case Grid::header_t::proton: return os << "proton";
case Grid::header_t::neutron: return os << "neutron";
}
return os;
}
}
diff --git a/CepGen/StructureFunctions/MSTWGrid.h b/CepGen/StructureFunctions/MSTWGrid.h
index fb4d6ab..c43dd4d 100644
--- a/CepGen/StructureFunctions/MSTWGrid.h
+++ b/CepGen/StructureFunctions/MSTWGrid.h
@@ -1,81 +1,81 @@
#ifndef CepGen_StructureFunctions_MSTWGrid_h
#define CepGen_StructureFunctions_MSTWGrid_h
#include "CepGen/IO/GridHandler.h"
#include "CepGen/StructureFunctions/StructureFunctions.h"
#define DEFAULT_MSTW_GRID_PATH "External/mstw_sf_scan_nnlo.dat"
/// Martin-Stirling-Thorne-Watt PDFs structure functions
namespace mstw
{
/// A \f$F_{2,L}\f$ grid interpolator
- class Grid : public CepGen::sf::Parameterisation, private CepGen::GridHandler<2,2>
+ class Grid : public cepgen::sf::Parameterisation, private cepgen::GridHandler<2,2>
{
public:
/// Grid header information as parsed from the file
struct header_t
{
/// Interpolation order
enum order_t : unsigned short { lo = 0, nlo = 1, nnlo = 2 };
/// Confidence level
enum cl_t : unsigned short { cl68 = 0, cl95 = 1 };
/// Type of nucleon interpolated
enum nucleon_t : unsigned short { proton = 1, neutron = 2 };
unsigned int magic; ///< Grid file magic number
order_t order; ///< Interpolation order
cl_t cl; ///< Confidence level
nucleon_t nucleon; ///< Type of nucleon interpolated
};
/// Structure functions value at a given \f$Q^2/x_{\rm Bj}\f$ coordinate
struct sfval_t
{
float q2; ///< four-momentum transfer, in GeV\f${}^2\f$
float xbj; ///< Bjorken's scaling variable
double f2; ///< Transverse structure function value
double fl; ///< Longitudinal structure function value
};
/// List of parameters for this grid definition
struct Parameters {
Parameters() : grid_path( DEFAULT_MSTW_GRID_PATH ) {}
/// Location of the grid to be interpolated
std::string grid_path;
};
public:
/// Retrieve the grid interpolator (singleton)
static Grid& get( const char* path = DEFAULT_MSTW_GRID_PATH );
/// Compute the structure functions at a given \f$Q^2/x_{\rm Bj}\f$
Grid& operator()( double xbj, double q2 ) override;
/// Retrieve the grid's header information
header_t header() const { return header_; }
/// Grid parameterisation object
Parameters params;
//--- already retrieved from grid, so no need to recompute it
- void computeFL( double xbj, double q2, const CepGen::sr::Parameterisation& ) override {}
+ void computeFL( double xbj, double q2, const cepgen::sr::Parameterisation& ) override {}
void computeFL( double xbj, double q2, double r ) override {}
public:
Grid( const Grid& ) = delete;
void operator=( const GridHandler& ) = delete;
private:
explicit Grid( const Parameters& = Parameters() );
std::string description() const override;
static const unsigned int good_magic;
static std::shared_ptr<Grid> singl_;
header_t header_;
};
std::ostream& operator<<( std::ostream&, const Grid::sfval_t& ); ///< Human-readable description of a values point
std::ostream& operator<<( std::ostream&, const Grid::header_t::order_t& ); ///< Human-readable description of an interpolation order
std::ostream& operator<<( std::ostream&, const Grid::header_t::cl_t& ); ///< Human-readable description of a confidence level
std::ostream& operator<<( std::ostream&, const Grid::header_t::nucleon_t& ); ///< Human-readable description of a nucleon type
}
#undef DEFAULT_MSTW_GRID_PATH
#endif
diff --git a/CepGen/StructureFunctions/Schaefer.cpp b/CepGen/StructureFunctions/Schaefer.cpp
index bc85b42..d61a7d8 100644
--- a/CepGen/StructureFunctions/Schaefer.cpp
+++ b/CepGen/StructureFunctions/Schaefer.cpp
@@ -1,150 +1,150 @@
#include "CepGen/StructureFunctions/Schaefer.h"
#include "CepGen/StructureFunctions/LHAPDF.h"
#include "CepGen/Core/Exception.h"
#include "CepGen/Physics/Constants.h"
#include "CepGen/Physics/ParticleProperties.h"
-namespace CepGen
+namespace cepgen
{
namespace sf
{
Schaefer::Parameters
Schaefer::Parameters::mstwGrid()
{
Parameters par;
par.q2_cut = 9.;
par.w2_hi = 4.;
par.w2_lo = 3.;
par.resonances_model = Parameterisation::build( Type::ChristyBosted );
par.perturbative_model = Parameterisation::build( Type::MSTWgrid );
par.continuum_model = Parameterisation::build( Type::GD11p );
par.higher_twist = 0;
return par;
}
Schaefer::Parameters
Schaefer::Parameters::mstwParton()
{
Parameters par;
par.q2_cut = 9.;
par.w2_hi = 4.;
par.w2_lo = 3.;
par.resonances_model = Parameterisation::build( Type::ChristyBosted );
par.perturbative_model = std::make_shared<sf::LHAPDF>( "MSTW2008nnlo90cl" );
par.continuum_model = Parameterisation::build( Type::GD11p );
par.higher_twist = 1;
return par;
}
Schaefer::Parameters
Schaefer::Parameters::cteq()
{
Parameters par;
par.q2_cut = 9.;
par.w2_hi = 4.;
par.w2_lo = 3.;
par.resonances_model = Parameterisation::build( Type::ChristyBosted );
par.perturbative_model = std::make_shared<sf::LHAPDF>( "cteq6l1" );
par.continuum_model = Parameterisation::build( sf::Type::GD11p );
par.higher_twist = 0;
return par;
}
Schaefer::Schaefer( const Parameters& params ) :
Parameterisation( Type::Schaefer ),
params( params ), initialised_( false ), inv_omega_range_( -1. )
{}
std::string
Schaefer::description() const
{
std::ostringstream os;
os << "LUXlike{"
<< "r=" << *params.resonances_model << ","
<< "p=" << *params.perturbative_model << ","
<< "c=" << *params.continuum_model;
if ( params.higher_twist )
os << ",HT";
os << "}";
return os.str();
}
void
Schaefer::initialise()
{
CG_INFO( "LUXlike" ) << "LUXlike structure functions evaluator successfully initialised.\n"
<< " * Q² cut: " << params.q2_cut << " GeV²\n"
<< " * W² ranges: " << params.w2_lo << " GeV² / " << params.w2_hi << " GeV²\n"
<< " * resonance model: " << *params.resonances_model << "\n"
<< " * perturbative model: " << *params.perturbative_model << "\n"
<< " * continuum model: " << *params.continuum_model << "\n"
<< " * higher-twist? " << std::boolalpha << params.higher_twist;
inv_omega_range_ = 1./( params.w2_hi-params.w2_lo );
initialised_ = true;
}
Schaefer&
Schaefer::operator()( double xbj, double q2 )
{
if ( !initialised_ )
initialise();
std::pair<double,double> nv = { xbj, q2 };
if ( nv == old_vals_ )
return *this;
old_vals_ = nv;
const double w2 = mp2_+q2*( 1.-xbj )/xbj;
sf::Parameterisation sel_sf;
if ( q2 < params.q2_cut ) {
if ( w2 < params.w2_lo )
sel_sf = ( *params.resonances_model )( xbj, q2 );
else if ( w2 < params.w2_hi ) {
auto sf_r = ( *params.resonances_model )( xbj, q2 );
auto sf_c = ( *params.continuum_model )( xbj, q2 );
sf_r.computeFL( xbj, q2 );
sf_c.computeFL( xbj, q2 );
const double r = rho( w2 );
F2 = r*sf_c.F2 + ( 1.-r )*sf_r.F2;
FL = r*sf_c.FL + ( 1.-r )*sf_r.FL;
return *this;
}
else
sel_sf = ( *params.continuum_model )( xbj, q2 );
}
else {
if ( w2 < params.w2_hi )
sel_sf = ( *params.continuum_model )( xbj, q2 );
else {
auto sf_p = ( *params.perturbative_model )( xbj, q2 );
F2 = sf_p.F2;
sf_p.computeFL( xbj, q2 );
FL = sel_sf.FL;
if ( params.higher_twist )
F2 *= ( 1.+5.5/q2 );
return *this;
}
}
F2 = sel_sf( xbj, q2 ).F2;
sel_sf.computeFL( xbj, q2 );
FL = sel_sf.FL;
return *this;
}
double
Schaefer::rho( double w2 ) const
{
if ( inv_omega_range_ <= 0. )
throw CG_FATAL( "LUXlike" ) << "Invalid W² limits: "
<< params.w2_lo << " / " << params.w2_hi << " GeV²!";
const double omega = ( w2-params.w2_lo )*inv_omega_range_;
const double omega2 = omega*omega;
return 2.*omega2-omega*omega;
}
}
}
diff --git a/CepGen/StructureFunctions/Schaefer.h b/CepGen/StructureFunctions/Schaefer.h
index f45aac0..3b8fe89 100644
--- a/CepGen/StructureFunctions/Schaefer.h
+++ b/CepGen/StructureFunctions/Schaefer.h
@@ -1,44 +1,44 @@
#ifndef CepGen_StructureFunctions_Schaefer_h
#define CepGen_StructureFunctions_Schaefer_h
#include "CepGen/StructureFunctions/StructureFunctions.h"
#include <memory>
-namespace CepGen
+namespace cepgen
{
namespace sf
{
/// LUX-like hybrid modelling of \f$F_{2/L}\f$ structure functions
class Schaefer : public Parameterisation
{
public:
/// Standard parameterisation for this SF set
struct Parameters
{
static Parameters mstwGrid(); ///< "Standard" parameterisation with MSTW grid NNLO perturbative model
static Parameters mstwParton(); ///< "Standard" parameterisation with partonic MSTW perturbative model
static Parameters cteq(); ///< "Standard" parameterisation with partonic CTEQ perturbative model
double q2_cut; ///< Transition \f$Q^2\f$ before reaching the continuum/perturbative regions
double w2_lo; ///< Transition \f$W^2\f$ between resonances and hybrid continuum/resonances low-\f$Q^2\f$ regions
double w2_hi; ///< Transition \f$W^2\f$ between hybrid continuum/resonances and continuum low-\f$Q^2\f$ regions, or continuum and perturbative high-\f$Q^2\f$ regions
std::shared_ptr<Parameterisation> resonances_model; ///< Resonances-dominated region (low-\f$Q^2/W^2\f$) modelling
std::shared_ptr<Parameterisation> perturbative_model; ///< Perturbative region (high-\f$Q^2/W^2\f$) modelling
std::shared_ptr<Parameterisation> continuum_model; ///< Continuum regions modelling
bool higher_twist; ///< Enable/disable the HT correction
};
Schaefer( const Parameters& param = Parameters::mstwGrid() );
Schaefer& operator()( double xbj, double q2 ) override;
Parameters params;
private:
std::string description() const override;
double rho( double w2 ) const;
void initialise();
bool initialised_;
double inv_omega_range_;
};
}
}
#endif
diff --git a/CepGen/StructureFunctions/SigmaRatio.cpp b/CepGen/StructureFunctions/SigmaRatio.cpp
index ec4aa98..5694b83 100644
--- a/CepGen/StructureFunctions/SigmaRatio.cpp
+++ b/CepGen/StructureFunctions/SigmaRatio.cpp
@@ -1,104 +1,104 @@
#include "CepGen/StructureFunctions/SigmaRatio.h"
#include "CepGen/Physics/PDG.h"
#include "CepGen/Physics/ParticleProperties.h"
#include <math.h>
#include <iostream>
-namespace CepGen
+namespace cepgen
{
namespace sr
{
- const double Parameterisation::mp_ = part::mass( PDG::proton );
+ const double Parameterisation::mp_ = particleproperties::mass( PDG::proton );
const double Parameterisation::mp2_ = Parameterisation::mp_*Parameterisation::mp_;
double
Parameterisation::theta( double xbj, double q2 ) const
{
return 1.+12.*( q2/( q2+1. ) )*( 0.125*0.125/( 0.125*0.125+xbj*xbj ) );
}
E143::Parameters
E143::Parameters::standard()
{
Parameters out;
out.q2_b = 0.34;
out.lambda2 = 0.2*0.2;
out.a = { { 0.0485, 0.5470, 2.0621, -0.3804, 0.5090, -0.0285 } };
out.b = { { 0.0481, 0.6114, -0.3509, -0.4611, 0.7172, -0.0317 } };
out.c = { { 0.0577, 0.4644, 1.8288, 12.3708, -43.1043, 41.7415 } };
return out;
}
E143::E143( const Parameters& param ) :
params_( param )
{}
double
E143::operator()( double xbj, double q2, double& err ) const
{
const double u = q2/params_.q2_b;
const double inv_xl = 1./log( q2/params_.lambda2 );
const double pa = ( 1.+params_.a[3]*xbj+params_.a[4]*xbj*xbj )*pow( xbj, params_.a[5] );
const double pb = ( 1.+params_.b[3]*xbj+params_.b[4]*xbj*xbj )*pow( xbj, params_.b[5] );
const double th = theta( xbj, q2 );
const double q2_thr = params_.c[3]*xbj + params_.c[4]*xbj*xbj+params_.c[5]*xbj*xbj*xbj;
// here come the three fits
const double ra = params_.a[0]*inv_xl*th + params_.a[1]/pow( pow( q2, 4 )+pow( params_.a[2], 4 ), 0.25 )*pa,
rb = params_.b[0]*inv_xl*th + ( params_.b[1]/q2+params_.b[2]/( q2*q2+0.3*0.3 ) )*pb,
rc = params_.c[0]*inv_xl*th + params_.c[1]*pow( pow( q2-q2_thr, 2 )+pow( params_.c[2], 2 ), -0.5 );
const double r = ( ra+rb+rc ) / 3.; // R is set to be the average of the three fits
// numerical safety for low-Q²
err = 0.0078-0.013*xbj+( 0.070-0.39*xbj+0.70*xbj*xbj )/( 1.7+q2 );
if ( q2 > params_.q2_b )
return r;
return r * 0.5 * ( 3.*u-u*u*u );
}
R1990::Parameters
R1990::Parameters::standard()
{
Parameters out;
out.lambda2 = 0.2*0.2;
out.b = { { 0.0635, 0.5747, -0.3534 } };
return out;
}
R1990::R1990( const Parameters& param ) :
params_( param )
{}
double
R1990::operator()( double xbj, double q2, double& err ) const
{
err = 0.;
return ( params_.b[0]+theta( xbj, q2 )/log( q2/params_.lambda2 )
+ params_.b[1]/q2
+ params_.b[2]/( q2*q2+0.09 ) );
}
double
CLAS::operator()( double xbj, double q2, double& err ) const
{
// 2 kinematic regions:
// - resonances ( w < 2.5 )
// - DIS ( w > 2.5 )
const double w2 = mp2_ + q2*( 1.-xbj )/xbj, w = sqrt( w2 );
const double xth = q2/( q2+2.5*2.5-mp2_ ); // xth = x( W = 2.5 GeV )
const double zeta = log( 25.*q2 );
const double xitmp = ( w < 2.5 ) ? theta( xth, q2 ) : theta( xbj, q2 );
const double tmp = 0.041*xitmp/zeta + 0.592/q2 - 0.331/( 0.09+q2*q2 );
if ( w < 2.5 )
return tmp * pow( ( 1.-xbj )/( 1.-xth ), 3 );
return tmp;
}
double
SibirtsevBlunden::operator()( double xbj, double q2, double& err ) const
{
err = 0.;
return 0.014*q2*( exp( -0.07*q2 )+41.*exp( -0.8*q2 ) );
}
}
}
diff --git a/CepGen/StructureFunctions/SigmaRatio.h b/CepGen/StructureFunctions/SigmaRatio.h
index 8c272c6..c7811e5 100644
--- a/CepGen/StructureFunctions/SigmaRatio.h
+++ b/CepGen/StructureFunctions/SigmaRatio.h
@@ -1,80 +1,80 @@
#ifndef CepGen_StructureFunctions_SigmaRatio_h
#define CepGen_StructureFunctions_SigmaRatio_h
#include <array>
-namespace CepGen
+namespace cepgen
{
/// A collector namespace for modellings of the \f$R=\sigma_L/\sigma_T\f$ ratio
namespace sr
{
/// A generic modelling of the \f$R=\sigma_L/\sigma_T\f$ ratio
class Parameterisation
{
public:
Parameterisation() {}
/// Extract the longitudinal/transverse cross section ratio and associated error for a given \f$(x_{\rm Bj},Q^2)\f$ couple.
virtual double operator()( double xbj, double q2, double& err ) const = 0;
protected:
/// \f$x_{\rm Bj}\f$ dependence for QCD-matching of R at high-\f$Q^2\f$
double theta( double xbj, double q2 ) const;
static const double mp_; ///< Proton mass, in GeV/c\f${}^2\f$
static const double mp2_; ///< Squared proton mass, in GeV\f${}^2\f$/c\f${}^4\f$
};
/// E143 experimental R measurement \cite Abe:1998ym
class E143 : public Parameterisation
{
public:
struct Parameters
{
double q2_b, lambda2;
std::array<double,6> a, b, c;
static Parameters standard();
};
explicit E143( const Parameters& param = Parameters::standard() );
double operator()( double xbj, double q2, double& err ) const override;
private:
Parameters params_;
};
/** \brief SLAC experimental R measurement \cite Whitlow:1990gk
* \warning valid for \f$Q^2\f$ > 0.3 GeV\f${}^2\f$
*/
class R1990: public Parameterisation
{
public:
struct Parameters
{
double lambda2;
std::array<double,3> b;
static Parameters standard();
};
explicit R1990( const Parameters& param = Parameters::standard() );
double operator()( double xbj, double q2, double& err ) const override;
private:
Parameters params_;
};
/// CLAS experimental R measurement
class CLAS : public Parameterisation
{
public:
CLAS() {}
double operator()( double xbj, double q2, double& err ) const override;
};
/// Sibirtsev & Blunden parameterisation of the R ratio \cite Sibirtsev:2013cga
class SibirtsevBlunden : public Parameterisation
{
public:
SibirtsevBlunden() {}
double operator()( double xbj, double q2, double& err ) const override;
};
}
}
#endif
diff --git a/CepGen/StructureFunctions/StructureFunctions.cpp b/CepGen/StructureFunctions/StructureFunctions.cpp
index 5152df0..eacc14e 100644
--- a/CepGen/StructureFunctions/StructureFunctions.cpp
+++ b/CepGen/StructureFunctions/StructureFunctions.cpp
@@ -1,90 +1,90 @@
#include "CepGen/StructureFunctions/StructureFunctions.h"
#include "CepGen/Physics/PDG.h"
#include "CepGen/Physics/ParticleProperties.h"
#include "CepGen/Core/Exception.h"
#include "CepGen/Core/utils.h"
#include <iostream>
-namespace CepGen
+namespace cepgen
{
namespace sf
{
- const double Parameterisation::mp_ = part::mass( PDG::proton );
+ const double Parameterisation::mp_ = particleproperties::mass( PDG::proton );
const double Parameterisation::mp2_ = Parameterisation::mp_*Parameterisation::mp_;
double
Parameterisation::F1( double xbj, double q2 ) const
{
if ( xbj == 0. || q2 == 0. ) {
CG_ERROR( "StructureFunctions:F1" )
<< "Invalid range for Q² = " << q2 << " or xBj = " << xbj << ".";
return 0.;
}
const double F1 = 0.5*( ( 1+4.*xbj*xbj*mp2_/q2 )*F2 - FL )/xbj;
CG_DEBUG_LOOP( "StructureFunctions:F1" )
<< "F1 for Q² = " << q2 << ", xBj = " << xbj << ": " << F1 << "\n\t"
<< "(F2 = " << F2 << ", FL = " << FL << ").";
return F1;
}
void
Parameterisation::computeFL( double xbj, double q2, const sr::Parameterisation& ratio )
{
double r_error = 0.;
computeFL( xbj, q2, ratio( xbj, q2, r_error ) );
}
void
Parameterisation::computeFL( double xbj, double q2, double r )
{
const double tau = 4.*xbj*xbj*mp2_/q2;
FL = F2 * ( 1.+tau ) * ( r/( 1.+r ) );
}
std::string
Parameterisation::description() const
{
std::ostringstream os;
os << type;
return os.str();
}
std::ostream&
operator<<( std::ostream& os, const Parameterisation& sf )
{
os << sf.description();
if ( sf.old_vals_ != std::pair<double,double>() )
os << " at (" << sf.old_vals_.first << ", " << sf.old_vals_.second << "): "
<< "F2 = " << sf.F2 << ", FL = " << sf.FL;
return os;
}
}
/// Human-readable format of a structure function type
std::ostream&
operator<<( std::ostream& os, const sf::Type& sf )
{
switch ( sf ) {
case sf::Type::Invalid: return os << "[INVALID]";
case sf::Type::Electron: return os << "electron";
case sf::Type::ElasticProton: return os << "elastic proton";
case sf::Type::SuriYennie: return os << "Suri-Yennie";
case sf::Type::SzczurekUleshchenko: return os << "Szczurek-Uleshchenko";
case sf::Type::FioreBrasse: return os << "Fiore-Brasse";
case sf::Type::ChristyBosted: return os << "Christy-Bosted";
case sf::Type::CLAS: return os << "CLAS";
case sf::Type::BlockDurandHa: return os << "BDH";
case sf::Type::ALLM91: return os << "ALLM91";
case sf::Type::ALLM97: return os << "ALLM97";
case sf::Type::GD07p: return os << "GD07p";
case sf::Type::GD11p: return os << "GD11p";
case sf::Type::Schaefer: return os << "LUXlike";
case sf::Type::MSTWgrid: return os << "MSTW (grid)";
case sf::Type::LHAPDF: return os << "LHAPDF";
}
return os;
}
}
diff --git a/CepGen/StructureFunctions/StructureFunctions.h b/CepGen/StructureFunctions/StructureFunctions.h
index 9e07e9d..5677909 100644
--- a/CepGen/StructureFunctions/StructureFunctions.h
+++ b/CepGen/StructureFunctions/StructureFunctions.h
@@ -1,85 +1,85 @@
#ifndef CepGen_StructureFunctions_StructureFunctions_h
#define CepGen_StructureFunctions_StructureFunctions_h
#include "CepGen/StructureFunctions/SigmaRatio.h"
#include <iostream>
#include <memory>
-namespace CepGen
+namespace cepgen
{
/// Structure functions modelling scope
namespace sf
{
/// Proton structure function to be used in the outgoing state description
/// \note Values correspond to the LPAIR legacy steering card values
enum struct Type {
Invalid = 0,
Electron = 1,
ElasticProton = 2,
SuriYennie = 11,
SzczurekUleshchenko = 12,
BlockDurandHa = 13,
FioreBrasse = 101,
ChristyBosted = 102,
CLAS = 103,
ALLM91 = 201,
ALLM97 = 202,
GD07p = 203,
GD11p = 204,
MSTWgrid = 205,
Schaefer = 301,
LHAPDF = 401,
};
/// Generic placeholder for the parameterisation of nucleon structure functions
class Parameterisation
{
public:
/// Copy constructor
Parameterisation( const Parameterisation& sf ) :
type( sf.type ), F2( sf.F2 ), FL( sf.FL ), old_vals_( sf.old_vals_ ) {}
/// Standard SF parameterisation constructor
Parameterisation( const Type& type = Type::Invalid, double f2 = 0., double fl = 0. ) :
type( type ), F2( f2 ), FL( fl ), old_vals_({ 0., 0. }) {}
~Parameterisation() {}
/// Assign from another SF parameterisation object
Parameterisation& operator=( const Parameterisation& sf ) {
type = sf.type, F2 = sf.F2, FL = sf.FL, old_vals_ = sf.old_vals_;
return *this;
}
/// Human-readable description of this SF parameterisation
friend std::ostream& operator<<( std::ostream&, const Parameterisation& );
/// Build a SF parameterisation for a given type
static std::shared_ptr<Parameterisation> build( const Type& );
/// Compute all relevant structure functions for a given \f$(x_{\rm Bj},Q^2)\f$ couple
virtual Parameterisation& operator()( double xbj, double q2 ) { return *this; }
/// Compute the longitudinal structure function for a given point
virtual void computeFL( double xbj, double q2, const sr::Parameterisation& ratio = sr::E143() );
/// Compute the longitudinal structure function for a given point
virtual void computeFL( double xbj, double q2, double r );
/// Compute the \f$F_1\f$ structure function for a given point
double F1( double xbj, double q2 ) const;
/// Interpolation type of structure functions
Type type;
double F2; ///< Last computed transverse structure function value
double FL; ///< Last computed longitudinal structure function value
protected:
virtual std::string description() const; ///< Human-readable description of this SF set
static const double mp_; ///< Proton mass, in GeV/c\f${}^2\f$
static const double mp2_; ///< Squared proton mass, in GeV\f${}^2\f$/c\f${}^4\f$
std::pair<double,double> old_vals_; ///< Last \f$(x_{\rm Bj},Q^2)\f$ couple computed
private:
std::string name_;
};
}
/// Human-readable description of this SF parameterisation type
std::ostream& operator<<( std::ostream&, const sf::Type& );
}
#endif
diff --git a/CepGen/StructureFunctions/StructureFunctionsBuilder.cpp b/CepGen/StructureFunctions/StructureFunctionsBuilder.cpp
index 488717d..bb8c956 100644
--- a/CepGen/StructureFunctions/StructureFunctionsBuilder.cpp
+++ b/CepGen/StructureFunctions/StructureFunctionsBuilder.cpp
@@ -1,41 +1,41 @@
#include "CepGen/StructureFunctions/ALLM.h"
#include "CepGen/StructureFunctions/BlockDurandHa.h"
#include "CepGen/StructureFunctions/FioreBrasse.h"
#include "CepGen/StructureFunctions/ChristyBosted.h"
#include "CepGen/StructureFunctions/CLAS.h"
#include "CepGen/StructureFunctions/LHAPDF.h"
#include "CepGen/StructureFunctions/SuriYennie.h"
#include "CepGen/StructureFunctions/SzczurekUleshchenko.h"
#include "CepGen/StructureFunctions/Schaefer.h"
#include "CepGen/StructureFunctions/MSTWGrid.h"
-namespace CepGen
+namespace cepgen
{
namespace sf
{
std::shared_ptr<Parameterisation>
Parameterisation::build( const Type& sf_type )
{
switch ( sf_type ) {
case Type::Electron:
case Type::ElasticProton:
default: return std::make_shared<Parameterisation>();
case Type::SzczurekUleshchenko: return std::make_shared<SzczurekUleshchenko>();
case Type::SuriYennie: return std::make_shared<SuriYennie>();
case Type::FioreBrasse: return std::make_shared<FioreBrasse>();
case Type::ChristyBosted: return std::make_shared<ChristyBosted>();
case Type::CLAS: return std::make_shared<CLAS>();
case Type::BlockDurandHa: return std::make_shared<BlockDurandHa>();
case Type::ALLM91: return std::make_shared<ALLM>( ALLM::Parameters::allm91() );
case Type::ALLM97: return std::make_shared<ALLM>( ALLM::Parameters::allm97() );
case Type::GD07p: return std::make_shared<ALLM>( ALLM::Parameters::gd07p() );
case Type::GD11p: return std::make_shared<ALLM>( ALLM::Parameters::gd11p() );
case Type::Schaefer: return std::make_shared<Schaefer>();
case Type::LHAPDF: return std::make_shared<sf::LHAPDF>();
//--- particular case for the MSTW grid as we are dealing
//--- with a singleton ; hence, no deleter is needed!
case Type::MSTWgrid: return std::shared_ptr<mstw::Grid>( &mstw::Grid::get(), [=]( mstw::Grid* ){} );
}
}
}
}
diff --git a/CepGen/StructureFunctions/SuriYennie.cpp b/CepGen/StructureFunctions/SuriYennie.cpp
index b49f207..0836cbc 100644
--- a/CepGen/StructureFunctions/SuriYennie.cpp
+++ b/CepGen/StructureFunctions/SuriYennie.cpp
@@ -1,67 +1,67 @@
#include "CepGen/StructureFunctions/SuriYennie.h"
#include "CepGen/Physics/ParticleProperties.h"
#include "CepGen/Core/Exception.h"
#include <math.h>
-namespace CepGen
+namespace cepgen
{
namespace sf
{
SuriYennie::Parameters
SuriYennie::Parameters::standard()
{
Parameters 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;
}
SuriYennie::Parameters
SuriYennie::Parameters::alternative()
{
Parameters 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;
}
SuriYennie::SuriYennie( const Parameters& param ) :
Parameterisation( Type::SuriYennie ),
F1( 0. ), FE( 0. ), FM( 0. ), params_( param )
{}
SuriYennie&
SuriYennie::operator()( double xbj, double q2 )
{
std::pair<double,double> nv = { xbj, q2 };
if ( nv == old_vals_ )
return *this;
old_vals_ = nv;
const double inv_q2 = 1./q2;
const double dm2 = q2*( 1.-xbj )/xbj;
const double mx2 = mp2_ + dm2; // [GeV^2]
const double en = dm2+q2, en2 = en*en; // [GeV^2]
const double nu = 0.5 * en / mp_, Xpr = q2/( q2+mx2 ), tau = 0.25 * q2/mp2_;
const double mq = params_.rho2+q2;
FM = ( params_.C1*dm2*pow( params_.rho2/mq, 2 )
+ ( params_.C2*mp2_*pow( 1.-Xpr, 4 ) ) / ( 1.+Xpr*( Xpr*params_.Cp-2.*params_.Bp ) ) ) * inv_q2;
FE = ( tau*FM + params_.D1*dm2*q2*params_.rho2/mp2_*pow( dm2/mq, 2 )/en2 ) / ( 1.+0.25*en2/mp2_*inv_q2 );
//const double w2 = 2.*mp*FE;
F1 = 0.5*FM*q2/mp_;
F2 = 2.*nu*FE;
return *this;
}
}
}
diff --git a/CepGen/StructureFunctions/SuriYennie.h b/CepGen/StructureFunctions/SuriYennie.h
index 2c70186..b4a9cd0 100644
--- a/CepGen/StructureFunctions/SuriYennie.h
+++ b/CepGen/StructureFunctions/SuriYennie.h
@@ -1,35 +1,35 @@
#ifndef CepGen_StructureFunctions_SuriYennie_h
#define CepGen_StructureFunctions_SuriYennie_h
#include "CepGen/StructureFunctions/StructureFunctions.h"
-namespace CepGen
+namespace cepgen
{
namespace sf
{
/// \f$F_{1/2/E/M}\f$ modelling by Suri and Yennie \cite Suri:1971yx
class SuriYennie : public Parameterisation
{
public:
/// Collection of parameterisation-dependent couplings
struct Parameters {
// values extracted from experimental fits
static Parameters standard();
static Parameters alternative();
double C1, C2, D1, rho2, Cp, Bp;
};
explicit SuriYennie( const Parameters& param = Parameters::standard() );
SuriYennie& operator()( double xbj, double q2 ) override;
double F1;
double FE; ///< Electric proton form factor
double FM; ///< Magnetic proton form factor
private:
Parameters params_;
};
}
}
#endif
diff --git a/CepGen/StructureFunctions/SzczurekUleshchenko.cpp b/CepGen/StructureFunctions/SzczurekUleshchenko.cpp
index 98decf8..e1cbfe7 100644
--- a/CepGen/StructureFunctions/SzczurekUleshchenko.cpp
+++ b/CepGen/StructureFunctions/SzczurekUleshchenko.cpp
@@ -1,50 +1,50 @@
#include "CepGen/StructureFunctions/SzczurekUleshchenko.h"
#include "CepGen/Core/Exception.h"
#include "CepGen/Core/utils.h"
-namespace CepGen
+namespace cepgen
{
namespace sf
{
SzczurekUleshchenko::SzczurekUleshchenko() :
Parameterisation( Type::SzczurekUleshchenko ), F1( 0. )
{}
SzczurekUleshchenko&
SzczurekUleshchenko::operator()( double xbj, double q2 )
{
#ifndef GRVPDF
throw CG_FATAL( "SzczurekUleshchenko" )
<< "Szczurek-Uleshchenko structure functions cannot be computed"
<< " as GRV PDF set is not linked to this instance!";
#else
std::pair<double,double> nv = { xbj, q2 };
if ( nv == old_vals_ )
return *this;
old_vals_ = nv;
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 );
CG_DEBUG_LOOP( "SzczurekUleshchenko" )
<< "Form factor content at xB = " << xbj << " (scale = " << amu2 << " GeV^2):\n\t"
<< " valence quarks: u / d = " << xuv << " / " << xdv << "\n\t"
<< " sea quarks: u / d / s = " << xus << " / " << xds << " / " << xss << "\n\t"
<< " gluons: = " << xg;
// standard partonic structure function
const double F2_aux = 4./9.*( xuv + 2.*xus )
+ 1./9.*( xdv + 2.*xds )
+ 1./9.*( 2.*xss );
F2 = F2_aux * q2 / amu2; // F2 corrected for low Q^2 behaviour
return *this;
#endif
}
}
}
diff --git a/CepGen/StructureFunctions/SzczurekUleshchenko.h b/CepGen/StructureFunctions/SzczurekUleshchenko.h
index 07be8d8..468591c 100644
--- a/CepGen/StructureFunctions/SzczurekUleshchenko.h
+++ b/CepGen/StructureFunctions/SzczurekUleshchenko.h
@@ -1,27 +1,27 @@
#ifndef CepGen_StructureFunctions_SzczurekUleshchenko_h
#define CepGen_StructureFunctions_SzczurekUleshchenko_h
#include "CepGen/StructureFunctions/StructureFunctions.h"
extern "C"
{
extern void grv95lo_( float&, float&, float&, float&, float&, float&, float&, float& );
}
-namespace CepGen
+namespace cepgen
{
namespace sf
{
/// Szcurek and Uleshchenko modelling of \f$F_{1/2}\f$ \cite Szczurek:1999wp
class SzczurekUleshchenko : public Parameterisation
{
public:
SzczurekUleshchenko();
SzczurekUleshchenko& operator()( double xbj, double q2 ) override;
double F1;
};
}
}
#endif
diff --git a/CepGen/Version.h b/CepGen/Version.h
index 64fd762..623afdc 100644
--- a/CepGen/Version.h
+++ b/CepGen/Version.h
@@ -1,18 +1,18 @@
#ifndef CepGen_Version_h
#define CepGen_Version_h
#include <string>
-namespace CepGen
+namespace cepgen
{
/// CepGen version
/// \note Format: 0xMMmmff, with
/// - MM = major version
/// - mm = minor version
/// - ff = feature(s) release
const unsigned int cepgen_version = 0x000900;
/// Human-readable version number
const std::string version();
}
#endif
diff --git a/test/Canvas.h b/test/Canvas.h
index ff8eb65..001718c 100644
--- a/test/Canvas.h
+++ b/test/Canvas.h
@@ -1,320 +1,320 @@
#ifndef Canvas_h
#define Canvas_h
#include "TCanvas.h"
#include "TLegend.h"
#include "TPaveText.h"
#include "TObjArray.h"
#include "TObjString.h"
#include "TH1.h"
#include "TGraphErrors.h"
#include "TStyle.h"
#include <string.h>
#define font_type(x) 130+x
-namespace CepGen
+namespace cepgen
{
class PaveText : public TPaveText
{
public:
inline PaveText( const float& x1, const float& y1, const float& x2, const float& y2, const char* text="" ) :
TPaveText( x1, y1, x2, y2, "NDC" )
{
TPaveText::SetTextAlign( 13 );
if ( strcmp( text, "" )!=0 ) {
TString txt = text;
if ( txt.Contains( "\\" ) ) {
TObjArray* tok = txt.Tokenize( "\\" );
for ( int i=0; i<tok->GetEntries(); i++ ) { TPaveText::AddText( dynamic_cast<TObjString*>( tok->At( i ) )->String() ); }
}
else TPaveText::AddText( text );
}
TPaveText::SetFillColor( 0 );
TPaveText::SetFillStyle( 0 );
TPaveText::SetLineColor( 0 );
TPaveText::SetLineWidth( 0 );
TPaveText::SetShadowColor( 0 );
TPaveText::SetTextFont( font_type( 2 ) );
TPaveText::SetTextSize( 0.058 );
}
};
class Canvas : public TCanvas
{
public:
inline Canvas( const char* name, const char* title="", bool ratio=false ) :
//TCanvas( name, "", 450, 450 ),
TCanvas( name, "", 600, 600 ),
fTitle( title ), fTopLabel( 0 ),
fLeg( 0 ), fLegX1( 0.5 ), fLegY1( 0.75 ),
fRatio( ratio )
{
gStyle->SetOptStat( 0 );
Build();
}
inline ~Canvas() {
if ( fLeg ) delete fLeg;
if ( fTopLabel ) delete fTopLabel;
}
inline void SetSize( const float& size=600 ) {
TCanvas::SetCanvasSize( size, 600 );
}
inline void Prettify( TH1* obj ) {
TAxis* x = dynamic_cast<TAxis*>( obj->GetXaxis() ),
*y = dynamic_cast<TAxis*>( obj->GetYaxis() ),
*z = dynamic_cast<TAxis*>( obj->GetZaxis() );
x->SetLabelFont( font_type( 3 ) ); x->SetLabelSize( 20 );
x->SetTitleFont( font_type( 3 ) ); x->SetTitleSize( 29 );
y->SetLabelFont( font_type( 3 ) ); y->SetLabelSize( 20 );
y->SetTitleFont( font_type( 3 ) ); y->SetTitleSize( 29 );
z->SetLabelFont( font_type( 3 ) ); z->SetLabelSize( 16 );
z->SetTitleFont( font_type( 3 ) ); z->SetTitleSize( 29 );
if ( fRatio ) {
x->SetTitleOffset( 3. );
x->SetLabelOffset( 0.02 );
}
y->SetTitleOffset( 1.3 );
x->SetTickLength( 0.03 );
y->SetTickLength( 0.03 );
// axis titles
TString ttle = obj->GetTitle();
if ( ttle.Contains( "\\" ) ) {
TObjArray* tok = ttle.Tokenize( "\\" );
TString x_title = "", y_title = "", unit = "", form_spec = "", distrib = "";
if ( tok->GetEntries()>0 ) x_title = dynamic_cast<TObjString*>( tok->At( 0 ) )->String();
if ( tok->GetEntries()>1 ) y_title = dynamic_cast<TObjString*>( tok->At( 1 ) )->String();
if ( tok->GetEntries()>2 ) {
unit = ( ( TObjString* )tok->At( 2 ) )->String();
if ( unit.Contains( "?" ) ) { // extract format specifier
TObjArray* tok2 = unit.Tokenize( "?" );
if ( tok2->GetEntries()>1 ) {
unit = dynamic_cast<TObjString*>( tok2->At( 0 ) )->String();
form_spec = dynamic_cast<TObjString*>( tok2->At( 1 ) )->String();
}
else {
unit = "";
form_spec = dynamic_cast<TObjString*>( tok2->At( 0 ) )->String();
}
}
}
if ( tok->GetEntries()>3 ) {
distrib = ( ( TObjString* )tok->At( 3 ) )->String();
}
if ( !unit.IsNull() or !form_spec.IsNull() ) {
if ( !unit.IsNull() ) x_title = ::Form( "%s (%s)", x_title.Data(), unit.Data() );
if ( !distrib.IsNull() ) {
if ( !form_spec.IsNull() ) {
TString format = ::Form( "%%s (%s / %%%s %%s)", distrib.Data(), form_spec.Data() );
y_title = ::Form( format.Data(), y_title.Data(), GetBinning( obj ), unit.Data() );
}
else y_title = ::Form( "%s (%s / %d %s)", y_title.Data(), distrib.Data(), static_cast<unsigned int>( GetBinning( obj ) ), unit.Data() );
}
else {
if ( !form_spec.IsNull() ) {
TString format = ::Form( "%%s / %%%s %%s", form_spec.Data() );
y_title = ::Form( format.Data(), y_title.Data(), GetBinning( obj ), unit.Data() );
}
else y_title = ::Form( "%s / %d %s", y_title.Data(), static_cast<unsigned int>( GetBinning( obj ) ), unit.Data() );
}
}
obj->GetXaxis()->SetTitle( x_title );
obj->GetYaxis()->SetTitle( y_title );
obj->SetTitle( "" );
}
//else obj->GetXaxis()->SetTitle(ttle);
}
inline void DrawDiagonal(const TH1* obj) {
TLine l;
l.SetLineWidth( 2 );
l.SetLineColor( kGray );
l.SetLineStyle( 2 );
l.DrawLine( obj->GetXaxis()->GetXmin(), obj->GetYaxis()->GetXmin(), obj->GetXaxis()->GetXmax(), obj->GetYaxis()->GetXmax() );
}
inline void RatioPlot(TH1* obj1, const TH1* obj2, const TH1* obj3, float ymin=-999., float ymax=-999.) {
if (!fRatio) return;
TH1* ratio1 = (TH1*)obj2->Clone(), *ratio2 = (TH1*)obj3->Clone();
//ratio1->Sumw2(); ratio2->Sumw2();
ratio1->Divide(obj1);
ratio2->Divide(obj1);
TCanvas::cd(2);
ratio1->Draw("p");
ratio2->Draw("p same");
obj1->GetXaxis()->SetTitle("");
if ( ymin!=ymax ) {
ratio1->GetYaxis()->SetRangeUser(ymin, ymax);
}
Prettify(ratio1);
TCanvas::cd();
}
inline TH1* RatioPlot( TH1* obj1, const TH1* obj2=0, float ymin=-999., float ymax=-999., const char* plot_type = "p" ) {
if ( !fRatio )
return obj1;
TH1* ratio;
if ( obj2 ) {
ratio = dynamic_cast<TH1*>( obj2->Clone() );
ratio->Divide( obj1 );
}
else
ratio = dynamic_cast<TH1*>( obj1->Clone() );
TCanvas::cd( 2 );
ratio->Draw( plot_type );
obj1->GetXaxis()->SetTitle( "" );
if ( ymin != ymax )
ratio->GetYaxis()->SetRangeUser( ymin, ymax );
Prettify( ratio );
ratio->GetYaxis()->SetTitle( "Ratio" );
TCanvas::cd();
return ratio;
}
inline TGraphErrors* RatioPlot(TGraphErrors* obj1, const TGraphErrors* obj2, float ymin=-999., float ymax=-999.) {
if (!fRatio) return 0;
TGraphErrors* ratio = new TGraphErrors;
ratio->SetTitle( obj1->GetTitle() );
unsigned int n = 0;
float min_x = 9.e10, max_x = -9.e10;
for ( int i=0; i<obj1->GetN(); i++ ) {
const float x1 = obj1->GetX()[i];
for ( int j=0; j<obj2->GetN(); j++ ) {
const float x2 = obj2->GetX()[j];
if (x2>max_x) max_x = x2;
if (x2<min_x) min_x = x2;
if ( fabs( x2-x1 )>1.e-3 ) continue;
const float y1 = obj1->GetY()[i], y1_err = obj1->GetEY()[i],
y2 = obj2->GetY()[j], y2_err = obj2->GetEY()[j];
const float y = (y2-y1)/y1,
err_y = sqrt( pow( y1_err/y1, 2 )+pow( y2_err/y2, 2 )*y2/y1 );
ratio->SetPoint( n, x1, y );
ratio->SetPointError( n, 0., err_y );
n++;
}
}
TCanvas::cd(2);
ratio->Draw("ap");
ratio->GetXaxis()->SetRangeUser( obj1->GetXaxis()->GetXmin(), obj1->GetXaxis()->GetXmax() );
ratio->SetMarkerStyle( 20 );
if ( ymin!=ymax ) {
ratio->GetYaxis()->SetRangeUser(ymin, ymax);
}
ratio->GetXaxis()->SetLimits(min_x, max_x);
Prettify( ratio->GetHistogram() );
obj1->GetXaxis()->SetTitle("");
TLine l( min_x, 0., max_x, 0. );
l.Draw();
ratio->GetYaxis()->SetLabelSize( 14 );
TCanvas::cd();
return ratio;
}
inline void SetTopLabel(const char* lab="") {
TCanvas::cd();
if (strcmp(lab, "")!=0) fTitle = lab;
if (!fTopLabel) BuildTopLabel();
else fTopLabel->Clear();
fTopLabel->AddText(fTitle);
//fTopLabel->Draw();
}
inline void SetLegendX1(double x) { fLegX1 = x; }
inline void SetLegendY1(double y) { fLegY1 = y; }
inline void AddLegendEntry(const TObject* obj, const char* title, Option_t* option="lpf") {
if (!fLeg) BuildLeg();
fLeg->AddEntry(obj, title, option);
const unsigned int num_entries = fLeg->GetNRows();
if ( num_entries>3 ) {
fLeg->SetY1( fLeg->GetY1()-( num_entries-3 )*0.015 );
}
}
inline void Save(const char* ext, const char* out_dir=".") {
if (strstr(ext, "pdf")==NULL)
if (strstr(ext, "eps")==NULL)
if (strstr(ext, "png")==NULL)
if (strstr(ext, "root")==NULL)
return;
TCanvas::cd();
if ( fLeg ) fLeg->Draw();
if ( fTopLabel ) fTopLabel->Draw();
TCanvas::SaveAs( ::Form( "%s/%s.%s", out_dir, TCanvas::GetName(), ext ) );
}
inline TLegend* GetLegend() { return fLeg; }
private:
inline void Build() {
TCanvas::SetLeftMargin(0.14);
TCanvas::SetTopMargin(0.06);
TCanvas::SetRightMargin(0.1);
TCanvas::SetBottomMargin(0.12);
TCanvas::SetTicks(1,1);
SetTopLabel();
if (fRatio) DivideCanvas();
}
inline void DivideCanvas() {
TCanvas::Divide(1,2);
TPad* p1 = (TPad*)TCanvas::GetPad(1), *p2 = (TPad*)TCanvas::GetPad(2);
p1->SetPad(0., 0.3, 1., 1.);
p2->SetPad(0., 0.0, 1., 0.3);
p1->SetLeftMargin(TCanvas::GetLeftMargin());
p1->SetRightMargin(TCanvas::GetRightMargin());
p2->SetLeftMargin(TCanvas::GetLeftMargin());
p2->SetRightMargin(TCanvas::GetRightMargin());
p1->SetTopMargin(TCanvas::GetTopMargin()+0.025);
p1->SetBottomMargin(0.02);
p2->SetTopMargin(0.02);
p2->SetBottomMargin(TCanvas::GetBottomMargin()+0.25);
p1->SetTicks(1,1); p2->SetTicks(1,1);
p2->SetGrid(0,1);
TCanvas::cd(1);
}
inline void BuildTopLabel() {
TCanvas::cd();
fTopLabel = new TPaveText(0.5, 0.95, 0.915, 0.96, "NB NDC");
fTopLabel->SetFillStyle(0);
fTopLabel->SetFillColor(0);
fTopLabel->SetLineColor(0);
fTopLabel->SetLineStyle(0);
fTopLabel->SetTextFont( font_type( 2 ) );
fTopLabel->SetTextSize(0.04);
fTopLabel->SetTextAlign(kHAlignRight+kVAlignBottom);
}
inline void BuildLeg() {
if ( fLeg ) return;
if ( fRatio ) TCanvas::cd(1);
fLeg = new TLegend(fLegX1, fLegY1, fLegX1+0.3, fLegY1+0.15);
fLeg->SetLineColor(kWhite);
fLeg->SetLineWidth(0);
fLeg->SetFillStyle(0);
fLeg->SetTextFont( font_type( 2 ) );
fLeg->SetTextSize(0.04);
}
inline float GetBinning(const TH1* h) {
return (h->GetXaxis()->GetXmax()-h->GetXaxis()->GetXmin())/h->GetXaxis()->GetNbins();
}
TString fTitle;
TPaveText* fTopLabel;
TLegend* fLeg;
double fLegX1, fLegY1;
bool fRatio;
};
}
#endif
diff --git a/test/TestProcess.h b/test/TestProcess.h
index a4be21a..c965048 100644
--- a/test/TestProcess.h
+++ b/test/TestProcess.h
@@ -1,43 +1,43 @@
#ifndef CepGen_Processes_TestProcess_h
#define CepGen_Processes_TestProcess_h
#include "CepGen/Processes/GenericProcess.h"
#include "CepGen/Core/Functional.h"
-namespace CepGen
+namespace cepgen
{
namespace process
{
/// Generic process to test the Vegas instance
template<size_t N>
class TestProcess : public GenericProcess
{
public:
TestProcess() :
GenericProcess( "test", ".oO TEST PROCESS Oo.", false ),
funct_( "1./(1.-cos(x*_pi)*cos(y*_pi)*cos(z*_pi))", { { "x", "y", "z" } } ) {}
TestProcess( const char* formula, std::array<std::string,N> args ) :
GenericProcess( "test", Form( ".oO TEST PROCESS (%s) Oo.", formula ), false ),
funct_( formula, args ) {}
ProcessPtr clone() const override { return ProcessPtr( new TestProcess<N>( *this ) ); }
void addEventContent() override {}
/// Number of dimensions on which to perform the integration
unsigned int numDimensions() const override { return N; }
/// Generic formula to compute a weight out of a point in the phase space
double computeWeight() override {
std::array<double,N> args;
std::copy_n( x_.begin(), N, args.begin() );
return funct_.eval( args );
}
/// Dummy function to be called on events generation
void fillKinematics( bool ) override { return; }
private:
Functional<N> funct_;
};
}
}
#endif
diff --git a/test/abort.h b/test/abort.h
index 5270b9e..5895bd8 100644
--- a/test/abort.h
+++ b/test/abort.h
@@ -1,55 +1,55 @@
#ifndef CepGen_Tests_abort_h
#define CepGen_Tests_abort_h
#include "CepGen/Core/Exception.h"
#include "CepGen/Core/utils.h"
#include <csignal>
-namespace CepGen
+namespace cepgen
{
extern volatile int gSignal;
/// Exception raised when the user terminates the process
struct RunAbortedException : Exception
{
using Exception::Exception;
~RunAbortedException() override {}
};
}
/// Object handling an user-driven process abortion
class AbortHandler
{
public:
AbortHandler( int flags = SA_SIGINFO ) {
action_.sa_sigaction = handle_ctrl_c;
sigemptyset( &action_.sa_mask );
action_.sa_flags = flags;
init();
}
/// Switch on/off multithreading capabilities
void setMT( bool mt_on = true ) {
if ( mt_on )
action_.sa_sigaction = handle_ctrl_c_mt;
else
action_.sa_sigaction = handle_ctrl_c;
init();
}
private:
static void handle_ctrl_c_mt( int signal, siginfo_t*, void* ) {
- CepGen::gSignal = signal;
+ cepgen::gSignal = signal;
}
static void handle_ctrl_c( int signal, siginfo_t*, void* ) {
- CepGen::gSignal = signal;
- throw CepGen::RunAbortedException( __PRETTY_FUNCTION__, CepGen::Exception::Type::info )
+ cepgen::gSignal = signal;
+ throw cepgen::RunAbortedException( __PRETTY_FUNCTION__, cepgen::Exception::Type::info )
<< "Run aborted.";
}
void init() {
if ( sigaction( SIGINT, &action_, nullptr ) != 0
|| sigaction( SIGTERM, &action_, nullptr ) != 0 )
throw CG_FATAL( "AbortHandler" ) << "Failed to initialise the C-c handler!";
}
struct sigaction action_;
};
#endif
diff --git a/test/cepgen-ascii.cpp b/test/cepgen-ascii.cpp
index 11d48fa..0dbb0ad 100644
--- a/test/cepgen-ascii.cpp
+++ b/test/cepgen-ascii.cpp
@@ -1,85 +1,85 @@
#include "CepGen/Cards/PythonHandler.h"
#include "CepGen/Cards/LpairHandler.h"
#include "CepGen/IO/HepMCHandler.h"
#include "CepGen/IO/LHEFHandler.h"
#include "CepGen/Generator.h"
#include "CepGen/Core/Exception.h"
#include "CepGen/Event/Event.h"
#include <iostream>
using namespace std;
// we use polymorphism here
-std::shared_ptr<CepGen::output::ExportHandler> writer;
+std::shared_ptr<cepgen::output::ExportHandler> writer;
-void storeEvent( const CepGen::Event& ev, unsigned long )
+void storeEvent( const cepgen::Event& ev, unsigned long )
{
if ( !writer )
throw CG_FATAL( "storeEvent" ) << "Failed to retrieve a valid writer!";
*writer << ev;
}
/**
* Main caller for this Monte Carlo generator. Loads the configuration files'
* variables if set as an argument to this program, else loads a default
* "LHC-like" configuration, then launches the cross-section computation and
* the events generation.
* \author Laurent Forthomme <laurent.forthomme@cern.ch>
*/
int main( int argc, char* argv[] ) {
if ( argc < 2 )
throw CG_FATAL( "main" )
<< "No config file provided!\n\t"
<< "Usage: " << argv[0] << " config-file [format=lhef,hepmc] [filename=example.dat]";
- CepGen::Generator mg;
+ cepgen::Generator mg;
//-----------------------------------------------------------------------------------------------
// Steering card readout
//-----------------------------------------------------------------------------------------------
CG_DEBUG( "main" ) << "Reading config file stored in \"" << argv[1] << "\"";
- const string extension = CepGen::cards::Handler::getExtension( argv[1] );
+ const string extension = cepgen::cards::Handler::getExtension( argv[1] );
if ( extension == "card" )
- mg.setParameters( CepGen::cards::LpairHandler( argv[1] ).parameters() );
+ mg.setParameters( cepgen::cards::LpairHandler( argv[1] ).parameters() );
else if ( extension == "py" )
- mg.setParameters( CepGen::cards::PythonHandler( argv[1] ).parameters() );
+ mg.setParameters( cepgen::cards::PythonHandler( argv[1] ).parameters() );
else
throw CG_FATAL( "main" ) << "Unrecognized card format: ." << extension;
//-----------------------------------------------------------------------------------------------
// Output file writer definition
//-----------------------------------------------------------------------------------------------
const string format = ( argc > 2 ) ? argv[2] : "lhef";
const char* filename = ( argc > 3 ) ? argv[3] : "example.dat";
if ( format == "lhef" )
- writer = std::make_shared<CepGen::output::LHEFHandler>( filename );
+ writer = std::make_shared<cepgen::output::LHEFHandler>( filename );
else if ( format == "hepmc" )
- writer = std::make_shared<CepGen::output::HepMCHandler>( filename );
+ writer = std::make_shared<cepgen::output::HepMCHandler>( filename );
else
throw CG_FATAL( "main" ) << "Unrecognized output format: " << format;
//-----------------------------------------------------------------------------------------------
// CepGen run part
//-----------------------------------------------------------------------------------------------
// We might want to cross-check visually the validity of our run
CG_INFO( "main" ) << mg.parameters.get();
// Let there be cross-section...
double xsec = 0., err = 0.;
mg.computeXsection( xsec, err );
writer->initialise( *mg.parameters );
writer->setCrossSection( xsec, err );
// The events generation starts here!
mg.generate( storeEvent );
return 0;
}
diff --git a/test/cepgen-root.cxx b/test/cepgen-root.cxx
index 3fe755d..da6fd43 100644
--- a/test/cepgen-root.cxx
+++ b/test/cepgen-root.cxx
@@ -1,114 +1,114 @@
#include "CepGen/Cards/PythonHandler.h"
#include "CepGen/Cards/LpairHandler.h"
#include "CepGen/Generator.h"
#include "CepGen/Event/Event.h"
#include <iomanip>
#include <iostream>
#include "TreeInfo.h"
#include "abort.h"
// ROOT includes
#include "TFile.h"
#include "TTree.h"
#include "TLorentzVector.h"
using namespace std;
std::unique_ptr<ROOT::CepGenRun> run;
std::unique_ptr<ROOT::CepGenEvent> ev;
-void fill_event_tree( const CepGen::Event& event, unsigned long ev_id )
+void fill_event_tree( const cepgen::Event& event, unsigned long ev_id )
{
//if ( ev_id % 10 == 0 )
// cout << ">> event " << ev_id << " generated" << endl;
if ( !ev || !run )
return;
ev->gen_time = event.time_generation;
ev->tot_time = event.time_total;
ev->np = 0;
//cout << event.particles().size() << endl;
ev->momentum.reserve( event.particles().size() );
for ( const auto& p : event.particles() ) {
- const CepGen::Particle::Momentum m = p.momentum();
+ const cepgen::Particle::Momentum m = p.momentum();
ev->momentum[ev->np].SetPxPyPzE( m.px(), m.py(), m.pz(), p.energy() );
ev->rapidity[ev->np] = m.rapidity();
ev->pt[ev->np] = m.pt();
ev->eta[ev->np] = m.eta();
ev->phi[ev->np] = m.phi();
ev->E[ev->np] = p.energy();
ev->m[ev->np] = p.mass();
ev->pdg_id[ev->np] = p.integerPdgId();
ev->parent1[ev->np] = ( p.mothers().size() > 0 ) ? *p.mothers().begin() : -1;
ev->parent2[ev->np] = ( p.mothers().size() > 1 ) ? *p.mothers().rbegin() : -1;
ev->status[ev->np] = (int)p.status();
ev->stable[ev->np] = ( (short)p.status() > 0 );
ev->charge[ev->np] = p.charge();
ev->role[ev->np] = p.role();
ev->np++;
}
run->num_events += 1;
ev->fill();
}
/**
* Generation of events and storage in a ROOT format
* @author Laurent Forthomme <laurent.forthomme@cern.ch>
* @date 27 jan 2014
*/
int main( int argc, char* argv[] ) {
- CepGen::Generator mg;
+ cepgen::Generator mg;
if ( argc < 2 )
throw CG_FATAL( "main" ) << "Usage: " << argv[0] << " input-card [filename=events.root]";
- const std::string extension = CepGen::cards::Handler::getExtension( argv[1] );
+ const std::string extension = cepgen::cards::Handler::getExtension( argv[1] );
if ( extension == "card" )
- mg.setParameters( CepGen::cards::LpairHandler( argv[1] ).parameters() );
+ mg.setParameters( cepgen::cards::LpairHandler( argv[1] ).parameters() );
else if ( extension == "py" )
- mg.setParameters( CepGen::cards::PythonHandler( argv[1] ).parameters() );
+ mg.setParameters( cepgen::cards::PythonHandler( argv[1] ).parameters() );
mg.parameters->generation.enabled = true;
CG_INFO( "main" ) << mg.parameters.get();
//----- open the output root file
const char* filename = ( argc > 2 ) ? argv[2] : "events.root";
std::unique_ptr<TFile> file( TFile::Open( filename, "recreate" ) );
if ( !file )
throw CG_FATAL( "main" ) << "Failed to create the output file!";
AbortHandler ctrl_c;
//----- start by computing the cross section for the list of parameters applied
double xsec, err;
mg.computeXsection( xsec, err );
//----- then generate the events and the container tree structure
std::unique_ptr<TTree> ev_tree( new TTree( "events", "A TTree containing information from the events produced from CepGen" ) );
run.reset( new ROOT::CepGenRun );
run->create();
run->xsect = xsec;
run->errxsect = err;
run->litigious_events = 0;
run->sqrt_s = mg.parameters->kinematics.sqrtS();
run->fill();
ev.reset( new ROOT::CepGenEvent );
ev->create( ev_tree.get() );
// launch the events generation
try {
mg.generate( fill_event_tree );
- } catch ( const CepGen::Exception& ) {}
+ } catch ( const cepgen::Exception& ) {}
file->Write();
CG_INFO( "main" ) << "Events written on \"" << filename << "\".";
return 0;
}
diff --git a/test/cepgen.cpp b/test/cepgen.cpp
index a46fee4..940ea6b 100644
--- a/test/cepgen.cpp
+++ b/test/cepgen.cpp
@@ -1,74 +1,74 @@
//--- steering cards
#include "CepGen/Cards/PythonHandler.h"
#include "CepGen/Cards/LpairHandler.h"
#include "CepGen/Generator.h"
#include "CepGen/Core/Exception.h"
//--- necessary include to build the default run
#include "CepGen/Processes/GamGamLL.h"
#include "CepGen/Physics/PDG.h"
#include "abort.h"
#include <iostream>
using namespace std;
/**
* Main caller for this MC generator.
* * loads the configuration files' variables if passed as an argument,
* or a default LPAIR-like configuration,
* * launches the cross-section computation and the events generation.
* \author Laurent Forthomme <laurent.forthomme@cern.ch>
*/
int main( int argc, char* argv[] ) {
//--- first start by defining the generator object
- CepGen::Generator gen;
+ cepgen::Generator gen;
if ( argc < 2 ) {
CG_INFO( "main" ) << "No config file provided. Setting the default parameters.";
//--- default run: LPAIR elastic ɣɣ → µ⁺µ¯ at 13 TeV
- CepGen::ParametersList pgen;
- pgen.set<int>( "pair", (int)CepGen::PDG::muon );
- gen.parameters->setProcess( new CepGen::process::GamGamLL( pgen ) );
- gen.parameters->kinematics.mode = CepGen::KinematicsMode::ElasticElastic;
+ cepgen::ParametersList pgen;
+ pgen.set<int>( "pair", (int)cepgen::PDG::muon );
+ gen.parameters->setProcess( new cepgen::process::GamGamLL( pgen ) );
+ gen.parameters->kinematics.mode = cepgen::KinematicsMode::ElasticElastic;
gen.parameters->kinematics.cuts.central.pt_single.min() = 15.;
gen.parameters->kinematics.cuts.central.eta_single = { -2.5, 2.5 };
gen.parameters->generation.enabled = true;
gen.parameters->generation.maxgen = 1e3;
}
else {
CG_INFO( "main" ) << "Reading config file stored in " << argv[1] << ".";
- const std::string extension = CepGen::cards::Handler::getExtension( argv[1] );
+ const std::string extension = cepgen::cards::Handler::getExtension( argv[1] );
if ( extension == "card" )
- gen.setParameters( CepGen::cards::LpairHandler( argv[1] ).parameters() );
+ gen.setParameters( cepgen::cards::LpairHandler( argv[1] ).parameters() );
#ifdef PYTHON
else if ( extension == "py" )
- gen.setParameters( CepGen::cards::PythonHandler( argv[1] ).parameters() );
+ gen.setParameters( cepgen::cards::PythonHandler( argv[1] ).parameters() );
#endif
else
throw CG_FATAL( "main" ) << "Unrecognized steering card extension: ." << extension << "!";
}
//--- list all parameters
CG_INFO( "main" ) << gen.parameters.get();
AbortHandler ctrl_c;
try {
//--- let there be a cross-section...
double xsec = 0., err = 0.;
gen.computeXsection( xsec, err );
if ( gen.parameters->generation.enabled )
//--- events generation starts here
// (one may use a callback function)
gen.generate();
- } catch ( const CepGen::RunAbortedException& e ) {
+ } catch ( const cepgen::RunAbortedException& e ) {
CG_INFO( "main" ) << "Run aborted!";
}
return 0;
}
diff --git a/test/test_cross_section_scan.cpp b/test/test_cross_section_scan.cpp
index 3a09e1b..cf36c95 100644
--- a/test/test_cross_section_scan.cpp
+++ b/test/test_cross_section_scan.cpp
@@ -1,53 +1,53 @@
#include "CepGen/Generator.h"
#include "CepGen/Parameters.h"
#include "CepGen/Core/Exception.h"
#include "CepGen/Core/utils.h"
#include "CepGen/Processes/GamGamLL.h"
#include <fstream>
using namespace std;
int main( int argc, char* argv[] )
{
if ( argc < 5 )
throw CG_FATAL( "main" )
<< "Usage:\n"
<< argv[0] << " <process mode=1..4> <num points> <min value> <max value> [output file=xsect.dat]";
const unsigned int proc_mode = atoi( argv[1] ),
npoints = atoi( argv[2] );
const float min_value = atof( argv[3] ),
max_value = atof( argv[4] );
const char* output_file = ( argc>5 ) ? argv[5] : "xsect.dat";
- CepGen::Generator mg;
+ cepgen::Generator mg;
- //CepGen::Logger::get().level = CepGen::Logger::Level::error;
+ //cepgen::Logger::get().level = cepgen::Logger::Level::error;
- CepGen::Parameters* par = mg.parameters.get();
+ cepgen::Parameters* par = mg.parameters.get();
par->kinematics.cuts.central.eta_single = { -2.5, 2.5 };
par->kinematics.cuts.remnants.mass_single.max() = 1000.0;
- par->setProcess( new CepGen::Process::GamGamLL );
- par->kinematics.mode = static_cast<CepGen::Kinematics::Mode>( proc_mode );
+ par->setProcess( new cepgen::Process::GamGamLL );
+ par->kinematics.mode = static_cast<cepgen::Kinematics::Mode>( proc_mode );
CG_INFO( "main" ) << par;
double xsect, err_xsect;
ofstream xsect_file( output_file );
if ( !xsect_file.is_open() )
throw CG_FATAL( "main" ) << "Output file \"" << output_file << "\" cannot be opened!";
for ( unsigned int i=0; i<npoints; i++ ) {
par->kinematics.cuts.central.pt_single.min() = min_value + (max_value-min_value)*i/npoints;
//par->kinematics.dump();
mg.computeXsection( xsect, err_xsect );
- xsect_file << CepGen::Form( "%.2f\t%.5f\t%.5f\n", par->kinematics.cuts.central.pt_single.min(), xsect, err_xsect );
- cout << CepGen::Form( "%.2f\t%.5f\t%.5f\n", par->kinematics.cuts.central.pt_single.min(), xsect, err_xsect );
+ xsect_file << cepgen::Form( "%.2f\t%.5f\t%.5f\n", par->kinematics.cuts.central.pt_single.min(), xsect, err_xsect );
+ cout << cepgen::Form( "%.2f\t%.5f\t%.5f\n", par->kinematics.cuts.central.pt_single.min(), xsect, err_xsect );
xsect_file.flush();
}
return 0;
}
diff --git a/test/test_distributions.cxx b/test/test_distributions.cxx
index 589666c..b1e76c0 100644
--- a/test/test_distributions.cxx
+++ b/test/test_distributions.cxx
@@ -1,63 +1,63 @@
#include "CepGen/Cards/PythonHandler.h"
#include "CepGen/Generator.h"
#include "CepGen/Event/Event.h"
#include "CepGen/Core/Exception.h"
#include "Canvas.h"
#include "TH1.h"
#include <sstream>
using namespace std;
void produce_plot( const char* name, TH1* hist )
{
- CepGen::Canvas c( name, "CepGen Simulation" );
+ cepgen::Canvas c( name, "CepGen Simulation" );
hist->Draw( "hist" );
c.Prettify( hist );
c.SetLogy();
c.Save( "pdf" );
}
unique_ptr<TH1D> h_mass, h_ptpair, h_ptsingle, h_etasingle;
-void process_event( const CepGen::Event& ev, unsigned long event_id )
+void process_event( const cepgen::Event& ev, unsigned long event_id )
{
- const auto central_system = ev.getByRole( CepGen::Particle::CentralSystem );
+ const auto central_system = ev.getByRole( cepgen::Particle::CentralSystem );
const auto pl1 = central_system[0].momentum(), pl2 = central_system[1].momentum();
h_mass->Fill( ( pl1+pl2 ).mass() );
h_ptpair->Fill( ( pl1+pl2 ).pt() );
h_ptsingle->Fill( pl1.pt() );
h_etasingle->Fill( pl1.eta() );
}
int main( int argc, char* argv[] )
{
- CepGen::Generator mg;
+ cepgen::Generator mg;
if ( argc < 2 )
throw CG_FATAL( "main" ) << "Usage: " << argv[0] << " [input card]";
- mg.setParameters( CepGen::cards::PythonHandler( argv[1] ).parameters() );
+ mg.setParameters( cepgen::cards::PythonHandler( argv[1] ).parameters() );
h_mass = unique_ptr<TH1D>( new TH1D( "invm", ";Dilepton invariant mass;d#sigma/dM (pb/GeV)", 500, 0., 500. ) );
h_ptpair = unique_ptr<TH1D>( new TH1D( "ptpair", ";Dilepton p_{T};d#sigma/dp_{T} (pb/GeV)", 500, 0., 50. ) );
h_ptsingle = unique_ptr<TH1D>( new TH1D( "pt_single", ";Single lepton p_{T};d#sigma/dp_{T} (pb/GeV)", 100, 0., 100. ) );
h_etasingle = unique_ptr<TH1D>( new TH1D( "eta_single", ";Single lepton #eta;d#sigma/d#eta (pb)\\?.2f", 60, -3., 3. ) );
CG_INFO( "main" ) << "Process name: " << mg.parameters->processName() << ".";
//mg.parameters->taming_functions.dump();
mg.generate( process_event );
const double weight = mg.crossSection()/mg.parameters->generation.maxgen;
h_mass->Scale( weight, "width" );
h_ptpair->Scale( weight, "width" );
h_ptsingle->Scale( weight, "width" );
h_etasingle->Scale( weight, "width" );
produce_plot( "dilepton_invm", h_mass.get() );
produce_plot( "dilepton_ptpair", h_ptpair.get() );
produce_plot( "singlelepton_pt", h_ptsingle.get() );
produce_plot( "singlelepton_eta", h_etasingle.get() );
return 0;
}
diff --git a/test/test_event_writer.cpp b/test/test_event_writer.cpp
index 6846bbf..485aed8 100644
--- a/test/test_event_writer.cpp
+++ b/test/test_event_writer.cpp
@@ -1,30 +1,30 @@
#include "CepGen/IO/HepMCHandler.h"
#include "CepGen/Physics/PDG.h"
#include "CepGen/Event/Event.h"
using namespace std;
-using namespace CepGen;
+using namespace cepgen;
int main() {
output::HepMCHandler writer( "example.dat" );
writer.setCrossSection(1., 2.);
Event ev;
Particle p1( Particle::IncomingBeam1, PDG::proton );
p1.setMomentum( 1., -15., 100. );
p1.setStatus( Particle::Status::Incoming );
ev.addParticle(p1);
Particle p2( Particle::IncomingBeam2, PDG::electron );
p2.setMomentum( 10., 5., 3200. );
p2.setStatus( Particle::Status::Incoming );
ev.addParticle(p2);
ev.dump();
writer << ev;
return 0;
}
diff --git a/test/test_exceptions.cpp b/test/test_exceptions.cpp
index 0154a97..ce2bda9 100644
--- a/test/test_exceptions.cpp
+++ b/test/test_exceptions.cpp
@@ -1,9 +1,9 @@
#include "CepGen/Core/Exception.h"
-using namespace CepGen;
+using namespace cepgen;
int main()
{
throw Exception( "Test", Exception::Type::warning ) << "Haha";
return 0;
}
diff --git a/test/test_function_parser.cpp b/test/test_function_parser.cpp
index a2e3641..f099dc9 100644
--- a/test/test_function_parser.cpp
+++ b/test/test_function_parser.cpp
@@ -1,50 +1,50 @@
#include "CepGen/Core/Functional.h"
#include "CepGen/Core/Exception.h"
#include <math.h>
#include <string>
#include <iostream>
using namespace std;
int
main()
{
const double epsilon = 1.e-9; // tolerance
{ // test with a 1-variable function
const double exp_result_test1 = 6.795704571;
- CepGen::Functional<1> test( "2.5*exp(0.1*x)", { { "x" } } );
+ cepgen::Functional<1> test( "2.5*exp(0.1*x)", { { "x" } } );
if ( fabs( test.eval( 10. ) - exp_result_test1 ) > epsilon )
throw CG_FATAL( "main" ) << "Test 1.1 failed!";
if ( fabs( test.eval( { { 10. } } ) - exp_result_test1 ) > epsilon )
throw CG_FATAL( "main" ) << "Test 1.2 failed!";
cout << "Test 1 passed!" << endl;
}
{ // test with an invalid function
bool passed = false;
try {
- CepGen::Functional<1> test( "sqrt(x+x**3-log(10)", { { "x" } } );
+ cepgen::Functional<1> test( "sqrt(x+x**3-log(10)", { { "x" } } );
test.eval( 10 );
- } catch ( CepGen::Exception& e ) { cout << "Test 2 passed!" /*<< e.what()*/ << endl; passed = true; }
+ } catch ( cepgen::Exception& e ) { cout << "Test 2 passed!" /*<< e.what()*/ << endl; passed = true; }
if ( !passed )
throw CG_FATAL( "main" ) << "Test 2 failed!";
}
{ // test with a 2-variables function
- CepGen::Functional<2> test( "sqrt(a^2+b^2)", { { "a", "b" } } );
+ cepgen::Functional<2> test( "sqrt(a^2+b^2)", { { "a", "b" } } );
if ( fabs( test.eval( { { 3, 4 } } ) - 5.0 ) > epsilon )
throw CG_FATAL( "main" ) << "Test 3 failed!";
cout << "Test 3 passed!" << endl;
}
{ // test with an invalid function
- CepGen::Functional<1> test( "a**2", { { "a" } } );
+ cepgen::Functional<1> test( "a**2", { { "a" } } );
bool passed = true;
- try { test.eval( 10 ); passed = false; } catch ( CepGen::Exception& e ) {}
- try { test.eval( { { 10 } } ); passed = false; } catch ( CepGen::Exception& e ) {}
+ try { test.eval( 10 ); passed = false; } catch ( cepgen::Exception& e ) {}
+ try { test.eval( { { 10 } } ); passed = false; } catch ( cepgen::Exception& e ) {}
if ( !passed )
throw CG_FATAL( "main" ) << "Test 4 failed!";
cout << "Test 4 passed!" << endl;
}
return 0;
}
diff --git a/test/test_function_parser_rootcomp.cxx b/test/test_function_parser_rootcomp.cxx
index 226f705..405c191 100644
--- a/test/test_function_parser_rootcomp.cxx
+++ b/test/test_function_parser_rootcomp.cxx
@@ -1,55 +1,55 @@
#include "TGraph.h"
#include "TF1.h"
#include "TMultiGraph.h"
#include "Canvas.h"
#include <iostream>
#include "CepGen/Core/Functional.h"
using namespace std;
int main( int argc, char* argv[] )
{
const unsigned short num_points = 100;
const double min_x = -1., max_x = 10.;
TGraph gr_fb, gr_rt;
TF1 f_rt( "f_rt", "TMath::Min(1.,TMath::Exp(-x/10))", min_x, max_x );
- CepGen::Functional<1> test1( "min(1,exp(-x/10))", { { "x" } } );
+ cepgen::Functional<1> test1( "min(1,exp(-x/10))", { { "x" } } );
for ( unsigned short i = 0; i < num_points; ++i ) {
const double x = min_x + ( max_x-min_x )/( num_points-1 )*i;
gr_rt.SetPoint( i, x, f_rt.Eval( x ) );
try {
gr_fb.SetPoint( i, x, test1.eval( x ) );
- } catch ( const CepGen::Exception& e ) { e.dump(); }
+ } catch ( const cepgen::Exception& e ) { e.dump(); }
}
TGraph gr_diff;
double chi2 = 0.;
for ( unsigned short i = 0; i < gr_fb.GetN(); ++i ) {
gr_diff.SetPoint( i, gr_fb.GetX()[i], gr_fb.GetY()[i]-gr_rt.GetY()[i] );
chi2 += pow( gr_fb.GetY()[i]-gr_rt.GetY()[i], 2 );
}
chi2 = sqrt( chi2 );
if ( chi2 > 1.e-9 )
throw CG_FATAL( "main" ) << "Test failed with chi2 = " << chi2 << "!";
cout << "Test passed!" << endl;
if ( argc > 1 && !strcmp( argv[1], "draw" ) ) {
- CepGen::Canvas c( "test_graph", "CepGen validation" );
+ cepgen::Canvas c( "test_graph", "CepGen validation" );
TMultiGraph mg;
mg.Add( &gr_fb );
mg.Add( &gr_rt );
mg.Add( &gr_diff );
mg.Draw( "al" );
c.AddLegendEntry( &gr_fb, "Functional", "l" );
c.AddLegendEntry( &gr_rt, "ROOT", "l" );
c.AddLegendEntry( &gr_diff, "Difference", "l" );
gr_fb.SetLineWidth( 3 );
gr_fb.SetLineStyle( 2 );
gr_diff.SetLineColor( kRed );
c.Prettify( mg.GetHistogram() );
c.Save( "pdf" );
}
return 0;
}
diff --git a/test/test_integrator.cpp b/test/test_integrator.cpp
index ba5f523..8c496b5 100644
--- a/test/test_integrator.cpp
+++ b/test/test_integrator.cpp
@@ -1,53 +1,53 @@
#include "CepGen/Generator.h"
#include "CepGen/Parameters.h"
#include "TestProcess.h"
#include <iostream>
using namespace std;
int
main( int argc, char* argv[] )
{
if ( argc < 3 || string( argv[2] ) != "debug" )
- CepGen::Logger::get().level = CepGen::Logger::Level::nothing;
+ cepgen::Logger::get().level = cepgen::Logger::Level::nothing;
const double max_sigma = 3.0;
- CepGen::Generator mg;
+ cepgen::Generator mg;
if ( argc > 1 && string( argv[1] ) == "plain" )
- mg.parameters->integrator.type = CepGen::Integrator::Type::plain;
+ mg.parameters->integrator.type = cepgen::Integrator::Type::plain;
if ( argc > 1 && string( argv[1] ) == "vegas" )
- mg.parameters->integrator.type = CepGen::Integrator::Type::Vegas;
+ mg.parameters->integrator.type = cepgen::Integrator::Type::Vegas;
if ( argc > 1 && string( argv[1] ) == "miser" )
- mg.parameters->integrator.type = CepGen::Integrator::Type::MISER;
+ mg.parameters->integrator.type = cepgen::Integrator::Type::MISER;
double result, error;
{ // test 1
const double exact = 1.3932039296856768591842462603255;
- mg.parameters->setProcess( new CepGen::Process::TestProcess<3> );
+ mg.parameters->setProcess( new cepgen::Process::TestProcess<3> );
mg.computeXsection( result, error );
if ( fabs( exact - result ) > max_sigma * error )
throw CG_FATAL( "main" ) << "pull = " << fabs( exact-result )/error << ".";
cout << "Test 1 passed!" << endl;
}
{ // test 2
const double exact = 2./3.;
- mg.parameters->setProcess( new CepGen::Process::TestProcess<2>( "x^2+y^2", { { "x", "y" } } ) );
+ mg.parameters->setProcess( new cepgen::Process::TestProcess<2>( "x^2+y^2", { { "x", "y" } } ) );
mg.computeXsection( result, error );
if ( fabs( exact - result ) > max_sigma * error )
throw CG_FATAL( "main" ) << "pull = " << fabs( exact-result )/error << ".";
cout << "Test 2 passed!" << endl;
}
{ // test 3
const double exact = 13./12.;
- mg.parameters->setProcess( new CepGen::Process::TestProcess<3>( "x+y^2+z^3", { { "x", "y", "z" } } ) );
+ mg.parameters->setProcess( new cepgen::Process::TestProcess<3>( "x+y^2+z^3", { { "x", "y", "z" } } ) );
mg.computeXsection( result, error );
if ( fabs( exact - result ) > max_sigma * error )
throw CG_FATAL( "main" ) << "pull = " << fabs( exact-result )/error << ".";
cout << "Test 3 passed!" << endl;
}
return 0;
}
diff --git a/test/test_physics_processes.cpp b/test/test_physics_processes.cpp
index 88865f4..172f366 100644
--- a/test/test_physics_processes.cpp
+++ b/test/test_physics_processes.cpp
@@ -1,211 +1,211 @@
#include "CepGen/Generator.h"
#include "CepGen/Parameters.h"
#include "CepGen/Core/ParametersList.h"
#include "CepGen/Core/Timer.h"
#include "CepGen/Processes/GamGamLL.h"
#include "CepGen/Processes/PPtoFF.h"
#include "CepGen/Processes/PPtoWW.h"
#include "CepGen/StructureFunctions/StructureFunctions.h"
#include "CepGen/Physics/PDG.h"
#include "abort.h"
#include <unordered_map>
#include <assert.h>
#include <string.h>
#include <math.h>
using namespace std;
-using namespace CepGen;
+using namespace cepgen;
int
main( int argc, char* argv[] )
{
typedef vector<pair<const char*,pair<double,double> > > KinematicsMap;
typedef vector<pair<float, KinematicsMap> > ValuesAtCutMap;
AbortHandler ctrl_c;
// values defined at pt(single lepton)>15 GeV, |eta(single lepton)|<2.5, mX<1000 GeV
// process -> { pt cut -> { kinematics -> ( sigma, delta(sigma) ) } }
vector<pair<const char*,ValuesAtCutMap> > values_map = {
//--- LPAIR values at sqrt(s) = 13 TeV
{ "lpair", {
{ 3.0, { // pt cut
{ "elastic", { 2.0871703e1, 3.542e-2 } },
{ "singlediss", { 1.5042536e1, 3.256e-2 } },
{ "doublediss", { 1.38835e1, 4.03018e-2 } }
} },
{ 15.0, { // pt cut
{ "elastic", { 4.1994803e-1, 8.328e-4 } },
{ "singlediss", { 4.8504819e-1, 1.171e-3 } },
{ "doublediss", { 6.35650e-1, 1.93968e-3 } }
} },
} },
//--- PPtoLL values
{ "pptoll", {
{ 3.0, { // pt cut
{ "elastic", { 2.0936541e1, 1.4096e-2 } },
{ "singlediss_su", { 1.4844881e1, 2.0723e-2 } }, // SU, qt<50
{ "doublediss_su", { 1.3580637e1, 2.2497e-2 } }, // SU, qt<50
} },
{ 15.0, { // pt cut
{ "elastic", { 4.2515888e-1, 3.0351e-4 } },
{ "singlediss_su", { 4.4903253e-1, 5.8970e-4 } }, // SU, qt<50
{ "doublediss_su", { 5.1923819e-1, 9.6549e-4 } }, // SU, qt<50
/*{ "2_singlediss", { 4.6710287e-1, 6.4842e-4 } }, // SU, qt<500
{ "3_doublediss", { 5.6316353e-1, 1.1829e-3 } }, // SU, qt<500*/
} },
} },
//--- PPtoWW values
{ "pptoww", {
{ 0.0, { // pt cut
{ "elastic", { 0.273, 0.01 } },
{ "elastic", { 0.273, 0.01 } }, // FIXME
{ "singlediss_lux", { 0.409, 0.01 } },
{ "doublediss_lux", { 1.090, 0.01 } },
{ "singlediss_allm", { 0.318, 0.01 } },
{ "doublediss_allm", { 0.701, 0.01 } }
} }
} },
};
const double num_sigma = 3.0;
if ( argc < 3 || strcmp( argv[2], "debug" ) != 0 )
Logger::get().level = Logger::Level::nothing;
Timer tmr;
Generator mg;
if ( argc > 1 && strcmp( argv[1], "plain" ) == 0 )
mg.parameters->integrator.type = Integrator::Type::plain;
if ( argc > 1 && strcmp( argv[1], "vegas" ) == 0 )
mg.parameters->integrator.type = Integrator::Type::Vegas;
if ( argc > 1 && strcmp( argv[1], "miser" ) == 0 )
mg.parameters->integrator.type = Integrator::Type::MISER;
{ cout << "Testing with " << mg.parameters->integrator.type << " integrator" << endl; }
mg.parameters->kinematics.setSqrtS( 13.e3 );
mg.parameters->kinematics.cuts.central.eta_single.in( -2.5, 2.5 );
mg.parameters->kinematics.cuts.remnants.mass_single.max() = 1000.;
//mg.parameters->integrator.ncvg = 50000;
CG_INFO( "main" ) << "Initial configuration time: " << tmr.elapsed()*1.e3 << " ms.";
tmr.reset();
unsigned short num_tests = 0, num_tests_passed = 0;
vector<string> failed_tests, passed_tests;
try {
for ( const auto& values_vs_generator : values_map ) { // loop over all generators
ParametersList param;
const string generator = values_vs_generator.first;
if ( generator == "lpair" ) {
param.set<int>( "pair", 13 );
mg.parameters->setProcess( new Process::GamGamLL( param ) );
}
else if ( generator == "pptoll" ) {
param.set<int>( "pair", 13 );
mg.parameters->setProcess( new Process::PPtoFF( param ) );
mg.parameters->kinematics.cuts.initial.qt = { 0., 50. };
}
else if ( generator == "pptoww" ) {
mg.parameters->setProcess( new Process::PPtoWW );
mg.parameters->kinematics.setSqrtS( 13.e3 );
//mg.parameters->kinematics.cuts.initial.qt = { 0., 50. };
}
else {
CG_ERROR( "main" ) << "Unrecognized generator mode: " << values_vs_generator.first << ".";
break;
}
for ( const auto& values_vs_cut : values_vs_generator.second ) { // loop over the single lepton pT cut
mg.parameters->kinematics.cuts.central.pt_single.min() = values_vs_cut.first;
for ( const auto& values_vs_kin : values_vs_cut.second ) { // loop over all possible kinematics
const string kin_mode = values_vs_kin.first;
if ( kin_mode.find( "elastic" ) != string::npos )
mg.parameters->kinematics.mode = KinematicsMode::ElasticElastic;
else if ( kin_mode.find( "singlediss" ) != string::npos )
mg.parameters->kinematics.mode = KinematicsMode::InelasticElastic;
else if ( kin_mode.find( "doublediss" ) != string::npos )
mg.parameters->kinematics.mode = KinematicsMode::InelasticInelastic;
else {
CG_ERROR( "main" ) << "Unrecognized kinematics mode: " << values_vs_kin.first << ".";
break;
}
if ( kin_mode.find( "_su" ) != string::npos )
mg.parameters->kinematics.structure_functions = sf::Parameterisation::build( sf::Type::SzczurekUleshchenko );
else if ( kin_mode.find( "_lux" ) != string::npos )
mg.parameters->kinematics.structure_functions = sf::Parameterisation::build( sf::Type::Schaefer );
else if ( kin_mode.find( "_allm" ) != string::npos )
mg.parameters->kinematics.structure_functions = sf::Parameterisation::build( sf::Type::ALLM97 );
else
mg.parameters->kinematics.structure_functions = sf::Parameterisation::build( sf::Type::SuriYennie );
//CG_INFO( "main" ) << mg.parameters.get();
CG_INFO( "main" )
<< "Process: "<< values_vs_generator.first << "/" << values_vs_kin.first << "\n\t"
<< "Configuration time: " << tmr.elapsed()*1.e3 << " ms.";
tmr.reset();
mg.clearRun();
const double xsec_ref = values_vs_kin.second.first;
const double err_xsec_ref = values_vs_kin.second.second;
double xsec_cepgen, err_xsec_cepgen;
mg.computeXsection( xsec_cepgen, err_xsec_cepgen );
const double sigma = fabs( xsec_ref-xsec_cepgen ) / std::hypot( err_xsec_cepgen, err_xsec_ref );
CG_INFO( "main" )
<< "Computed cross section:\n\t"
<< "Ref. = " << xsec_ref << " +/- " << err_xsec_ref << "\n\t"
<< "CepGen = " << xsec_cepgen << " +/- " << err_xsec_cepgen << "\n\t"
<< "Pull: " << sigma << ".";
CG_INFO( "main" ) << "Computation time: " << tmr.elapsed()*1.e3 << " ms.";
tmr.reset();
ostringstream oss; oss << values_vs_kin.first;
string test_res = Form( "%-10s", values_vs_generator.first )+"\t"+
Form( "pt-gt-%.1f", values_vs_cut.first )+"\t"+
Form( "%-16s", oss.str().c_str() )+"\t"
"ref="+Form( "%g", xsec_ref )+"\t"
"got="+Form( "%g", xsec_cepgen )+"\t"
"pull="+Form( "%+g", sigma );
if ( fabs( sigma ) < num_sigma ) {
passed_tests.emplace_back( test_res );
num_tests_passed++;
}
else
failed_tests.emplace_back( test_res );
num_tests++;
cout << "Test " << num_tests_passed << "/"
<< num_tests << " passed!" << endl;
}
}
}
} catch ( Exception& e ) {}
if ( failed_tests.size() != 0 ) {
ostringstream os_failed, os_passed;
for ( const auto& fail : failed_tests )
os_failed << " (*) " << fail << endl;
for ( const auto& pass : passed_tests )
os_passed << " (*) " << pass << endl;
throw CG_FATAL( "main" )
<< "Some tests failed!\n"
<< os_failed.str() << "\n"
<< "Passed tests:\n"
<< os_passed.str() << ".";
}
CG_INFO( "main" ) << "ALL TESTS PASSED!";
return 0;
}
diff --git a/test/test_process_builder.cpp b/test/test_process_builder.cpp
index 0b52a31..bf716af 100644
--- a/test/test_process_builder.cpp
+++ b/test/test_process_builder.cpp
@@ -1,27 +1,27 @@
#include "CepGen/Processes/ProcessesHandler.h"
#include "CepGen/Event/Event.h"
#include "CepGen/Core/ParametersList.h"
#include <iostream>
using namespace std;
int main( int argc, const char* argv[] )
{
const char* proc_name = ( argc > 1 ) ? argv[1] : "lpair";
cout << "Will build a process named \"" << proc_name << "\"." << endl;
- CepGen::ProcessesHandler::get().dump();
+ cepgen::ProcessesHandler::get().dump();
- auto proc = CepGen::ProcessesHandler::get().build( proc_name, CepGen::ParametersList() );
+ auto proc = cepgen::ProcessesHandler::get().build( proc_name, cepgen::ParametersList() );
//--- at this point, the process has been found
std::cout << "Successfully built the process \"" << proc->name() << "\"!\n"
<< " *) description: " << proc->description() << "\n"
<< " *) has event? " << proc->hasEvent() << "\n";
if ( proc->hasEvent() ) { //--- dump a typical event content
std::cout << " event content (invalid kinematics, only check the parentage):\n";
proc->addEventContent();
proc->event()->dump();
}
return 0;
}
diff --git a/test/test_pythoncfg_parser.cpp b/test/test_pythoncfg_parser.cpp
index 701b4bd..c20b13a 100644
--- a/test/test_pythoncfg_parser.cpp
+++ b/test/test_pythoncfg_parser.cpp
@@ -1,22 +1,22 @@
#include "CepGen/Cards/PythonHandler.h"
#include "CepGen/Core/Exception.h"
#include <string>
#include <iostream>
using namespace std;
int
main( int argc, char* argv[] )
{
if ( argc < 2 )
throw CG_FATAL( "main" ) << "One argument required!";
try {
- CepGen::cards::PythonHandler py( argv[1] );
+ cepgen::cards::PythonHandler py( argv[1] );
CG_INFO( "main" ) << py.parameters();
- } catch ( CepGen::Exception& e ) {
+ } catch ( cepgen::Exception& e ) {
e.dump();
}
return 0;
}
diff --git a/test/test_singlepoint.cpp b/test/test_singlepoint.cpp
index 57d4f5f..0e18b72 100644
--- a/test/test_singlepoint.cpp
+++ b/test/test_singlepoint.cpp
@@ -1,32 +1,32 @@
#include "CepGen/Generator.h"
#include "CepGen/Parameters.h"
#include "CepGen/Processes/GamGamLL.h"
#include "CepGen/Core/Exception.h"
using namespace std;
int main()
{
- CepGen::Generator g;
- CepGen::Parameters* p = g.parameters.get();
+ cepgen::Generator g;
+ cepgen::Parameters* p = g.parameters.get();
//p->setProcess( new GamGamLL );
- p->setProcess( new CepGen::Process::GamGamLL );
- p->kinematics.mode = CepGen::Kinematics::Mode::ElasticElastic;
- //p->kinematics.mode = CepGen::Kinematics::Mode::InelasticElastic;
- //p->kinematics.mode = CepGen::Kinematics::Mode::ElasticInelastic;
+ p->setProcess( new cepgen::Process::GamGamLL );
+ p->kinematics.mode = cepgen::Kinematics::Mode::ElasticElastic;
+ //p->kinematics.mode = cepgen::Kinematics::Mode::InelasticElastic;
+ //p->kinematics.mode = cepgen::Kinematics::Mode::ElasticInelastic;
p->kinematics.cuts.central.pt_single = 5.;
p->kinematics.cuts.central.eta_single = { -2.5, 2.5 };
p->kinematics.cuts.remnants.mass_single = { 1.07, 320. };
CG_INFO( "main" ) << p;
- CepGen::Logger::get().level = CepGen::Logger::Level::debugInsideLoop;
+ cepgen::Logger::get().level = cepgen::Logger::Level::debugInsideLoop;
const unsigned short ndim = g.numDimensions();
double x[12];
for ( unsigned int i = 0; i < ndim; ++i )
x[i] = 0.3;
cout << g.computePoint( x ) << endl;
return 0;
}

File Metadata

Mime Type
text/x-diff
Expires
Sat, May 3, 6:34 AM (1 d, 17 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4983081
Default Alt Text
(591 KB)

Event Timeline