8 #ifndef Pythia8_LHAMadgraph_H
9 #define Pythia8_LHAMadgraph_H
11 #include "Pythia8/Pythia.h"
12 #include "Pythia8Plugins/JetMatching.h"
13 #include "Pythia8Plugins/GeneratorInput.h"
63 class LHAupMadgraph :
public LHAup {
68 enum Stage{Auto, Configure, Generate, Launch};
71 LHAupMadgraph(Pythia* pythiaIn,
bool matchIn =
true,
72 string dirIn =
"madgraphrun",
string exeIn =
"mg5_aMC");
79 bool readString(
string line, Stage stage = Auto);
82 void addCard(
string src,
string dst);
85 void setEvents(
int eventsIn);
88 bool setSeed(
int seedIn,
int runsIn = 30081);
91 void setJets(
int jetsIn);
97 bool setEvent(
int = 0);
104 bool execute(
string line);
116 bool run(
int eventsIn,
int seedIn = -1);
119 bool reader(
bool init);
122 void errorMsg(
string messageIn) {
124 int times = messages[messageIn];
125 ++messages[messageIn];
127 if (times < TIMESTOPRINT) cout <<
" PYTHIA " << messageIn << endl;
135 shared_ptr<JetMatchingMadgraph> hook;
138 int events, seed, runs, nRuns, jets;
139 bool match, amcatnlo;
140 string dir, exe, lhegz;
141 vector< pair<string, string> > cards;
144 vector<string> configureLines, generateLines, launchLines;
147 vector<bool>
override;
150 map<string, int> messages;
152 static const int TIMESTOPRINT = 1;
160 LHAupMadgraph::LHAupMadgraph(Pythia *pythiaIn,
bool matchIn,
string dirIn,
162 pythia(pythiaIn), lhef(0), hook(0), events(10000), seed(-1), runs(30081),
163 nRuns(0), jets(-1), match(matchIn), dir(dirIn), exe(exeIn),
164 lhegz(dirIn +
"/events.lhe.gz"), override(vector<bool>(3, false)) {
165 mkdir(dir.c_str(), 0777);
166 if (pythia) pythia->readString(
"Beams:frameType = 5");
173 LHAupMadgraph::~LHAupMadgraph() {
175 if (lhef)
delete lhef;
178 cout <<
"\n *------- LHAupMadgraph Error and Warning Messages Statistics"
179 <<
" ---------------------------------------------------* \n"
182 <<
" | times message "
188 map<string, int>::iterator messageEntry = messages.begin();
189 if (messageEntry == messages.end())
190 cout <<
" | 0 no errors or warnings to report "
192 while (messageEntry != messages.end()) {
194 string temp = messageEntry->first;
195 int len = temp.length();
196 temp.insert( len, max(0, 102 - len),
' ');
197 cout <<
" | " << setw(6) << messageEntry->second <<
" "
205 <<
" *------- End LHAupMadgraph Error and Warning Messages "
206 <<
"Statistics -----------------------------------------------* "
231 bool LHAupMadgraph::readString(
string line, Stage stage) {
233 if (line.substr(0, 4) ==
" set") launchLines.push_back(line);
234 else if (line.substr(0, 10) ==
"configure ")
235 configureLines.push_back(line.substr(10));
236 else if (line.substr(0, 6) !=
"output" && line.substr(0, 6) !=
"launch")
237 generateLines.push_back(line);
239 }
else if (stage == Configure) {
240 override[Configure] =
true;
if (line !=
"") configureLines.push_back(line);
241 }
else if (stage == Generate) {
242 override[Generate] =
true; generateLines.push_back(line);
243 }
else if (stage == Launch) {
244 override[Launch] =
true; launchLines.push_back(line);
260 void LHAupMadgraph::addCard(
string src,
string dst) {
261 cards.push_back(make_pair(src, dst));
284 bool LHAupMadgraph::setSeed(
int seedIn,
int runsIn) {
286 if (!pythia)
return false;
289 seed = pythia->settings.mode(
"Random:seed");
291 errorMsg(
"Error from LHAupMadgraph::setSeed: the given "
292 "Pythia seed is less than 1.");
return false;}
295 if (seed * runs > 30081 * 30081) {
296 errorMsg(
"Error from LHAupMadgraph::setSeed: the given seed "
297 "exceeds the MadGraph limit.");
return false;}
307 void LHAupMadgraph::setEvents(
int eventsIn) {events = eventsIn;}
317 void LHAupMadgraph::setJets(
int jetsIn) {jets = jetsIn;}
323 bool LHAupMadgraph::execute(
string line) {
return system(line.c_str()) != -1;}
333 bool LHAupMadgraph::configure() {
335 if (
override[Configure] && configureLines.size() == 0)
return true;
336 mkdir((dir +
"/.mg5").c_str(), 0777);
337 fstream config((dir +
"/.mg5/mg5_configuration.txt").c_str(), ios::out);
338 for (
int iLine = 0; iLine < (int)configureLines.size(); ++iLine)
339 config << configureLines[iLine] <<
"\n";
340 if (!
override[Configure])
341 config <<
"automatic_html_opening = False\n"
342 <<
"auto_update = 0\n";
357 bool LHAupMadgraph::generate() {
360 if (!pythia)
return false;
361 fstream config((dir +
"/generate.py").c_str(), ios::out);
362 for (
int iLine = 0; iLine < (int)generateLines.size(); ++iLine)
363 config << generateLines[iLine] <<
"\n";
364 if (!
override[Generate]) config <<
"output " << dir <<
"/tmp -f -nojpeg\n";
368 fstream orig((dir +
"/.mg5/mg5_configuration.txt").c_str(), ios::in);
369 char *home = getenv(
"HOME");
370 setenv(
"HOME", dir.c_str(), 1);
371 bool success = execute(exe +
" " + dir +
"/generate.py");
372 setenv(
"HOME", home, 1);
373 if (!success) {orig.close();
return false;}
374 else if (access((dir +
"/tmp/Cards/run_card.dat").c_str(), F_OK) == -1) {
375 errorMsg(
"Error from LHAupMadgraph::generate: MadGraph "
376 "failed to produce run_card.dat");
377 orig.close();
return false;
378 }
else execute(
"mv " + dir +
"/tmp/* " + dir +
"; rmdir " + dir +
"/tmp");
382 access((dir +
"/Cards/amcatnlo_configuration.txt").c_str(), F_OK) != -1;
384 fstream copy((dir +
"/Cards/" + (amcatnlo ?
"amcatnlo" :
"me5") +
385 "_configuration.txt").c_str(), ios::out);
386 copy << orig.rdbuf(); copy.close();
391 for (
int iCard = 0; iCard < (int)cards.size(); ++iCard) {
392 ifstream src((cards[iCard].first).c_str(), ios::binary);
393 ofstream dst((dir +
"/Cards/" + cards[iCard].second).c_str(), ios::binary);
407 bool LHAupMadgraph::launch() {
410 if (!pythia)
return false;
411 fstream config((dir +
"/launch.py").c_str(), ios::out);
412 if (!
override[Launch]) {
413 config <<
"launch " << dir <<
" -n run";
414 if (amcatnlo) config <<
" -p\n" <<
"set parton_shower PYTHIA8\n"
415 <<
"set ickkw 3\n" <<
"set nevents 0\n"
416 <<
"set req_acc 0.001\n";
417 else config <<
" -s parton\n" <<
"set ickkw 1\n" <<
"set gridpack True\n";
421 for (
int iLine = 0; iLine < (int)launchLines.size(); ++iLine)
422 config << launchLines[iLine] <<
"\n";
423 if (!
override[Launch]) config <<
"done\n";
428 string line =
"cd " + dir +
"/MCatNLO/lib; LINKS=`ls`; for LINK in $LINKS;"
429 " do TARG=`readlink $LINK`; if [[ $TARG = ../* ]]; then "
430 "rm $LINK; ln -s ${TARG:3} $LINK; fi; done";
431 if (!execute(line)) {
432 errorMsg(
"Error from LHAupMadgraph::launch: failed to "
433 "link aMC@NLO libraries");
return false;}
437 if (!execute(exe +
" " + dir +
"/launch.py"))
return false;
439 if (access((dir +
"/SubProcesses/results.dat").c_str(), F_OK) == -1) {
440 errorMsg(
"Error from LHAupMadgraph::launch: aMC@NLO failed "
441 "to produce results.dat");
return false;}
442 fstream script((dir +
"/run.sh").c_str(), ios::out);
443 script <<
"#!/usr/bin/env bash\n"
444 <<
"sed -i \"s/.*= *nevents/$1 = nevents/g\" ./Cards/run_card.dat\n"
445 <<
"sed -i \"s/.*= *iseed/$2 = iseed/g\" ./Cards/run_card.dat\n"
446 <<
"./bin/generate_events --parton --nocompile --only_generation "
447 "--force --name run\n" <<
"mv Events/run/events.lhe.gz ./\n";
448 script.close(); execute(
"chmod 755 " + dir +
"/run.sh");
450 string gpk =
"run_gridpack.tar.gz";
451 if (access((dir +
"/" + gpk).c_str(), F_OK) == -1) {
452 errorMsg(
"Error from LHAupMadgraph::launch: MadEvent failed"
453 " to produce " + gpk);
return false;}
454 string line =
"cd " + dir +
"; tar -xzf " + gpk +
"; cd madevent/lib; "
455 "LINK=`readlink libLHAPDF.a`; if [[ $LINK = ../* ]]; then "
456 "rm libLHAPDF.a; ln -s ../$LINK libLHAPDF.a; fi; cd ../; "
457 "./bin/compile dynamic; ./bin/clean4grid";
458 if (!execute(line)) {
459 errorMsg(
"Error from LHAupMadgraph::launch: failed to "
460 "compile MadEvent code");
return false;}
470 bool LHAupMadgraph::run(
int eventsIn,
int seedIn) {
472 if (!pythia)
return false;
474 errorMsg(
"Error from LHAupMadgraph::run: maximum number "
475 "of allowed runs exceeded.");
return false;}
476 if (access((dir +
"/run.sh").c_str(), F_OK) == -1)
return false;
477 if (seed < 0 && !setSeed(seed, runs))
return false;
478 if (seedIn < 0) seedIn = (seed - 1) * runs + nRuns + 1;
480 line <<
"cd " + dir +
"; ./run.sh " << eventsIn <<
" " << seedIn;
481 if (!amcatnlo) line <<
"; rm -rf ./madevent/Events/*";
482 if (!execute(line.str()))
return false;
483 if (access(lhegz.c_str(), F_OK) == -1)
return false;
493 bool LHAupMadgraph::reader(
bool init) {
496 if (!pythia)
return false;
497 if (lhef)
delete lhef;
498 bool setScales(pythia->settings.flag(
"Beams:setProductionScalesFromLHEF"));
499 lhef =
new LHAupLHEF(infoPtr, lhegz.c_str(), NULL,
false, setScales);
500 if (!lhef->setInit()) {
501 errorMsg(
"Error from LHAupMadgraph::reader: failed to "
502 "initialize the LHEF reader");
return false;}
503 if (lhef->sizeProc() != 1) {
504 errorMsg(
"Error from LHAupMadgraph::reader: number of "
505 "processes is not 1");
return false;}
510 double sig(lhef->xSec(0)), err(lhef->xErr(0));
512 fstream results((dir +
"/madevent/SubProcesses/"
513 "run_results.dat").c_str(), ios::in);
514 string v; vector<double> vs;
515 while (std::getline(results, v,
' ')) vs.push_back(atof(v.c_str()));
517 errorMsg(
"Error from LHAupMadgraph::reader: could not "
518 "extract cross-section");
return false;}
519 sig = vs[0]; err = vs[1];
523 setBeamA(lhef->idBeamA(), lhef->eBeamA(), lhef->pdfGroupBeamA(),
524 lhef->pdfSetBeamA());
525 setBeamB(lhef->idBeamB(), lhef->eBeamB(), lhef->pdfGroupBeamB(),
526 lhef->pdfSetBeamB());
527 setStrategy(lhef->strategy());
528 addProcess(lhef->idProcess(0), sig, err, lhef->xMax(0));
529 xSecSumSave = sig; xErrSumSave = err;
542 bool LHAupMadgraph::setInit() {
545 if (!pythia)
return false;
546 if (access((dir +
"/run.sh").c_str(), F_OK) == -1) {
548 errorMsg(
"Error from LHAupMadgraph::setInit: failed to "
549 "create the MadGraph configuration");
return false;}
551 errorMsg(
"Error from LHAupMadgraph::setInit: failed to "
552 "generate the MadGraph process");
return false;}
554 errorMsg(
"Error from LHAupMadgraph::setInit: failed to "
555 "launch the MadGraph process");
return false;}
558 access((dir +
"/Cards/amcatnlo_configuration.txt").c_str(), F_OK) != -1;
564 ifstream card((dir +
"/Cards/run_card.dat").c_str());
565 string str((std::istreambuf_iterator<char>(card)),
566 std::istreambuf_iterator<char>());
572 int iLine = jets < 0 ? 0 : generateLines.size();
573 for (; iLine < (int)generateLines.size(); ++iLine) {
574 string line = generateLines[iLine];
575 size_t found = line.find(
">");
576 if (found == string::npos)
continue;
577 else line = line.substr(found);
578 stringstream sline(line);
string p;
int n(0);
579 while (std::getline(sline, p,
' ') && p !=
",")
580 if (p ==
"j" || p ==
"g" || p ==
"u" || p ==
"d" || p ==
"c" ||
581 p ==
"s" || p ==
"b" || p ==
"u~" || p ==
"d~" || p ==
"c~" ||
582 p ==
"s~" || p ==
"b~") ++n;
583 if (n > jets) jets = n;
587 double etaj = mad.getParam(
"etaj");
588 Settings &set = pythia->settings;
589 set.flag(
"JetMatching:merge",
true);
590 set.mode(
"JetMatching:scheme", 1);
591 set.flag(
"JetMatching:setMad",
false);
592 set.mode(
"JetMatching:nQmatch", mad.getParamAsInt(
"maxjetflavor"));
593 set.parm(
"JetMatching:qCut", mad.getParam(
"ptj"));
594 set.parm(
"JetMatching:etaJetMax", etaj > 0 ? etaj : 100);
595 set.mode(
"JetMatching:nJetMax", jets);
596 set.parm(
"Check:epTolErr", 1e-2);
600 set.parm(
"JetMatching:coneRadius", mad.getParam(
"jetradius"));
601 set.mode(
"JetMatching:slowJetPower", mad.getParam(
"jetalgo"));
602 set.parm(
"JetMatching:qCutME", mad.getParam(
"ptj"));
603 set.mode(
"JetMatching:jetAlgorithm", 2);
604 set.flag(
"JetMatching:doFxFx",
true);
605 set.flag(
"SpaceShower:MEcorrections",
false);
606 set.parm(
"TimeShower:pTmaxMatch", 1);
607 set.parm(
"TimeShower:pTmaxFudge", 1);
608 set.flag(
"TimeShower:MEcorrections",
false);
609 set.flag(
"TimeShower:globalRecoil",
true);
610 set.flag(
"TimeShower:limitPTmaxGlobal",
true);
611 set.mode(
"TimeShower:nMaxGlobalRecoil", 1);
612 set.mode(
"TimeShower:globalRecoilMode", 2);
615 }
else set.parm(
"JetMatching:clFact", mad.getParam(
"alpsfact"));
618 hook = make_shared<JetMatchingMadgraph>();
619 pythia->setUserHooksPtr((UserHooksPtr)hook);
623 if (!run(events))
return false;
624 if (!reader(
true))
return false;
634 bool LHAupMadgraph::setEvent(
int) {
637 if (!pythia)
return false;
639 errorMsg(
"Error from LHAupMadgraph::setEvent: LHAupLHEF "
640 "object not correctly initialized");
return false;}
641 if (!lhef->fileFound()) {
642 errorMsg(
"Error from LHAupMadgraph::setEvent: LHEF "
643 "event file was not found");
return false;}
644 if (!lhef->setEvent()) {
645 if (!run(events))
return false;
646 if (!reader(
false))
return false;
651 setProcess(lhef->idProcess(), lhef->weight(), lhef->scale(),
652 lhef->alphaQED(), lhef->alphaQCD());
653 for (
int ip = 1; ip < lhef->sizePart(); ++ip)
654 addParticle(lhef->id(ip), lhef->status(ip), lhef->mother1(ip),
655 lhef->mother2(ip), lhef->col1(ip), lhef->col2(ip),
656 lhef->px(ip), lhef->py(ip), lhef->pz(ip), lhef->e(ip),
657 lhef->m(ip), lhef->tau(ip), lhef->spin(ip), lhef->scale(ip));
658 setIdX(lhef->id1(), lhef->id2(), lhef->x1(), lhef->x2());
659 setPdf(lhef->id1pdf(), lhef->id2pdf(), lhef->x1pdf(), lhef->x2pdf(),
660 lhef->scalePDF(), lhef->pdf1(), lhef->pdf2(), lhef->pdfIsSet());
669 #endif // Pythia8_LHAMadgraph_H