17#include "GaudiKernel/IAppMgrUI.h"
18#include "GaudiKernel/Bootstrap.h"
19#include "GaudiKernel/ITHistSvc.h"
21#include "Rivet/Rivet.hh"
22#include "Rivet/Analysis.hh"
23#include "Rivet/Config/RivetConfig.hh"
24#include "Rivet/Tools/RivetYODA.hh"
62 char const* val = getenv(key.c_str());
63 return val == NULL ? std::string() : std::string(val);
69 ATH_MSG_INFO(
"Using Rivet version " << Rivet::version());
80 std::string env_rap(
getenv_str(
"RIVET_ANALYSIS_PATH"));
81 if (!m_anapath.empty()) {
82 ATH_MSG_INFO(
"Setting Rivet plugin analyses loader env path: " << m_anapath);
83 if (!env_rap.empty())
ATH_MSG_INFO(
"Overwriting environment's RIVET_ANALYSIS_PATH = " << env_rap <<
"!");
84 setenv(
"RIVET_ANALYSIS_PATH", m_anapath.c_str(), 1);
89 if (!env_rap.empty())
ATH_MSG_DEBUG(
"Loading Rivet plugin analyses from env path: " << env_rap);
92 #if RIVET_VERSION_CODE >= 40100
93 m_analysisHandler =
new Rivet::AnalysisHandler();
95 m_analysisHandler =
new Rivet::AnalysisHandler(m_runname);
97 assert(m_analysisHandler);
99 #if RIVET_VERSION_CODE >= 40000
100 m_analysisHandler->setCheckBeams(!m_ignorebeams);
101 m_analysisHandler->matchWeightNames(m_matchWeights);
102 m_analysisHandler->unmatchWeightNames(m_unmatchWeights);
104 m_analysisHandler->setIgnoreBeams(m_ignorebeams);
105 m_analysisHandler->selectMultiWeights(m_matchWeights);
106 m_analysisHandler->deselectMultiWeights(m_unmatchWeights);
108 m_analysisHandler->skipMultiWeights(m_skipweights);
109 m_analysisHandler->setNominalWeightName(m_nominalWeightName);
110 if (m_weightcap>0) m_analysisHandler->setWeightCap(m_weightcap);
116 if (msgLvl(MSG::VERBOSE)) {
117 std::vector<std::string> analysisNames = Rivet::AnalysisLoader::analysisNames();
123 for (
const std::string&
a : m_analysisNames) {
125 m_analysisHandler->addAnalysis(
a);
126 Rivet::Log::setLevel(
"Rivet.Analysis."+
a,
rivetLevel(
msg().level()));
133 if (m_preload!=
"") {
134 m_analysisHandler->readData(m_preload);
137 return StatusCode::SUCCESS;
148 std::unique_ptr<HepMC::GenEvent> checkedEvent;
151 if (
evtStore()->retrieve(truthCollection,
"TruthEvents").isFailure()) {
152 ATH_MSG_ERROR(
"Could not retrieve TruthEvents collection, aborting.");
153 return StatusCode::FAILURE;
157 ATH_MSG_DEBUG(
"Attempt xAOD::Truth to HepMC::GenEvent conversion.");
158 std::vector<HepMC::GenEvent>&& hepmc_evts =
m_xAODtoHepMCTool->getHepMCEvents(truthCollection, eventInfo.
cptr());
160 if (hepmc_evts.empty()) {
161 ATH_MSG_ERROR(
"Conversion didn't yield HepMC::GenEvent, aborting.");
162 return StatusCode::FAILURE;
164 checkedEvent =
checkEvent(std::move(hepmc_evts[0]), ctx);
171 if (
sc.isFailure() || eventCollection == 0) {
173 return StatusCode::FAILURE;
182 if (event ==
nullptr) {
184 return StatusCode::FAILURE;
193 return StatusCode::FAILURE;
205 return StatusCode::SUCCESS;
223 if (
m_file.find(
".yoda") == std::string::npos)
m_file +=
".yoda.gz";
224 auto pos =
m_file.find(
".gz.");
225 if (pos == std::string::npos) {
232 if (std::rename((
m_file.substr(0, pos)+
".gz").c_str(),
m_file.c_str()) !=0) {
233 std::string error_msg =
"Impossible to rename ";
234 error_msg +=
m_file.substr(0, pos)+
".gz";
238 return StatusCode::FAILURE;
242 return StatusCode::SUCCESS;
249 return a->momentum().e() > b->momentum().e();
252inline std::vector<std::string>
split(
const std::string& input,
const std::string& regex) {
254 std::regex
re(regex);
255 std::sregex_token_iterator
256 first{input.begin(), input.end(),
re, -1},
258 return {first, last};
262 auto modEvent = std::make_unique<HepMC::GenEvent>(event);
267 modEvent->set_event_number(
static_cast<int>(evtInfo->eventNumber()));
271 std::shared_ptr<HepMC3::GenRunInfo> modRunInfo;
272 if (event.run_info()) {
273 modRunInfo = std::make_shared<HepMC3::GenRunInfo>(*(event.run_info().get()));
274 if (event.run_info()->weight_names().empty() && event.weights().size() == 1) {
275 modRunInfo->set_weight_names({
"Default"});
279 ATH_MSG_DEBUG(
"No run info, event weights size is " << event.weights().size() );
280 modRunInfo = std::make_shared<HepMC3::GenRunInfo>();
281 std::vector<std::string> w_names;
282 for (
size_t i = 0; i <
event.weights().
size(); i++) { w_names.push_back(std::string(
"badweight") + std::to_string(i)); }
283 modRunInfo->set_weight_names(w_names);
285 modEvent->set_run_info(std::move(modRunInfo));
286 std::vector<std::string> w_names = modEvent->weight_names();
287 if (w_names.size()) {
288 std::vector<std::pair<std::string,std::string> > w_subs = {
301 for (std::string& wname : w_names) {
302 for (
const auto& sub : w_subs) {
303 size_t start_pos = wname.find(sub.first);
304 while (start_pos != std::string::npos) {
305 wname.replace(start_pos, sub.first.length(), sub.second);
306 start_pos = wname.find(sub.first);
310 modEvent->run_info()->set_weight_names(w_names);
313 modEvent->set_units(HepMC3::Units::GEV, HepMC3::Units::MM);
314 if (modEvent->particles().size() == 1) modEvent->set_beam_particles(modEvent->particles().front(), modEvent->particles().front());
319 for (
const auto& p : modEvent->particles()) {
321 etotal += p->momentum().e();
323 const double ebeam = 0.5*etotal;
328 std::vector<HepMC::GenParticlePtr> notBeams;
333 for (
const auto& bp : notBeams) bp->production_vertex()->remove_particle_out(bp);
335 modEvent->set_beam_particles(std::move(b1), std::move(b2));
337 if (modEvent->beams().front()->momentum().e() > 50000.0) {
345 for (
auto& p: evt.particles()) {
346 p->set_momentum(p->momentum()*0.001);
347 p->set_generated_mass(p->generated_mass()*0.001);
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
Helpers for checking error return status codes and reporting errors.
ATLAS-specific HepMC functions.
Rivet::Log::Level rivetLevel(MSG::Level gaudiLevel)
bool cmpGenParticleByEDesc(HepMC::ConstGenParticlePtr a, HepMC::ConstGenParticlePtr b)
Helper function to sort GenParticles by descending energy.
std::string getenv_str(const std::string &key)
StatusCode Rivet_i::initialize ATLAS_NOT_THREAD_SAFE()
Install fatal handler with default options.
std::vector< std::string > split(const std::string &input, const std::string ®ex)
size_t size() const
Number of registered mappings.
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
ServiceHandle< StoreGateSvc > & evtStore()
const T * front() const
Access the first element in the collection as an rvalue.
This defines the McEventCollection, which is really just an ObjectVector of McEvent objectsFile: Gene...
bool m_skipweights
Skip variation weights and only run nominal.
double m_weightcap
Weight cap to set allowed maximum for weights.
std::vector< std::string > m_analysisNames
A list of names of the analyses to run (set from the job properties).
bool m_ignorebeams
Whether to avoid the beam consistency checks.
double m_crossSection
The cross section for this run of events, set from the job properties.
bool m_patchBeams
Flag to insert beam protons when they are unavailable in the event.
virtual StatusCode finalize() override
Finalise each analysis and commit the plots to the YODA tree and the THistSvc ROOT tree.
virtual StatusCode execute(const EventContext &ctx) override
Run the Rivet analyses on one event, which is retrieved from StoreGate.
std::string m_anapath
The analysis plugin search path.
bool m_init
Flag to determine whether Rivet init has already happened (in execute()).
ToolHandle< IxAODtoHepMCTool > m_xAODtoHepMCTool
A tool to convert xAOD::Truth to HepMC::GenEvent.
std::string m_file
The base file name to write results to.
std::string m_unmatchWeights
String of weight names (or regex) to veto multiweights.
std::string m_matchWeights
String of weight names (or regex) to select multiweights.
SG::ReadHandleKey< xAOD::EventInfo > m_evtInfoKey
double m_crossSection_uncert
The uncertainity of the cross section for this run of events, set from the job properties.
bool m_needsConversion
Do we need to convert xAOD::Truth back to HepMC::GenEvemt?
Rivet::AnalysisHandler * m_analysisHandler
A Rivet analysis handler.
bool m_doRootHistos
Will we convert Rivet's internal histo format into a ROOT histo for streaming with THistSvc?
std::string m_stream
A pointer to the THistSvc.
Rivet_i(const std::string &name, ISvcLocator *pSvcLocator)
Standard algorithm constructor.
std::unique_ptr< HepMC::GenEvent > checkEvent(const HepMC::GenEvent &event, const EventContext &ctx)
std::string m_genEventKey
The GenEvent StoreGate key (default "GEN_EVENT").
std::string m_nominalWeightName
String to specify non-standard nominal weight.
void MeV2GeV(HepMC::GenEvent &event)
std::string m_runname
The name of the run (prepended to plot paths).
const_pointer_type cptr()
Dereference the pointer.
HepMC3::FourVector FourVector
HepMC3::GenParticlePtr GenParticlePtr
HepMC3::ConstGenParticlePtr ConstGenParticlePtr
HepMC3::GenEvent GenEvent
bool isStable(const T &p)
Identify if the particle is stable, i.e. has not decayed.
bool isBeam(const T &p)
Identify if the particle is beam particle.
TruthEventContainer_v1 TruthEventContainer
Declare the latest version of the truth event container.