6 #include "Pythia8/Pythia.h"
7 using namespace Pythia8;
18 PowhegHooks(
int nFinalIn,
int vetoModeIn,
int vetoCountIn,
19 int pThardModeIn,
int pTemtModeIn,
int emittedModeIn,
20 int pTdefModeIn,
int MPIvetoModeIn) : nFinal(nFinalIn),
21 vetoMode(vetoModeIn), vetoCount(vetoCountIn),
22 pThardMode(pThardModeIn), pTemtMode(pTemtModeIn),
23 emittedMode(emittedModeIn), pTdefMode(pTdefModeIn),
24 MPIvetoMode(MPIvetoModeIn) {};
35 double pTpythia(
const Event &e,
int RadAfterBranch,
int EmtAfterBranch,
36 int RecAfterBranch,
bool FSR) {
39 Vec4 radVec = e[RadAfterBranch].p();
40 Vec4 emtVec = e[EmtAfterBranch].p();
41 Vec4 recVec = e[RecAfterBranch].p();
42 int radID = e[RadAfterBranch].id();
45 double sign = (FSR) ? 1. : -1.;
46 Vec4 Q(radVec + sign * emtVec);
47 double Qsq = sign * Q.m2Calc();
50 double m2Rad = (abs(radID) >= 4 && abs(radID) < 7) ?
51 pow2(particleDataPtr->m0(radID)) : 0.;
57 Vec4 sum = radVec + recVec + emtVec;
58 double m2Dip = sum.m2Calc();
59 double x1 = 2. * (sum * radVec) / m2Dip;
60 double x3 = 2. * (sum * emtVec) / m2Dip;
66 Vec4 qBR(radVec - emtVec + recVec);
67 Vec4 qAR(radVec + recVec);
68 z = qBR.m2Calc() / qAR.m2Calc();
73 pTnow *= (Qsq - sign * m2Rad);
77 cout <<
"Warning: pTpythia was negative" << endl;
82 cout <<
"pTpythia: rad = " << RadAfterBranch <<
", emt = "
83 << EmtAfterBranch <<
", rec = " << RecAfterBranch
84 <<
", pTnow = " << sqrt(pTnow) << endl;
92 double pTpowheg(
const Event &e,
int i,
int j,
bool FSR) {
100 int iInA = partonSystemsPtr->getInA(0);
101 int iInB = partonSystemsPtr->getInB(0);
102 double betaZ = - ( e[iInA].pz() + e[iInB].pz() ) /
103 ( e[iInA].e() + e[iInB].e() );
104 Vec4 iVecBst(e[i].p()), jVecBst(e[j].p());
105 iVecBst.bst(0., 0., betaZ);
106 jVecBst.bst(0., 0., betaZ);
107 pTnow = sqrt( (iVecBst + jVecBst).m2Calc() *
108 iVecBst.e() * jVecBst.e() /
109 pow2(iVecBst.e() + jVecBst.e()) );
118 cout <<
"Warning: pTpowheg was negative" << endl;
123 cout <<
"pTpowheg: i = " << i <<
", j = " << j
124 <<
", pTnow = " << pTnow << endl;
135 double pTcalc(
const Event &e,
int i,
int j,
int k,
int r,
int xSRin) {
138 double pTemt = -1., pTnow;
139 int xSR1 = (xSRin == -1) ? 0 : xSRin;
140 int xSR2 = (xSRin == -1) ? 2 : xSRin + 1;
141 for (
int xSR = xSR1; xSR < xSR2; xSR++) {
143 bool FSR = (xSR == 0) ?
false :
true;
147 if ((pTdefMode == 0 || pTdefMode == 1) && i > 0 && j > 0) {
148 pTemt = pTpowheg(e, i, j, (pTdefMode == 0) ?
false : FSR);
151 }
else if (!FSR && pTdefMode == 2 && i > 0 && j > 0 && r > 0) {
152 pTemt = pTpythia(e, i, j, r, FSR);
155 }
else if (FSR && pTdefMode == 2 && j > 0 && k > 0 && r > 0) {
156 pTemt = pTpythia(e, k, j, r, FSR);
164 int iInA = partonSystemsPtr->getInA(0);
165 int iInB = partonSystemsPtr->getInB(0);
166 while (e[iInA].mother1() != 1) { iInA = e[iInA].mother1(); }
167 while (e[iInB].mother1() != 2) { iInB = e[iInB].mother1(); }
170 int jNow = (j > 0) ? j : 0;
171 int jMax = (j > 0) ? j + 1 : e.size();
172 for (; jNow < jMax; jNow++) {
175 if (!e[jNow].isFinal() || e[jNow].colType() == 0)
continue;
178 if (pTdefMode == 0 || pTdefMode == 1) {
182 pTnow = pTpowheg(e, iInA, jNow, (pTdefMode == 0) ?
false : FSR);
183 if (pTnow > 0.) pTemt = (pTemt < 0) ? pTnow : min(pTemt, pTnow);
190 int outSize = partonSystemsPtr->sizeOut(0);
191 for (
int iMem = 0; iMem < outSize; iMem++) {
192 int iNow = partonSystemsPtr->getOut(0, iMem);
195 if (iNow == jNow || e[iNow].colType() == 0)
continue;
196 if (jNow == e[iNow].daughter1()
197 && jNow == e[iNow].daughter2())
continue;
199 pTnow = pTpowheg(e, iNow, jNow, (pTdefMode == 0)
201 if (pTnow > 0.) pTemt = (pTemt < 0)
202 ? pTnow : min(pTemt, pTnow);
208 }
else if (pTdefMode == 2) {
212 pTnow = pTpythia(e, iInA, jNow, iInB, FSR);
213 if (pTnow > 0.) pTemt = (pTemt < 0) ? pTnow : min(pTemt, pTnow);
214 pTnow = pTpythia(e, iInB, jNow, iInA, FSR);
215 if (pTnow > 0.) pTemt = (pTemt < 0) ? pTnow : min(pTemt, pTnow);
220 for (
int kNow = 0; kNow < e.size(); kNow++) {
221 if (kNow == jNow || !e[kNow].isFinal() ||
222 e[kNow].colType() == 0)
continue;
226 pTnow = pTpythia(e, kNow, jNow, iInA, FSR);
227 if (pTnow > 0.) pTemt = (pTemt < 0)
228 ? pTnow : min(pTemt, pTnow);
229 pTnow = pTpythia(e, kNow, jNow, iInB, FSR);
230 if (pTnow > 0.) pTemt = (pTemt < 0)
231 ? pTnow : min(pTemt, pTnow);
234 for (
int rNow = 0; rNow < e.size(); rNow++) {
235 if (rNow == kNow || rNow == jNow ||
236 !e[rNow].isFinal() || e[rNow].colType() == 0)
continue;
237 pTnow = pTpythia(e, kNow, jNow, rNow, FSR);
238 if (pTnow > 0.) pTemt = (pTemt < 0)
239 ? pTnow : min(pTemt, pTnow);
250 cout <<
"pTcalc: i = " << i <<
", j = " << j <<
", k = " << k
251 <<
", r = " << r <<
", xSR = " << xSRin
252 <<
", pTemt = " << pTemt << endl;
265 bool canVetoMPIStep() {
return true; }
266 int numberVetoMPIStep() {
return 1; }
267 bool doVetoMPIStep(
int nMPI,
const Event &e) {
269 if (nMPI > 1)
return false;
275 double pT1 = 0., pTsum = 0.;
276 for (
int i = e.size() - 1; i > 0; i--) {
277 if (e[i].isFinal()) {
284 if (count != nFinal && count != nFinal + 1) {
285 cout <<
"Error: wrong number of final state particles in event" << endl;
289 bool isEmt = (count == nFinal) ?
false :
true;
290 int iEmt = (isEmt) ? e.size() - 1 : -1;
293 if (!isEmt || pThardMode == 0) {
294 pThard = infoPtr->scalup();
298 }
else if (pThardMode == 1) {
299 pThard = pTcalc(e, -1, iEmt, -1, -1, -1);
304 }
else if (pThardMode == 2) {
305 pThard = pTcalc(e, -1, -1, -1, -1, -1);
309 if (MPIvetoMode == 1) {
310 pTMPI = (isEmt) ? pTsum / 2. : pT1;
314 cout <<
"doVetoMPIStep: Qfac = " << infoPtr->scalup()
315 <<
", pThard = " << pThard << endl << endl;
320 nAcceptSeq = nISRveto = nFSRveto = 0;
330 bool canVetoISREmission() {
return (vetoMode == 0) ?
false :
true; }
331 bool doVetoISREmission(
int,
const Event &e,
int iSys) {
333 if (iSys != 0)
return false;
336 if (vetoMode == 1 && nAcceptSeq >= vetoCount)
return false;
339 int iRadAft = -1, iEmt = -1, iRecAft = -1;
340 for (
int i = e.size() - 1; i > 0; i--) {
341 if (iRadAft == -1 && e[i].status() == -41) iRadAft = i;
342 else if (iEmt == -1 && e[i].status() == 43) iEmt = i;
343 else if (iRecAft == -1 && e[i].status() == -42) iRecAft = i;
344 if (iRadAft != -1 && iEmt != -1 && iRecAft != -1)
break;
346 if (iRadAft == -1 || iEmt == -1 || iRecAft == -1) {
348 cout <<
"Error: couldn't find Pythia ISR emission" << endl;
355 int xSR = (pTemtMode == 0) ? 0 : -1;
356 int i = (pTemtMode == 0) ? iRadAft : -1;
357 int j = (pTemtMode != 2) ? iEmt : -1;
359 int r = (pTemtMode == 0) ? iRecAft : -1;
360 double pTemt = pTcalc(e, i, j, k, r, xSR);
363 cout <<
"doVetoISREmission: pTemt = " << pTemt << endl << endl;
367 if (pTemt > pThard) {
383 bool canVetoFSREmission() {
return (vetoMode == 0) ?
false :
true; }
384 bool doVetoFSREmission(
int,
const Event &e,
int iSys,
bool) {
386 if (iSys != 0)
return false;
389 if (vetoMode == 1 && nAcceptSeq >= vetoCount)
return false;
392 int iRecAft = e.size() - 1;
393 int iEmt = e.size() - 2;
394 int iRadAft = e.size() - 3;
395 int iRadBef = e[iEmt].mother1();
396 if ( (e[iRecAft].status() != 52 && e[iRecAft].status() != -53) ||
397 e[iEmt].status() != 51 || e[iRadAft].status() != 51) {
399 cout <<
"Error: couldn't find Pythia FSR emission" << endl;
407 int xSR = (pTemtMode == 0) ? 1 : -1;
408 int i = (pTemtMode == 0) ? iRadBef : -1;
409 int k = (pTemtMode == 0) ? iRadAft : -1;
410 int r = (pTemtMode == 0) ? iRecAft : -1;
414 if (pTemtMode == 0 || pTemtMode == 1) {
421 if (emittedMode == 0 || (emittedMode == 2 && rndmPtr->flat() < 0.5)) j++;
423 for (
int jLoop = 0; jLoop < 2; jLoop++) {
424 if (jLoop == 0) pTemt = pTcalc(e, i, j, k, r, xSR);
425 else if (jLoop == 1) pTemt = min(pTemt, pTcalc(e, i, j, k, r, xSR));
428 if (emittedMode != 3)
break;
429 if (k != -1) swap(j, k);
else j = iEmt;
433 }
else if (pTemtMode == 2) {
434 pTemt = pTcalc(e, i, -1, k, r, xSR);
439 cout <<
"doVetoFSREmission: pTemt = " << pTemt << endl << endl;
443 if (pTemt > pThard) {
459 bool canVetoMPIEmission() {
return (MPIvetoMode == 0) ?
false :
true; }
460 bool doVetoMPIEmission(
int,
const Event &e) {
461 if (MPIvetoMode == 1) {
462 if (e[e.size() - 1].pT() > pTMPI) {
464 cout <<
"doVetoMPIEmission: pTnow = " << e[e.size() - 1].pT()
465 <<
", pTMPI = " << pTMPI << endl << endl;
477 int getNISRveto() {
return nISRveto; }
478 int getNFSRveto() {
return nFSRveto; }
481 int nFinal, vetoMode, vetoCount, pThardMode, pTemtMode,
482 emittedMode, pTdefMode, MPIvetoMode;
483 double pThard, pTMPI;
488 unsigned long int nISRveto, nFSRveto;
494 int main(
int,
char **) {
500 pythia.settings.addMode(
"POWHEG:nFinal", 2,
true,
false, 1, 0);
501 pythia.settings.addMode(
"POWHEG:veto", 0,
true,
true, 0, 2);
502 pythia.settings.addMode(
"POWHEG:vetoCount", 3,
true,
false, 0, 0);
503 pythia.settings.addMode(
"POWHEG:pThard", 0,
true,
true, 0, 2);
504 pythia.settings.addMode(
"POWHEG:pTemt", 0,
true,
true, 0, 2);
505 pythia.settings.addMode(
"POWHEG:emitted", 0,
true,
true, 0, 3);
506 pythia.settings.addMode(
"POWHEG:pTdef", 0,
true,
true, 0, 2);
507 pythia.settings.addMode(
"POWHEG:MPIveto", 0,
true,
true, 0, 1);
510 pythia.readFile(
"main31.cmnd");
513 int nEvent = pythia.settings.mode(
"Main:numberOfEvents");
514 int nError = pythia.settings.mode(
"Main:timesAllowErrors");
516 int nFinal = pythia.settings.mode(
"POWHEG:nFinal");
517 int vetoMode = pythia.settings.mode(
"POWHEG:veto");
518 int vetoCount = pythia.settings.mode(
"POWHEG:vetoCount");
519 int pThardMode = pythia.settings.mode(
"POWHEG:pThard");
520 int pTemtMode = pythia.settings.mode(
"POWHEG:pTemt");
521 int emittedMode = pythia.settings.mode(
"POWHEG:emitted");
522 int pTdefMode = pythia.settings.mode(
"POWHEG:pTdef");
523 int MPIvetoMode = pythia.settings.mode(
"POWHEG:MPIveto");
524 bool loadHooks = (vetoMode > 0 || MPIvetoMode > 0);
532 pythia.readString(
"SpaceShower:pTmaxMatch = 2");
533 pythia.readString(
"TimeShower:pTmaxMatch = 2");
537 if (MPIvetoMode > 0) {
538 pythia.readString(
"MultipartonInteractions:pTmaxMatch = 2");
541 powhegHooks =
new PowhegHooks(nFinal, vetoMode, vetoCount,
542 pThardMode, pTemtMode, emittedMode, pTdefMode, MPIvetoMode);
543 pythia.setUserHooksPtr((
UserHooks *) powhegHooks);
550 unsigned long int nISRveto = 0, nFSRveto = 0;
554 int iEvent = 0, iError = 0;
558 if (!pythia.next()) {
561 if (pythia.info.atEndOfFile())
break;
564 cout <<
"Warning: event " << iEvent <<
" failed" << endl;
565 if (++iError == nError) {
566 cout <<
"Error: too many event failures.. exiting" << endl;
579 nISRveto += powhegHooks->getNISRveto();
580 nFSRveto += powhegHooks->getNFSRveto();
585 if (nEvent != 0 && iEvent == nEvent)
break;
591 cout <<
"Number of ISR emissions vetoed: " << nISRveto << endl;
592 cout <<
"Number of FSR emissions vetoed: " << nFSRveto << endl;
596 if (powhegHooks)
delete powhegHooks;