00001 #include "GeneratorInterface/Pythia8Interface/interface/EmissionVetoHook1.h"
00002
00003 #include "FWCore/ServiceRegistry/interface/Service.h"
00004 void EmissionVetoHook1::fatalEmissionVeto(string message) {
00005 throw edm::Exception(edm::errors::Configuration,"Pythia8Interface")
00006 << "EmissionVeto: " << message << endl;
00007 }
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 double EmissionVetoHook1::pTpythia(const Pythia8::Event &e, int RadAfterBranch,
00018 int EmtAfterBranch, int RecAfterBranch, bool FSR) {
00019
00020
00021 Pythia8::Vec4 radVec = e[RadAfterBranch].p();
00022 Pythia8::Vec4 emtVec = e[EmtAfterBranch].p();
00023 Pythia8::Vec4 recVec = e[RecAfterBranch].p();
00024 int radID = e[RadAfterBranch].id();
00025
00026
00027 double sign = (FSR) ? 1. : -1.;
00028 Pythia8::Vec4 Q(radVec + sign * emtVec);
00029 double Qsq = sign * Q.m2Calc();
00030
00031
00032 double m2Rad = (abs(radID) >= 4 && abs(radID) < 7) ?
00033 Pythia8::pow2(particleDataPtr->m0(radID)) : 0.;
00034
00035
00036 double z, pTnow;
00037 if (FSR) {
00038
00039 Pythia8::Vec4 sum = radVec + recVec + emtVec;
00040 double m2Dip = sum.m2Calc();
00041 double x1 = 2. * (sum * radVec) / m2Dip;
00042 double x3 = 2. * (sum * emtVec) / m2Dip;
00043 z = x1 / (x1 + x3);
00044 pTnow = z * (1. - z);
00045
00046 } else {
00047
00048 Pythia8::Vec4 qBR(radVec - emtVec + recVec);
00049 Pythia8::Vec4 qAR(radVec + recVec);
00050 z = qBR.m2Calc() / qAR.m2Calc();
00051 pTnow = (1. - z);
00052 }
00053
00054
00055 pTnow *= (Qsq - sign * m2Rad);
00056
00057
00058 if (pTnow < 0.) {
00059 cout << "Warning: pTpythia was negative" << endl;
00060 return -1.;
00061 }
00062
00063 #ifdef DBGOUTPUT
00064 cout << "pTpythia: rad = " << RadAfterBranch << ", emt = "
00065 << EmtAfterBranch << ", rec = " << RecAfterBranch
00066 << ", pTnow = " << sqrt(pTnow) << endl;
00067 #endif
00068
00069
00070 return sqrt(pTnow);
00071 }
00072
00073
00074 double EmissionVetoHook1::pTpowheg(const Pythia8::Event &e, int i, int j, bool FSR) {
00075
00076
00077 double pTnow = 0.;
00078 if (FSR) {
00079
00080
00081
00082 int iInA = partonSystemsPtr->getInA(0);
00083 int iInB = partonSystemsPtr->getInB(0);
00084 double betaZ = - ( e[iInA].pz() + e[iInB].pz() ) /
00085 ( e[iInA].e() + e[iInB].e() );
00086 Pythia8::Vec4 iVecBst(e[i].p()), jVecBst(e[j].p());
00087 iVecBst.bst(0., 0., betaZ);
00088 jVecBst.bst(0., 0., betaZ);
00089 pTnow = sqrt( (iVecBst + jVecBst).m2Calc() *
00090 iVecBst.e() * jVecBst.e() /
00091 Pythia8::pow2(iVecBst.e() + jVecBst.e()) );
00092
00093 } else {
00094
00095 pTnow = e[j].pT();
00096 }
00097
00098
00099 if (pTnow < 0.) {
00100 cout << "Warning: pTpowheg was negative" << endl;
00101 return -1.;
00102 }
00103
00104 #ifdef DBGOUTPUT
00105 cout << "pTpowheg: i = " << i << ", j = " << j
00106 << ", pTnow = " << pTnow << endl;
00107 #endif
00108
00109 return pTnow;
00110 }
00111
00112
00113
00114
00115
00116
00117 double EmissionVetoHook1::pTcalc(const Pythia8::Event &e, int i, int j, int k, int r, int xSRin) {
00118
00119
00120 double pTemt = -1., pTnow;
00121 int xSR1 = (xSRin == -1) ? 0 : xSRin;
00122 int xSR2 = (xSRin == -1) ? 2 : xSRin + 1;
00123 for (int xSR = xSR1; xSR < xSR2; xSR++) {
00124
00125 bool FSR = (xSR == 0) ? false : true;
00126
00127
00128
00129 if ((pTdefMode == 0 || pTdefMode == 1) && i > 0 && j > 0) {
00130 pTemt = pTpowheg(e, i, j, (pTdefMode == 0) ? false : FSR);
00131
00132
00133 } else if (!FSR && pTdefMode == 2 && i > 0 && j > 0 && r > 0) {
00134 pTemt = pTpythia(e, i, j, r, FSR);
00135
00136
00137 } else if (FSR && pTdefMode == 2 && j > 0 && k > 0 && r > 0) {
00138 pTemt = pTpythia(e, k, j, r, FSR);
00139
00140
00141 } else {
00142
00143
00144
00145
00146 int iInA = partonSystemsPtr->getInA(0);
00147 int iInB = partonSystemsPtr->getInB(0);
00148 while (e[iInA].mother1() != 1) { iInA = e[iInA].mother1(); }
00149 while (e[iInB].mother1() != 2) { iInB = e[iInB].mother1(); }
00150
00151
00152 int jNow = (j > 0) ? j : 0;
00153 int jMax = (j > 0) ? j + 1 : e.size();
00154 for (; jNow < jMax; jNow++) {
00155
00156
00157 if (!e[jNow].isFinal() || e[jNow].colType() == 0) continue;
00158
00159
00160 if (pTdefMode == 0 || pTdefMode == 1) {
00161
00162
00163 if (!FSR) {
00164 pTnow = pTpowheg(e, iInA, jNow, (pTdefMode == 0) ? false : FSR);
00165 if (pTnow > 0.) pTemt = (pTemt < 0) ? pTnow : min(pTemt, pTnow);
00166
00167
00168
00169
00170 } else {
00171
00172 int outSize = partonSystemsPtr->sizeOut(0);
00173 for (int iMem = 0; iMem < outSize; iMem++) {
00174 int iNow = partonSystemsPtr->getOut(0, iMem);
00175
00176
00177 if (iNow == jNow || e[iNow].colType() == 0) continue;
00178 if (jNow == e[iNow].daughter1()
00179 && jNow == e[iNow].daughter2()) continue;
00180
00181 pTnow = pTpowheg(e, iNow, jNow, (pTdefMode == 0)
00182 ? false : FSR);
00183 if (pTnow > 0.) pTemt = (pTemt < 0)
00184 ? pTnow : min(pTemt, pTnow);
00185 }
00186
00187 }
00188
00189
00190 } else if (pTdefMode == 2) {
00191
00192
00193 if (!FSR) {
00194 pTnow = pTpythia(e, iInA, jNow, iInB, FSR);
00195 if (pTnow > 0.) pTemt = (pTemt < 0) ? pTnow : min(pTemt, pTnow);
00196 pTnow = pTpythia(e, iInB, jNow, iInA, FSR);
00197 if (pTnow > 0.) pTemt = (pTemt < 0) ? pTnow : min(pTemt, pTnow);
00198
00199
00200
00201 } else {
00202 for (int kNow = 0; kNow < e.size(); kNow++) {
00203 if (kNow == jNow || !e[kNow].isFinal() ||
00204 e[kNow].colType() == 0) continue;
00205
00206
00207
00208 pTnow = pTpythia(e, kNow, jNow, iInA, FSR);
00209 if (pTnow > 0.) pTemt = (pTemt < 0)
00210 ? pTnow : min(pTemt, pTnow);
00211 pTnow = pTpythia(e, kNow, jNow, iInB, FSR);
00212 if (pTnow > 0.) pTemt = (pTemt < 0)
00213 ? pTnow : min(pTemt, pTnow);
00214
00215
00216 for (int rNow = 0; rNow < e.size(); rNow++) {
00217 if (rNow == kNow || rNow == jNow ||
00218 !e[rNow].isFinal() || e[rNow].colType() == 0) continue;
00219 pTnow = pTpythia(e, kNow, jNow, rNow, FSR);
00220 if (pTnow > 0.) pTemt = (pTemt < 0)
00221 ? pTnow : min(pTemt, pTnow);
00222 }
00223
00224 }
00225 }
00226 }
00227 }
00228 }
00229 }
00230
00231 #ifdef DBGOUTPUT
00232 cout << "pTcalc: i = " << i << ", j = " << j << ", k = " << k
00233 << ", r = " << r << ", xSR = " << xSRin
00234 << ", pTemt = " << pTemt << endl;
00235 #endif
00236
00237 return pTemt;
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247 bool EmissionVetoHook1::doVetoMPIStep(int nMPI, const Pythia8::Event &e) {
00248
00249 if (nMPI > 1) return false;
00250
00251
00252
00253
00254 int count = 0, inonfinal = 0;
00255 double pT1 = 0., pTsum = 0.;
00256 for (int i = e.size() - 1; i > 0; i--) {
00257 inonfinal = i;
00258 if (e[i].isFinal()) {
00259 count++;
00260 pT1 = e[i].pT();
00261 pTsum += e[i].pT();
00262 } else break;
00263 }
00264
00265 nFinal = nFinalExt;
00266
00267 if (nFinal < 0) {
00268 int first = -1, myid;
00269 int last = -1;
00270 for(int ip = 2; ip < e.size(); ip++) {
00271 myid = e[ip].id();
00272 if(abs(myid) < 6 || abs(myid) == 21) continue;
00273 first = ip;
00274 break;
00275 }
00276 if(first < 0) fatalEmissionVeto(string("signal particles not found"));
00277 for(int ip = first; ip < e.size(); ip++) {
00278 myid = e[ip].id();
00279 if(abs(myid) < 6 || abs(myid) == 21) continue;
00280 last = ip;
00281 }
00282 nFinal = last - inonfinal;
00283 }
00284
00285
00286 if (count != nFinal && count != nFinal + 1)
00287 fatalEmissionVeto(string("Wrong number of final state particles in event"));
00288
00289
00290 bool isEmt = (count == nFinal) ? false : true;
00291 int iEmt = (isEmt) ? e.size() - 1 : -1;
00292
00293
00294 if (!isEmt || pThardMode == 0) {
00295 pThard = infoPtr->QFac();
00296
00297
00298
00299 } else if (pThardMode == 1) {
00300 pThard = pTcalc(e, -1, iEmt, -1, -1, -1);
00301
00302
00303
00304
00305 } else if (pThardMode == 2) {
00306 pThard = pTcalc(e, -1, -1, -1, -1, -1);
00307
00308 }
00309
00310
00311 if (MPIvetoOn) {
00312 pTMPI = (isEmt) ? pTsum / 2. : pT1;
00313 }
00314
00315 if(Verbosity)
00316 cout << "doVetoMPIStep: Qfac = " << infoPtr->QFac()
00317 << ", pThard = " << pThard << endl << endl;
00318
00319
00320 accepted = false;
00321 nAcceptSeq = 0;
00322
00323
00324 return false;
00325 }
00326
00327
00328
00329
00330
00331 bool EmissionVetoHook1::doVetoISREmission(int, const Pythia8::Event &e, int iSys) {
00332
00333 if (iSys != 0) return false;
00334
00335
00336 if (vetoOn && nAcceptSeq >= vetoCount) return false;
00337
00338
00339 int iRadAft = -1, iEmt = -1, iRecAft = -1;
00340 for (int i = e.size() - 1; i > 0; i--) {
00341 if (iRadAft == -1 && e[i].status() == -41) iRadAft = i;
00342 else if (iEmt == -1 && e[i].status() == 43) iEmt = i;
00343 else if (iRecAft == -1 && e[i].status() == -42) iRecAft = i;
00344 if (iRadAft != -1 && iEmt != -1 && iRecAft != -1) break;
00345 }
00346 if (iRadAft == -1 || iEmt == -1 || iRecAft == -1) {
00347 e.list();
00348 fatalEmissionVeto(string("Couldn't find Pythia ISR emission"));
00349 }
00350
00351
00352
00353
00354 int xSR = (pTemtMode == 0) ? 0 : -1;
00355 int i = (pTemtMode == 0) ? iRadAft : -1;
00356 int j = (pTemtMode != 2) ? iEmt : -1;
00357 int k = -1;
00358 int r = (pTemtMode == 0) ? iRecAft : -1;
00359 double pTemt = pTcalc(e, i, j, k, r, xSR);
00360
00361 #ifdef DBGOUTPUT
00362 cout << "doVetoISREmission: pTemt = " << pTemt << endl << endl;
00363 #endif
00364
00365
00366 if (pTemt > pThard) {
00367 nAcceptSeq = 0;
00368 nISRveto++;
00369 return true;
00370 }
00371
00372
00373 nAcceptSeq++;
00374 accepted = true;
00375 return false;
00376 }
00377
00378
00379
00380
00381
00382 bool EmissionVetoHook1::doVetoFSREmission(int, const Pythia8::Event &e, int iSys, bool) {
00383
00384 if (iSys != 0) return false;
00385
00386
00387 if (vetoOn && nAcceptSeq >= vetoCount) return false;
00388
00389
00390 int iRecAft = e.size() - 1;
00391 int iEmt = e.size() - 2;
00392 int iRadAft = e.size() - 3;
00393 int iRadBef = e[iEmt].mother1();
00394 if ( (e[iRecAft].status() != 52 && e[iRecAft].status() != -53) ||
00395 e[iEmt].status() != 51 || e[iRadAft].status() != 51) {
00396 e.list();
00397 fatalEmissionVeto(string("Couldn't find Pythia FSR emission"));
00398 }
00399
00400
00401
00402
00403
00404 int xSR = (pTemtMode == 0) ? 1 : -1;
00405 int i = (pTemtMode == 0) ? iRadBef : -1;
00406 int k = (pTemtMode == 0) ? iRadAft : -1;
00407 int r = (pTemtMode == 0) ? iRecAft : -1;
00408
00409
00410 double pTemt = -1.;
00411 if (pTemtMode == 0 || pTemtMode == 1) {
00412
00413
00414
00415
00416
00417 int j = iRadAft;
00418 if (emittedMode == 0 || (emittedMode == 2 && rndmPtr->flat() < 0.5)) j++;
00419
00420 for (int jLoop = 0; jLoop < 2; jLoop++) {
00421 if (jLoop == 0) pTemt = pTcalc(e, i, j, k, r, xSR);
00422 else if (jLoop == 1) pTemt = min(pTemt, pTcalc(e, i, j, k, r, xSR));
00423
00424
00425 if (emittedMode != 3) break;
00426 if (k != -1) swap(j, k); else j = iEmt;
00427 }
00428
00429
00430 } else if (pTemtMode == 2) {
00431 pTemt = pTcalc(e, i, -1, k, r, xSR);
00432
00433 }
00434
00435 #ifdef DBGOUTPUT
00436 cout << "doVetoFSREmission: pTemt = " << pTemt << endl << endl;
00437 #endif
00438
00439
00440 if (pTemt > pThard) {
00441 nAcceptSeq = 0;
00442 nFSRveto++;
00443 return true;
00444 }
00445
00446
00447 nAcceptSeq++;
00448 accepted = true;
00449 return false;
00450 }
00451
00452
00453
00454
00455
00456 bool EmissionVetoHook1::doVetoMPIEmission(int, const Pythia8::Event &e) {
00457 if (MPIvetoOn) {
00458 if (e[e.size() - 1].pT() > pTMPI) {
00459 #ifdef DBGOUTPUT
00460 cout << "doVetoMPIEmission: pTnow = " << e[e.size() - 1].pT()
00461 << ", pTMPI = " << pTMPI << endl << endl;
00462 #endif
00463 return true;
00464 }
00465 }
00466 return false;
00467 }
00468