diff --git a/CepGen/Event/EventBrowser.cpp b/CepGen/Event/EventBrowser.cpp new file mode 100644 index 0000000..4def071 --- /dev/null +++ b/CepGen/Event/EventBrowser.cpp @@ -0,0 +1,83 @@ +#include "CepGen/Event/EventBrowser.h" +#include "CepGen/Event/Event.h" + +#include "CepGen/Core/Exception.h" +#include "CepGen/Core/utils.h" + +namespace cepgen +{ + namespace utils + { + const std::regex EventBrowser::rgx_select_id_( "(\\w+)\\((\\d+)\\)" ); + const std::regex EventBrowser::rgx_select_role_( "(\\w+)\\(([a-z]+\\d?)\\)" ); + + double + EventBrowser::get( const Event& ev, const std::string& var ) const + { + std::smatch sm; + if ( std::regex_match( var, sm, rgx_select_id_ ) ) { // per-id variable + const auto& var_name = sm[1].str(); + const auto& part = ev[std::stod( sm[2].str() )]; + return variable( part, var_name ); + } + else if ( std::regex_match( var, sm, rgx_select_role_ ) ) { // per-role variable + const auto& var_name = sm[1].str(); + const auto& str_role = sm[2].str(); + if ( role_str_.count( str_role ) == 0 ) { + CG_WARNING( "TextHandler" ) + << "Invalid particle role retrieved from configuration: \"" << str_role << "\".\n\t" + << "Skipping the variable \"" << var << "\" in the output module."; + return INVALID_OUTPUT; + } + const auto& part = ev[role_str_.at( str_role )][0]; + return variable( part, var_name ); + } + else // event-level variable + return variable( ev, var ); + } + + double + EventBrowser::variable( const Particle& part, const std::string& var ) const + { + if ( m_mom_str_.count( var ) ) { + auto meth = m_mom_str_.at( var ); + return ( part.momentum().*meth )(); + } + //if ( var == "xi" ) return 1.-part.momentum().energy()*2./sqrts_; + if ( var == "pdg" ) return (double)part.integerPdgId(); + if ( var == "charge" ) return part.charge(); + if ( var == "status" ) return (double)part.status(); + CG_WARNING( "EventBrowser" ) + << "Failed to retrieve variable \"" << var << "\"."; + return INVALID_OUTPUT; + } + + double + EventBrowser::variable( const Event& ev, const std::string& var ) const + { + if ( var == "np" ) + return (double)ev.size(); + //if ( var == "nev" ) + // return (double)num_evts_+1; + if ( var == "nob1" || var == "nob2" ) { + unsigned short out = 0.; + for ( const auto& part : ev[ + var == "nob1" + ? Particle::Role::OutgoingBeam1 + : Particle::Role::OutgoingBeam2 + ] ) + if ( (int)part.status() > 0 ) + out++; + return (double)out; + } + if ( var == "tgen" ) + return ev.time_generation; + if ( var == "ttot" ) + return ev.time_total; + CG_WARNING( "EventBrowser" ) + << "Failed to retrieve the event-level variable \"" << var << "\"."; + return INVALID_OUTPUT; + } + } +} + diff --git a/CepGen/Event/EventBrowser.h b/CepGen/Event/EventBrowser.h new file mode 100644 index 0000000..512e479 --- /dev/null +++ b/CepGen/Event/EventBrowser.h @@ -0,0 +1,61 @@ +#ifndef CepGen_Event_EventBrowser_h +#define CepGen_Event_EventBrowser_h + +#include "CepGen/Event/Particle.h" +#include + +namespace cepgen +{ + class Event; + namespace utils + { + /** + * \brief A user-friendly browser for the Event content + * \author Laurent Forthomme + * \date Jul 2019 + */ + class EventBrowser + { + public: + explicit EventBrowser(); + double get( const Event& ev, const std::string& var ) const; + + private: + /// Retrieve a named variable from a particle + double variable( const Particle&, const std::string& ) const; + /// Retrieve a named variable from the whole event + double variable( const Event&, const std::string& ) const; + + static const std::regex rgx_select_id_, rgx_select_role_; + static constexpr double INVALID_OUTPUT = -999.; + + //--- auxiliary helper maps + const std::unordered_map role_str_ = { + { "ib1", Particle::Role::IncomingBeam1 }, { "ib2", Particle::Role::IncomingBeam2 }, + { "ob1", Particle::Role::OutgoingBeam1 }, { "ob2", Particle::Role::OutgoingBeam2 }, + { "pa1", Particle::Role::Parton1 }, { "pa2", Particle::Role::Parton2 }, + { "cs", Particle::Role::CentralSystem }, + { "int", Particle::Role::Intermediate } + }; + typedef double( Particle::Momentum::*pMethod )(void) const; + /// Mapping of string variables to momentum getter methods + const std::unordered_map m_mom_str_ = { + { "px", &Particle::Momentum::px }, + { "py", &Particle::Momentum::py }, + { "pz", &Particle::Momentum::pz }, + { "pt", &Particle::Momentum::pt }, + { "eta", &Particle::Momentum::eta }, + { "phi", &Particle::Momentum::phi }, + { "m", &Particle::Momentum::mass }, + { "e", &Particle::Momentum::energy }, + { "p", &Particle::Momentum::p }, + { "pt2", &Particle::Momentum::pt2 }, + { "th", &Particle::Momentum::theta }, + { "y", &Particle::Momentum::rapidity } + }; + }; + } +} + +#endif +