14 #ifndef Pythia8_PowhegHooks_H 15 #define Pythia8_PowhegHooks_H 18 #include "Pythia8/Pythia.h" 19 #include "Pythia8/Plugins.h" 49 showerModel =
settingsPtr->mode(
"PartonShowers:model");
61 inline double pT(
const Event& e,
int RadAfterBranch,
62 int EmtAfterBranch,
int RecAfterBranch,
bool FSR) {
65 return pTvincia(e, RadAfterBranch, EmtAfterBranch, RecAfterBranch);
68 return pTdire(e, RadAfterBranch, EmtAfterBranch, RecAfterBranch);
69 return pTpythia(e, RadAfterBranch, EmtAfterBranch, RecAfterBranch, FSR);
77 int EmtAfterBranch,
int RecAfterBranch,
bool FSR) {
80 Vec4 radVec = e[RadAfterBranch].p();
81 Vec4 emtVec = e[EmtAfterBranch].p();
82 Vec4 recVec = e[RecAfterBranch].p();
83 int radID = e[RadAfterBranch].id();
86 double sign = (FSR) ? 1. : -1.;
87 Vec4 Q(radVec + sign * emtVec);
88 double Qsq = sign * Q.m2Calc();
91 double m2Rad = (abs(radID) >= 4 && abs(radID) < 7) ?
98 Vec4 sum = radVec + recVec + emtVec;
99 double m2Dip = sum.m2Calc();
100 double x1 = 2. * (sum * radVec) / m2Dip;
101 double x3 = 2. * (sum * emtVec) / m2Dip;
103 pTnow = z * (1. - z);
107 Vec4 qBR(radVec - emtVec + recVec);
108 Vec4 qAR(radVec + recVec);
109 z = qBR.m2Calc() / qAR.m2Calc();
114 pTnow *= (Qsq - sign * m2Rad);
133 Vec4 p1 =
event[i1].p();
134 Vec4 p3 =
event[i3].p();
135 Vec4 p2 =
event[i2].p();
138 int iMoth1 =
event[i1].mother1();
139 int iMoth2 =
event[i2].mother1();
140 if (iMoth1 == 0 || iMoth2 == 0) {
141 loggerPtr->ABORT_MSG(
"could not find mothers of particles");
146 double mMoth1Sq =
event[iMoth1].m2();
147 double mMoth2Sq =
event[iMoth2].m2();
148 double sgn1 =
event[i1].isFinal() ? 1. : -1.;
149 double sgn2 =
event[i2].isFinal() ? 1. : -1.;
150 double qSq13 = sgn1*(
m2(sgn1*p1+p3) - mMoth1Sq);
151 double qSq23 = sgn2*(
m2(sgn2*p2+p3) - mMoth2Sq);
155 if (event[i1].isFinal() &&
event[i2].isFinal()) {
157 sMax =
m2(p1+p2+p3) - mMoth1Sq - mMoth2Sq;
158 }
else if ((event[i1].isResonance() && event[i2].isFinal())
159 || (!event[i1].isFinal() && event[i2].isFinal())) {
161 sMax = 2.*p1*p3 + 2.*p1*p2;
162 }
else if ((event[i1].isFinal() && event[i2].isResonance())
163 || (event[i1].isFinal() && !event[i2].isFinal())) {
165 sMax = 2.*p2*p3 + 2.*p1*p2;
166 }
else if (!event[i1].isFinal() || !event[i2].isFinal()) {
170 loggerPtr->ABORT_MSG(
"could not determine branching type");
175 double pT2now = qSq13*qSq23/sMax;
192 inline double pTdire(
const Event& event,
int iRad,
int iEmt,
int iRec) {
201 if (rad.isFinal() && rec.isFinal()) {
203 const double sij = 2.*rad.p()*emt.p();
204 const double sik = 2.*rad.p()*rec.p();
205 const double sjk = 2.*rec.p()*emt.p();
206 pT2 = sij*sjk/(sij+sik+sjk);
207 }
else if (rad.isFinal() && !rec.isFinal()) {
209 const double sij = 2.*rad.p()*emt.p();
210 const double sai = -2.*rec.p()*rad.p();
211 const double saj = -2.*rec.p()*emt.p();
212 pT2 = sij*saj/(sai+saj)*(sij+saj+sai)/(sai+saj);
213 if (sij+saj+sai < 1e-5 && abs(sij+saj+sai) < 1e-5) pT2 = sij;
214 }
else if (!rad.isFinal() && rec.isFinal()) {
216 const double sai = -2.*rad.p()*emt.p();
217 const double sik = 2.*rec.p()*emt.p();
218 const double sak = -2.*rad.p()*rec.p();
219 pT2 = sai*sik/(sai+sak)*(sai+sik+sak)/(sai+sak);
220 }
else if (!rad.isFinal() || !rec.isFinal()) {
222 const double sai = -2.*rad.p()*emt.p();
223 const double sbi = -2.*rec.p()*emt.p();
224 const double sab = 2.*rad.p()*rec.p();
225 pT2 = sai*sbi/sab*(sai+sbi+sab)/sab;
227 loggerPtr->ABORT_MSG(
"could not determine branching type");
254 double betaZ = - ( e[iInA].pz() + e[iInB].pz() ) /
255 ( e[iInA].e() + e[iInB].e() );
256 Vec4 iVecBst(e[i].p()), jVecBst(e[j].p());
257 iVecBst.bst(0., 0., betaZ);
258 jVecBst.
bst(0., 0., betaZ);
259 pTnow = sqrt( (iVecBst + jVecBst).m2Calc() *
260 iVecBst.e() * jVecBst.e() /
261 pow2(iVecBst.e() + jVecBst.e()) );
284 inline double pTcalc(
const Event &e,
int i,
int j,
int k,
int r,
int xSRin) {
287 double pTemt = -1., pTnow;
288 int xSR1 = (xSRin == -1) ? 0 : xSRin;
289 int xSR2 = (xSRin == -1) ? 2 : xSRin + 1;
290 for (
int xSR = xSR1; xSR < xSR2; xSR++) {
292 bool FSR = (xSR == 0) ?
false :
true;
296 if ((pTdefMode == 0 || pTdefMode == 1) && i > 0 && j > 0) {
297 pTemt =
pTpowheg(e, i, j, (pTdefMode == 0) ?
false : FSR);
300 }
else if (!FSR && pTdefMode == 2 && i > 0 && j > 0 && r > 0) {
301 pTemt =
pT(e, i, j, r, FSR);
304 }
else if (FSR && pTdefMode == 2 && j > 0 && k > 0 && r > 0) {
305 pTemt =
pT(e, k, j, r, FSR);
315 while (e[iInA].mother1() != 1) { iInA = e[iInA].mother1(); }
316 while (e[iInB].mother1() != 2) { iInB = e[iInB].mother1(); }
319 int jNow = (j > 0) ? j : 0;
320 int jMax = (j > 0) ? j + 1 : e.
size();
321 for (; jNow < jMax; jNow++) {
324 if (!e[jNow].isFinal())
continue;
326 if (QEDvetoMode==0 && e[jNow].colType() == 0)
continue;
329 if (pTdefMode == 0 || pTdefMode == 1) {
333 pTnow =
pTpowheg(e, iInA, jNow, (pTdefMode == 0) ?
false : FSR);
334 if (pTnow > 0.) pTemt = (pTemt < 0) ? pTnow : min(pTemt, pTnow);
342 for (
int iMem = 0; iMem < outSize; iMem++) {
346 if (iNow == jNow )
continue;
348 if (QEDvetoMode==0 && e[iNow].colType() == 0)
continue;
349 if (jNow == e[iNow].daughter1()
350 && jNow == e[iNow].daughter2())
continue;
352 pTnow =
pTpowheg(e, iNow, jNow, (pTdefMode == 0)
354 if (pTnow > 0.) pTemt = (pTemt < 0)
355 ? pTnow : min(pTemt, pTnow);
361 }
else if (pTdefMode == 2) {
365 pTnow =
pT(e, iInA, jNow, iInB, FSR);
366 if (pTnow > 0.) pTemt = (pTemt < 0) ? pTnow : min(pTemt, pTnow);
367 pTnow =
pT(e, iInB, jNow, iInA, FSR);
368 if (pTnow > 0.) pTemt = (pTemt < 0) ? pTnow : min(pTemt, pTnow);
373 for (
int kNow = 0; kNow < e.
size(); kNow++) {
374 if (kNow == jNow || !e[kNow].isFinal())
continue;
375 if (QEDvetoMode==0 && e[kNow].colType() == 0)
continue;
379 pTnow =
pT(e, kNow, jNow, iInA, FSR);
380 if (pTnow > 0.) pTemt = (pTemt < 0)
381 ? pTnow : min(pTemt, pTnow);
382 pTnow =
pT(e, kNow, jNow, iInB, FSR);
383 if (pTnow > 0.) pTemt = (pTemt < 0)
384 ? pTnow : min(pTemt, pTnow);
387 for (
int rNow = 0; rNow < e.
size(); rNow++) {
388 if (rNow == kNow || rNow == jNow ||
389 !e[rNow].isFinal())
continue;
390 if(QEDvetoMode==0 && e[rNow].colType() == 0)
continue;
391 pTnow =
pT(e, kNow, jNow, rNow, FSR);
392 if (pTnow > 0.) pTemt = (pTemt < 0)
393 ? pTnow : min(pTemt, pTnow);
422 if (nMPI > 1)
return false;
424 double pT1(0.), pTsum(0.);
434 for (
int i = e.
size() - 1; i > 0; i--) {
435 if (e[i].isFinal()) {
442 if (count != nFinal && count != nFinal + 1) {
443 loggerPtr->ABORT_MSG(
"wrong number of final state particles in event");
447 isEmt = (count == nFinal) ?
false :
true;
448 iEmt = (isEmt) ? e.
size() - 1 : -1;
457 for (
int i = e.
size() - 1; i > 0; i--) {
458 if (e[i].isFinal()) {
459 if ( e[i].isParton() && iEmt < 0
460 && e[e[i].mother1()].isParton() ) {
471 if (!isEmt || pThardMode == 0) {
476 }
else if (pThardMode == 1) {
479 "pThard == 1 not available for nFinal == -1, reset pThard = 0.");
483 pThard =
pTcalc(e, -1, iEmt, -1, -1, -1);
489 }
else if (pThardMode == 2) {
492 "pThard == 2 not available for nFinal == -1, reset pThard = 0.");
496 pThard =
pTcalc(e, -1, -1, -1, -1, -1);
501 if (MPIvetoMode == 1) {
502 pTMPI = (isEmt) ? pTsum / 2. : pT1;
507 nAcceptSeq = nISRveto = nFSRveto = 0;
520 if (iSys != 0)
return false;
523 if (vetoMode == 1 && nAcceptSeq >= vetoCount)
return false;
526 int iRadAft = -1, iEmt = -1, iRecAft = -1;
527 for (
int i = e.
size() - 1; i > 0; i--) {
528 if (showerModel == 1) {
530 if (iRadAft == -1 && e[i].status() == -41) iRadAft = i;
531 else if (iEmt == -1 && e[i].status() == 43) iEmt = i;
532 else if (iRecAft == -1 && e[i].status() == -42) iRecAft = i;
533 }
else if (showerModel == 2) {
535 if (iRadAft == -1 && e[i].status() == -41) iRadAft = i;
536 else if (iEmt == -1 && e[i].status() == 43) iEmt = i;
537 else if (iRecAft == -1
538 && (e[i].status() == -41 || e[i].status() == 44)) iRecAft = i;
539 }
else if (showerModel == 3) {
541 if (iRadAft == -1 && e[i].status() == -41) iRadAft = i;
542 else if (iEmt == -1 && e[i].status() == 43) iEmt = i;
543 else if (iRecAft == -1
544 && (e[i].status() == -41
545 || e[i].status() == 44 || e[i].status() == 48)) iRecAft = i;
547 if (iRadAft != -1 && iEmt != -1 && iRecAft != -1)
break;
549 if (iRadAft == -1 || iEmt == -1 || iRecAft == -1) {
550 loggerPtr->ABORT_MSG(
"could not find ISR emission");
557 int xSR = (pTemtMode == 0) ? 0 : -1;
558 int i = (pTemtMode == 0) ? iRadAft : -1;
559 int j = (pTemtMode != 2) ? iEmt : -1;
561 int r = (pTemtMode == 0) ? iRecAft : -1;
562 double pTemt =
pTcalc(e, i, j, k, r, xSR);
566 bool vetoParton = (!isEmt && e[iEmt].colType()==0 && QEDvetoMode==2)
570 if (pTemt > pThard) {
573 nAcceptSeq = vetoCount-1;
594 if (iSys != 0)
return false;
597 if (vetoMode == 1 && nAcceptSeq >= vetoCount)
return false;
600 int iRecAft = e.
size() - 1;
601 int iEmt = e.
size() - 2;
602 int iRadAft = e.
size() - 3;
603 int iRadBef = e[iEmt].mother1();
605 if (showerModel == 1 || showerModel == 3) {
607 if ( (e[iRecAft].status() != 52 && e[iRecAft].status() != -53) ||
608 e[iEmt].status() != 51 || e[iRadAft].status() != 51) stop =
true;
609 }
else if (showerModel == 2) {
611 if ( (e[iRecAft].status() != 51 && e[iRecAft].status() != 52) ||
612 e[iEmt].status() != 51 || e[iRadAft].status() != 51) stop =
true;
615 loggerPtr->ABORT_MSG(
"could not find FSR emission");
623 int xSR = (pTemtMode == 0) ? 1 : -1;
624 int i = (pTemtMode == 0) ? iRadBef : -1;
625 int k = (pTemtMode == 0) ? iRadAft : -1;
626 int r = (pTemtMode == 0) ? iRecAft : -1;
630 if (pTemtMode == 0 || pTemtMode == 1) {
637 if (emittedMode == 0 || (emittedMode == 2 &&
rndmPtr->
flat() < 0.5)) j++;
639 for (
int jLoop = 0; jLoop < 2; jLoop++) {
640 if (jLoop == 0) pTemt =
pTcalc(e, i, j, k, r, xSR);
641 else if (jLoop == 1) pTemt = min(pTemt,
pTcalc(e, i, j, k, r, xSR));
644 if (emittedMode != 3)
break;
645 if (k != -1) swap(j, k);
else j = iEmt;
649 }
else if (pTemtMode == 2) {
650 pTemt =
pTcalc(e, i, -1, k, r, xSR);
656 bool vetoParton = (!isEmt && e[iEmt].colType()==0 && QEDvetoMode==2)
660 if (pTemt > pThard) {
663 nAcceptSeq = vetoCount-1;
683 if (MPIvetoMode == 1) {
684 if (e[e.
size() - 1].pT() > pTMPI)
return true;
694 inline int getNFSRveto() {
return nFSRveto; }
699 int showerModel, nFinal, vetoMode, MPIvetoMode, QEDvetoMode, vetoCount;
700 int pThardMode, pTemtMode, emittedMode, pTdefMode;
701 double pThard, pTMPI;
702 bool accepted, isEmt;
707 unsigned long int nISRveto, nFSRveto;
716 PYTHIA8_PLUGIN_VERSIONS(PYTHIA_VERSION_INTEGER)
double pTpowheg(const Event &e, int i, int j, bool FSR)
Compute the POWHEG pT separation between i and j.
Definition: PowhegHooks.h:244
constexpr double pow2(const double &x)
Powers of small integers - for balance speed/code clarity.
Definition: PythiaStdlib.h:182
bool initAfterBeams()
Initialize settings, detailing merging strategy to use.
Definition: PowhegHooks.h:39
Settings * settingsPtr
Pointer to the settings database.
Definition: PhysicsBase.h:81
The Event class holds all info on the generated event.
Definition: Event.h:453
bool canVetoMPIStep()
Definition: PowhegHooks.h:418
PartonSystems * partonSystemsPtr
Pointer to information on subcollision parton locations.
Definition: PhysicsBase.h:112
Rndm * rndmPtr
Pointer to the random number generator.
Definition: PhysicsBase.h:93
Use userhooks to veto PYTHIA emissions above the POWHEG scale.
Definition: PowhegHooks.h:27
double pTdire(const Event &event, int iRad, int iEmt, int iRec)
Definition: PowhegHooks.h:192
ParticleData * particleDataPtr
Pointer to the particle data table.
Definition: PhysicsBase.h:84
bool canVetoMPIEmission()
MPI veto.
Definition: PowhegHooks.h:681
double pTvincia(const Event &event, int i1, int i3, int i2)
Definition: PowhegHooks.h:130
bool doVetoMPIStep(int nMPI, const Event &e)
Definition: PowhegHooks.h:420
int getNISRveto()
Functions to return information.
Definition: PowhegHooks.h:693
void bst(double betaX, double betaY, double betaZ)
Boost (simple).
Definition: Basics.cc:434
bool doVetoFSREmission(int, const Event &e, int iSys, bool)
Definition: PowhegHooks.h:592
bool doVetoISREmission(int, const Event &e, int iSys)
Definition: PowhegHooks.h:518
int size() const
Event record size.
Definition: Event.h:504
bool canVetoISREmission()
ISR veto.
Definition: PowhegHooks.h:517
double pTpythia(const Event &e, int RadAfterBranch, int EmtAfterBranch, int RecAfterBranch, bool FSR)
Definition: PowhegHooks.h:76
double m2(const Vec4 &v1)
The squared invariant mass of one or more four-vectors.
Definition: Basics.cc:605
Logger * loggerPtr
Pointer to logger.
Definition: PhysicsBase.h:87
bool doVetoMPIEmission(int, const Event &e)
Definition: PowhegHooks.h:682
Header for classes to set beam momentum and interaction vertex spread.
Definition: Analysis.h:20
The Pythia class contains the top-level routines to generate an event.
Definition: Pythia.h:71
Info * infoPtr
Definition: PhysicsBase.h:78
UserHooks is base class for user access to program execution.
Definition: UserHooks.h:32
int numberVetoMPIStep()
Up to how many MPI steps should be checked.
Definition: PowhegHooks.h:419
double flat()
Generate next random number uniformly between 0 and 1.
Definition: Basics.cc:189
double pTcalc(const Event &e, int i, int j, int k, int r, int xSRin)
Definition: PowhegHooks.h:284
bool canVetoFSREmission()
FSR veto.
Definition: PowhegHooks.h:591
double pT(const Event &e, int RadAfterBranch, int EmtAfterBranch, int RecAfterBranch, bool FSR)
Top-level wrapper for shower pTs.
Definition: PowhegHooks.h:61
PowhegHooks()
Constructors and destructor.
Definition: PowhegHooks.h:32
Definition: Settings.h:195