File indexing completed on 2025-01-18 10:06:36
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #ifndef Pythia8_ColourReconnectionHooks_H
0023 #define Pythia8_ColourReconnectionHooks_H
0024
0025
0026 #include "Pythia8/Pythia.h"
0027 namespace Pythia8 {
0028
0029
0030
0031
0032
0033 class MBReconUserHooks : public UserHooks {
0034
0035 public:
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047 MBReconUserHooks(int modeIn = 0, int flipIn = 0, double dLamCutIn = 0.,
0048 double fracGluonIn = 1.) : mode(modeIn), flip(flipIn), dLamCut(dLamCutIn),
0049 fracGluon(fracGluonIn) { m2Ref = 1.; dLamCut = max(0., dLamCut); }
0050 ~MBReconUserHooks() {}
0051
0052
0053 virtual bool canReconnectResonanceSystems() {return true;}
0054
0055
0056 virtual bool doReconnectResonanceSystems( int, Event& event) {
0057
0058
0059 if (mode <= 0 || mode > 2) return true;
0060
0061
0062
0063 if (infoPtr->isDiffractiveA() && infoPtr->isDiffractiveB())
0064 return true;
0065
0066
0067 if (!setupConfig( event)) return false;
0068
0069
0070 if ( (mode == 1 && nGlu < 2) || (mode == 2 && nGlu < 1) ) return true;
0071
0072
0073 bool hasRec = (mode == 1) ? doReconnectSwap( event)
0074 : doReconnectMove( event);
0075 if (!hasRec) return false;
0076
0077
0078 if (flip > 0) return doReconnectFlip( event);
0079 return true;
0080
0081 }
0082
0083
0084
0085
0086
0087 private:
0088
0089
0090 int mode, flip, nRec, nGlu, nAllCol, nCol;
0091 double dLamCut, fracGluon, m2Ref, dLamTot;
0092
0093
0094 vector<int> iGlu;
0095
0096
0097 vector<int> iToAllCol, iAllCol;
0098
0099
0100 map<int, int> colMap, acolMap;
0101
0102
0103 vector<double> lambdaij;
0104
0105
0106 double lambda12( int i, int j) {
0107 int iAC = iToAllCol[i]; int jAC = iToAllCol[j];
0108 return lambdaij[nAllCol * min( iAC, jAC) + max( iAC, jAC)];
0109 }
0110
0111
0112 double lambda123( int i, int j, int k) {
0113 int iAC = iToAllCol[i]; int jAC = iToAllCol[j]; int kAC = iToAllCol[k];
0114 return lambdaij[nAllCol * min( iAC, jAC) + max( iAC, jAC)]
0115 + lambdaij[nAllCol * min( iAC, kAC) + max( iAC, kAC)]
0116 - lambdaij[nAllCol * min( jAC, kAC) + max( jAC, kAC)];
0117 }
0118
0119
0120 class InfoSwapMove{
0121 public:
0122 InfoSwapMove(int i1in = 0, int i2in = 0) : i1(i1in), i2(i2in) {}
0123 InfoSwapMove(int i1in, int i2in, int iCol1in, int iAcol1in, int iCol2in,
0124 int iAcol2in, int dLamIn) : i1(i1in), i2(i2in), iCol1(iCol1in),
0125 iAcol1(iAcol1in), iCol2(iCol2in), iAcol2(iAcol2in), dLam(dLamIn) {}
0126 ~InfoSwapMove() {}
0127 int i1, i2, col1, acol1, iCol1, iAcol1, col2, acol2, iCol2, iAcol2;
0128 double lamNow, dLam;
0129 };
0130
0131
0132 vector<InfoSwapMove> infoSM;
0133
0134
0135
0136
0137
0138 inline bool setupConfig(Event& event) {
0139
0140
0141 iGlu.clear();
0142 iToAllCol.resize( event.size() );
0143 iAllCol.clear();
0144 colMap.clear();
0145 acolMap.clear();
0146 infoSM.clear();
0147 nRec = 0;
0148 dLamTot = 0.;
0149
0150
0151 for (int i = 3; i < event.size(); ++i) if (event[i].isFinal()) {
0152 if (event[i].id() == 21 && rndmPtr->flat() < fracGluon)
0153 iGlu.push_back(i);
0154
0155
0156 if (event[i].col() > 0 || event[i].acol() > 0) {
0157 iToAllCol[i] = iAllCol.size();
0158 iAllCol.push_back(i);
0159 if (event[i].col() > 0) colMap[event[i].col()] = i;
0160 if (event[i].acol() > 0) acolMap[event[i].acol()] = i;
0161 }
0162 }
0163
0164
0165 for (int iJun = 0; iJun < event.sizeJunction(); ++iJun) {
0166 if (event.kindJunction(iJun) == 1) {
0167 for (int j = 0; j < 3; ++j) {
0168 int jCol = event.colJunction( iJun, j);
0169 for (map<int, int>::iterator colM = colMap.begin();
0170 colM != colMap.end(); ++colM)
0171 if (colM->first == jCol) {
0172 colMap.erase( colM);
0173 break;
0174 }
0175 for (int iG = 0; iG < int(iGlu.size()); ++iG)
0176 if (event[iGlu[iG]].col() == jCol) {
0177 iGlu.erase(iGlu.begin() + iG);
0178 break;
0179 }
0180 }
0181 } else if (event.kindJunction(iJun) == 2) {
0182 for (int j = 0; j < 3; ++j) {
0183 int jCol = event.colJunction( iJun, j);
0184 for (map<int, int>::iterator acolM = acolMap.begin();
0185 acolM != acolMap.end(); ++acolM)
0186 if (acolM->first == jCol) {
0187 acolMap.erase( acolM);
0188 break;
0189 }
0190 for (int iG = 0; iG < int(iGlu.size()); ++iG)
0191 if (event[iGlu[iG]].acol() == jCol) {
0192 iGlu.erase(iGlu.begin() + iG);
0193 break;
0194 }
0195 }
0196 }
0197 }
0198
0199
0200 nGlu = iGlu.size();
0201 nCol = colMap.size();
0202 if (int(acolMap.size()) != nCol) {
0203 loggerPtr->ERROR_MSG("map sizes do not match");
0204 return false;
0205 }
0206 map<int, int>::iterator colM = colMap.begin();
0207 map<int, int>::iterator acolM = acolMap.begin();
0208 for (int iCol = 0; iCol < nCol; ++iCol) {
0209 if (colM->first != acolM->first) {
0210 loggerPtr->ERROR_MSG("map elements do not match");
0211 return false;
0212 }
0213 ++colM;
0214 ++acolM;
0215 }
0216
0217
0218 nAllCol = iAllCol.size();
0219 lambdaij.resize( pow2(nAllCol) );
0220 int i, j;
0221 for (int iAC = 0; iAC < nAllCol - 1; ++iAC) {
0222 i = iAllCol[iAC];
0223 for (int jAC = iAC + 1; jAC < nAllCol; ++jAC) {
0224 j = iAllCol[jAC];
0225 lambdaij[nAllCol * iAC + jAC]
0226 = log1p(m2( event[i], event[j]) / m2Ref);
0227 }
0228 }
0229
0230
0231 return true;
0232
0233 }
0234
0235
0236
0237
0238
0239 inline bool doReconnectSwap(Event& event) {
0240
0241
0242 for (int iG1 = 0; iG1 < nGlu - 1; ++iG1) {
0243 int i1 = iGlu[iG1];
0244 for (int iG2 = iG1 + 1; iG2 < nGlu; ++iG2) {
0245 int i2 = iGlu[iG2];
0246 InfoSwapMove tmpSM( i1, i2);
0247 calcLamSwap( tmpSM, event);
0248 infoSM.push_back( tmpSM);
0249 }
0250 }
0251 int nPair = infoSM.size();
0252
0253
0254 for ( int iSwap = 0; iSwap < nGlu; ++iSwap) {
0255 int iPairMin = -1;
0256 double dLamMin = 1e4;
0257
0258
0259 for (int iPair = 0; iPair < nPair; ++iPair)
0260 if (infoSM[iPair].dLam < dLamMin) {
0261 iPairMin = iPair;
0262 dLamMin = infoSM[iPair].dLam;
0263 }
0264
0265
0266 if (dLamMin > -dLamCut) break;
0267 ++nRec;
0268 dLamTot += dLamMin;
0269 int i1min = infoSM[iPairMin].i1;
0270 int i2min = infoSM[iPairMin].i2;
0271
0272
0273 int col1 = event[i1min].col();
0274 int acol1 = event[i1min].acol();
0275 int col2 = event[i2min].col();
0276 int acol2 = event[i2min].acol();
0277 event[i1min].cols( col2, acol2);
0278 event[i2min].cols( col1, acol1);
0279
0280
0281 colMap[col1] = i2min;
0282 acolMap[acol1] = i2min;
0283 colMap[col2] = i1min;
0284 acolMap[acol2] = i1min;
0285
0286
0287 infoSM[iPairMin] = infoSM.back();
0288 infoSM.pop_back();
0289 --nPair;
0290
0291
0292 for (int iPair = 0; iPair < nPair; ++iPair) {
0293 InfoSwapMove& tmpSM = infoSM[iPair];
0294 if ( tmpSM.i1 == i1min || tmpSM.i1 == i2min
0295 || tmpSM.i2 == i1min || tmpSM.i2 == i2min
0296 || tmpSM.iCol1 == i1min || tmpSM.iCol1 == i2min
0297 || tmpSM.iAcol1 == i1min || tmpSM.iAcol1 == i2min
0298 || tmpSM.iCol2 == i1min || tmpSM.iCol2 == i2min
0299 || tmpSM.iAcol2 == i1min || tmpSM.iAcol2 == i2min)
0300 calcLamSwap( tmpSM, event);
0301 }
0302 }
0303
0304
0305 return true;
0306
0307 }
0308
0309
0310
0311
0312
0313 inline void calcLamSwap( InfoSwapMove& tmpSM, Event& event) {
0314
0315
0316 tmpSM.col1 = event[tmpSM.i1].col();
0317 tmpSM.acol1 = event[tmpSM.i1].acol();
0318 tmpSM.iCol1 = acolMap[tmpSM.col1];
0319 tmpSM.iAcol1 = colMap[tmpSM.acol1];
0320 tmpSM.col2 = event[tmpSM.i2].col();
0321 tmpSM.acol2 = event[tmpSM.i2].acol();
0322 tmpSM.iCol2 = acolMap[tmpSM.col2];
0323 tmpSM.iAcol2 = colMap[tmpSM.acol2];
0324
0325
0326 double lam1c = lambda12( tmpSM.i1, tmpSM.iCol1);
0327 double lam1a = lambda12( tmpSM.i1, tmpSM.iAcol1);
0328 double lam2c = lambda12( tmpSM.i2, tmpSM.iCol2);
0329 double lam2a = lambda12( tmpSM.i2, tmpSM.iAcol2);
0330 double lam3c = lambda12( tmpSM.i1, tmpSM.iCol2);
0331 double lam3a = lambda12( tmpSM.i1, tmpSM.iAcol2);
0332 double lam4c = lambda12( tmpSM.i2, tmpSM.iCol1);
0333 double lam4a = lambda12( tmpSM.i2, tmpSM.iAcol1);
0334 if (tmpSM.col1 == tmpSM.acol2 && tmpSM.acol1 == tmpSM.col2)
0335 tmpSM.dLam = 2e4;
0336 else if (tmpSM.col1 == tmpSM.acol2)
0337 tmpSM.dLam = (lam3c + lam4a) - (lam1a + lam2c);
0338 else if (tmpSM.acol1 == tmpSM.col2)
0339 tmpSM.dLam = (lam3a + lam4c) - (lam1c + lam2a);
0340 else tmpSM.dLam = (lam3c + lam3a + lam4c + lam4a)
0341 - (lam1c + lam1a + lam2c + lam2a);
0342
0343
0344 }
0345
0346
0347
0348
0349
0350 inline bool doReconnectMove(Event& event) {
0351
0352
0353 int iNow, colNow, acolNow, iColNow, iAcolNow, col2Now;
0354 double lamNow;
0355
0356
0357 for (int iG = 0; iG < nGlu; ++iG) {
0358
0359
0360 iNow = iGlu[iG];
0361 colNow = event[iNow].col();
0362 acolNow = event[iNow].acol();
0363 iColNow = acolMap[colNow];
0364 iAcolNow = colMap[acolNow];
0365
0366
0367 lamNow = lambda123( iNow, iColNow, iAcolNow);
0368
0369
0370 for (map<int, int>::iterator colM = colMap.begin();
0371 colM != colMap.end(); ++colM) {
0372 col2Now = colM->first;
0373
0374
0375 InfoSwapMove tmpSM( iNow);
0376 tmpSM.col1 = colNow;
0377 tmpSM.acol1 = acolNow;
0378 tmpSM.iCol1 = iColNow;
0379 tmpSM.iAcol1 = iAcolNow;
0380 tmpSM.lamNow = lamNow;
0381 tmpSM.col2 = col2Now;
0382 tmpSM.iCol2 = colMap[col2Now];
0383 tmpSM.iAcol2 = acolMap[col2Now];
0384
0385
0386 tmpSM.dLam = (tmpSM.iCol2 == tmpSM.i1 || tmpSM.iAcol2 == tmpSM.i1
0387 || tmpSM.iCol1 == tmpSM.iAcol1) ? 2e4
0388 : lambda123( tmpSM.i1, tmpSM.iCol2, tmpSM.iAcol2) - tmpSM.lamNow;
0389 infoSM.push_back( tmpSM);
0390 }
0391 }
0392 int nPair = infoSM.size();
0393
0394
0395 for ( int iMove = 0; iMove < nGlu; ++iMove) {
0396 int iPairMin = -1;
0397 double dLamMin = 1e4;
0398
0399
0400 for (int iPair = 0; iPair < nPair; ++iPair)
0401 if (infoSM[iPair].dLam < dLamMin) {
0402 iPairMin = iPair;
0403 dLamMin = infoSM[iPair].dLam;
0404 }
0405
0406
0407 if (dLamMin > -dLamCut) break;
0408 ++nRec;
0409 dLamTot += dLamMin;
0410
0411
0412 InfoSwapMove& selSM = infoSM[iPairMin];
0413 int i1Sel = selSM.i1;
0414 int iCol1Sel = selSM.iCol1;
0415 int iAcol1Sel = selSM.iAcol1;
0416 int iCol2Sel = selSM.iCol2;
0417 int iAcol2Sel = selSM.iAcol2;
0418 int iCol2Mod[3] = { iAcol1Sel , i1Sel , iCol2Sel };
0419 int col2Mod[3] = { selSM.col1, selSM.col2, selSM.acol1};
0420
0421
0422 for (int i = 0; i < 3; ++i) {
0423 event[ iCol2Mod[i] ].col( col2Mod[i] );
0424 colMap[ col2Mod[i] ] = iCol2Mod[i];
0425 }
0426
0427
0428 int i1Now = 0;
0429 bool doUpdate = false;
0430 for (int iPair = 0; iPair < nPair; ++iPair) {
0431 InfoSwapMove& tmpSM = infoSM[iPair];
0432 if (tmpSM.i1 != i1Now) {
0433 i1Now = tmpSM.i1;
0434 doUpdate = false;
0435 if (i1Now == i1Sel || i1Now == iCol1Sel || i1Now == iAcol1Sel
0436 || i1Now == iCol2Sel || i1Now == iAcol2Sel) {
0437 colNow = event[i1Now].col();
0438 acolNow = event[i1Now].acol();
0439 iColNow = acolMap[colNow];
0440 iAcolNow = colMap[acolNow];
0441 lamNow = lambda123( i1Now, iColNow, iAcolNow);
0442 doUpdate = true;
0443 }
0444 }
0445 if (doUpdate) {
0446 tmpSM.col1 = colNow;
0447 tmpSM.acol1 = acolNow;
0448 tmpSM.iCol1 = iColNow;
0449 tmpSM.iAcol1 = iAcolNow;
0450 tmpSM.lamNow = lamNow;
0451 }
0452 }
0453
0454
0455 for (int iPair = 0; iPair < nPair; ++iPair) {
0456 InfoSwapMove& tmpSM = infoSM[iPair];
0457 int iMod = -1;
0458 for (int i = 0; i < 3; ++i) if (tmpSM.col2 == col2Mod[i]) iMod = i;
0459 if (iMod > -1) tmpSM.iCol2 = iCol2Mod[iMod];
0460 if (tmpSM.i1 == i1Sel || tmpSM.i1 == iCol1Sel || tmpSM.i1 == iAcol1Sel
0461 || tmpSM.i1 == iCol2Sel || tmpSM.i1 == iAcol2Sel || iMod > -1)
0462 tmpSM.dLam = (tmpSM.iCol2 == tmpSM.i1 || tmpSM.iAcol2 == tmpSM.i1
0463 || tmpSM.iCol1 == tmpSM.iAcol1) ? 2e4
0464 : lambda123( tmpSM.i1, tmpSM.iCol2, tmpSM.iAcol2) - tmpSM.lamNow;
0465 }
0466
0467
0468 }
0469
0470
0471 return true;
0472
0473 }
0474
0475
0476
0477
0478
0479 inline bool doReconnectFlip(Event& event) {
0480
0481
0482 vector<int> iTmp, iVec, iBeg, iEnd;
0483
0484
0485 for (int i = 3; i < event.size(); ++i)
0486 if (event[i].isFinal() && event[i].col() > 0 && event[i].acol() == 0) {
0487 iTmp.clear();
0488 iTmp.push_back( i);
0489
0490
0491 int iNow = i;
0492 map<int, int>::iterator acolM = acolMap.find( event[iNow].col() );
0493 bool foundEnd = false;
0494 while (acolM != acolMap.end()) {
0495 iNow = acolM->second;
0496 iTmp.push_back( iNow);
0497 if (event[iNow].col() == 0) {
0498 foundEnd = true;
0499 break;
0500 }
0501 acolM = acolMap.find( event[iNow].col() );
0502 }
0503
0504
0505 if (foundEnd || flip == 2) {
0506 iBeg.push_back( iVec.size());
0507 for (int j = 0; j < int(iTmp.size()); ++j) iVec.push_back( iTmp[j]);
0508 iEnd.push_back( iVec.size());
0509 }
0510 }
0511
0512
0513 if (flip == 2) for (int i = 3; i < event.size(); ++i)
0514 if (event[i].isFinal() && event[i].acol() > 0 && event[i].col() == 0) {
0515 iTmp.clear();
0516 iTmp.push_back( i);
0517
0518
0519 int iNow = i;
0520 map<int, int>::iterator colM = colMap.find( event[iNow].acol() );
0521 bool foundEnd = false;
0522 while (colM != colMap.end()) {
0523 iNow = colM->second;
0524 iTmp.push_back( iNow);
0525 if (event[iNow].acol() == 0) {
0526 foundEnd = true;
0527 break;
0528 }
0529 colM = colMap.find( event[iNow].acol() );
0530 }
0531
0532
0533 if (!foundEnd) {
0534 iBeg.push_back( iVec.size());
0535 for (int j = 0; j < int(iTmp.size()); ++j) iVec.push_back( iTmp[j]);
0536 iEnd.push_back( iVec.size());
0537 }
0538 }
0539
0540
0541
0542 int nSys = iBeg.size();
0543 int i1c, i1a, i2c, i2a, i1cMin, i1aMin, i2cMin, i2aMin, iSMin;
0544 double dLam, dLamMin;
0545 vector<InfoSwapMove> flipMin;
0546
0547
0548 for (int iSys1 = 0; iSys1 < nSys - 1; ++iSys1) if (iBeg[iSys1] >= 0)
0549 for (int iSys2 = iSys1 + 1; iSys2 < nSys; ++iSys2) if (iBeg[iSys2] >= 0) {
0550 i1cMin = 0;
0551 i1aMin = 0;
0552 i2cMin = 0;
0553 i2aMin = 0;
0554 dLamMin = 1e4;
0555
0556
0557 for (int j1 = iBeg[iSys1]; j1 < iEnd[iSys1] - 1; ++j1)
0558 for (int j2 = iBeg[iSys2]; j2 < iEnd[iSys2] - 1; ++j2) {
0559 i1c = iVec[j1];
0560 i1a = iVec[j1 + 1];
0561 i2c = iVec[j2];
0562 i2a = iVec[j2 + 1];
0563 dLam = lambda12( i1c, i2a) + lambda12( i2c, i1a)
0564 - lambda12( i1c, i1a) - lambda12( i2c, i2a);
0565 if (dLam < dLamMin) {
0566 i1cMin = i1c;
0567 i1aMin = i1a;
0568 i2cMin = i2c;
0569 i2aMin = i2a;
0570 dLamMin = dLam;
0571 }
0572 }
0573
0574
0575 if (dLamMin < -dLamCut) flipMin.push_back( InfoSwapMove(
0576 iSys1, iSys2, i1cMin, i1aMin, i2cMin, i2aMin, dLamMin) );
0577 }
0578 int flipSize = flipMin.size();
0579
0580
0581 for (int iFlip = 0; iFlip < min( nSys / 2, flipSize); ++iFlip) {
0582 iSMin = -1;
0583 dLamMin = 1e4;
0584 for (int iSys12 = 0; iSys12 < flipSize; ++iSys12)
0585 if (flipMin[iSys12].i1 >= 0 && flipMin[iSys12].dLam < dLamMin) {
0586 iSMin = iSys12;
0587 dLamMin = flipMin[iSys12].dLam;
0588 }
0589
0590
0591 if (iSMin >= 0) {
0592 InfoSwapMove& flipNow = flipMin[iSMin];
0593 int iS1 = flipNow.i1;
0594 int iS2 = flipNow.i2;
0595 event[ flipNow.iAcol1 ].acol( event[flipNow.iCol2].col() );
0596 event[ flipNow.iAcol2 ].acol( event[flipNow.iCol1].col() );
0597 ++nRec;
0598 dLamTot += flipNow.dLam;
0599 for (int iSys12 = 0; iSys12 < flipSize; ++iSys12)
0600 if ( flipMin[iSys12].i1 == iS1 || flipMin[iSys12].i1 == iS2
0601 || flipMin[iSys12].i2 == iS1 || flipMin[iSys12].i2 == iS2)
0602 flipMin[iSys12].i1 = -1;
0603 }
0604 else break;
0605 }
0606
0607
0608 return true;
0609
0610 }
0611
0612 };
0613
0614
0615
0616
0617
0618
0619 class TopReconUserHooks : public UserHooks {
0620
0621 public:
0622
0623
0624
0625
0626
0627
0628
0629
0630
0631
0632
0633
0634
0635
0636
0637 TopReconUserHooks(int modeIn = 0, double strengthIn = 1.) : mode(modeIn),
0638 strength(strengthIn) { iList = 0; nList = 0; pTolerance = 0.01;
0639 m2Ref = 1.;}
0640 ~TopReconUserHooks() {}
0641
0642
0643 virtual bool canReconnectResonanceSystems() {return true;}
0644
0645
0646 virtual bool doReconnectResonanceSystems( int, Event& event) {
0647
0648
0649 if (mode <= 0 || mode > 5) return true;
0650
0651
0652 classifyFinalPartons(event);
0653
0654
0655 if (!checkClassification(event)) return false;
0656
0657
0658 if (iList++ < nList) {
0659 listClassification();
0660 event.list();
0661 }
0662
0663
0664 bool tqrkFirst = (rndmPtr->flat() < 0.5);
0665 doReconnect( tqrkFirst, event);
0666 doReconnect(!tqrkFirst, event);
0667
0668
0669 return true;
0670 }
0671
0672
0673
0674
0675 private:
0676
0677
0678 int mode, iList, nList, nRec;
0679 double strength, pTolerance, m2Ref;
0680
0681
0682
0683 vector<int> iBqrk, iWpos, iTqrk, iBbar, iWneg, iTbar, iRest;
0684
0685
0686 map<int, int> colMap, acolMap;
0687
0688
0689
0690
0691
0692
0693 inline bool classifyFinalPartons(Event& event) {
0694
0695
0696 iBqrk.clear();
0697 iWpos.clear();
0698 iTqrk.clear();
0699 iBbar.clear();
0700 iWneg.clear();
0701 iTbar.clear();
0702 iRest.clear();
0703 colMap.clear();
0704 acolMap.clear();
0705 nRec = 0;
0706
0707
0708 for (int i = 3; i < event.size(); ++i) if (event[i].isFinal()) {
0709 bool hasCol = (event[i].colType() != 0);
0710
0711
0712 bool fsrFromT = false;
0713 bool fromTqrk = false;
0714 bool fromBqrk = false;
0715 bool fromWpos = false;
0716 bool fromTbar = false;
0717 bool fromBbar = false;
0718 bool fromWneg = false;
0719
0720
0721 int iNow = i;
0722 int idOld = 0;
0723 do {
0724 int idNow = event[iNow].id();
0725
0726
0727 if (abs(idNow) == 6 && (idOld == 21 || idOld == 22)) fsrFromT = true;
0728
0729
0730 else if (idNow == 6) fromTqrk = true;
0731 else if (idNow == 5) fromBqrk = true;
0732 else if (idNow == 24) fromWpos = true;
0733 else if (idNow == -6) fromTbar = true;
0734 else if (idNow == -5) fromBbar = true;
0735 else if (idNow == -24) fromWneg = true;
0736
0737
0738 iNow = event[iNow].mother1();
0739 idOld = idNow;
0740 } while (iNow > 2 && !fsrFromT);
0741
0742
0743
0744 if (fromTqrk && fromWpos && hasCol) iWpos.push_back(i);
0745 else if (fromTqrk && fromBqrk && hasCol) iBqrk.push_back(i);
0746 else if (fromTqrk) iTqrk.push_back(i);
0747 else if (fromTbar && fromWneg && hasCol) iWneg.push_back(i);
0748 else if (fromTbar && fromBbar && hasCol) iBbar.push_back(i);
0749 else if (fromTbar) iTbar.push_back(i);
0750 else if (hasCol) iRest.push_back(i);
0751
0752
0753 if (hasCol && (mode == 4 || mode == 5)) {
0754 if (event[i].col() > 0) colMap[event[i].col()] = i;
0755 if (event[i].acol() > 0) acolMap[event[i].acol()] = i;
0756 }
0757 }
0758
0759
0760 return true;
0761
0762 }
0763
0764
0765
0766
0767
0768 inline bool checkClassification(Event& event) {
0769
0770
0771 int iTqrkLoc = 0;
0772 int iTbarLoc = 0;
0773 for (int i = 3; i < event.size(); ++i) {
0774 if(event[i].id() == 6) iTqrkLoc = i;
0775 if(event[i].id() == -6) iTbarLoc = i;
0776 }
0777
0778
0779 Vec4 tqrkDiff = event[iTqrkLoc].p();
0780 for (int i = 0; i < int(iBqrk.size()); ++i)
0781 tqrkDiff -= event[iBqrk[i]].p();
0782 for (int i = 0; i < int(iWpos.size()); ++i)
0783 tqrkDiff -= event[iWpos[i]].p();
0784 for (int i = 0; i < int(iTqrk.size()); ++i)
0785 tqrkDiff -= event[iTqrk[i]].p();
0786
0787
0788 Vec4 tbarDiff = event[iTbarLoc].p();
0789 for (int i = 0; i < int(iBbar.size()); ++i)
0790 tbarDiff -= event[iBbar[i]].p();
0791 for (int i = 0; i < int(iWneg.size()); ++i)
0792 tbarDiff -= event[iWneg[i]].p();
0793 for (int i = 0; i < int(iTbar.size()); ++i)
0794 tbarDiff -= event[iTbar[i]].p();
0795
0796
0797 double totErr = abs(tqrkDiff.px()) + abs(tqrkDiff.py())
0798 + abs(tqrkDiff.pz()) + abs(tqrkDiff.e()) + abs(tbarDiff.px())
0799 + abs(tbarDiff.py()) + abs(tbarDiff.pz()) + abs(tqrkDiff.e());
0800 if (totErr > pTolerance) {
0801 loggerPtr->ERROR_MSG("Error in t/tbar daughter search");
0802 cout << "\n Error in t/tbar daughter search: \n t difference "
0803 << tqrkDiff << " tbar difference "<< tbarDiff;
0804 listClassification();
0805 event.list();
0806 }
0807
0808
0809 return (totErr < pTolerance);
0810 }
0811
0812
0813
0814
0815
0816 inline void listClassification() {
0817
0818 cout << "\n Final-state coloured partons classified by source: ";
0819 cout << "\n From Bqrk:";
0820 for (int i = 0; i < int(iBqrk.size()); ++i) cout << " " << iBqrk[i];
0821 cout << "\n From Wpos:";
0822 for (int i = 0; i < int(iWpos.size()); ++i) cout << " " << iWpos[i];
0823 cout << "\n From Tqrk:";
0824 for (int i = 0; i < int(iTqrk.size()); ++i) cout << " " << iTqrk[i];
0825 cout << "\n From Bbar:";
0826 for (int i = 0; i < int(iBbar.size()); ++i) cout << " " << iBbar[i];
0827 cout << "\n From Wneg:";
0828 for (int i = 0; i < int(iWneg.size()); ++i) cout << " " << iWneg[i];
0829 cout << "\n From Tbar:";
0830 for (int i = 0; i < int(iTbar.size()); ++i) cout << " " << iTbar[i];
0831 cout << "\n From Rest:";
0832 for (int i = 0; i < int(iRest.size()); ++i) {
0833 cout << " " << iRest[i];
0834 if (i%20 == 19 && i + 1 != int(iRest.size())) cout << "\n ";
0835 }
0836 cout << endl;
0837 }
0838
0839
0840
0841
0842
0843 inline bool doReconnect(bool doTqrk, Event& event) {
0844
0845
0846 vector<int> iTdec;
0847 if (doTqrk) {
0848 for (int i = 0; i < int(iBqrk.size()); ++i) iTdec.push_back(iBqrk[i]);
0849 for (int i = 0; i < int(iWpos.size()); ++i) iTdec.push_back(iWpos[i]);
0850 } else {
0851 for (int i = 0; i < int(iBbar.size()); ++i) iTdec.push_back(iBbar[i]);
0852 for (int i = 0; i < int(iWneg.size()); ++i) iTdec.push_back(iWneg[i]);
0853 }
0854
0855
0856 vector<int> iGT;
0857 for (int i = 0; i < int(iTdec.size()); ++i) {
0858 int colNow = event[iTdec[i]].col();
0859 int acolNow = event[iTdec[i]].acol();
0860 if (colNow > 0 && acolNow > 0) iGT.push_back(iTdec[i]);
0861 }
0862 int nGT = iGT.size();
0863
0864
0865 if (nGT > 1) for (int i = 0; i < nGT; ++i) {
0866 int j = min( int(nGT * rndmPtr->flat()), nGT - 1 );
0867 swap( iGT[i], iGT[j]);
0868 }
0869
0870
0871 vector<int> iGR;
0872 for (int i = 0; i < int(iRest.size()); ++i) {
0873 int colNow = event[iRest[i]].col();
0874 int acolNow = event[iRest[i]].acol();
0875 if (colNow > 0 && acolNow > 0) iGR.push_back(iRest[i]);
0876 }
0877 int nGR = iGR.size();
0878 int iR, colT, acolT, iColT, iAcolT, colR, acolR, iColR, iAcolR;
0879 double mTR2, mTR2now, dLam = 0.0, lamT, lamNow, lamRec;
0880
0881
0882 if (nGT > 0 && nGR > 0)
0883 for (int iT = 0; iT < nGT; ++iT) {
0884 if (strength < rndmPtr->flat()) continue;
0885
0886
0887 if (mode == 1) iR = min( int(nGR * rndmPtr->flat()), nGR - 1 );
0888
0889
0890 else if (mode < 4) {
0891 iR = 0;
0892 mTR2 = m2( event[iGT[iT]], event[iGR[iR]]);
0893 for (int ii = 1; ii < nGR; ++ii) {
0894 mTR2now = m2( event[iGT[iT]], event[iGR[ii]]);
0895 if (mode == 2 && mTR2now < mTR2) {iR = ii; mTR2 = mTR2now;}
0896 if (mode == 3 && mTR2now > mTR2) {iR = ii; mTR2 = mTR2now;}
0897 }
0898
0899
0900 } else {
0901 iR = -1;
0902 dLam = 1e10;
0903 colT = event[iGT[iT]].col();
0904 acolT = event[iGT[iT]].acol();
0905 iColT = acolMap[colT];
0906 iAcolT = colMap[acolT];
0907 lamT = log1p(m2( event[iGT[iT]], event[iColT]) / m2Ref)
0908 + log1p(m2( event[iGT[iT]], event[iAcolT]) / m2Ref);
0909 for (int ii = 0; ii < nGR; ++ii) {
0910 colR = event[iGR[ii]].col();
0911 acolR = event[iGR[ii]].acol();
0912 iColR = acolMap[colR];
0913 iAcolR = colMap[acolR];
0914 lamNow = lamT
0915 + log1p(m2( event[iGR[ii]], event[iColR]) / m2Ref)
0916 + log1p(m2( event[iGR[ii]], event[iAcolR]) / m2Ref);
0917 lamRec = log1p(m2( event[iGT[iT]], event[iColR]) / m2Ref)
0918 + log1p(m2( event[iGT[iT]], event[iAcolR]) / m2Ref)
0919 + log1p(m2( event[iGR[ii]], event[iColT]) / m2Ref)
0920 + log1p(m2( event[iGR[ii]], event[iAcolT]) / m2Ref);
0921 if (lamRec - lamNow < dLam) {iR = ii; dLam = lamRec - lamNow;}
0922 }
0923 if (mode == 5 && dLam > 0.) continue;
0924 }
0925
0926
0927 ++nRec;
0928 swapCols( iGT[iT], iGR[iR], event);
0929 }
0930
0931
0932 return true;
0933
0934 }
0935
0936
0937
0938
0939
0940 inline void swapCols( int i, int j, Event& event) {
0941
0942
0943 int coli = event[i].col();
0944 int acoli = event[i].acol();
0945 int colj = event[j].col();
0946 int acolj = event[j].acol();
0947 event[i].cols( colj, acolj);
0948 event[j].cols( coli, acoli);
0949
0950
0951 colMap[coli] = j;
0952 acolMap[acoli] = j;
0953 colMap[colj] = i;
0954 acolMap[acolj] = i;
0955
0956 }
0957
0958 };
0959
0960
0961
0962 }
0963
0964 #endif