diff --git a/Changes.md b/Changes.md index ebdf244..c6f80f7 100644 --- a/Changes.md +++ b/Changes.md @@ -1,20 +1,23 @@ # Version 2.0 ## 2.X.0 * Made `MatrixElement::tree_kin` and `MatrixElement::tree_param` public -* Allow multiplication and division of multiple scale functions e.g. `H_T/2*m_j1j2` +* Allow multiplication and division of multiple scale functions e.g. + `H_T/2*m_j1j2` +* Follow HepMC convention for particle Status codes: incoming = 11, + decaying = 2, outgoing = 1 (unchanged) ## 2.0.3 * Fixed parsing of (numerical factor) * (base scale) in configuration * Don't change scale names, but sanitise Rivet output file names instead ## 2.0.2 * Changed scale names to `"_over_"` and `"_times_"` for proper file names (was - `"/"` and `"*"` before) + `"/"` and `"*"` before) ## 2.0.1 * Fixed name of fixed-order generator in error message. diff --git a/src/HepMCInterface.cc b/src/HepMCInterface.cc index a50c8f8..f83ece6 100644 --- a/src/HepMCInterface.cc +++ b/src/HepMCInterface.cc @@ -1,177 +1,177 @@ /** * \authors Jeppe Andersen, Tuomas Hapola, Marian Heil, Andreas Maier, Jennifer Smillie * \date 2019 * \copyright GPLv2 or later */ #include "HEJ/HepMCInterface.hh" #include "HEJ/exceptions.hh" #ifdef HEJ_BUILD_WITH_HepMC_VERSION #include #include #include "HEJ/Event.hh" #include "HEJ/Particle.hh" #include "HepMC/GenCrossSection.h" #include "HepMC/GenEvent.h" #include "HepMC/GenParticle.h" #include "HepMC/GenVertex.h" namespace HEJ{ namespace { HepMC::FourVector to_FourVector(Particle const & sp){ return {sp.px(), sp.py(), sp.pz(), sp.E()}; } - constexpr int status_in = -1; - constexpr int status_decayed = 3; + constexpr int status_in = 11; + constexpr int status_decayed = 2; constexpr int status_out = 1; template auto make_ptr(Args&&... args){ #if HEJ_BUILD_WITH_HepMC_VERSION >= 3 return HepMC::make_shared(std::forward(args)...); #else return new HepMCClass(std::forward(args)...); #endif } } // namespace anonymous HepMCInterface::HepMCInterface(): event_count_(0.), tot_weight_(0.), tot_weight2_(0.) {} HepMC::GenCrossSection HepMCInterface::cross_section() const { HepMC::GenCrossSection xs; #if HEJ_BUILD_WITH_HepMC_VERSION >= 3 xs.set_cross_section(tot_weight_, sqrt(tot_weight2_), event_count_); /// @TODO add number of attempted events #else // HepMC 2 xs.set_cross_section(tot_weight_, sqrt(tot_weight2_)); #endif return xs; } HepMC::GenEvent HepMCInterface::init_kinematics(Event const & event) { HepMC::GenEvent out_ev{HepMC::Units::GEV, HepMC::Units::MM}; auto vx = make_ptr(); for(auto const & in: event.incoming()){ vx->add_particle_in( make_ptr( to_FourVector(in), static_cast(in.type), status_in ) ); } for(size_t i=0; i < event.outgoing().size(); ++i){ auto const & out = event.outgoing()[i]; auto particle = make_ptr( to_FourVector(out), static_cast(out.type), status_out ); const int status = event.decays().count(i)?status_decayed:status_out; particle->set_status(status); if( status == status_decayed){ auto vx_decay = make_ptr(); vx_decay->add_particle_in(particle); for( auto const & out: event.decays().at(i)){ vx_decay->add_particle_out( make_ptr( to_FourVector(out), static_cast(out.type), status_out ) ); } out_ev.add_vertex(vx_decay); } vx->add_particle_out(particle); } out_ev.add_vertex(vx); return out_ev; } void HepMCInterface::set_central(HepMC::GenEvent & out_ev, Event const & event, ssize_t const weight_index ) { EventParameters event_param; if(weight_index < 0) event_param = event.central(); else if ( (size_t) weight_index < event.variations().size()) event_param = event.variations(weight_index); else throw std::invalid_argument{ "HepMCInterface tried to access a weight outside of the variation range." }; const double wt = event_param.weight; tot_weight_ += wt; tot_weight2_ += wt * wt; if(out_ev.weights().size() == 0){ out_ev.weights().push_back(wt); } else { // central always on first out_ev.weights()[0] = wt; } #if HEJ_BUILD_WITH_HepMC_VERSION >= 3 out_ev.set_cross_section( HepMC::make_shared(cross_section()) ); #else // HepMC 2 out_ev.set_cross_section( cross_section() ); out_ev.set_signal_process_id(event.type()+1); // "+1": conistent with lhe out_ev.set_event_scale(event_param.mur); #endif ++event_count_; out_ev.set_event_number(event_count_); /// @TODO add alphaQCD (need function) and alphaQED /// @TODO output pdf (currently not avaiable from event alone) } void HepMCInterface::add_variation(HepMC::GenEvent & out_ev, std::vector const & varis ) { for(auto const & var: varis){ out_ev.weights().push_back(var.weight); } /// @TODO add name list for weights } HepMC::GenEvent HepMCInterface::operator()(Event const & event, ssize_t const weight_index ) { HepMC::GenEvent out_ev(init_kinematics(event)); set_central(out_ev, event, weight_index); add_variation(out_ev, event.variations()); return out_ev; } } #else // no HepMC => empty class namespace HepMC { class GenEvent {}; class GenCrossSection {}; } namespace HEJ{ HepMCInterface::HepMCInterface(){ throw std::invalid_argument( "Failed to create HepMCInterface: " "HEJ 2 was built without HepMC support" ); } HepMC::GenEvent HepMCInterface::operator()(Event const &, ssize_t) {return HepMC::GenEvent();} HepMC::GenEvent HepMCInterface::init_kinematics(Event const &) {return HepMC::GenEvent();} void HepMCInterface::add_variation(HepMC::GenEvent &, std::vector const &){} void HepMCInterface::set_central(HepMC::GenEvent &, Event const &, ssize_t) {} HepMC::GenCrossSection HepMCInterface::cross_section() const {return HepMC::GenCrossSection();} } #endif