File indexing completed on 2026-04-18 08:20:49
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef Pythia8_RivetHooks_H
0013 #define Pythia8_RivetHooks_H
0014
0015
0016 #include "Pythia8/Pythia.h"
0017 #include "Pythia8/Plugins.h"
0018 #include "Pythia8Plugins/HepMC3.h"
0019
0020
0021 #include "Rivet/AnalysisHandler.hh"
0022
0023
0024 #include <sys/stat.h>
0025
0026 namespace Pythia8 {
0027
0028
0029
0030
0031
0032
0033 bool makeDir(vector<string> path, mode_t mode = 0777) {
0034
0035
0036 struct stat info;
0037
0038
0039 string pathNow = "";
0040 bool first = true;
0041 for (string& dir : path) {
0042
0043
0044 pathNow += (first ? "" : "/") + dir;
0045 first = false;
0046 if (stat(pathNow.c_str(), &info) == 0) {
0047 if ((info.st_mode & S_IFDIR) == 0) return false;
0048 else continue;
0049 }
0050
0051
0052 if (mkdir(pathNow.c_str(), mode) != 0) return false;
0053 }
0054 return true;
0055
0056 }
0057
0058
0059
0060
0061
0062 class RivetHooks : public UserHooks {
0063
0064 public:
0065
0066
0067 RivetHooks() {}
0068 RivetHooks(Pythia* pythiaPtrIn, Settings*, Logger*) :
0069 pythiaPtr(pythiaPtrIn) {}
0070 ~RivetHooks() {if (rivetPtr != nullptr) delete rivetPtr;}
0071
0072
0073
0074
0075 void onEndEvent(Status) override {
0076
0077
0078 if (flag("Rivet:skipZeroWeights") && pythiaPtr->info.weight() == 0) {
0079 loggerPtr->INFO_MSG("skipping zero-weight event");
0080 return;
0081 }
0082
0083
0084 hepmc.fillNextEvent(*pythiaPtr);
0085
0086
0087
0088
0089 if (rivetPtr == nullptr) {
0090 mutexPtr->lock();
0091
0092
0093 rivetPtr = new Rivet::AnalysisHandler();
0094
0095
0096 rivetPtr->setCheckBeams(flag("Rivet:checkBeams"));
0097
0098
0099 if (mode("Rivet:dumpPeriod") > 0) {
0100 string dumpName = word("Rivet:dumpName");
0101 if (dumpName == "") dumpName = word("Rivet:fileName");
0102 rivetPtr->setFinalizePeriod(dumpName, mode("Rivet:dumpPeriod"));
0103 }
0104
0105
0106 for (string& preload : wvec("Rivet:preloads"))
0107 rivetPtr->readData(preload);
0108
0109
0110 for (string& analysis : wvec("Rivet:analyses"))
0111 rivetPtr->addAnalysis(analysis);
0112
0113
0114 rivetPtr->init(hepmc.event());
0115 mutexPtr->unlock();
0116 }
0117
0118
0119 rivetPtr->analyze(hepmc.event());
0120
0121 }
0122
0123
0124
0125
0126 void onStat() override {
0127
0128
0129 if (rivetPtr == nullptr) return;
0130 string filename = word("Rivet:fileName");
0131 vector<string> path = splitString(filename, "/");
0132 if (path.size() > 1) {
0133 mutexPtr->lock();
0134 makeDir(vector<string>(path.begin(), path.end() - 1));
0135 mutexPtr->unlock();
0136 }
0137
0138
0139 rivetPtr->finalize();
0140 rivetPtr->writeData(filename);
0141
0142 }
0143
0144
0145
0146
0147 void onStat(vector<PhysicsBase*> hookPtrs, Pythia*) override {
0148
0149
0150 Rivet::AnalysisHandler* rivetMain = rivetPtr;
0151 if (rivetMain == nullptr) {
0152 loggerPtr->ERROR_MSG("could not retrieve first RivetHooks");
0153 return;
0154 }
0155
0156
0157 int iPtr = 0;
0158 for (PhysicsBase* hookPtr : hookPtrs) {
0159 if (hookPtr == this) continue;
0160 RivetHooks* hookNow = dynamic_cast<RivetHooks*>(hookPtr);
0161 if (hookNow == nullptr) {
0162 loggerPtr->ERROR_MSG("could not retrieve RivetHooks for thread ",
0163 toString(iPtr));
0164 return;
0165 } else ++iPtr;
0166
0167
0168 Rivet::AnalysisHandler* rivetNow = hookNow->rivetPtr;
0169 if (rivetNow == nullptr) {
0170 loggerPtr->ERROR_MSG("could not retrieve AnalysisHandler for thread ",
0171 toString(iPtr));
0172 return;
0173 }
0174
0175
0176
0177
0178
0179
0180 try {
0181 rivetMain->merge(*rivetNow);
0182 } catch (const Rivet::UserError err) {
0183 loggerPtr->ERROR_MSG("failed to merge analyses in thread ",
0184 toString(iPtr));
0185 return;
0186 }
0187 rivetMain->merge(*rivetNow);
0188 }
0189
0190
0191 onStat();
0192
0193 }
0194
0195
0196
0197 private:
0198
0199 Pythia* pythiaPtr{};
0200 Rivet::AnalysisHandler* rivetPtr{};
0201 Pythia8ToHepMC hepmc;
0202
0203 };
0204
0205
0206
0207
0208
0209 void rivetSettings(Settings *settingsPtr) {
0210 settingsPtr->addWord("Rivet:fileName", "rivet.yoda");
0211 settingsPtr->addWVec("Rivet:analyses", {});
0212 settingsPtr->addWVec("Rivet:preloads", {});
0213 settingsPtr->addFlag("Rivet:checkBeams", true);
0214 settingsPtr->addWord("Rivet:dumpName", "");
0215 settingsPtr->addMode("Rivet:dumpPeriod", -1, true, false, -1, 0);
0216 settingsPtr->addFlag("Rivet:skipZeroWeights", false);
0217 }
0218
0219
0220
0221
0222
0223 PYTHIA8_PLUGIN_CLASS(UserHooks, RivetHooks, true, false, false)
0224 PYTHIA8_PLUGIN_SETTINGS(rivetSettings)
0225 PYTHIA8_PLUGIN_PARALLEL(true);
0226 PYTHIA8_PLUGIN_VERSIONS(PYTHIA_VERSION_INTEGER)
0227
0228
0229
0230 }
0231
0232 #endif