File indexing completed on 2025-01-18 10:06:38
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef Pythia8_LHAMadgraph_H
0009 #define Pythia8_LHAMadgraph_H
0010
0011 #include "Pythia8/Pythia.h"
0012 #include "Pythia8Plugins/JetMatching.h"
0013 #include "Pythia8Plugins/GeneratorInput.h"
0014 #include <unistd.h>
0015 #include <sys/stat.h>
0016
0017 namespace Pythia8 {
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063 class LHAupMadgraph : public LHAup {
0064
0065 public:
0066
0067
0068 enum Stage{Auto, Configure, Generate, Launch};
0069
0070
0071 LHAupMadgraph(Pythia* pythiaIn, bool matchIn = true,
0072 string dirIn = "madgraphrun", string exeIn = "mg5_aMC");
0073
0074
0075
0076 ~LHAupMadgraph();
0077
0078
0079 bool readString(string line, Stage stage = Auto);
0080
0081
0082 void addCard(string src, string dst);
0083
0084
0085 void setEvents(int eventsIn);
0086
0087
0088 bool setSeed(int seedIn, int runsIn = 30081);
0089
0090
0091 void setJets(int jetsIn);
0092
0093
0094 bool setInit();
0095
0096
0097 bool setEvent(int = 0);
0098
0099
0100
0101
0102
0103
0104 bool execute(string line);
0105
0106
0107 bool configure();
0108
0109
0110 bool generate();
0111
0112
0113 bool launch();
0114
0115
0116 bool run(int eventsIn, int seedIn = -1);
0117
0118
0119 bool reader(bool init);
0120
0121
0122 void errorMsg(string messageIn) {
0123
0124 int times = messages[messageIn];
0125 ++messages[messageIn];
0126
0127 if (times < TIMESTOPRINT) cout << " PYTHIA " << messageIn << endl;
0128 }
0129
0130 private:
0131
0132
0133 Pythia *pythia;
0134 LHAupLHEF *lhef;
0135 shared_ptr<JetMatchingMadgraph> hook;
0136
0137
0138 int events, seed, runs, nRuns, jets;
0139 bool match, amcatnlo;
0140 string dir, exe, lhegz;
0141 vector< pair<string, string> > cards;
0142
0143
0144 vector<string> configureLines, generateLines, launchLines;
0145
0146
0147 vector<bool> override;
0148
0149
0150 map<string, int> messages;
0151
0152 static const int TIMESTOPRINT = 1;
0153
0154 };
0155
0156
0157
0158
0159
0160 LHAupMadgraph::LHAupMadgraph(Pythia *pythiaIn, bool matchIn, string dirIn,
0161 string exeIn) :
0162 pythia(pythiaIn), lhef(0), hook(0), events(10000), seed(-1), runs(30081),
0163 nRuns(0), jets(-1), match(matchIn), dir(dirIn), exe(exeIn),
0164 lhegz(dirIn + "/events.lhe.gz"), override(vector<bool>(3, false)) {
0165 mkdir(dir.c_str(), 0777);
0166 if (pythia) pythia->readString("Beams:frameType = 5");
0167 }
0168
0169
0170
0171
0172
0173 LHAupMadgraph::~LHAupMadgraph() {
0174
0175 if (lhef) delete lhef;
0176
0177
0178 cout << "\n *------- LHAupMadgraph Error and Warning Messages Statistics"
0179 << " ---------------------------------------------------* \n"
0180 << " | "
0181 << " | \n"
0182 << " | times message "
0183 << " | \n"
0184 << " | "
0185 << " | \n";
0186
0187
0188 map<string, int>::iterator messageEntry = messages.begin();
0189 if (messageEntry == messages.end())
0190 cout << " | 0 no errors or warnings to report "
0191 << " | \n";
0192 while (messageEntry != messages.end()) {
0193
0194 string temp = messageEntry->first;
0195 int len = temp.length();
0196 temp.insert( len, max(0, 102 - len), ' ');
0197 cout << " | " << setw(6) << messageEntry->second << " "
0198 << temp << " | \n";
0199 ++messageEntry;
0200 }
0201
0202
0203 cout << " | "
0204 << " | \n"
0205 << " *------- End LHAupMadgraph Error and Warning Messages "
0206 << "Statistics -----------------------------------------------* "
0207 << endl;
0208 }
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231 bool LHAupMadgraph::readString(string line, Stage stage) {
0232 if (stage == Auto) {
0233 if (line.substr(0, 4) == " set") launchLines.push_back(line);
0234 else if (line.substr(0, 10) == "configure ")
0235 configureLines.push_back(line.substr(10));
0236 else if (line.substr(0, 6) != "output" && line.substr(0, 6) != "launch")
0237 generateLines.push_back(line);
0238 else return false;
0239 } else if (stage == Configure) {
0240 override[Configure] = true; if (line != "") configureLines.push_back(line);
0241 } else if (stage == Generate) {
0242 override[Generate] = true; generateLines.push_back(line);
0243 } else if (stage == Launch) {
0244 override[Launch] = true; launchLines.push_back(line);
0245 } else return false;
0246 return true;
0247 }
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260 void LHAupMadgraph::addCard(string src, string dst) {
0261 cards.push_back(make_pair(src, dst));
0262 }
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284 bool LHAupMadgraph::setSeed(int seedIn, int runsIn) {
0285
0286 if (!pythia) return false;
0287 seed = seedIn;
0288 if (seed < 0) {
0289 seed = pythia->settings.mode("Random:seed");
0290 if (seed < 1) {
0291 errorMsg("Error from LHAupMadgraph::setSeed: the given "
0292 "Pythia seed is less than 1."); return false;}
0293 }
0294 runs = runsIn;
0295 if (seed * runs > 30081 * 30081) {
0296 errorMsg("Error from LHAupMadgraph::setSeed: the given seed "
0297 "exceeds the MadGraph limit."); return false;}
0298 nRuns = 0;
0299 return true;
0300
0301 }
0302
0303
0304
0305
0306
0307 void LHAupMadgraph::setEvents(int eventsIn) {events = eventsIn;}
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317 void LHAupMadgraph::setJets(int jetsIn) {jets = jetsIn;}
0318
0319
0320
0321
0322
0323 bool LHAupMadgraph::execute(string line) {return system(line.c_str()) != -1;}
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333 bool LHAupMadgraph::configure() {
0334
0335 if (override[Configure] && configureLines.size() == 0) return true;
0336 mkdir((dir + "/.mg5").c_str(), 0777);
0337 fstream config((dir + "/.mg5/mg5_configuration.txt").c_str(), ios::out);
0338 for (int iLine = 0; iLine < (int)configureLines.size(); ++iLine)
0339 config << configureLines[iLine] << "\n";
0340 if (!override[Configure])
0341 config << "automatic_html_opening = False\n"
0342 << "auto_update = 0\n";
0343 config.close();
0344 return true;
0345
0346 }
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357 bool LHAupMadgraph::generate() {
0358
0359
0360 if (!pythia) return false;
0361 fstream config((dir + "/generate.py").c_str(), ios::out);
0362 for (int iLine = 0; iLine < (int)generateLines.size(); ++iLine)
0363 config << generateLines[iLine] << "\n";
0364 if (!override[Generate]) config << "output " << dir << "/tmp -f -nojpeg\n";
0365 config.close();
0366
0367
0368 fstream orig((dir + "/.mg5/mg5_configuration.txt").c_str(), ios::in);
0369 char *home = getenv("HOME");
0370 setenv("HOME", dir.c_str(), 1);
0371 bool success = execute(exe + " " + dir + "/generate.py");
0372 setenv("HOME", home, 1);
0373 if (!success) {orig.close(); return false;}
0374 else if (access((dir + "/tmp/Cards/run_card.dat").c_str(), F_OK) == -1) {
0375 errorMsg("Error from LHAupMadgraph::generate: MadGraph "
0376 "failed to produce run_card.dat");
0377 orig.close(); return false;
0378 } else execute("mv " + dir + "/tmp/* " + dir + "; rmdir " + dir + "/tmp");
0379
0380
0381 amcatnlo =
0382 access((dir + "/Cards/amcatnlo_configuration.txt").c_str(), F_OK) != -1;
0383 if (orig.good()) {
0384 fstream copy((dir + "/Cards/" + (amcatnlo ? "amcatnlo" : "me5") +
0385 "_configuration.txt").c_str(), ios::out);
0386 copy << orig.rdbuf(); copy.close();
0387 }
0388 orig.close();
0389
0390
0391 for (int iCard = 0; iCard < (int)cards.size(); ++iCard) {
0392 ifstream src((cards[iCard].first).c_str(), ios::binary);
0393 ofstream dst((dir + "/Cards/" + cards[iCard].second).c_str(), ios::binary);
0394 dst << src.rdbuf();
0395 }
0396 return true;
0397
0398 }
0399
0400
0401
0402
0403
0404
0405
0406
0407 bool LHAupMadgraph::launch() {
0408
0409
0410 if (!pythia) return false;
0411 fstream config((dir + "/launch.py").c_str(), ios::out);
0412 if (!override[Launch]) {
0413 config << "launch " << dir << " -n run";
0414 if (amcatnlo) config << " -p\n" << "set parton_shower PYTHIA8\n"
0415 << "set ickkw 3\n" << "set nevents 0\n"
0416 << "set req_acc 0.001\n";
0417 else config << " -s parton\n" << "set ickkw 1\n" << "set gridpack True\n";
0418 }
0419
0420
0421 for (int iLine = 0; iLine < (int)launchLines.size(); ++iLine)
0422 config << launchLines[iLine] << "\n";
0423 if (!override[Launch]) config << "done\n";
0424 config.close();
0425
0426
0427 if (amcatnlo) {
0428 string line = "cd " + dir + "/MCatNLO/lib; LINKS=`ls`; for LINK in $LINKS;"
0429 " do TARG=`readlink $LINK`; if [[ $TARG = ../* ]]; then "
0430 "rm $LINK; ln -s ${TARG:3} $LINK; fi; done";
0431 if (!execute(line)) {
0432 errorMsg("Error from LHAupMadgraph::launch: failed to "
0433 "link aMC@NLO libraries"); return false;}
0434 }
0435
0436
0437 if (!execute(exe + " " + dir + "/launch.py")) return false;
0438 if (amcatnlo) {
0439 if (access((dir + "/SubProcesses/results.dat").c_str(), F_OK) == -1) {
0440 errorMsg("Error from LHAupMadgraph::launch: aMC@NLO failed "
0441 "to produce results.dat"); return false;}
0442 fstream script((dir + "/run.sh").c_str(), ios::out);
0443 script << "#!/usr/bin/env bash\n"
0444 << "sed -i \"s/.*= *nevents/$1 = nevents/g\" ./Cards/run_card.dat\n"
0445 << "sed -i \"s/.*= *iseed/$2 = iseed/g\" ./Cards/run_card.dat\n"
0446 << "./bin/generate_events --parton --nocompile --only_generation "
0447 "--force --name run\n" << "mv Events/run/events.lhe.gz ./\n";
0448 script.close(); execute("chmod 755 " + dir + "/run.sh");
0449 } else {
0450 string gpk = "run_gridpack.tar.gz";
0451 if (access((dir + "/" + gpk).c_str(), F_OK) == -1) {
0452 errorMsg("Error from LHAupMadgraph::launch: MadEvent failed"
0453 " to produce " + gpk); return false;}
0454 string line = "cd " + dir + "; tar -xzf " + gpk + "; cd madevent/lib; "
0455 "LINK=`readlink libLHAPDF.a`; if [[ $LINK = ../* ]]; then "
0456 "rm libLHAPDF.a; ln -s ../$LINK libLHAPDF.a; fi; cd ../; "
0457 "./bin/compile dynamic; ./bin/clean4grid";
0458 if (!execute(line)) {
0459 errorMsg("Error from LHAupMadgraph::launch: failed to "
0460 "compile MadEvent code"); return false;}
0461 }
0462 return true;
0463
0464 }
0465
0466
0467
0468
0469
0470 bool LHAupMadgraph::run(int eventsIn, int seedIn) {
0471
0472 if (!pythia) return false;
0473 if (nRuns >= runs) {
0474 errorMsg("Error from LHAupMadgraph::run: maximum number "
0475 "of allowed runs exceeded."); return false;}
0476 if (access((dir + "/run.sh").c_str(), F_OK) == -1) return false;
0477 if (seed < 0 && !setSeed(seed, runs)) return false;
0478 if (seedIn < 0) seedIn = (seed - 1) * runs + nRuns + 1;
0479 stringstream line;
0480 line << "cd " + dir + "; ./run.sh " << eventsIn << " " << seedIn;
0481 if (!amcatnlo) line << "; rm -rf ./madevent/Events/*";
0482 if (!execute(line.str())) return false;
0483 if (access(lhegz.c_str(), F_OK) == -1) return false;
0484 ++nRuns;
0485 return true;
0486
0487 }
0488
0489
0490
0491
0492
0493 bool LHAupMadgraph::reader(bool init) {
0494
0495
0496 if (!pythia) return false;
0497 if (lhef) delete lhef;
0498 bool setScales(pythia->settings.flag("Beams:setProductionScalesFromLHEF"));
0499 lhef = new LHAupLHEF(infoPtr, lhegz.c_str(), nullptr, false, setScales);
0500 if (!lhef->setInit()) {
0501 errorMsg("Error from LHAupMadgraph::reader: failed to "
0502 "initialize the LHEF reader"); return false;}
0503 if (lhef->sizeProc() != 1) {
0504 errorMsg("Error from LHAupMadgraph::reader: number of "
0505 "processes is not 1"); return false;}
0506
0507 if (init) {
0508
0509
0510 double sig(lhef->xSec(0)), err(lhef->xErr(0));
0511 if (!amcatnlo) {
0512 fstream results((dir + "/madevent/SubProcesses/"
0513 "run_results.dat").c_str(), ios::in);
0514 string v; vector<double> vs;
0515 while (std::getline(results, v, ' ')) vs.push_back(atof(v.c_str()));
0516 if (vs.size() < 2) {
0517 errorMsg("Error from LHAupMadgraph::reader: could not "
0518 "extract cross-section"); return false;}
0519 sig = vs[0]; err = vs[1];
0520 }
0521
0522
0523 setBeamA(lhef->idBeamA(), lhef->eBeamA(), lhef->pdfGroupBeamA(),
0524 lhef->pdfSetBeamA());
0525 setBeamB(lhef->idBeamB(), lhef->eBeamB(), lhef->pdfGroupBeamB(),
0526 lhef->pdfSetBeamB());
0527 setStrategy(lhef->strategy());
0528 addProcess(lhef->idProcess(0), sig, err, lhef->xMax(0));
0529 xSecSumSave = sig; xErrSumSave = err;
0530 }
0531 return true;
0532
0533 }
0534
0535
0536
0537
0538
0539
0540
0541
0542 bool LHAupMadgraph::setInit() {
0543
0544
0545 if (!pythia) return false;
0546 if (access((dir + "/run.sh").c_str(), F_OK) == -1) {
0547 if (!configure()) {
0548 errorMsg("Error from LHAupMadgraph::setInit: failed to "
0549 "create the MadGraph configuration"); return false;}
0550 if (!generate()) {
0551 errorMsg("Error from LHAupMadgraph::setInit: failed to "
0552 "generate the MadGraph process"); return false;}
0553 if (!launch()) {
0554 errorMsg("Error from LHAupMadgraph::setInit: failed to "
0555 "launch the MadGraph process"); return false;}
0556 } else
0557 amcatnlo =
0558 access((dir + "/Cards/amcatnlo_configuration.txt").c_str(), F_OK) != -1;
0559
0560
0561 if (match) {
0562
0563
0564 ifstream card((dir + "/Cards/run_card.dat").c_str());
0565 string str((std::istreambuf_iterator<char>(card)),
0566 std::istreambuf_iterator<char>());
0567 MadgraphPar mad;
0568 mad.parse(str);
0569 mad.printParams();
0570
0571
0572 int iLine = jets < 0 ? 0 : generateLines.size();
0573 for (; iLine < (int)generateLines.size(); ++iLine) {
0574 string line = generateLines[iLine];
0575 size_t found = line.find(">");
0576 if (found == string::npos) continue;
0577 else line = line.substr(found);
0578 stringstream sline(line); string p; int n(0);
0579 while (std::getline(sline, p, ' ') && p != ",")
0580 if (p == "j" || p == "g" || p == "u" || p == "d" || p == "c" ||
0581 p == "s" || p == "b" || p == "u~" || p == "d~" || p == "c~" ||
0582 p == "s~" || p == "b~") ++n;
0583 if (n > jets) jets = n;
0584 }
0585
0586
0587 double etaj = mad.getParam("etaj");
0588 Settings &set = pythia->settings;
0589 set.flag("JetMatching:merge", true);
0590 set.mode("JetMatching:scheme", 1);
0591 set.flag("JetMatching:setMad", false);
0592 set.mode("JetMatching:nQmatch", mad.getParamAsInt("maxjetflavor"));
0593 set.parm("JetMatching:qCut", mad.getParam("ptj"));
0594 set.parm("JetMatching:etaJetMax", etaj > 0 ? etaj : 100);
0595 set.mode("JetMatching:nJetMax", jets);
0596 set.parm("Check:epTolErr", 1e-2);
0597
0598
0599 if (amcatnlo) {
0600 set.parm("JetMatching:coneRadius", mad.getParam("jetradius"));
0601 set.mode("JetMatching:slowJetPower", mad.getParam("jetalgo"));
0602 set.parm("JetMatching:qCutME", mad.getParam("ptj"));
0603 set.mode("JetMatching:jetAlgorithm", 2);
0604 set.flag("JetMatching:doFxFx", true);
0605 set.flag("SpaceShower:MEcorrections", false);
0606 set.parm("TimeShower:pTmaxMatch", 1);
0607 set.parm("TimeShower:pTmaxFudge", 1);
0608 set.flag("TimeShower:MEcorrections", false);
0609 set.flag("TimeShower:globalRecoil", true);
0610 set.flag("TimeShower:limitPTmaxGlobal", true);
0611 set.mode("TimeShower:nMaxGlobalRecoil", 1);
0612 set.mode("TimeShower:globalRecoilMode", 2);
0613
0614
0615 } else set.parm("JetMatching:clFact", mad.getParam("alpsfact"));
0616
0617
0618 hook = make_shared<JetMatchingMadgraph>();
0619 pythia->setUserHooksPtr((UserHooksPtr)hook);
0620 }
0621
0622
0623 if (!run(events)) return false;
0624 if (!reader(true)) return false;
0625 listInit();
0626 return true;
0627
0628 }
0629
0630
0631
0632
0633
0634 bool LHAupMadgraph::setEvent(int) {
0635
0636
0637 if (!pythia) return false;
0638 if (!lhef) {
0639 errorMsg("Error from LHAupMadgraph::setEvent: LHAupLHEF "
0640 "object not correctly initialized"); return false;}
0641 if (!lhef->fileFound()) {
0642 errorMsg("Error from LHAupMadgraph::setEvent: LHEF "
0643 "event file was not found"); return false;}
0644 if (!lhef->setEvent()) {
0645 if (!run(events)) return false;
0646 if (!reader(false)) return false;
0647 lhef->setEvent();
0648 }
0649
0650
0651 setProcess(lhef->idProcess(), lhef->weight(), lhef->scale(),
0652 lhef->alphaQED(), lhef->alphaQCD());
0653 for (int ip = 1; ip < lhef->sizePart(); ++ip)
0654 addParticle(lhef->id(ip), lhef->status(ip), lhef->mother1(ip),
0655 lhef->mother2(ip), lhef->col1(ip), lhef->col2(ip),
0656 lhef->px(ip), lhef->py(ip), lhef->pz(ip), lhef->e(ip),
0657 lhef->m(ip), lhef->tau(ip), lhef->spin(ip), lhef->scale(ip));
0658 setIdX(lhef->id1(), lhef->id2(), lhef->x1(), lhef->x2());
0659 setPdf(lhef->id1pdf(), lhef->id2pdf(), lhef->x1pdf(), lhef->x2pdf(),
0660 lhef->scalePDF(), lhef->pdf1(), lhef->pdf2(), lhef->pdfIsSet());
0661 return true;
0662
0663 }
0664
0665
0666
0667 }
0668
0669 #endif