File indexing completed on 2024-05-02 05:09:45
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
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
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100 #ifndef Pythia8_PowhegHooksBB4L_H
0101 #define Pythia8_PowhegHooksBB4L_H
0102
0103 #include "Pythia8/Pythia.h"
0104 #include <cassert>
0105
0106 namespace Pythia8 {
0107
0108 class PowhegHooksBB4L : public UserHooks {
0109 public:
0110 PowhegHooksBB4L() {}
0111 ~PowhegHooksBB4L() { std::cout << "Number of FSR vetoed in BB4l = " << nInResonanceFSRveto << std::endl; }
0112
0113
0114 bool initAfterBeams() {
0115
0116 vetoFSREmission = settingsPtr->flag("POWHEG:bb4l:FSREmission:veto");
0117 vetoDipoleFrame = settingsPtr->flag("POWHEG:bb4l:FSREmission:vetoDipoleFrame");
0118 pTpythiaVeto = settingsPtr->flag("POWHEG:bb4l:FSREmission:pTpythiaVeto");
0119 vetoQED = settingsPtr->flag("POWHEG:bb4l:FSREmission:vetoQED");
0120 scaleResonanceVeto = settingsPtr->flag("POWHEG:bb4l:ScaleResonance:veto");
0121 debug = settingsPtr->flag("POWHEG:bb4l:DEBUG");
0122 pTmin = settingsPtr->parm("POWHEG:bb4l:pTminVeto");
0123 vetoAllRadtypes = settingsPtr->flag("POWHEG:bb4l:vetoAllRadtypes");
0124 nInResonanceFSRveto = 0;
0125 return true;
0126 }
0127
0128
0129
0130
0131 inline bool canVetoProcessLevel() { return true; }
0132 inline bool doVetoProcessLevel(Event &e) {
0133
0134 stringstream ss;
0135
0136 ss << infoPtr->getEventAttribute("#rwgt");
0137 string temp;
0138 ss >> temp >> radtype;
0139 assert(temp == "#rwgt");
0140
0141
0142 if (!vetoAllRadtypes && radtype == 2)
0143 return false;
0144
0145 int i_top = -1, i_atop = -1, i_wp = -1, i_wm = -1;
0146 for (int i = 0; i < e.size(); i++) {
0147 if (e[i].id() == 6)
0148 i_top = i;
0149 if (e[i].id() == -6)
0150 i_atop = i;
0151 if (e[i].id() == 24)
0152 i_wp = i;
0153 if (e[i].id() == -24)
0154 i_wm = i;
0155 }
0156
0157 topresscale = findresscale(i_top, e);
0158
0159 atopresscale = findresscale(i_atop, e);
0160
0161 wpresscale = findresscale(i_wp, e);
0162 wmresscale = findresscale(i_wm, e);
0163
0164
0165 return false;
0166 }
0167
0168
0169
0170
0171 inline bool canVetoFSREmission() { return vetoFSREmission; }
0172 inline bool doVetoFSREmission(int sizeOld, const Event &e, int iSys, bool inResonance) {
0173
0174 if (inResonance && vetoFSREmission) {
0175
0176 int iRecAft = e.size() - 1;
0177 int iEmt = e.size() - 2;
0178 int iRadAft = e.size() - 3;
0179 int iRadBef = e[iEmt].mother1();
0180
0181
0182 int iRes = e[iRadBef].mother1();
0183 while (iRes > 0 && (abs(e[iRes].id()) != 6 && abs(e[iRes].id()) != 24)) {
0184 iRes = e[iRes].mother1();
0185 }
0186 if (iRes == 0) {
0187 loggerPtr->errorMsg("PowhegHooksBB4L::doVetoFSREmission",
0188 "Emission in resonance not from the top quark or from the "
0189 "W boson, not vetoing");
0190 return doVetoFSR(false, 0);
0191 }
0192 int iResId = e[iRes].id();
0193
0194
0195 double scale;
0196
0197 if (pTpythiaVeto)
0198 scale = pTpythia(e, iRadAft, iEmt, iRecAft);
0199
0200 else {
0201 Vec4 pr(e[iRadAft].p()), pe(e[iEmt].p()), pres(e[iRes].p()), prec(e[iRecAft].p()), psystem;
0202
0203
0204
0205 if (vetoDipoleFrame)
0206 psystem = pr + pe + prec;
0207 else
0208 psystem = pres;
0209
0210
0211 if (e[iRadBef].id() == 21)
0212 scale = gSplittingScale(psystem, pr, pe);
0213
0214 else if (abs(e[iRadBef].id()) <= 5 && ((e[iEmt].id() == 21) && !vetoQED))
0215 scale = qSplittingScale(psystem, pr, pe);
0216
0217 else {
0218 scale = 0;
0219 }
0220 }
0221
0222
0223 if (iResId == 6) {
0224 if (debug && scale > topresscale)
0225 cout << iResId << ": " << e[iRadBef].id() << " > " << e[iRadAft].id() << " + " << e[iEmt].id() << "; "
0226 << scale << endl;
0227 return doVetoFSR(scale > topresscale, scale);
0228 } else if (iResId == -6) {
0229 if (debug && scale > atopresscale)
0230 cout << iResId << ": " << e[iRadBef].id() << " > " << e[iRadAft].id() << " + " << e[iEmt].id() << "; "
0231 << scale << endl;
0232 return doVetoFSR(scale > atopresscale, scale);
0233 } else if (iResId == 24) {
0234 if (debug && scale > wpresscale)
0235 cout << iResId << ": " << e[iRadBef].id() << " > " << e[iRadAft].id() << " + " << e[iEmt].id() << "; "
0236 << scale << endl;
0237 return doVetoFSR(scale > wpresscale, scale);
0238 } else if (iResId == -24) {
0239 if (debug && scale > wmresscale)
0240 cout << iResId << ": " << e[iRadBef].id() << " > " << e[iRadAft].id() << " + " << e[iEmt].id() << "; "
0241 << scale << endl;
0242 return doVetoFSR(scale > wmresscale, scale);
0243 } else {
0244 loggerPtr->errorMsg("PowhegHooksBB4L::doVetoFSREmissio", "Unimplemented case");
0245 exit(-1);
0246 }
0247 }
0248
0249
0250 else {
0251 return false;
0252 }
0253 }
0254
0255 inline bool doVetoFSR(bool condition, double scale) {
0256 if (!vetoAllRadtypes && radtype == 2)
0257 return false;
0258 if (condition) {
0259 nInResonanceFSRveto++;
0260 return true;
0261 }
0262 return false;
0263 }
0264
0265
0266
0267 inline bool canSetResonanceScale() { return scaleResonanceVeto; }
0268
0269
0270
0271
0272
0273
0274 inline double scaleResonance(int iRes, const Event &e) {
0275 if (!vetoAllRadtypes && radtype == 2)
0276 return sqrt(e[iRes].m2Calc());
0277 else {
0278 if (e[iRes].id() == 6)
0279 return topresscale;
0280 else if (e[iRes].id() == -6)
0281 return atopresscale;
0282 else if (e[iRes].id() == 24)
0283 return wpresscale;
0284 else if (e[iRes].id() == 24)
0285 return wmresscale;
0286 else
0287 return 1e30;
0288 }
0289 }
0290
0291
0292
0293
0294 inline double findresscale(const int iRes, const Event &event) {
0295
0296 if (iRes < 0)
0297 return 1e30;
0298
0299
0300 int nDau = event[iRes].daughterList().size();
0301
0302
0303
0304 if (nDau == 0) {
0305 return 1e30;
0306 }
0307
0308
0309 else if (nDau < 3) {
0310 return pTmin;
0311 }
0312
0313 else if (abs(event[iRes].id()) == 6) {
0314
0315 int idw = -1, idb = -1, idg = -1;
0316 for (int i = 0; i < nDau; i++) {
0317 int iDau = event[iRes].daughterList()[i];
0318 if (abs(event[iDau].id()) == 24)
0319 idw = iDau;
0320 if (abs(event[iDau].id()) == 5)
0321 idb = iDau;
0322 if (abs(event[iDau].id()) == 21)
0323 idg = iDau;
0324 }
0325
0326
0327 Vec4 pw(event[idw].p());
0328 pw.bstback(event[iRes].p());
0329 Vec4 pb(event[idb].p());
0330 pb.bstback(event[iRes].p());
0331 Vec4 pg(event[idg].p());
0332 pg.bstback(event[iRes].p());
0333
0334
0335 return sqrt(2 * pg * pb * pg.e() / pb.e());
0336 }
0337
0338 else if (abs(event[iRes].id()) == 24) {
0339
0340 int idq = -1, ida = -1, idg = -1;
0341 for (int i = 0; i < nDau; i++) {
0342 int iDau = event[iRes].daughterList()[i];
0343 if (event[iDau].id() == 21)
0344 idg = iDau;
0345 else if (event[iDau].id() > 0)
0346 idq = iDau;
0347 else if (event[iDau].id() < 0)
0348 ida = iDau;
0349 }
0350
0351
0352 Vec4 pq(event[idq].p());
0353 pq.bstback(event[iRes].p());
0354 Vec4 pa(event[ida].p());
0355 pa.bstback(event[iRes].p());
0356 Vec4 pg(event[idg].p());
0357 pg.bstback(event[iRes].p());
0358
0359
0360 Vec4 pw = pq + pa + pg;
0361 double q2 = pw * pw;
0362 double csi = 2 * pg.e() / sqrt(q2);
0363 double yq = 1 - pg * pq / (pg.e() * pq.e());
0364 double ya = 1 - pg * pa / (pg.e() * pa.e());
0365
0366 return sqrt(min(1 - yq, 1 - ya) * pow2(csi) * q2 / 2);
0367 }
0368
0369
0370 return 1e30;
0371 }
0372
0373
0374
0375
0376
0377 inline bool match_decay(int iparticle,
0378 const Event &e,
0379 const vector<int> &ids,
0380 vector<int> &positions,
0381 vector<Vec4> &momenta,
0382 bool exitOnExtraLegs = true) {
0383
0384 if (e[iparticle].daughterList().size() != ids.size()) {
0385 if (exitOnExtraLegs && e[iparticle].daughterList().size() > ids.size()) {
0386 cout << "extra leg" << endl;
0387 exit(-1);
0388 }
0389 return false;
0390 }
0391
0392 for (unsigned i = 0; i < e[iparticle].daughterList().size(); i++) {
0393 int di = e[iparticle].daughterList()[i];
0394 if (ids[i] != 0 && e[di].id() != ids[i])
0395 return false;
0396 }
0397
0398 positions.clear();
0399 momenta.clear();
0400
0401 for (unsigned i = 0; i < e[iparticle].daughterList().size(); i++) {
0402 int di = e[iparticle].daughterList()[i];
0403 positions.push_back(di);
0404 momenta.push_back(e[di].p());
0405 }
0406 return true;
0407 }
0408
0409 inline double qSplittingScale(Vec4 pt, Vec4 p1, Vec4 p2) {
0410 p1.bstback(pt);
0411 p2.bstback(pt);
0412 return sqrt(2 * p1 * p2 * p2.e() / p1.e());
0413 }
0414
0415 inline double gSplittingScale(Vec4 pt, Vec4 p1, Vec4 p2) {
0416 p1.bstback(pt);
0417 p2.bstback(pt);
0418 return sqrt(2 * p1 * p2 * p1.e() * p2.e() / (pow(p1.e() + p2.e(), 2)));
0419 }
0420
0421
0422
0423
0424
0425 inline double pTpythia(const Event &e, int RadAfterBranch, int EmtAfterBranch, int RecAfterBranch) {
0426
0427 Vec4 radVec = e[RadAfterBranch].p();
0428 Vec4 emtVec = e[EmtAfterBranch].p();
0429 Vec4 recVec = e[RecAfterBranch].p();
0430 int radID = e[RadAfterBranch].id();
0431
0432
0433 Vec4 Q(radVec + emtVec);
0434 double Qsq = Q.m2Calc();
0435
0436
0437 double m2Rad = (abs(radID) >= 4 && abs(radID) < 7) ? pow2(particleDataPtr->m0(radID)) : 0.;
0438
0439
0440 double z, pTnow;
0441
0442 Vec4 sum = radVec + recVec + emtVec;
0443 double m2Dip = sum.m2Calc();
0444
0445 double x1 = 2. * (sum * radVec) / m2Dip;
0446 double x3 = 2. * (sum * emtVec) / m2Dip;
0447 z = x1 / (x1 + x3);
0448 pTnow = z * (1. - z);
0449
0450
0451 pTnow *= (Qsq - m2Rad);
0452
0453 if (pTnow < 0.) {
0454 cout << "Warning: pTpythia was negative" << endl;
0455 return -1.;
0456 } else
0457 return (sqrt(pTnow));
0458 }
0459
0460
0461 inline int getNInResonanceFSRVeto() { return nInResonanceFSRveto; }
0462
0463
0464
0465 private:
0466
0467 bool vetoFSREmission, vetoQED;
0468
0469 double scaleResonanceVeto;
0470
0471 bool debug;
0472 bool vetoDipoleFrame;
0473 bool pTpythiaVeto;
0474 double pTmin;
0475 bool vetoAllRadtypes;
0476
0477 int nInResonanceFSRveto;
0478
0479 double topresscale, atopresscale, wpresscale, wmresscale;
0480 int radtype;
0481 };
0482
0483
0484
0485 }
0486
0487 #endif