9 #include "Pythia8/ColourReconnection.h"
21 BeamDipole(
int colIn = 0,
int iColIn = 0,
int iAcolIn = 0)
22 : col(colIn), iCol(iColIn), iAcol(iAcolIn) {}
38 void ColourDipole::list() {
40 cout << setw(10) <<
this << setw(6) << col << setw(3) << colReconnection
41 << setw(6) << iCol << setw(5) << iAcol << setw(6) << iColLeg << setw(5)
42 << iAcolLeg << setw(6) << isJun << setw(5) << isAntiJun << setw(10)
43 << p1p2 <<
" colDips: ";
44 for (
int i = 0;i < int(colDips.size());++i)
45 cout << setw(10) << colDips[i];
46 cout <<
" acolDips: ";
47 for (
int i = 0;i < int(acolDips.size());++i)
48 cout << setw(10) << acolDips[i];
49 cout << setw(3) << isActive << endl;
62 InfoGluonMove(
int i1in,
int col1in,
int acol1in,
int iCol1in,
int iAcol1in,
63 int col2in,
int iCol2in,
int iAcol2in,
double lambdaRefIn,
64 double dLambdaIn) : i1(i1in), i2(0), col1(col1in), acol1(acol1in),
65 iCol1(iCol1in), iAcol1(iAcol1in), col2(col2in), iCol2(iCol2in),
66 iAcol2(iAcol2in), lambdaRef(lambdaRefIn), dLambda(dLambdaIn) {}
67 InfoGluonMove(
int i1in,
int i2in,
int iCol1in,
int iAcol1in,
int iCol2in,
68 int iAcol2in,
int dLambdaIn) : i1(i1in), i2(i2in), col1(0), acol1(0),
69 iCol1(iCol1in), iAcol1(iAcol1in), col2(0), iCol2(iCol2in),
70 iAcol2(iAcol2in), lambdaRef(0.), dLambda(dLambdaIn) {}
73 int i1, i2, col1, acol1, iCol1, iAcol1, col2, iCol2, iAcol2;
74 double lambdaRef, dLambda;
86 void ColourJunction::list() {
88 cout << setw(6) << kind() << setw(6)
89 << col(0) << setw(6) << col(1) << setw(6) << col(2) << setw(6)
90 << endCol(0) << setw(6) << endCol(1) << setw(6) << endCol(2) << setw(6)
91 << status(0) << setw(6) << status(1) << setw(6) << status(2) << setw(10)
92 << dips[0] << setw(10) << dips[1] << setw(10) << dips[2] << setw(10)
94 cout <<
" " << setw(10) << dipsOrig[0] << setw(10) << dipsOrig[1]
95 << setw(10) << dipsOrig[2] << endl;
107 void ColourParticle::listParticle() {
109 const Particle& pt = (*this);
112 cout << setw(10) << pt.id() <<
" " << left
113 << setw(18) << pt.nameWithStatus(18) << right << setw(4)
114 << pt.status() << setw(6) << pt.mother1() << setw(6)
115 << pt.mother2() << setw(6) << pt.daughter1() << setw(6)
116 << pt.daughter2() << setw(6) << pt.col() << setw(6) << pt.acol()
118 << setw(11) << pt.px() << setw(11) << pt.py() << setw(11)
119 << pt.pz() << setw(11) << pt.e() << setw(11) << pt.m() <<
"\n";
127 void ColourParticle::listActiveDips() {
129 cout <<
"active dips: " << endl;
130 for (
int i = 0; i < int(activeDips.size()); ++i)
131 activeDips[i]->list();
139 void ColourParticle::listDips() {
141 cout <<
"--- Particle ---" << endl;
142 for (
int i = 0; i < int(dips.size()); ++i) {
143 cout <<
"(" <<colEndIncluded[i] <<
") ";
144 for (
int j = 0; j < int(dips[i].size()); ++j) {
145 cout << dips[i][j]->iCol <<
" (" << dips[i][j]->col <<
") ";
146 if (j ==
int(dips[i].size() - 1))
147 cout << dips[i][j]->iAcol <<
" (" << acolEndIncluded[i] <<
")" << endl;
158 const double ColourReconnection::MINIMUMGAIN = 1E-10;
161 const double ColourReconnection::MINIMUMGAINJUN = 1E-10;
164 const double ColourReconnection::HBAR = 0.197327;
167 const double ColourReconnection::TINYP1P2 = 1e-20;
172 const int ColourReconnection::MAXRECONNECTIONS = 1000;
178 bool cmpTrials(TrialReconnection j1, TrialReconnection j2) {
179 return (j1.lambdaDiff < j2.lambdaDiff);
186 bool ColourReconnection::init( Info* infoPtrIn, Settings& settings,
187 Rndm* rndmPtrIn, ParticleData* particleDataPtrIn, BeamParticle* beamAPtrIn,
188 BeamParticle* beamBPtrIn, PartonSystems* partonSystemsPtrIn) {
193 particleDataPtr = particleDataPtrIn;
194 beamAPtr = beamAPtrIn;
195 beamBPtr = beamBPtrIn;
196 partonSystemsPtr = partonSystemsPtrIn;
199 eCM = infoPtr->eCM();
203 reconnectMode = settings.mode(
"ColourReconnection:mode");
206 pT0Ref = settings.parm(
"MultipartonInteractions:pT0Ref");
207 ecmRef = settings.parm(
"MultipartonInteractions:ecmRef");
208 ecmPow = settings.parm(
"MultipartonInteractions:ecmPow");
209 pT0 = pT0Ref * pow(eCM / ecmRef, ecmPow);
212 reconnectRange = settings.parm(
"ColourReconnection:range");
213 pT20Rec = pow2(reconnectRange * pT0);
216 m0 = settings.parm(
"ColourReconnection:m0");
218 allowJunctions = settings.flag(
"ColourReconnection:allowJunctions");
219 nReconCols = settings.mode(
"ColourReconnection:nColours");
220 sameNeighbourCol = settings.flag(
"ColourReconnection:sameNeighbourColours");
222 timeDilationMode = settings.mode(
"ColourReconnection:timeDilationMode");
223 timeDilationPar = settings.parm(
"ColourReconnection:timeDilationPar");
224 timeDilationParGeV = timeDilationPar / HBAR;
227 m2Lambda = settings.parm(
"ColourReconnection:m2Lambda");
228 fracGluon = settings.parm(
"ColourReconnection:fracGluon");
229 dLambdaCut = settings.parm(
"ColourReconnection:dLambdaCut");
230 flipMode = settings.mode(
"ColourReconnection:flipMode");
233 singleReconOnly = settings.flag(
"ColourReconnection:singleReconnection");
234 lowerLambdaOnly = settings.flag(
"ColourReconnection:lowerLambdaOnly");
235 tfrag = settings.parm(
"ColourReconnection:fragmentationTime");
236 blowR = settings.parm(
"ColourReconnection:blowR");
237 blowT = settings.parm(
"ColourReconnection:blowT");
238 rHadron = settings.parm(
"ColourReconnection:rHadron");
239 kI = settings.parm(
"ColourReconnection:kI");
242 stringLength.init(infoPtr, settings);
253 bool ColourReconnection::next(
Event& event,
int iFirst) {
256 if (reconnectMode == 0)
return reconnectMPIs(event, iFirst);
259 else if (reconnectMode == 1)
return nextNew(event, iFirst);
262 else if (reconnectMode == 2)
return reconnectMove(event, iFirst);
265 else if (reconnectMode == 3 || reconnectMode == 4)
266 return reconnectTypeCommon(event, iFirst);
270 infoPtr->errorMsg(
"Warning in ColourReconnection::next: "
271 "Colour reconnecion mode not found");
281 bool ColourReconnection::nextNew(
Event& event,
int iFirst) {
284 while (!dipoles.empty()) {
285 delete dipoles.back();
292 formationTimes.clear();
295 setupDipoles(event, iFirst);
296 makeAllPseudoParticles(event, iFirst);
300 vector<vector<int> > iDips;
301 iDips.resize(nReconCols);
302 for (
int i = 0; i < int(iDips.size()); ++i)
303 iDips[i] = vector<int>();
305 for (
int i = 0; i < int(dipoles.size()); ++i)
306 if (dipoles[i]->isActive)
307 iDips[dipoles[i]->colReconnection].push_back(i);
310 for (
int i = 0;i < int(iDips.size()); ++i)
311 for (
int j = 0; j < int(iDips[i].size()); ++j)
312 for (
int k = j + 1; k < int(iDips[i].size()); ++k)
313 singleReconnection(dipoles[iDips[i][j]], dipoles[iDips[i][k]]);
316 bool alreadyWarned =
false;
319 for (
int iOuterLoop = 0; iOuterLoop < 20; ++iOuterLoop) {
320 bool finished =
true;
323 for (
int iInnerLoop = 0;dipTrials.size() > 0; ++iInnerLoop) {
326 if (iInnerLoop > MAXRECONNECTIONS) {
328 infoPtr->errorMsg(
"Warning in ColourReconnection::nextNew:"
329 "Too many reconnections, stopping before minimum reached.");
330 alreadyWarned =
true;
336 storeUsedDips(dipTrials.back());
339 doDipoleTrial(dipTrials.back());
342 sort(usedDipoles.begin(), usedDipoles.end());
343 for (
int i = 0;i < int(usedDipoles.size() - 1); ++i)
344 if (usedDipoles[i] == usedDipoles[i + 1]) {
345 usedDipoles.erase(usedDipoles.begin() + i);
350 updateDipoleTrials();
354 if (allowJunctions) {
359 for (
int i = 0; i < int(iDips.size()); ++i)
360 iDips[i] = vector<int>();
362 for (
int i = 0; i < int(dipoles.size()); ++i)
363 if (dipoles[i]->isActive)
364 iDips[dipoles[i]->colReconnection % 3].push_back(i);
367 for (
int i = 0;i < int(iDips.size()); ++i)
368 for (
int j = 0; j < int(iDips[i].size()); ++j)
369 for (
int k = j + 1; k < int(iDips[i].size()); ++k)
370 singleJunction(dipoles[iDips[i][j]], dipoles[iDips[i][k]]);
374 for (
int i = 0;i < int(iDips.size()); ++i)
375 for (
int j = 0; j < int(iDips[i].size()); ++j)
376 for (
int k = j + 1; k < int(iDips[i].size()); ++k)
377 for (
int l = k + 1; l < int(iDips[i].size()); ++l)
378 singleJunction(dipoles[iDips[i][j]], dipoles[iDips[i][k]],
379 dipoles[iDips[i][l]]);
382 for (
int iInnerLoop = 0;junTrials.size() > 0; ++iInnerLoop) {
385 if (iInnerLoop > MAXRECONNECTIONS) {
387 infoPtr->errorMsg(
"Warning in ColourReconnection::nextNew:"
388 "Too many reconnections, stopping before minimum reached.");
389 alreadyWarned =
true;
395 storeUsedDips(junTrials.back());
398 doJunctionTrial(event, junTrials.back());
401 sort(usedDipoles.begin(), usedDipoles.end());
402 for (
int i = 0;i < int(usedDipoles.size() - 1); ++i)
403 if (usedDipoles[i] == usedDipoles[i + 1]) {
404 usedDipoles.erase(usedDipoles.begin() + i);
409 updateJunctionTrials();
410 updateDipoleTrials();
421 updateEvent(event, iFirst);
433 void ColourReconnection::setupDipoles(
Event& event,
int iFirst) {
436 vector< vector<int > > chains;
438 vector<bool> isAntiJun;
439 vector<bool> isGluonLoop;
440 vector<bool> inChain(event.size(),
false);
443 for (
int i = iFirst; i <
event.size(); ++i) {
444 if ( (event[i].isFinal() && !inChain[i]
445 && event[i].isQuark() && event[i].
id() > 0)
446 || (
event[i].isFinal() && !inChain[i]
447 &&
event[i].isDiquark() &&
event[i].id() < 0) ) {
448 int curCol =
event[i].col();
452 isAntiJun.push_back(
false);
453 isJun.push_back(
false);
454 isGluonLoop.push_back(
false);
455 for (
int iSteps = 0; curCol != 0 && iSteps < 1000; ++iSteps) {
458 for (
int j = iFirst; j <
event.size(); j++) {
459 if (event[j].isFinal() && !inChain[j] &&
event[j].acol() == curCol) {
462 curCol =
event[j].col();
468 for (
int iJun = 0; iJun <
event.sizeJunction(); ++iJun) {
469 for (
int j = 0; j < 3; ++j) {
470 if (event.colJunction(iJun,j) == curCol) {
471 isJun[isJun.size() -1] =
true;
473 chain.push_back( -(10 + 10 * iJun + j) );
478 chains.push_back(chain);
483 for (
int i = 0; i <
event.sizeJunction(); ++i) {
486 int checkCol =
event.colJunction(i,0);
487 bool wrongSystem =
false;
488 for (
int j = 0; j < iFirst; ++j)
489 if (event[j].isFinal() && event[j].acol() == checkCol)
495 if (event.kindJunction(i) == 2)
496 for (
int jCol = 0; jCol < 3; ++jCol) {
497 int curCol =
event.colJunction(i,jCol);
499 chain.push_back( -(10 + 10 * i + jCol));
500 isAntiJun.push_back(
true);
501 isJun.push_back(
false);
502 isGluonLoop.push_back(
false);
503 for (
int iSteps = 0; curCol != 0 && iSteps < 1000; ++iSteps) {
506 for (
int j = iFirst; j <
event.size(); ++j)
507 if (event[j].isFinal() && !inChain[j] &&
508 event[j].acol() == curCol) {
511 curCol =
event[j].col();
516 for (
int iJun = 0; iJun <
event.sizeJunction(); ++iJun)
517 if (event.kindJunction(iJun) == 1)
518 for (
int j = 0; j < 3; ++j)
519 if (event.colJunction(iJun,j) == curCol) {
520 isJun[isJun.size() - 1] =
true;
522 chain.push_back( -(10 + 10 * iJun + j));
525 chains.push_back(chain);
530 for (
int i = iFirst; i <
event.size(); ++i)
531 if (event[i].isFinal() && !inChain[i] &&
event[i].col() != 0) {
532 int curCol =
event[i].col();
536 isAntiJun.push_back(
false);
537 isJun.push_back(
false);
538 isGluonLoop.push_back(
true);
539 for (
int iSteps = 0; curCol != 0 && iSteps < 1000; ++iSteps) {
540 bool foundNext =
false;
541 for (
int j = iFirst; j <
event.size(); ++j)
542 if (event[j].isFinal() && !inChain[j] &&
event[j].acol() == curCol) {
545 curCol =
event[j].col();
553 chains.push_back(chain);
557 for (
int i = 0; i < int(chains.size()); ++i) {
558 if (chains[i].size() == 1)
continue;
564 for (
int j = 0; j < int(chains[i].size()); ++j) {
565 if (j !=
int(chains[i].size() - 1)) {
568 int newCol = int(rndmPtr->flat() * nReconCols);
569 while (newCol == lastCol && !sameNeighbourCol) {
570 newCol = int(rndmPtr->flat() * nReconCols);
575 if (j == 0 && !isAntiJun[i] && !isGluonLoop[i]) {
577 int iMother =
event[
event[ chains[i][j] ].iTopCopy()].mother1();
578 if ( event[iMother].idAbs() == 21) {
579 vector<int> sisters =
event[ chains[i][j] ].sisterList(
true);
581 if (sisters.size() == 1 &&
event[ chains[i][j] ].id()
582 == -
event[ sisters[0] ].id()) {
586 for (
int k = 0; k < int(dipoles.size()); ++k)
587 if (dipoles[k]->iAcol == sisters[0]) {
588 colSis = dipoles[k]->colReconnection;
593 while (colSis == newCol && !sameNeighbourCol)
594 newCol = int(rndmPtr->flat() * nReconCols);
601 if (j ==
int(chains[i].size() - 2) && !isJun[i] && !isGluonLoop[i]) {
603 int iMother =
event[
event[chains[i][j + 1]].iTopCopy()].mother1();
604 if (event[iMother].idAbs() == 21) {
605 vector<int> sisters =
event[ chains[i][j + 1] ].sisterList(
true);
607 if (sisters.size() == 1 &&
event[ chains[i][j + 1] ].id()
608 == -
event[ sisters[0] ].id()) {
612 for (
int k = 0; k < int(dipoles.size()); ++k)
613 if (dipoles[k]->iCol == sisters[0]) {
614 colSis = dipoles[k]->colReconnection;
619 while ((colSis == newCol || newCol == lastCol)
620 && !sameNeighbourCol)
621 newCol =
int(rndmPtr->flat() * nReconCols);
628 if ((chains[i][j] > 0 && event[chains[i][j]].status() == 75) ||
629 (chains[i][j + 1] > 0 &&
630 event[ chains[i][j + 1] ].status() == 75) ) {
634 if (chains[i][j] > 0 && event[ chains[i][j] ].status() == 75)
635 sisters = event[ chains[i][j] ].sisterList();
637 sisters =
event[ chains[i][j + 1] ].sisterList();
639 if (sisters.size() == 3 ) {
642 int acolSis1 = -1, acolSis2 = -1, acolSis3 = -1;
643 int colSis1 = -1, colSis2 = -1, colSis3 = -1;
644 for (
int k = 0;k < int(dipoles.size()); ++k) {
645 if (dipoles[k]->iAcol == sisters[0])
646 acolSis1 = dipoles[k]->colReconnection;
648 if (dipoles[k]->iAcol == sisters[1])
649 acolSis2 = dipoles[k]->colReconnection;
651 if (dipoles[k]->iAcol == sisters[2])
652 acolSis3 = dipoles[k]->colReconnection;
654 if (dipoles[k]->iCol == sisters[0])
655 colSis1 = dipoles[k]->colReconnection;
657 if (dipoles[k]->iCol == sisters[1])
658 colSis2 = dipoles[k]->colReconnection;
660 if (dipoles[k]->iCol == sisters[2])
661 colSis3 = dipoles[k]->colReconnection;
665 while ((colSis1 == newCol || colSis2 == newCol ||
666 colSis3 == newCol || acolSis1 == newCol ||
667 acolSis2 == newCol || acolSis3 == newCol)
668 && !sameNeighbourCol)
669 newCol =
int(rndmPtr->flat() * nReconCols);
674 if (j == 0) firstCol = newCol;
678 if (j == 0 && isAntiJun[i]) {
679 int col =
event.colJunction( -
int(chains[i][j]/10) - 1,
681 dipoles.push_back(
new ColourDipole(col, chains[i][j],
682 chains[i][j+1], newCol));
683 dipoles.back()->isAntiJun =
true;
687 else dipoles.push_back(
new ColourDipole(event[ chains[i][j] ].col(),
688 chains[i][j], chains[i][j+1], newCol));
691 if (j ==
int(chains[i].size() - 2) && isJun[i])
692 dipoles.back()->isJun =
true;
696 dipoles[dipoles.size() - 1]->leftDip = dipoles[dipoles.size() - 2];
697 dipoles[dipoles.size() - 2]->rightDip = dipoles[dipoles.size() - 1];
705 if (event[ chains[i][j] ].col() == event[ chains[i][0] ].acol()) {
706 int newCol = int(rndmPtr->flat() * nReconCols);
707 while ( (newCol == lastCol || newCol == firstCol)
708 && !sameNeighbourCol) {
709 newCol = int(rndmPtr->flat() * nReconCols);
711 dipoles.push_back(
new ColourDipole(event[ chains[i][j] ].col(),
712 chains[i][j], chains[i][0], newCol));
715 dipoles[dipoles.size() - 1]->leftDip = dipoles[dipoles.size() - 2];
716 dipoles[dipoles.size() - 2]->rightDip = dipoles[dipoles.size() - 1];
717 dipoles[dipoles.size() - chains[i].size()]->leftDip =
718 dipoles[dipoles.size() -1];
719 dipoles[dipoles.size() - 1]->rightDip =
720 dipoles[dipoles.size() - chains[i].size()];
728 iColJun.resize(event.sizeJunction());
729 for (
int i = 0; i < int(iColJun.size()); ++i) iColJun[i] = vector<int>(3,0);
732 for (
int i = iFirst; i <
event.size(); ++i)
733 if (event[i].isFinal())
734 for (
int j = 0; j <
event.sizeJunction(); ++j)
735 for (
int jLeg = 0; jLeg < 3; ++jLeg)
736 if (event[i].col() ==
event.colJunction(j,jLeg) ||
737 event[i].acol() ==
event.colJunction(j,jLeg))
738 iColJun[j][jLeg] = i;
741 for (
int i = 0;i <
event.sizeJunction(); ++i)
742 for (
int iLeg = 0; iLeg < 3; ++iLeg)
743 for (
int j = i + 1;j <
event.sizeJunction(); ++j)
744 for (
int jLeg = 0; jLeg < 3; ++jLeg)
745 if (event.colJunction(i, iLeg) ==
event.colJunction(j, jLeg)) {
746 iColJun[i][iLeg] = -(10*j + 10 + jLeg);
747 iColJun[j][jLeg] = -(10*i + 10 + iLeg);
751 setupFormationTimes(event);
760 double ColourReconnection::calculateStringLength(ColourDipole * dip,
761 vector<ColourDipole *> &dips) {
764 for (
int i = 0; i < int(dips.size()); ++i)
765 if (dips[i] == dip)
return 0.;
768 if (!dip->isJun && !dip->isAntiJun) {
769 return calculateStringLength(dip->iCol, dip->iAcol);
774 vector<int> iParticles;
775 vector<bool> usedJuns(junctions.size(),
false);
778 if (!findJunctionParticles( -
int(dip->iAcol/10) - 1, iParticles,
779 usedJuns, nJuns, dips))
return 1e9;
781 if (!findJunctionParticles(-
int(dip->iCol/10) - 1, iParticles,
782 usedJuns, nJuns, dips))
return 1e9;
785 if (
int(iParticles.size()) == 3)
786 return calculateJunctionLength(iParticles[0], iParticles[1],
790 else if (
int(iParticles.size()) == 4) {
791 return calculateDoubleJunctionLength(iParticles[0], iParticles[1],
792 iParticles[2], iParticles[3]);
803 void ColourReconnection::updateEvent(
Event& event,
int iFirst) {
806 int oldSize =
event.size();
807 for (
int i = iFirst; i < oldSize;++i)
808 if (event[i].isFinal())
event.copy(i, 79);
811 event.clearJunctions();
812 for (
int i = 0; i < int(junctions.size()); ++i) {
813 for (
int j = 0; j < 3; ++j) {
814 if ( junctions[i].dipsOrig[j] != 0) {
815 junctions[i].col(j, junctions[i].dipsOrig[j]->col);
818 event.appendJunction(Junction(junctions[i]));
822 for (
int i = 0; i < int(dipoles.size()); ++i)
823 if (dipoles[i]->isReal) {
824 if (dipoles[i]->iCol >= 0)
825 event[
event[ dipoles[i]->iCol ].daughter1() ].col(dipoles[i]->col);
827 event.colJunction(-(dipoles[i]->iCol/10 + 1), -dipoles[i]->iCol % 10,
829 if (dipoles[i]->iAcol >= 0)
830 event[
event[ dipoles[i]->iAcol ].daughter1() ].acol(dipoles[i]->col);
832 event.colJunction(-(dipoles[i]->iAcol/10 + 1), -dipoles[i]->iAcol % 10,
843 bool ColourReconnection::findJunctionParticles(
int iJun,
844 vector<int>& iParticles, vector<bool> &usedJuns,
int &nJuns,
845 vector<ColourDipole*> &dips ) {
848 usedJuns[iJun] =
true;
856 if (junctions[iJun].kind() % 2 == 1)
857 for (
int i = 0; i < 3; ++i)
858 iParticles.push_back(junctions[iJun].dips[i]->iCol);
860 for (
int i = 0; i < 3; ++i)
861 iParticles.push_back(junctions[iJun].dips[i]->iAcol);
864 for (
int i = 0; i < 3; ++i) {
866 for (
int j = 0; j < int(dips.size()); ++j) {
867 if (dips[j] == junctions[iJun].dips[i]) {
872 if (addDip) dips.push_back(junctions[iJun].dips[i]);
876 for (
int i = 0; i < int(iParticles.size()); ++i)
877 if (iParticles[i] < 0) {
878 int iNewJun = - int(iParticles[i] / 10) -1;
879 iParticles.erase(iParticles.begin() + i);
881 if (!usedJuns[iNewJun] && !findJunctionParticles( iNewJun, iParticles,
882 usedJuns, nJuns, dips) )
894 double ColourReconnection::calculateStringLength(
int i,
int j) {
895 return stringLength.getStringLength(particles[i].p(), particles[j].p());
902 double ColourReconnection::calculateJunctionLength(
int i,
906 if ( i == j || i == k || j == k)
return 1e9;
908 Vec4 p1 = particles[i].p();
909 Vec4 p2 = particles[j].p();
910 Vec4 p3 = particles[k].p();
912 return stringLength.getJuncLength(p1, p2, p3);
921 double ColourReconnection::calculateDoubleJunctionLength(
int i,
int j,
925 if (i == j || i == k || i == l || j == k || j == l || k == l)
return 1e9;
927 Vec4 p1 = particles[i].p();
928 Vec4 p2 = particles[j].p();
929 Vec4 p3 = particles[k].p();
930 Vec4 p4 = particles[l].p();
932 return stringLength.getJuncLength(p1, p2, p3, p4);
940 void ColourReconnection::singleReconnection(ColourDipole* dip1,
941 ColourDipole* dip2) {
944 if (dip1 == dip2)
return;
947 if (dip1->colReconnection != dip2->colReconnection)
return;
950 if (!dip1->isActive || !dip2->isActive)
return;
953 if (dip1->iCol == dip2->iAcol || dip1->iAcol == dip2->iCol)
return;
956 if (!checkTimeDilation(dip1, dip2))
return;
959 double lambdaDiff = getLambdaDiff(dip1, dip2);
962 if (lambdaDiff > MINIMUMGAIN) {
963 TrialReconnection dipTrial(dip1, dip2, 0, 0, 5, lambdaDiff);
964 dipTrials.insert(lower_bound(dipTrials.begin(), dipTrials.end(),
965 dipTrial, cmpTrials), dipTrial);
974 void ColourReconnection::swapDipoles(ColourDipole* dip1,
975 ColourDipole* dip2,
bool back) {
978 swap(dip1->iAcol, dip2->iAcol);
979 swap(dip1->isJun, dip2->isJun);
980 swap(dip1->iAcolLeg, dip2->iAcolLeg);
984 if (dip1->iAcol != dip2->iAcol) {
986 if (dip1->iAcol >= 0)
987 for (
int i = 0; i < int(particles[dip1->iAcol].activeDips.size()); ++i)
988 if (particles[dip1->iAcol].activeDips[i] == dip2) {
989 particles[dip1->iAcol].activeDips[i] = dip1;
993 if (dip2->iAcol >= 0)
994 for (
int i = 0; i < int(particles[dip2->iAcol].activeDips.size()); ++i)
995 if (particles[dip2->iAcol].activeDips[i] == dip1) {
996 particles[dip2->iAcol].activeDips[i] = dip2;
1001 if (dip1->iAcol >= 0) particles[dip1->iAcol].activeDips[swap2] = dip1;
1002 if (dip2->iAcol >= 0) particles[dip2->iAcol].activeDips[swap1] = dip2;
1007 for (
int i = 0; i < int(junctions.size()); ++i)
1008 if (junctions[i].kind() % 2 == 1)
1009 for (
int iLeg = 0; iLeg < 3; ++iLeg) {
1010 if (junctions[i].dips[iLeg] == dip1) {
1011 junctions[i].dips[iLeg] = dip2;
1014 if (junctions[i].dips[iLeg] == dip2) {
1015 junctions[i].dips[iLeg] = dip1;
1027 void ColourReconnection::singleJunction(ColourDipole* dip1,
1028 ColourDipole* dip2) {
1034 int iCol1 = dip1->iCol;
1035 int iCol2 = dip2->iCol;
1036 int iAcol1 = dip1->iAcol;
1037 int iAcol2 = dip2->iAcol;
1040 if (iCol1 == iCol2)
return;
1041 if (iAcol1 == iAcol2)
return;
1044 if (!dip1->isActive || !dip2->isActive)
return;
1047 if (dip1->isJun || dip1->isAntiJun)
return;
1048 if (dip2->isJun || dip2->isAntiJun)
return;
1052 if (
int(particles[iCol1].dips.size()) != 1 ||
1053 int(particles[iAcol1].dips.size()) != 1 ||
1054 int(particles[iCol2].dips.size()) != 1 ||
1055 int(particles[iAcol2].dips.size()) != 1)
1059 if ( (dip1->colReconnection) % 3 !=
1060 dip2->colReconnection % 3)
return;
1062 if ( (dip1->colReconnection) ==
1063 dip2->colReconnection)
return;
1066 if (!checkTimeDilation(dip1, dip2))
return;
1069 int junCol = (3 - (dip1->colReconnection / 3)
1070 - (dip2->colReconnection / 3) ) * 3
1071 + (dip1->colReconnection % 3);
1074 if (nReconCols != 9) {
1075 while (junCol < 0 || junCol % 3 != dip1->colReconnection % 3 ||
1076 junCol == dip1->colReconnection || junCol == dip2->colReconnection)
1077 junCol = int(nReconCols * rndmPtr->flat());
1081 ColourDipole* dip3 = dip1;
1082 ColourDipole* dip4 = dip2;
1084 double lambdaDiff = getLambdaDiff(dip1, dip2, dip3, dip4, 0);
1085 if (lambdaDiff > MINIMUMGAINJUN) {
1086 TrialReconnection junTrial(dip1, dip2, dip3, dip4, 0, lambdaDiff);
1087 junTrials.insert(lower_bound(junTrials.begin(), junTrials.end(),
1088 junTrial, cmpTrials), junTrial);
1097 if (dip3->colReconnection == junCol)
1100 if (dip4->colReconnection == dip2->colReconnection)
1101 if (checkTimeDilation(dip1, dip2, dip3, dip4)) {
1104 lambdaDiff = getLambdaDiff(dip1, dip2, dip3, dip4, 1);
1106 if (lambdaDiff > MINIMUMGAINJUN) {
1108 TrialReconnection junTrial(dip1, dip2, dip3, dip4, 1, lambdaDiff);
1109 junTrials.insert(lower_bound(junTrials.begin(), junTrials.end(),
1110 junTrial, cmpTrials), junTrial);
1116 if (!findAntiNeighbour(dip4))
1120 if (dip4 == dip2 || dip4 == dip1)
1129 if (dip3->colReconnection == dip1->colReconnection)
1132 if (dip4->colReconnection == junCol)
1133 if (checkTimeDilation(dip1, dip2, dip3, dip4)) {
1136 lambdaDiff = getLambdaDiff(dip1, dip2, dip3, dip4, 2);
1138 if (lambdaDiff > MINIMUMGAINJUN) {
1140 TrialReconnection junTrial(dip1, dip2, dip3, dip4, 2, lambdaDiff);
1141 junTrials.insert(lower_bound(junTrials.begin(), junTrials.end(),
1142 junTrial, cmpTrials), junTrial);
1147 if (!findAntiNeighbour(dip4))
1151 if (dip4 == dip2 || dip4 == dip1)
1157 if (!findAntiNeighbour(dip3))
1161 if (dip3 == dip1 || dip3 == dip2)
1173 void ColourReconnection::singleJunction(ColourDipole* dip1,
1174 ColourDipole* dip2, ColourDipole* dip3) {
1177 if (dip1->isJun || dip1->isAntiJun)
return;
1178 if (dip2->isJun || dip2->isAntiJun)
return;
1179 if (dip3->isJun || dip3->isAntiJun)
return;
1183 if (!dip1->isActive || !dip2->isActive || !dip3->isActive)
return;
1186 if ( dip1->colReconnection % 3 != dip2->colReconnection % 3
1187 || dip1->colReconnection % 3 != dip3->colReconnection % 3)
return;
1189 if ( !(dip1->colReconnection != dip2->colReconnection
1190 && dip1->colReconnection != dip3->colReconnection
1191 && dip2->colReconnection != dip3->colReconnection) )
1195 if (
int(particles[dip1->iCol].dips.size()) != 1 ||
1196 int(particles[dip1->iAcol].dips.size()) != 1 ||
1197 int(particles[dip2->iCol].dips.size()) != 1 ||
1198 int(particles[dip2->iAcol].dips.size()) != 1 ||
1199 int(particles[dip3->iCol].dips.size()) != 1 ||
1200 int(particles[dip3->iAcol].dips.size()) != 1 )
1204 if (!checkTimeDilation(dip1, dip2, dip3))
return;
1206 double lambdaDiff = getLambdaDiff(dip1, dip2, dip3, 0, 3);
1208 if (lambdaDiff > MINIMUMGAINJUN) {
1209 TrialReconnection junTrial(dip1, dip2, dip3, 0, 3, lambdaDiff);
1210 junTrials.insert(lower_bound(junTrials.begin(), junTrials.end(), junTrial,
1211 cmpTrials), junTrial);
1222 void ColourReconnection::makePseudoParticle(ColourDipole* dip ,
int status,
1226 if (!dip->isJun && !dip->isAntiJun) {
1229 int iCol = dip->iCol;
1230 int iAcol = dip->iAcol;
1231 int iColLeg = dip->iColLeg;
1232 int iAcolLeg = dip->iAcolLeg;
1235 int iNew = particles.size();
1236 particles.push_back(particles[iCol]);
1237 particles[iNew].acol(particles[iCol].acol());
1238 particles[iNew].col(particles[iAcol].col());
1239 particles[iNew].mother1(iCol);
1240 particles[iNew].mother2(iAcol);
1241 particles[iNew].id(99);
1242 particles[iNew].status(status);
1243 particles[iNew].isJun =
false;
1244 particles[iAcol].statusNeg();
1245 particles[iAcol].daughter1(iNew);
1246 particles[iCol].statusNeg();
1247 particles[iCol].daughter1(iNew);
1249 particles[iNew].p(particles[iCol].p() + particles[iAcol].p());
1251 particles[iNew].p(particles[iCol].p());
1255 particles[iNew].dips = particles[dip->iCol].dips;
1256 particles[iNew].colEndIncluded = particles[dip->iCol].colEndIncluded;
1257 particles[iNew].acolEndIncluded = particles[dip->iCol].acolEndIncluded;
1260 if (iCol != iAcol) {
1261 for (
int i = 0; i < int(particles[dip->iAcol].dips.size()); ++i) {
1262 if (i != dip->iAcolLeg) {
1264 particles[iNew].dips.push_back(particles[dip->iAcol].dips[i]);
1265 particles[iNew].colEndIncluded.push_back(
1266 particles[dip->iAcol].colEndIncluded[i]);
1267 particles[iNew].acolEndIncluded.push_back(
1268 particles[dip->iAcol].acolEndIncluded[i]);
1271 particles[iNew].acolEndIncluded[iColLeg] =
1272 particles[iAcol].acolEndIncluded[i];
1273 particles[iNew].dips[iColLeg].pop_back();
1274 particles[iNew].dips[iColLeg].insert(
1275 particles[iNew].dips[iColLeg].end(),
1276 particles[iAcol].dips[i].begin(), particles[iAcol].dips[i].end() );
1280 if (iCol != iAcol) {
1282 for (
int i = 0; i < int(particles[iAcol].activeDips.size()); ++i) {
1283 if ( particles[iAcol].activeDips[i]->iAcol == iAcol) {
1284 if (particles[iAcol].activeDips[i]->iAcolLeg < iAcolLeg)
1285 particles[iAcol].activeDips[i]->iAcolLeg +=
1286 particles[iCol].dips.size();
1287 else if (particles[iAcol].activeDips[i]->iAcolLeg == iAcolLeg)
1288 particles[iAcol].activeDips[i]->iAcolLeg = iColLeg;
1289 else if (particles[iAcol].activeDips[i]->iAcolLeg > iAcolLeg)
1290 particles[iAcol].activeDips[i]->iAcolLeg +=
1291 particles[iCol].dips.size() - 1;
1293 if (particles[iAcol].activeDips[i]->iCol == iAcol) {
1294 if (particles[iAcol].activeDips[i]->iColLeg < iAcolLeg)
1295 particles[iAcol].activeDips[i]->iColLeg +=
1296 particles[iCol].dips.size();
1297 else if (particles[iAcol].activeDips[i]->iColLeg == iAcolLeg)
1298 particles[iAcol].activeDips[i]->iColLeg = iColLeg;
1299 else if (particles[iAcol].activeDips[i]->iColLeg > iAcolLeg)
1300 particles[iAcol].activeDips[i]->iColLeg +=
1301 particles[iCol].dips.size() - 1;
1307 particles[iNew].activeDips.clear();
1308 particles[iNew].activeDips.insert(particles[iNew].activeDips.end(),
1309 particles[iCol].activeDips.begin(), particles[iCol].activeDips.end());
1311 particles[iNew].activeDips.insert(particles[iNew].activeDips.end(),
1312 particles[iAcol].activeDips.begin(), particles[iAcol].activeDips.end());
1315 for (
int i = 0; i < int(particles[iNew].activeDips.size()); ++i)
1316 if (particles[iNew].activeDips[i] == dip) {
1317 particles[iNew].activeDips.erase(
1318 particles[iNew].activeDips.begin() + i);
1323 for (
int i = 0; i < int(particles[iNew].activeDips.size()); ++i) {
1324 if (particles[iNew].activeDips[i]->iCol == iAcol)
1325 particles[iNew].activeDips[i]->iCol = iNew;
1326 if (particles[iNew].activeDips[i]->iCol == iCol)
1327 particles[iNew].activeDips[i]->iCol = iNew;
1328 if (particles[iNew].activeDips[i]->iAcol == iAcol)
1329 particles[iNew].activeDips[i]->iAcol = iNew;
1330 if (particles[iNew].activeDips[i]->iAcol == iCol)
1331 particles[iNew].activeDips[i]->iAcol = iNew;
1332 particles[iNew].activeDips[i]->p1p2
1333 = mDip(particles[iNew].activeDips[i]);
1339 for (
int i = 0; i < int(particles[iNew].activeDips.size()); ++i)
1340 for (
int j = i + 1; j < int(particles[iNew].activeDips.size()); ++j)
1341 if (particles[iNew].activeDips[i] == particles[iNew].activeDips[j]) {
1342 particles[iNew].activeDips.erase(particles[iNew].activeDips.begin() + j);
1347 for (
int i = 0; i < int(particles[iNew].activeDips.size()); ++i) {
1348 if (particles[iNew].activeDips[i]->iCol >= 0)
1349 usedDipoles.push_back(particles[iNew].activeDips[i]);
1351 for (
int j = 0;j < 3; ++j)
1352 usedDipoles.push_back(junctions[-(particles[iNew].
1353 activeDips[i]->iCol / 10 + 1)].getColDip(j));
1355 if (particles[iNew].activeDips[i]->iAcol >= 0)
1356 usedDipoles.push_back(particles[iNew].activeDips[i]);
1358 for (
int j = 0;j < 3; ++j)
1359 usedDipoles.push_back(junctions[-(particles[iNew].
1360 activeDips[i]->iAcol / 10 + 1)].getColDip(j));
1364 dip->isActive =
false;
1371 else if (dip->isJun && dip->isAntiJun) {
1377 int iJun, i0, i1, i2, junLeg0, junLeg1, junLeg2;
1378 getJunctionIndices(dip, iJun, i0, i1, i2, junLeg0, junLeg1, junLeg2);
1379 ColourDipole* dip2 = junctions[iJun].dips[junLeg1];
1380 ColourDipole* dip3 = junctions[iJun].dips[junLeg2];
1383 int iNew = particles.size();
1384 particles.push_back(ColourParticle( Particle( 99, status, i0, i1, 0, 0, 0,
1385 0, particles[i0].p() + particles[i1].p() ) ) );
1386 particles[iNew].isJun =
true;
1387 particles[iNew].junKind = junctions[iJun].kind();
1388 if (i0 == i1) particles[iNew].p(particles[i0].p());
1391 particles[i0].statusNeg();
1392 particles[i0].daughter1(iNew);
1393 particles[i1].statusNeg();
1394 particles[i1].daughter1(iNew);
1397 particles[iNew].dips.clear();
1398 particles[iNew].dips.insert(particles[iNew].dips.end(),
1399 particles[i0].dips.begin(),particles[i0].dips.end());
1401 particles[iNew].dips.insert(particles[iNew].dips.end(),
1402 particles[i1].dips.begin(),particles[i1].dips.end());
1405 particles[iNew].colEndIncluded.clear();
1406 particles[iNew].colEndIncluded.insert(
1407 particles[iNew].colEndIncluded.end(),
1408 particles[i0].colEndIncluded.begin(),
1409 particles[i0].colEndIncluded.end() );
1411 particles[iNew].colEndIncluded.insert(
1412 particles[iNew].colEndIncluded.end(),
1413 particles[i1].colEndIncluded.begin(),
1414 particles[i1].colEndIncluded.end() );
1417 particles[iNew].acolEndIncluded.clear();
1418 particles[iNew].acolEndIncluded.insert(
1419 particles[iNew].acolEndIncluded.end(),
1420 particles[i0].acolEndIncluded.begin(),
1421 particles[i0].acolEndIncluded.end() );
1423 particles[iNew].acolEndIncluded.insert(
1424 particles[iNew].acolEndIncluded.end(),
1425 particles[i1].acolEndIncluded.begin(),
1426 particles[i1].acolEndIncluded.end() );
1429 if (dip->isJun && i2 >= 0 && i2 != i0 && i2 != i1) {
1430 particles[iNew].dips.push_back(particles[i2].dips[dip3->iColLeg]);
1431 particles[iNew].dips.back().erase(particles[iNew].dips.back().begin(),
1432 particles[iNew].dips.back().end() - 1);
1435 if (dip->isAntiJun && i2 >= 0 && i2 != i0 && i2 != i1) {
1436 particles[iNew].dips.push_back(particles[i2].dips[dip3->iAcolLeg]);
1437 particles[iNew].dips.back().erase(
1438 particles[iNew].dips.back().begin() + 1,
1439 particles[iNew].dips.back().end() );
1443 if (i2 != i0 && i2 != i1) {
1444 particles[iNew].acolEndIncluded.push_back(
false);
1445 particles[iNew].colEndIncluded.push_back(
false);
1450 particles[iNew].dips.push_back(vector<ColourDipole *>());
1453 for (
int i = 0; i < int(dipoles.size()); ++i)
1454 if (dipoles[i]->isReal && dipoles[i]->iCol == dip3->iCol &&
1455 dipoles[i]->iAcol == dip3->iAcol)
1456 particles[iNew].dips.back().push_back(dipoles[i]);
1459 particles[iNew].acolEndIncluded.back() =
true;
1460 particles[iNew].colEndIncluded.back() =
true;
1465 for (
int i = 0; i < int(particles[iNew].acolEndIncluded.size()); ++i)
1466 particles[iNew].acolEndIncluded[i] =
true;
1468 for (
int i = 0; i < int(particles[iNew].colEndIncluded.size()); ++i)
1469 particles[iNew].colEndIncluded[i] =
true;
1473 dip->isActive =
false;
1474 dip2->isActive =
false;
1475 dip3->isActive =
true;
1481 for (
int i = 0; i < int(particles[i1].activeDips.size()); ++i) {
1482 if (particles[i1].activeDips[i]->iAcol == i1)
1483 particles[i1].activeDips[i]->iAcolLeg += particles[i0].dips.size();
1484 if (particles[i1].activeDips[i]->iCol == i1)
1485 particles[i1].activeDips[i]->iColLeg += particles[i0].dips.size();
1489 particles[iNew].activeDips.clear();
1490 particles[iNew].activeDips.insert(particles[iNew].activeDips.end(),
1491 particles[i0].activeDips.begin(), particles[i0].activeDips.end());
1493 particles[iNew].activeDips.insert(particles[iNew].activeDips.end(),
1494 particles[i1].activeDips.begin(), particles[i1].activeDips.end());
1495 if (i2 != i0 && i2 != i1)
1496 particles[iNew].activeDips.push_back(dip3);
1499 for (
int i = 0; i < int(particles[iNew].activeDips.size()); ++i) {
1500 if (particles[iNew].activeDips[i] == dip) {
1501 particles[iNew].activeDips.erase(
1502 particles[iNew].activeDips.begin() + i);
1506 if (particles[iNew].activeDips[i] == dip2) {
1507 particles[iNew].activeDips.erase(
1508 particles[iNew].activeDips.begin() + i);
1515 for (
int i = 0; i < int(particles[iNew].activeDips.size()); ++i) {
1516 if (particles[iNew].activeDips[i]->iCol == i1)
1517 particles[iNew].activeDips[i]->iCol = iNew;
1518 if (particles[iNew].activeDips[i]->iCol == i0)
1519 particles[iNew].activeDips[i]->iCol = iNew;
1520 if (particles[iNew].activeDips[i]->iAcol == i1)
1521 particles[iNew].activeDips[i]->iAcol = iNew;
1522 if (particles[iNew].activeDips[i]->iAcol == i0)
1523 particles[iNew].activeDips[i]->iAcol = iNew;
1524 particles[iNew].activeDips[i]->p1p2
1525 = mDip(particles[iNew].activeDips[i]);
1530 dip3->isJun =
false;
1532 if (i2 != i0 && i2 != i1)
1533 dip3->iAcolLeg = particles[iNew].dips.size() - 1;
1536 dip3->isAntiJun =
false;
1538 if (i2 != i0 && i2 != i1)
1539 dip3->iColLeg = particles[iNew].dips.size() - 1;
1543 for (
int i = 0; i < int(particles[iNew].activeDips.size()); ++i) {
1545 for (
int j = 0;j < int(usedDipoles.size()); ++j)
1546 if (particles[iNew].activeDips[i] == usedDipoles[j]) {
1550 if (!added) usedDipoles.push_back(particles[iNew].activeDips[i]);
1552 usedDipoles.push_back(dip);
1553 usedDipoles.push_back(dip2);
1554 usedDipoles.push_back(dip3);
1558 if (setupDone && mDip(dip3) < m0)
1559 makePseudoParticle(dip3, status,
true);
1570 bool sortFunc(ColourDipole* a, ColourDipole* b) {
1571 return (a->p1p2 < b->p1p2);
1578 void ColourReconnection::makeAllPseudoParticles(
Event & event,
int iFirst) {
1581 for (
int i = 0; i <
event.sizeJunction(); ++i)
1582 junctions.push_back(event.getJunction(i));
1585 int oldSize = int(dipoles.size());
1586 for (
int i = 0; i < oldSize; ++i) {
1587 dipoles.push_back(
new ColourDipole(*dipoles[i]));
1588 dipoles[i + oldSize]->iColLeg = 0;
1589 dipoles[i + oldSize]->iAcolLeg = 0;
1590 dipoles[i]->iColLeg = 0;
1591 dipoles[i]->iAcolLeg = 0;
1592 dipoles[i]->isActive =
false;
1593 dipoles[i]->isReal =
true;
1594 dipoles[i + oldSize]->isReal =
false;
1597 if (dipoles[i]->iCol < 0) {
1598 junctions[-(dipoles[i]->iCol / 10 + 1)].dipsOrig[(-dipoles[i]->iCol)
1601 if (dipoles[i]->iAcol < 0) {
1602 junctions[-(dipoles[i]->iAcol / 10 + 1)].dipsOrig[-(dipoles[i]->iAcol
1603 % 10)] = dipoles[i];
1608 for (
int i = 0; i < oldSize; ++i) {
1609 if (dipoles[i]->leftDip != 0)
1610 for (
int j = 0; j < oldSize; ++j)
1611 if (dipoles[i]->leftDip == dipoles[j]) {
1612 dipoles[i + oldSize]->colDips.push_back(dipoles[j + oldSize]);
1616 if (dipoles[i]->rightDip != 0)
1617 for (
int j = 0; j < oldSize; ++j)
1618 if (dipoles[i]->rightDip == dipoles[j]) {
1619 dipoles[i + oldSize]->acolDips.push_back(dipoles[j + oldSize]);
1626 for (
int i = iFirst; i <
event.size(); ++i)
1627 if (event[i].isFinal()) {
1628 particles.push_back(ColourParticle(event[i]));
1629 particles.back().dips.resize(1,vector<ColourDipole *>());
1632 for (
int j = 0; j < int(dipoles.size()); ++j) {
1633 if (dipoles[j]->iCol == i) {
1634 if (dipoles[j]->isActive) {
1635 dipoles[j]->iCol = particles.size() - 1;
1636 particles.back().activeDips.push_back(dipoles[j]);
1638 else particles.back().dips[0].push_back(dipoles[j]);
1641 if (dipoles[j]->iAcol == i) {
1642 if (dipoles[j]->isActive) {
1643 dipoles[j]->iAcol = particles.size() - 1;
1644 particles.back().activeDips.push_back(dipoles[j]);
1646 else particles.back().dips[0].insert(particles.back().dips[0].begin(),
1652 if (event[i].isQuark() &&
event[i].id() > 0)
1653 particles.back().colEndIncluded.push_back(
true);
1654 else particles.back().colEndIncluded.push_back(
false);
1656 if (event[i].isQuark() && event[i].
id() < 0)
1657 particles.back().acolEndIncluded.push_back(
true);
1658 else particles.back().acolEndIncluded.push_back(
false);
1667 for (
int i = 0; i < int(dipoles.size()); ++i) {
1668 if (dipoles[i]->iCol < 0) {
1669 int j = (- dipoles[i]->iCol / 10) - 1;
1670 int jLeg = - dipoles[i]->iCol % 10;
1671 junctions[j].setColDip(jLeg, dipoles[i]);
1673 if (dipoles[i]->iAcol < 0) {
1674 int j = (- dipoles[i]->iAcol / 10) - 1;
1675 int jLeg = - dipoles[i]->iAcol % 10;
1676 junctions[j].setColDip(jLeg, dipoles[i]);
1681 for (
int i = 0; i < int(dipoles.size()); ++i) {
1682 if (dipoles[i]->isActive)
1683 dipoles[i]->p1p2 = mDip(dipoles[i]);
1685 dipoles[i]->p1p2 = 1e9;
1690 sort(dipoles.begin(), dipoles.end(), sortFunc);
1691 bool finished =
true;
1692 for (
int i = 0; i < int(dipoles.size()); ++i) {
1693 if (!dipoles[i]->isActive)
continue;
1694 if (dipoles[i]->p1p2 < m0) {
1695 makePseudoParticle( dipoles[i], 110);
1701 if (finished)
break;
1705 sort(dipoles.begin(), dipoles.end(), sortFunc);
1717 void ColourReconnection::checkRealDipoles(
Event& event,
int iFirst) {
1718 vector<int> dipConnections(event.size(),0);
1719 for (
int i = 0;i < int(dipoles.size()); ++i)
1720 if (dipoles[i]->isReal) {
1721 if (dipoles[i]->iCol >= 0)
1722 dipConnections[dipoles[i]->iCol]++;
1723 if (dipoles[i]->iAcol >= 0)
1724 dipConnections[dipoles[i]->iAcol]++;
1726 bool working =
true;
1727 for (
int i = iFirst ;i <
event.size(); ++i) {
1728 if (event[i].isFinal()) {
1729 if (event[i].isQuark() && dipConnections[i] != 1) {
1730 cout <<
"quark " << i <<
" is wrong!!" << endl;
1733 else if (event[i].idAbs() == 21 && dipConnections[i] != 2) {
1734 cout <<
"gluon " << i <<
" is wrong!!" << endl;
1740 infoPtr->errorMsg(
"Error in ColourReconnection::checkRealDipoles:"
1741 "Real dipoles not setup properply");
1751 void ColourReconnection::checkDipoles() {
1753 for (
int i = 0;i < int(dipoles.size()); ++i) {
1754 if (dipoles[i] == 0) { cout <<
"dipole empty" << endl;}
1755 if (dipoles[i]->isActive) {
1756 if (dipoles[i]->iCol >= 0) {
1757 bool foundMyself =
false;
1758 for (
int j = 0; j < int(particles[ dipoles[i]->iCol ].
1759 activeDips.size()); ++j) {
1760 if (!particles[dipoles[i]->iCol].activeDips[j]->isActive) {
1761 infoPtr->errorMsg(
"Error in ColourReconnection::checkDipoles:"
1762 "Found inactive dipole, where only active was expected");
1764 if (particles[dipoles[i]->iCol].activeDips[j] == dipoles[i])
1769 infoPtr->errorMsg(
"Error in ColourReconnection::checkDipoles:"
1770 "Linking between active dipoles and particles is wrong");
1772 if (dipoles[i]->iColLeg
1773 >=
int(particles[dipoles[i]->iCol].dips.size())) {
1774 infoPtr->errorMsg(
"Error in ColourReconnection::checkDipoles:"
1775 "Original dipoles not stored correct");
1779 if (dipoles[i]->col !=
1780 particles[dipoles[i]->iCol].dips[dipoles[i]->iColLeg].back()->col) {
1781 infoPtr->errorMsg(
"Error in ColourReconnection::checkDipoles:"
1782 "Original dipoles do not match in");
1786 if (dipoles[i]->iAcol >= 0) {
1787 bool foundMyself =
false;
1788 for (
int j = 0;j < int(particles[ dipoles[i]->iAcol ].
1789 activeDips.size()); ++j) {
1791 if (!particles[dipoles[i]->iAcol].activeDips[j]->isActive) {
1792 infoPtr->errorMsg(
"Error in ColourReconnection::checkDipoles:"
1793 "Found inactive dipole, where only active was expected");
1795 if (particles[dipoles[i]->iAcol].activeDips[j] == dipoles[i])
1800 infoPtr->errorMsg(
"Error in ColourReconnection::checkDipoles:"
1801 "Linking between active dipoles and particles is wrong");
1803 if (dipoles[i]->iAcolLeg >=
int(particles[dipoles[i]->iAcol].
1805 infoPtr->errorMsg(
"Error in ColourReconnection::checkDipoles:"
1806 "Original dipoles not stored correct");
1810 if (dipoles[i]->col != particles[dipoles[i]->iAcol].
1811 dips[dipoles[i]->iAcolLeg].front()->col) {
1812 infoPtr->errorMsg(
"Error in ColourReconnection::checkDipoles:"
1813 "Original dipoles do not match in");
1824 void ColourReconnection::listAllChains() {
1826 cout <<
" ----- PRINTING CHAINS ----- " << dipoles.size() << endl;
1827 for (
int i = 0; i < int(dipoles.size()); ++i)
1828 dipoles[i]->printed =
false;
1830 for (
int i = 0;i < int(dipoles.size()); ++i)
1831 if (!dipoles[i]->printed)
1832 listChain(dipoles[i]);
1833 cout <<
" ----- PRINTED CHAINS ----- " << endl;
1841 void ColourReconnection::listChain(ColourDipole *dip) {
1844 if (dip == 0)
return;
1847 if (!dip->isActive) {
1851 ColourDipole * colDip = dip;
1854 while (particles[colDip->iCol].dips.size() == 1 && findColNeighbour(colDip))
1858 ColourDipole * endDip = colDip;
1860 cout << colDip->iCol <<
" (" << colDip->p1p2 <<
", " << colDip->col
1861 <<
") (" << colDip->isActive <<
") ";
1862 colDip->printed =
true;
1865 while (particles[colDip->iAcol].dips.size() == 1 && findAntiNeighbour(colDip)
1866 && colDip != endDip);
1869 cout << colDip->iAcol<< endl;
1878 bool ColourReconnection::getJunctionIndices(ColourDipole * dip,
int &iJun,
1879 int &i0,
int &i1,
int &i2,
int &junLeg0,
int &junLeg1,
int &junLeg2) {
1882 int indxJun = dip->iCol;
1884 indxJun = dip->iAcol;
1885 iJun = (- indxJun / 10) - 1;
1886 junLeg0 = -(indxJun % 10);
1889 if (junLeg0 == 1) junLeg1 = 0;
1890 else if (junLeg0 == 2) junLeg2 = 0;
1892 if (dip->iCol < 0) {
1894 i1 = junctions[iJun].dips[junLeg1]->iAcol;
1895 i2 = junctions[iJun].dips[junLeg2]->iAcol;
1899 i1 = junctions[iJun].dips[junLeg1]->iCol;
1900 i2 = junctions[iJun].dips[junLeg2]->iCol;
1905 if (i1 < 0 && i2 < 0)
return false;
1908 double m1 = 1e9, m2 = 1e9;
1910 m1 = m(particles[i0].p(),particles[i1].p());
1912 m2 = m(particles[i0].p(),particles[i2].p());
1916 swap(junLeg1,junLeg2);
1921 swap(junLeg1,junLeg2);
1932 bool ColourReconnection::checkTimeDilation(ColourDipole * dip1,
1933 ColourDipole * dip2, ColourDipole * dip3, ColourDipole * dip4) {
1935 if (timeDilationMode == 0)
return true;
1939 Vec4 p1 = getDipoleMomentum(dip1);
1940 Vec4 p2 = getDipoleMomentum(dip2);
1941 double t1 = formationTimes[dip1->col];
1942 double t2 = formationTimes[dip2->col];
1943 if (dip1 == dip2)
return true;
1944 else return checkTimeDilation(p1, p2, t1, t2);
1947 }
else if (dip4 == 0) {
1948 Vec4 p1 = getDipoleMomentum(dip1);
1949 Vec4 p2 = getDipoleMomentum(dip2);
1950 Vec4 p3 = getDipoleMomentum(dip3);
1951 double t1 = formationTimes[dip1->col];
1952 double t2 = formationTimes[dip2->col];
1953 double t3 = formationTimes[dip3->col];
1955 if (timeDilationMode == 1 || timeDilationMode == 2 ||
1956 timeDilationMode == 4) {
1957 if (dip1 != dip2 && !checkTimeDilation(p1, p2, t1, t2))
return false;
1958 if (dip1 != dip3 && !checkTimeDilation(p1, p3, t1, t3))
return false;
1959 if (dip2 != dip3 && !checkTimeDilation(p2, p3, t2, t3))
return false;
1963 if (dip1 != dip2 && checkTimeDilation(p1, p2, t1, t2))
return true;
1964 if (dip1 != dip3 && checkTimeDilation(p1, p3, t1, t3))
return true;
1965 if (dip2 != dip3 && checkTimeDilation(p2, p3, t2, t3))
return true;
1971 Vec4 p1 = getDipoleMomentum(dip1);
1972 Vec4 p2 = getDipoleMomentum(dip2);
1973 Vec4 p3 = getDipoleMomentum(dip3);
1974 Vec4 p4 = getDipoleMomentum(dip4);
1975 double t1 = formationTimes[dip1->col];
1976 double t2 = formationTimes[dip2->col];
1977 double t3 = formationTimes[dip3->col];
1978 double t4 = formationTimes[dip4->col];
1980 if (timeDilationMode == 1 || timeDilationMode == 2 ||
1981 timeDilationMode == 4) {
1982 if (dip1 != dip2 && !checkTimeDilation(p1, p2, t1, t2))
return false;
1983 if (dip1 != dip3 && !checkTimeDilation(p1, p3, t1, t3))
return false;
1984 if (dip1 != dip4 && !checkTimeDilation(p1, p4, t1, t4))
return false;
1985 if (dip2 != dip3 && !checkTimeDilation(p2, p3, t2, t3))
return false;
1986 if (dip2 != dip4 && !checkTimeDilation(p2, p4, t2, t4))
return false;
1987 if (dip3 != dip4 && !checkTimeDilation(p3, p4, t3, t4))
return false;
1991 if (dip1 != dip2 && checkTimeDilation(p1, p2, t1, t2))
return true;
1992 if (dip1 != dip3 && checkTimeDilation(p1, p3, t1, t3))
return true;
1993 if (dip1 != dip4 && checkTimeDilation(p1, p4, t1, t4))
return true;
1994 if (dip2 != dip3 && checkTimeDilation(p2, p3, t2, t3))
return true;
1995 if (dip2 != dip4 && checkTimeDilation(p2, p4, t2, t4))
return true;
1996 if (dip3 != dip4 && checkTimeDilation(p3, p4, t3, t4))
return true;
2008 Vec4 ColourReconnection::getDipoleMomentum(ColourDipole * dip) {
2009 vector<int> iPar, usedJuncs;
2010 if (!dip->isJun) iPar.push_back(dip->iAcol);
2011 else addJunctionIndices(dip->iAcol, iPar, usedJuncs);
2012 if (!dip->isAntiJun) iPar.push_back(dip->iCol);
2013 else addJunctionIndices(dip->iCol, iPar, usedJuncs);
2016 sort(iPar.begin(),iPar.end());
2017 for (
int i = 0;i < int(iPar.size()) - 1; ++i)
2018 if (iPar[i] == iPar[i+1]) {
2019 iPar.erase(iPar.begin()+i);
2023 if (iPar.size() == 0) {
2024 infoPtr->errorMsg(
"Error in ColourReconnection::getDipoleMomentum: "
2025 "No particles connected to junction.");
2026 return Vec4(0,0,0,0);
2029 Vec4 p = particles[iPar[0]].p();
2030 for (
int i = 1;i < int(iPar.size()); ++i)
2031 p += particles[iPar[i]].p();
2040 bool ColourReconnection::checkTimeDilation(Vec4 p1,
2041 Vec4 p2,
double t1,
double t2) {
2043 if (timeDilationMode == 0)
return true;
2046 else if (timeDilationMode == 1) {
2048 if (p2.e() / p2.mCalc() > timeDilationPar)
return false;
2052 }
else if (timeDilationMode == 2) {
2055 if (p2.e() / p2.mCalc() > timeDilationParGeV * p2.mCalc()) part1 =
false;
2059 if (p1.e() / p1.mCalc() > timeDilationParGeV * p1.mCalc()) part2 =
false;
2061 if (part1 && part2)
return true;
2065 }
else if (timeDilationMode == 3) {
2068 if (p2.e() / p2.mCalc() > timeDilationParGeV * p2.mCalc()) part1 =
false;
2072 if (p1.e() / p1.mCalc() > timeDilationParGeV * p1.mCalc()) part2 =
false;
2074 if (part1 || part2)
return true;
2078 }
else if (timeDilationMode == 4) {
2080 if (p2.e() / p2.mCalc() < timeDilationParGeV * min(t1,t2))
return true;
2084 }
else if (timeDilationMode == 5) {
2086 if (p2.e() / p2.mCalc() < timeDilationParGeV * max(t1,t2))
return true;
2097 void ColourReconnection::setupFormationTimes(
Event & event) {
2099 for (
int i = 0;i <
event.size(); ++i) {
2101 if (event[i].col() != 0 && formationTimes.count(event[i].col()) == 0) {
2102 int col =
event[i].col();
2104 bool foundCol =
false;
2106 for (
int j = i;j <
event.size(); ++j) {
2107 if (event[j].acol() == col) {
2116 formationTimes[col] = max( m0,
2117 (event[i].p() + event[iAcol].p()).mCalc() );
2120 formationTimes[col] = max(m0, getJunctionMass(event, col));
2125 if (event[i].acol() != 0 && formationTimes.count(event[i].acol()) == 0) {
2126 int acol =
event[i].acol();
2128 bool foundCol =
false;
2130 for (
int j = i;j <
event.size(); ++j) {
2131 if (event[j].col() == acol) {
2140 formationTimes[acol] = max(m0, (event[i].p() + event[iCol].p())
2144 formationTimes[acol] = max(m0, getJunctionMass(event, acol));
2150 for (
int i = 0; i <
event.sizeJunction(); ++i)
2151 for (
int j = 0; j < 3; ++j)
2152 if (formationTimes.count(event.colJunction(i,j)) == 0)
2153 formationTimes[
event.colJunction(i,j)] = max(m0,
2154 getJunctionMass(event, event.colJunction(i,j)));
2163 double ColourReconnection::getJunctionMass(
Event & event,
int col) {
2166 vector<int> iPar, usedJuncs;
2167 addJunctionIndices(event, col, iPar, usedJuncs);
2170 sort(iPar.begin(), iPar.end());
2171 for (
int i = 0;i < int(iPar.size() -1); ++i) {
2172 if (iPar[i] == iPar[i + 1]) {
2173 iPar.erase(iPar.begin() + i);
2180 if (
int(iPar.size()) == 0)
return 0;
2182 Vec4 p =
event[iPar[0]].p();
2183 for (
int i = 1; i < int(iPar.size()); ++i)
2184 p += event[iPar[i]].p();
2195 void ColourReconnection::addJunctionIndices(
Event & event,
int col,
2196 vector<int> &iPar, vector<int> &usedJuncs) {
2200 for (
int j = 0;j <
event.sizeJunction(); ++j) {
2201 for (
int k = 0; k < 3; ++k) {
2202 if (event.colJunction(j,k) == col) {
2210 for (
int i = 0;i < int(juncs.size()); ++i) {
2211 for (
int j = 0;j < int(usedJuncs.size()); ++j) {
2212 if (juncs[i] == usedJuncs[j]) {
2213 juncs.erase(juncs.begin() + i);
2221 if (juncs.size() == 0)
return;
2224 for (
int i = 0;i < int(juncs.size()); ++i)
2225 usedJuncs.push_back(juncs[i]);
2228 for (
int iJunc = 0; iJunc < int(juncs.size()); ++iJunc) {
2229 int iTempPars[3] = {-1,-1,-1};
2230 int cols[3] = {
event.colJunction(juncs[iJunc],0),
2231 event.colJunction(juncs[iJunc],1),
event.colJunction(juncs[iJunc],2)};
2234 for (
int i = 0;i <
event.size(); ++i) {
2235 for (
int j = 0;j < 3; ++j) {
2236 if (iTempPars[j] == -1 && event.kindJunction(juncs[iJunc]) % 2 == 1 &&
2237 event[i].col() == cols[j]) iTempPars[j] = i;
2238 if (iTempPars[j] == -1 && event.kindJunction(juncs[iJunc]) % 2 == 0 &&
2239 event[i].acol() == cols[j]) iTempPars[j] = i;
2243 for (
int i = 0;i < 3;++i) {
2244 if (iTempPars[i] >= 0) iPar.push_back(iTempPars[i]);
2245 else addJunctionIndices(event, cols[i], iPar, usedJuncs);
2256 void ColourReconnection::addJunctionIndices(
int iSinglePar, vector<int> &iPar,
2257 vector<int> &usedJuncs) {
2260 int iJun = -(1 + iSinglePar/10);
2261 for (
int i = 0;i < int(usedJuncs.size()); ++i)
2262 if (iJun == usedJuncs[i])
return;
2265 usedJuncs.push_back(iJun);
2266 for (
int i = 0; i < 3; ++i)
2267 if (junctions[iJun].kind() % 2 == 1) {
2268 int iCol = junctions[iJun].dips[i]->iCol;
2269 if (iCol >= 0) iPar.push_back(iCol);
2270 else addJunctionIndices(iCol, iPar, usedJuncs);
2272 int iAcol = junctions[iJun].dips[i]->iAcol;
2273 if (iAcol >= 0) iPar.push_back(iAcol);
2274 else addJunctionIndices(iAcol, iPar, usedJuncs);
2282 double ColourReconnection::mDip(ColourDipole* dip) {
2285 if (dip->isJun && dip->isAntiJun)
return 1e9;
2287 else if (dip->isJun || dip->isAntiJun) {
2288 int iJun, i0, i1, i2, junLeg0, junLeg1, junLeg2;
2289 getJunctionIndices(dip, iJun, i0, i1, i2, junLeg0, junLeg1, junLeg2);
2291 return particles[i0].m();
2294 return m(particles[i0].p(),particles[i1].p());
2297 if (dip->iCol == dip->iAcol)
2298 return particles[dip->iCol].m();
2300 return m(particles[dip->iCol].p(),particles[dip->iAcol].p());
2309 void ColourReconnection::listDipoles(
bool onlyActive,
bool onlyReal) {
2311 cout <<
" --- listing dipoles ---" << endl;
2312 for (
int i = 0; i < int(dipoles.size()); ++i) {
2313 if (onlyActive && !dipoles[i]->isActive)
2315 if (onlyReal && !dipoles[i]->isReal)
2319 cout <<
" --- finished listing ---" << endl;
2327 void ColourReconnection::listParticles() {
2329 for (
int i = 0; i < int(particles.size()); ++i) {
2330 const ColourParticle& pt = particles[i];
2333 cout << setw(6) << i << setw(10) << pt.id() <<
" " << left
2334 << setw(18) << pt.nameWithStatus(18) << right << setw(4)
2335 << pt.status() << setw(6) << pt.mother1() << setw(6)
2336 << pt.mother2() << setw(6) << pt.daughter1() << setw(6)
2337 << pt.daughter2() << setw(6) << pt.col() << setw(6) << pt.acol()
2339 << setw(11) << pt.px() << setw(11) << pt.py() << setw(11)
2340 << pt.pz() << setw(11) << pt.e() << setw(11) << pt.m();
2341 for (
int j = 0;j < int(pt.activeDips.size());++j)
2342 cout << setw(10) << pt.activeDips[j];
2352 void ColourReconnection::listJunctions() {
2354 cout <<
" --- listing junctions ---" << endl;
2355 for (
int i = 0; i < int(junctions.size()); ++i)
2356 junctions[i].list();
2357 cout <<
" --- finished listing ---" << endl;
2370 bool ColourReconnection::reconnectMPIs(
Event& event,
int oldSize) {
2373 BeamParticle& beamA = *beamAPtr;
2374 BeamParticle& beamB = *beamBPtr;
2378 nSys = partonSystemsPtr->sizeSys();
2379 vector<int> iMerge(nSys);
2380 vector<bool> hasColour(nSys);
2381 for (
int iSys = 0; iSys < nSys; ++iSys) {
2382 iMerge[iSys] = iSys;
2383 bool hasCol =
false;
2384 for (
int iMem = 0; iMem < partonSystemsPtr->sizeOut(iSys); ++iMem) {
2385 int iNow = partonSystemsPtr->getOut( iSys, iMem);
2386 if (event[iNow].isFinal() && (event[iNow].col() > 0
2387 || event[iNow].acol() > 0) ) {
2392 hasColour[iSys] = hasCol;
2396 for (
int iRec = nSys - 1; iRec > 0; --iRec) {
2399 double pT2Rec = pow2( partonSystemsPtr->getPTHat(iRec) );
2400 double probRec = pT20Rec / (pT20Rec + pT2Rec);
2404 for (
int iSys = iRec - 1; iSys >= 0; --iSys)
2405 if (hasColour[iSys] && probRec > rndmPtr->flat()) {
2408 iMerge[iRec] = iSys;
2409 for (
int iRec2 = iRec + 1; iRec2 < nSys; ++iRec2)
2410 if (iMerge[iRec2] == iRec) iMerge[iRec2] = iSys;
2418 for (
int iSys = 0; iSys < nSys; ++iSys) {
2420 for (
int iRec = iSys + 1; iRec < nSys; ++iRec)
2421 if (iMerge[iRec] == iSys) ++nMerge;
2422 if (nMerge == 0)
continue;
2425 int iInASys = partonSystemsPtr->getInA(iSys);
2426 bool hasInA = (beamA[iSys].isFromBeam());
2427 int iInBSys = partonSystemsPtr->getInB(iSys);
2428 bool hasInB = (beamB[iSys].isFromBeam());
2431 vector<BeamDipole> bmdipoles;
2432 int sizeOut = partonSystemsPtr->sizeOut(iSys);
2433 for (
int iMem = 0; iMem < sizeOut; ++iMem) {
2436 int iNow = partonSystemsPtr->getOut( iSys, iMem);
2437 if (!event[iNow].isFinal())
continue;
2438 int col =
event[iNow].col();
2440 if (hasInA && event[iInASys].col() == col)
2441 bmdipoles.push_back( BeamDipole( col, iNow, iInASys ) );
2442 else if (hasInB && event[iInBSys].col() == col)
2443 bmdipoles.push_back( BeamDipole( col, iNow, iInBSys ) );
2446 else for (
int iMem2 = 0; iMem2 < sizeOut; ++iMem2)
2447 if (iMem2 != iMem) {
2448 int iNow2 = partonSystemsPtr->getOut( iSys, iMem2);
2449 if (!event[iNow2].isFinal())
continue;
2450 if (event[iNow2].acol() == col) {
2451 bmdipoles.push_back( BeamDipole( col, iNow, iNow2) );
2458 int acol =
event[iNow].acol();
2460 if (hasInA && event[iInASys].acol() == acol)
2461 bmdipoles.push_back( BeamDipole( acol, iInASys, iNow ) );
2462 else if (hasInB && event[iInBSys].acol() == acol)
2463 bmdipoles.push_back( BeamDipole( acol, iInBSys, iNow ) );
2468 if (bmdipoles.size() == 0)
continue;
2471 for (
int iDip = 0; iDip < int(bmdipoles.size()); ++iDip)
2472 bmdipoles[iDip].p1p2 = event[bmdipoles[iDip].iCol].p()
2473 *
event[bmdipoles[iDip].iAcol].p();
2476 for (
int iRec = iSys + 1; iRec < nSys; ++iRec) {
2477 if (iMerge[iRec] != iSys)
continue;
2480 int sizeRec = partonSystemsPtr->sizeOut(iRec);
2481 int iInARec = partonSystemsPtr->getInA(iRec);
2482 int iInBRec = partonSystemsPtr->getInB(iRec);
2484 vector<int> iGluRec;
2485 vector<double> pT2GluRec;
2487 vector<int> iAnyRec;
2488 vector<bool> freeAnyRec;
2491 for (
int iMem = 0; iMem < sizeRec; ++iMem) {
2492 int iNow = partonSystemsPtr->getOut( iRec, iMem);
2493 if (!event[iNow].isFinal())
continue;
2494 if (event[iNow].isGluon()) {
2496 iGluRec.push_back( iNow );
2497 pT2GluRec.push_back( event[iNow].pT2() );
2498 for (
int i = nGluRec - 1; i > 1; --i) {
2499 if (pT2GluRec[i - 1] > pT2GluRec[i])
break;
2500 swap( iGluRec[i - 1], iGluRec[i] );
2501 swap( pT2GluRec[i - 1], pT2GluRec[i] );
2506 iAnyRec.push_back( iNow );
2507 freeAnyRec.push_back(
true );
2513 for (
int iGRec = 0; iGRec < nGluRec; ++iGRec) {
2514 int iGlu = iGluRec[iGRec];
2515 Vec4 pGlu =
event[iGlu].p();
2517 double pT2DipMin = sCM;
2518 for (
int iDip = 0; iDip < int(bmdipoles.size()); ++iDip)
2519 if (bmdipoles[iDip].p1p2 > TINYP1P2) {
2520 double pT2Dip = (pGlu *
event[bmdipoles[iDip].iCol].p())
2521 * (pGlu * event[bmdipoles[iDip].iAcol].p()) / bmdipoles[iDip].p1p2;
2522 if (pT2Dip < pT2DipMin) {
2529 int colGlu =
event[iGlu].col();
2530 int acolGlu =
event[iGlu].acol();
2531 int colDip = bmdipoles[iDipMin].col;
2532 int iColDip = bmdipoles[iDipMin].iCol;
2533 int iAcolDip = bmdipoles[iDipMin].iAcol;
2534 event[iGlu].acol( colDip );
2535 if (event[iAcolDip].acol() == colDip)
2536 event[iAcolDip].acol( colGlu );
2537 else event[iAcolDip].col( colGlu );
2538 bmdipoles[iDipMin].iAcol = iGlu;
2539 bmdipoles[iDipMin].p1p2 =
event[iColDip].p() * pGlu;
2540 bmdipoles.push_back( BeamDipole( colGlu, iGlu, iAcolDip ) );
2541 bmdipoles.back().p1p2 = pGlu *
event[iAcolDip].p();
2544 for (
int i = oldSize; i <
event.size(); ++i)
2545 if (i != iGlu && i != iAcolDip) {
2546 if (event[i].isFinal()) {
2547 if (event[i].acol() == colGlu) event[i].acol( acolGlu );
2549 if (event[i].col() == colGlu) event[i].col( acolGlu );
2554 for (
int iJun = 0; iJun <
event.sizeJunction(); ++iJun) {
2557 if (event.kindJunction(iJun) % 2 == 0)
continue;
2558 for (
int leg = 0; leg < 3; ++leg) {
2559 int col =
event.colJunction(iJun, leg);
2561 event.colJunction(iJun, leg, colGlu);
2568 for (
int iQRec = 0; iQRec < nAnyRec; ++iQRec) {
2569 int iQ = iAnyRec[iQRec];
2570 int idQ =
event[iQ].id();
2571 if (freeAnyRec[iQRec] && idQ > 0 && idQ < 6)
2572 for (
int iQbarRec = 0; iQbarRec < nAnyRec; ++iQbarRec) {
2573 int iQbar = iAnyRec[iQbarRec];
2574 if (freeAnyRec[iQbarRec] && event[iQbar].
id() == -idQ) {
2578 int iTopQ =
event[iQ].iTopCopyId();
2579 int iTopQbar =
event[iQbar].iTopCopyId();
2580 int iMother =
event[iTopQ].mother1();
2581 if (event[iTopQbar].mother1() == iMother
2582 && event[iMother].isGluon() && event[iMother].status() != -34
2583 && event[iMother + 1].status() != -34 ) {
2587 Vec4 pGlu =
event[iQ].p() +
event[iQbar].p();
2589 double pT2DipMin = sCM;
2590 for (
int iDip = 0; iDip < int(bmdipoles.size()); ++iDip) {
2591 double pT2Dip = (pGlu *
event[bmdipoles[iDip].iCol].p())
2592 * (pGlu * event[bmdipoles[iDip].iAcol].p())
2593 / bmdipoles[iDip].p1p2;
2594 if (pT2Dip < pT2DipMin) {
2601 int colGlu =
event[iQ].col();
2602 int acolGlu =
event[iQbar].acol();
2603 int colDip = bmdipoles[iDipMin].col;
2604 int iColDip = bmdipoles[iDipMin].iCol;
2605 int iAcolDip = bmdipoles[iDipMin].iAcol;
2606 event[iQbar].acol( colDip );
2607 if (event[iAcolDip].acol() == colDip)
2608 event[iAcolDip].acol( colGlu );
2609 else event[iAcolDip].col( colGlu );
2610 bmdipoles[iDipMin].iAcol = iQbar;
2611 bmdipoles[iDipMin].p1p2 =
event[iColDip].p() *
event[iQbar].p();
2612 bmdipoles.push_back( BeamDipole( colGlu, iQ, iAcolDip ) );
2613 bmdipoles.back().p1p2 =
event[iQ].p() *
event[iAcolDip].p();
2616 freeAnyRec[iQRec] =
false;
2617 freeAnyRec[iQbarRec] =
false;
2618 for (
int i = oldSize; i <
event.size(); ++i)
2619 if (i != iQRec && i != iQbarRec && i != iColDip
2621 if (event[i].isFinal()) {
2622 if (event[i].acol() == colGlu) event[i].acol( acolGlu );
2624 if (event[i].col() == colGlu) event[i].col( acolGlu );
2629 for (
int iJun = 0; iJun <
event.sizeJunction(); ++iJun) {
2632 if (event.kindJunction(iJun) % 2 == 0)
continue;
2633 for (
int leg = 0; leg < 3; ++leg) {
2634 int col =
event.colJunction(iJun, leg);
2636 event.colJunction(iJun, leg, colGlu);
2648 if ( event[iInARec].isGluon() && !event[iInARec].isRescatteredIncoming()
2649 && event[iInBRec].isGluon() && !event[iInBRec].isRescatteredIncoming()
2650 && event[iInARec].col() == event[iInBRec].acol()
2651 && event[iInARec].acol() == event[iInBRec].col() ) {
2652 event[iInARec].acol( event[iInARec].col() );
2653 event[iInBRec].acol( event[iInBRec].col() );
2669 bool ColourReconnection::findAntiNeighbour(ColourDipole*& dip) {
2671 if (
int(particles[dip->iAcol].activeDips.size()) == 1)
2675 if (
int(particles[dip->iAcol].activeDips.size()) != 2) {
2676 infoPtr->errorMsg(
"Warning in ColourReconnection::findAntiNeighbour: "
2677 "Wrong number of active dipoles");
2682 if (dip == particles[dip->iAcol].activeDips[0])
2683 dip = particles[dip->iAcol].activeDips[1];
2684 else dip = particles[dip->iAcol].activeDips[0];
2687 if (dip->isAntiJun || dip->isJun)
2692 if (
int(particles[dip->iAcol].dips.size()) != 1)
2702 bool ColourReconnection::checkJunctionTrials() {
2703 for (
int i = 0;i < int(junTrials.size());++i) {
2705 if (junTrials[i].mode == 3)
2707 for (
int j = 0;j < int(junTrials[i].dips.size()) - minus; ++j) {
2708 ColourDipole* dip = junTrials[i].dips[j];
2709 if (dip->isJun || dip->isAntiJun) {
2710 junTrials[i].list();
2713 if (particles[dip->iCol].dips.size() != 1 ||
2714 particles[dip->iAcol].dips.size() != 1) {
2715 junTrials[i].list();
2729 bool ColourReconnection::findColNeighbour(ColourDipole*& dip) {
2731 if (
int(particles[dip->iCol].activeDips.size()) == 1)
2735 if (
int(particles[dip->iCol].activeDips.size()) != 2) {
2736 infoPtr->errorMsg(
"Warning in ColourReconnection::findAntiNeighbour: "
2737 "Wrong number of active dipoles");
2741 if (dip == particles[dip->iCol].activeDips[0])
2742 dip = particles[dip->iCol].activeDips[1];
2743 else dip = particles[dip->iCol].activeDips[0];
2746 if (dip->isJun || dip->isAntiJun)
2751 if (
int(particles[dip->iCol].dips.size()) != 1)
2761 void ColourReconnection::storeUsedDips(TrialReconnection& trial) {
2763 if (trial.mode == 5) {
2765 for (
int i = 0;i < 2; ++i) {
2766 ColourDipole* dip = trial.dips[i];
2768 for (
int j = 0;j < 3; ++j)
2769 usedDipoles.push_back(junctions[-(dip->iCol / 10 + 1)].getColDip(j));
2771 for (
int j = 0;j < 3; ++j)
2772 usedDipoles.push_back(junctions[-(dip->iAcol / 10 + 1)].getColDip(j));
2774 usedDipoles.push_back(dip);
2779 for (
int i = 0;i < 4; ++i) {
2780 if (trial.mode == 3 && i == 3)
2782 usedDipoles.push_back(trial.dips[i]);
2783 ColourDipole* dip = trial.dips[i];
2786 while (findAntiNeighbour(dip) && dip != trial.dips[i])
2787 usedDipoles.push_back(dip);
2789 dip = trial.dips[i];
2790 while (findColNeighbour(dip) && dip != trial.dips[i])
2791 usedDipoles.push_back(dip);
2800 double ColourReconnection::getLambdaDiff(ColourDipole* dip1,
2801 ColourDipole* dip2) {
2804 vector<ColourDipole*> oldDips, newDips;
2807 double oldLambda = calculateStringLength(dip1, oldDips)
2808 + calculateStringLength( dip2, oldDips);
2811 swapDipoles(dip1,dip2);
2814 double newLambda = calculateStringLength(dip1, newDips)
2815 + calculateStringLength(dip2, newDips);
2818 swapDipoles(dip1, dip2,
true);
2821 if (newLambda >= 0.5E9)
return -1e9;
2824 return oldLambda - newLambda;
2831 double ColourReconnection::getLambdaDiff(ColourDipole* dip1,
2832 ColourDipole* dip2, ColourDipole* dip3, ColourDipole* dip4,
int mode) {
2836 double oldLambda = calculateStringLength(dip1->iCol, dip1->iAcol)
2837 + calculateStringLength(dip2->iCol, dip2->iAcol);
2839 oldLambda += calculateStringLength(dip3->iCol, dip3->iAcol);
2840 if (dip4 != 0 && dip4 != dip2)
2841 oldLambda += calculateStringLength(dip4->iCol, dip4->iAcol);
2844 double newLambda = 0;
2847 newLambda = calculateDoubleJunctionLength(dip1->iCol, dip2->iCol,
2848 dip1->iAcol, dip2->iAcol);
2849 else if (mode == 1) {
2851 newLambda = calculateJunctionLength(dip1->iCol, dip2->iCol, dip3->iCol)
2852 + calculateJunctionLength(dip1->iAcol, dip2->iAcol, dip3->iAcol);
2854 newLambda = calculateJunctionLength(dip1->iCol, dip2->iCol, dip3->iCol)
2855 + calculateJunctionLength(dip2->iAcol, dip3->iAcol, dip4->iAcol)
2856 + calculateStringLength(dip4->iCol, dip1->iAcol);
2859 else if (mode == 2) {
2861 newLambda = calculateJunctionLength(dip1->iCol, dip2->iCol, dip4->iCol)
2862 + calculateJunctionLength(dip1->iAcol, dip2->iAcol, dip4->iAcol);
2864 newLambda = calculateJunctionLength(dip1->iCol, dip2->iCol, dip4->iCol)
2865 + calculateJunctionLength(dip1->iAcol, dip3->iAcol, dip4->iAcol)
2866 + calculateStringLength(dip3->iCol, dip2->iAcol);
2871 newLambda = calculateJunctionLength(dip1->iCol, dip2->iCol, dip3->iCol)
2872 + calculateJunctionLength(dip1->iAcol, dip2->iAcol, dip3->iAcol);
2875 if (newLambda >= 0.5E9)
return -1e9;
2878 return oldLambda - newLambda;
2886 void ColourReconnection::doDipoleTrial(TrialReconnection& trial) {
2889 ColourDipole* dip1 = trial.dips[0];
2890 ColourDipole* dip2 = trial.dips[1];
2893 if (dip1->iAcol >= 0 && dip2->iAcol >= 0) {
2894 swap(particles[dip1->iAcol].dips[dip1->iAcolLeg].front()->iAcol,
2895 particles[dip2->iAcol].dips[dip2->iAcolLeg].front()->iAcol);
2896 swap(particles[dip1->iAcol].dips[dip1->iAcolLeg].front(),
2897 particles[dip2->iAcol].dips[dip2->iAcolLeg].front());
2899 }
else if (dip1->iAcol >= 0) {
2900 swap(particles[dip1->iAcol].dips[dip1->iAcolLeg].front()->iAcol,
2901 junctions[-(dip2->iAcol / 10 + 1)].dipsOrig[-dip2->iAcol % 10]->iAcol);
2902 swap(particles[dip1->iAcol].dips[dip1->iAcolLeg].front(),
2903 junctions[-(dip2->iAcol / 10 + 1)].dipsOrig[-dip2->iAcol % 10]);
2905 }
else if (dip2->iAcol >= 0) {
2906 swap(particles[dip2->iAcol].dips[dip2->iAcolLeg].front()->iAcol,
2907 junctions[-(dip1->iAcol / 10 + 1)].dipsOrig[-dip1->iAcol % 10]->iAcol);
2908 swap(particles[dip2->iAcol].dips[dip2->iAcolLeg].front(),
2909 junctions[-(dip1->iAcol / 10 + 1)].dipsOrig[-dip1->iAcol % 10]);
2912 swap(junctions[ -(dip1->iAcol / 10 + 1) ].dipsOrig[
2913 -dip1->iAcol % 10 ]->iAcol,
2914 junctions[ -(dip2->iAcol / 10 + 1) ].dipsOrig[
2915 -dip2->iAcol % 10 ]->iAcol);
2916 swap(junctions[ -(dip1->iAcol / 10 + 1) ].dipsOrig[ -dip1->iAcol % 10],
2917 junctions[ -(dip2->iAcol / 10 + 1) ].dipsOrig[ -dip2->iAcol % 10] );
2921 swapDipoles(dip1, dip2);
2924 if (mDip(dip1) < m0) makePseudoParticle(dip1, 110,
true);
2925 if (mDip(dip2) < m0) makePseudoParticle(dip2, 110,
true);
2935 void ColourReconnection::updateDipoleTrials() {
2938 for (
int i = 0; i < int(dipTrials.size()); ++i)
2939 for (
int j = 0;j < 2; ++j) {
2940 if (binary_search(usedDipoles.begin(), usedDipoles.end(),
2941 dipTrials[i].dips[j]) ) {
2942 dipTrials.erase(dipTrials.begin() + i);
2949 vector<ColourDipole*> activeDipoles;
2950 for (
int i = 0;i < int(dipoles.size()); ++i)
2951 if (dipoles[i]->isActive)
2952 activeDipoles.push_back(dipoles[i]);
2955 for (
int i = 0;i < int(usedDipoles.size()); ++i)
2956 if (usedDipoles[i]->isActive)
2957 for (
int j = 0; j < int(activeDipoles.size()); ++j)
2958 singleReconnection(usedDipoles[i], activeDipoles[j]);
2966 void ColourReconnection::updateJunctionTrials() {
2969 for (
int i = 0; i < int(junTrials.size()); ++i)
2970 for (
int j = 0; j < 4; ++j) {
2971 if (binary_search(usedDipoles.begin(), usedDipoles.end(),
2972 junTrials[i].dips[j]) ) {
2973 junTrials.erase(junTrials.begin() + i);
2980 vector<ColourDipole*> activeDipoles;
2981 for (
int i = 0;i < int(dipoles.size()); ++i)
2982 if (dipoles[i]->isActive)
2983 activeDipoles.push_back(dipoles[i]);
2986 for (
int i = 0;i < int(usedDipoles.size()); ++i)
2987 if (usedDipoles[i]->isActive)
2988 for (
int j = 0; j < int(activeDipoles.size()); ++j)
2989 singleJunction(usedDipoles[i], activeDipoles[j]);
2992 for (
int i = 0;i < int(usedDipoles.size()); ++i)
2993 if (usedDipoles[i]->isActive)
2994 for (
int j = 0; j < int(activeDipoles.size()); ++j)
2995 for (
int k = j + 1; k < int(activeDipoles.size()); ++k)
2996 singleJunction(usedDipoles[i], activeDipoles[j], activeDipoles[k]);
3004 void ColourReconnection::doJunctionTrial(
Event& event,
3005 TrialReconnection& juncTrial) {
3007 int mode = juncTrial.mode;
3010 doTripleJunctionTrial(event, juncTrial);
3015 ColourDipole* dip1 = juncTrial.dips[0];
3016 ColourDipole* dip2 = juncTrial.dips[1];
3017 ColourDipole* dip3 = juncTrial.dips[2];
3018 ColourDipole* dip4 = juncTrial.dips[3];
3020 int iCol1 = dip1->iCol;
3021 int iCol2 = dip2->iCol;
3022 int iCol3 = dip3->iCol;
3023 int iCol4 = dip4->iCol;
3024 int iAcol1 = dip1->iAcol;
3025 int iAcol2 = dip2->iAcol;
3026 int iAcol3 = dip3->iAcol;
3027 int iAcol4 = dip4->iAcol;
3029 int oldCol1 = dip1->col;
3030 int oldCol2 = dip2->col;
3031 int oldCol3 = dip3->col;
3032 int oldCol4 = dip4->col;
3035 int newCol1 =
event.nextColTag();
3036 int newCol2 =
event.nextColTag();
3037 int newCol3 =
event.nextColTag();
3040 double mCalc = (particles[iCol1].p() + particles[iAcol1].p() +
3041 particles[iCol2].p() + particles[iAcol2].p() +
3042 particles[iCol3].p() + particles[iAcol3].p() +
3043 particles[iCol4].p() + particles[iAcol4].p()).mCalc();
3044 formationTimes[newCol1] = mCalc;
3045 formationTimes[newCol2] = mCalc;
3046 formationTimes[newCol3] = mCalc;
3053 int junCol = 3 * (3 - (dip1->colReconnection / 3)
3054 - (dip2->colReconnection / 3) ) + dip1->colReconnection % 3;
3057 if (nReconCols != 9) {
3058 while (junCol < 0 || junCol % 3 != dip1->colReconnection % 3 ||
3059 junCol == dip1->colReconnection || junCol == dip2->colReconnection)
3060 junCol = int(nReconCols * rndmPtr->flat());
3063 int iJun = junctions.size();
3064 int iAntiJun = junctions.size() + 1;
3067 ColourDipole* dip3real = particles[iCol3].dips[dip3->iColLeg].back();
3068 ColourDipole* dip4real = particles[iCol4].dips[dip4->iColLeg].back();
3071 int iActive1 = 0, iReal1 = 0;
3073 dipoles.push_back(
new ColourDipole(newCol1, -( iAntiJun * 10 + 10 + 2) ,
3074 -( iJun * 10 + 10 + 2), junCol,
true,
true,
false,
true));
3075 iReal1 = dipoles.size() - 1;
3076 dipoles.push_back(
new ColourDipole(newCol1, -( iAntiJun * 10 + 10 + 2) ,
3077 -( iJun * 10 + 10 + 2), junCol,
true,
true));
3078 iActive1 = dipoles.size() - 1;
3079 }
else if (mode == 1) {
3080 int iCol3real = particles[iCol3].dips[dip3->iColLeg].back()->iCol;
3081 dipoles.push_back(
new ColourDipole(newCol1, iCol3real ,
3082 -( iJun * 10 + 10 + 2), junCol,
true,
false,
false,
true));
3083 iReal1 = dipoles.size() - 1;
3084 particles[iCol3].dips[dip3->iColLeg].back() = dipoles.back();
3085 dipoles.push_back(
new ColourDipole(newCol1, dip3->iCol,
3086 -( iJun * 10 + 10 + 2), junCol,
true,
false));
3087 iActive1 = dipoles.size() - 1;
3088 }
else if (mode == 2) {
3089 int iCol4real = particles[iCol4].dips[dip4->iColLeg].back()->iCol;
3090 dipoles.push_back(
new ColourDipole(newCol1, iCol4real,
3091 -( iJun * 10 + 10 + 2), junCol,
true,
false,
false,
true));
3092 iReal1 = dipoles.size() - 1;
3093 particles[iCol4].dips[dip4->iColLeg].back() = dipoles.back();
3094 dipoles.push_back(
new ColourDipole(newCol1, dip4->iCol,
3095 -( iJun * 10 + 10 + 2), junCol,
true,
false));
3096 iActive1 = dipoles.size() - 1;
3101 int iAcol3real = particles[iAcol3].dips[dip3->iAcolLeg].front()->iAcol;
3102 dipoles.push_back(
new ColourDipole(newCol2, -( iAntiJun * 10 + 10),
3103 iAcol3real, dip3->colReconnection,
false,
true,
false,
true));
3104 int iReal2 = dipoles.size() - 1;
3105 particles[iAcol3].dips[dip3->iAcolLeg].front() = dipoles.back();
3107 dipoles.push_back(
new ColourDipole(newCol2, -( iAntiJun * 10 + 10),
3108 iAcol3, dip3->colReconnection,
false,
true));
3109 dipoles.back()->iAcolLeg = dip3->iAcolLeg;
3110 int iActive2 = dipoles.size() - 1;
3114 int iAcol4real = particles[iAcol4].dips[dip4->iAcolLeg].front()->iAcol;
3115 dipoles.push_back(
new ColourDipole(newCol3, -( iAntiJun * 10 + 10 + 1),
3116 iAcol4real, dip4->colReconnection,
false,
true,
false,
true));
3117 int iReal3 = dipoles.size() - 1;
3118 particles[iAcol4].dips[dip4->iAcolLeg].front() = dipoles.back();
3120 dipoles.push_back(
new ColourDipole(newCol3, -( iAntiJun * 10 + 10 + 1),
3121 iAcol4, dip4->colReconnection,
false,
true));
3122 dipoles.back()->iAcolLeg = dip4->iAcolLeg;
3123 int iActive3 = dipoles.size() - 1;
3132 dip3real->iAcol = particles[dip1->iAcol].dips[dip1->iAcolLeg].
3134 dip3real->iCol = -( iAntiJun * 10 + 10 + 2);
3135 dip3real->isAntiJun =
true;
3138 dip3->iAcol = dip1->iAcol;
3139 dip3->iAcolLeg = dip1->iAcolLeg;
3140 dip3->isAntiJun =
true;
3141 dip3->iCol = -( iAntiJun * 10 + 10 + 2);
3145 particles[dip3->iAcol].dips[dip3->iAcolLeg].front() = dip3real;
3150 dip3real->iAcol = particles[dip2->iAcol].dips[dip2->iAcolLeg].
3152 dip3real->iCol = -( iAntiJun * 10 + 10 + 2);
3153 dip3real->isAntiJun =
true;
3154 dip4real->iAcol = particles[dip1->iAcol].dips[dip1->iAcolLeg].
3158 dip3->iAcol = dip2->iAcol;
3159 dip3->iAcolLeg = dip2->iAcolLeg;
3160 dip3->isAntiJun =
true;
3161 dip3->iCol = -( iAntiJun * 10 + 10 + 2);
3165 dip4->iAcol = dip1->iAcol;
3166 dip4->iAcolLeg = dip1->iAcolLeg;
3169 particles[dip3->iAcol].dips[dip3->iAcolLeg].front() = dip3real;
3170 particles[dip4->iAcol].dips[dip4->iAcolLeg].front() = dip4real;
3173 }
else if (mode == 2) {
3177 dip4real->iAcol = particles[dip2->iAcol].dips[dip2->iAcolLeg].
3179 dip4real->iCol = -( iAntiJun * 10 + 10 + 2);
3180 dip4real->isAntiJun =
true;
3183 dip4->iAcol = dip2->iAcol;
3184 dip4->iAcolLeg = dip2->iAcolLeg;
3185 dip4->isAntiJun =
true;
3186 dip4->iCol = -( iAntiJun * 10 + 10 + 2);
3190 particles[dip4->iAcol].dips[dip4->iAcolLeg].front() = dip4real;
3195 dip4real->iAcol = particles[dip1->iAcol].dips[dip1->iAcolLeg].
3197 dip4real->iCol = -( iAntiJun * 10 + 10 + 2);
3198 dip4real->isAntiJun =
true;
3199 dip3real->iAcol = particles[dip2->iAcol].dips[dip2->iAcolLeg].
3203 dip4->iAcol = dip1->iAcol;
3204 dip4->iAcolLeg = dip1->iAcolLeg;
3205 dip4->isAntiJun =
true;
3206 dip4->iCol = -( iAntiJun * 10 + 10 + 2);
3210 dip3->iAcol = dip2->iAcol;
3211 dip3->iAcolLeg = dip2->iAcolLeg;
3214 particles[dip3->iAcol].dips[dip3->iAcolLeg].front() = dip3real;
3215 particles[dip4->iAcol].dips[dip4->iAcolLeg].front() = dip4real;
3221 particles[iCol1].dips[dip1->iColLeg].back()->iAcol = - (iJun * 10 + 10);
3222 particles[iCol2].dips[dip2->iColLeg].back()->iAcol = - (iJun * 10 + 10 + 1);
3223 particles[iCol1].dips[dip1->iColLeg].back()->isJun =
true;
3224 particles[iCol2].dips[dip2->iColLeg].back()->isJun =
true;
3229 dip1->iAcol = - (iJun * 10 + 10);
3230 dip2->iAcol = - (iJun * 10 + 10 + 1);
3238 for (
int i = 0; i < int(particles[iAcol3].activeDips.size()); ++i)
3239 if (particles[iAcol3].activeDips[i] == dip3) {
3240 particles[iAcol3].activeDips[i] = dipoles[iActive2];
3244 for (
int i = 0; i < int(particles[iAcol4].activeDips.size()); ++i)
3245 if (particles[iAcol4].activeDips[i] == dip4) {
3246 particles[iAcol4].activeDips[i] = dipoles[iActive3];
3252 for (
int i = 0; i < int(particles[iCol3].activeDips.size()); ++i)
3253 if (particles[iCol3].activeDips[i] == dip3) {
3254 particles[iCol3].activeDips[i] = dipoles[iActive1];
3259 for (
int i = 0; i < int(particles[iAcol1].activeDips.size()); ++i)
3260 if (particles[iAcol1].activeDips[i] == dip1) {
3261 particles[iAcol1].activeDips[i] = dip3;
3265 for (
int i = 0; i < int(particles[iAcol2].activeDips.size()); ++i)
3266 if (particles[iAcol2].activeDips[i] == dip2) {
3267 particles[iAcol2].activeDips[i] = dip3;
3271 for (
int i = 0; i < int(particles[iAcol1].activeDips.size()); ++i)
3272 if (particles[iAcol1].activeDips[i] == dip1) {
3273 particles[iAcol1].activeDips[i] = dip4;
3277 }
else if (mode == 2) {
3278 for (
int i = 0; i < int(particles[iCol4].activeDips.size()); ++i)
3279 if (particles[iCol4].activeDips[i] == dip4) {
3280 particles[iCol4].activeDips[i] = dipoles[iActive1];
3285 for (
int i = 0; i < int(particles[iAcol2].activeDips.size()); ++i)
3286 if (particles[iAcol2].activeDips[i] == dip2) {
3287 particles[iAcol2].activeDips[i] = dip4;
3291 for (
int i = 0; i < int(particles[iAcol1].activeDips.size()); ++i)
3292 if (particles[iAcol1].activeDips[i] == dip1) {
3293 particles[iAcol1].activeDips[i] = dip4;
3297 for (
int i = 0; i < int(particles[iAcol2].activeDips.size()); ++i)
3298 if (particles[iAcol2].activeDips[i] == dip2) {
3299 particles[iAcol2].activeDips[i] = dip3;
3306 junctions.push_back(Junction(1, oldCol1, oldCol2, newCol1));
3307 if (mode == 0) junctions.push_back(Junction(2, newCol2, newCol3, newCol1));
3309 junctions.push_back(Junction(2, newCol2, newCol3, oldCol3));
3311 junctions.push_back(Junction(2, newCol2, newCol3, oldCol4));
3314 junctions[iJun].dipsOrig[0] =
3315 particles[iCol1].dips[dip1->iColLeg].back();
3316 junctions[iJun].dipsOrig[1] =
3317 particles[iCol2].dips[dip2->iColLeg].back();
3318 junctions[iJun].dipsOrig[2] = dipoles[iReal1];
3319 junctions[iJun].dips[0] = dip1;
3320 junctions[iJun].dips[1] = dip2;
3321 junctions[iJun].dips[2] = dipoles[iActive1];
3324 junctions[iAntiJun].dips[0] = dipoles[iActive2];
3325 junctions[iAntiJun].dips[1] = dipoles[iActive3];
3326 junctions[iAntiJun].dipsOrig[0] = dipoles[iReal2];
3327 junctions[iAntiJun].dipsOrig[1] = dipoles[iReal3];
3330 junctions[iAntiJun].dips[2] = dipoles[iActive1];
3331 junctions[iAntiJun].dipsOrig[2] = dipoles[iReal1];
3332 }
else if (mode == 1) {
3333 junctions[iAntiJun].dips[2] = dip3;
3334 junctions[iAntiJun].dipsOrig[2] =
3335 particles[dip3->iAcol].dips[dip3->iAcolLeg].front();
3336 }
else if (mode == 2) {
3337 junctions[iAntiJun].dips[2] = dip4;
3338 junctions[iAntiJun].dipsOrig[2] =
3339 particles[dip4->iAcol].dips[dip4->iAcolLeg].front();
3343 if (dip1->isActive && mDip(dip1) < m0)
3344 makePseudoParticle(dip1, 110,
true);
3345 if (dip2->isActive && mDip(dip2) < m0)
3346 makePseudoParticle(dip2, 110,
true);
3347 if (dip3->isActive && mDip(dip3) < m0)
3348 makePseudoParticle(dip3, 110,
true);
3349 if (dip4->isActive && mDip(dip4) < m0)
3350 makePseudoParticle(dip4, 110,
true);
3352 if (dipoles[iActive1]->isActive && mDip(dipoles[iActive1]) < m0)
3353 makePseudoParticle(dipoles[iActive1], 110,
true);
3354 if (dipoles[iActive2]->isActive && mDip(dipoles[iActive2]) < m0)
3355 makePseudoParticle(dipoles[iActive2], 110,
true);
3356 if (dipoles[iActive3]->isActive && mDip(dipoles[iActive3]) < m0)
3357 makePseudoParticle(dipoles[iActive3], 110,
true);
3360 usedDipoles.push_back(dipoles[iActive1]);
3361 usedDipoles.push_back(dipoles[iActive2]);
3362 usedDipoles.push_back(dipoles[iActive3]);
3371 void ColourReconnection::doTripleJunctionTrial(
Event& event,
3372 TrialReconnection& juncTrial) {
3375 ColourDipole* dip1 = juncTrial.dips[0];
3376 ColourDipole* dip2 = juncTrial.dips[1];
3377 ColourDipole* dip3 = juncTrial.dips[2];
3380 int iCol1 = dip1->iCol;
3381 int iCol2 = dip2->iCol;
3382 int iCol3 = dip3->iCol;
3383 int iAcol1 = dip1->iAcol;
3384 int iAcol2 = dip2->iAcol;
3385 int iAcol3 = dip3->iAcol;
3388 int oldCol1 = dip1->col;
3389 int oldCol2 = dip2->col;
3390 int oldCol3 = dip3->col;
3391 int newCol1 =
event.nextColTag();
3392 int newCol2 =
event.nextColTag();
3393 int newCol3 =
event.nextColTag();
3396 int iJun = junctions.size();
3397 int iAntiJun = junctions.size() + 1;
3402 = particles[iAcol1].dips[dip1->iAcolLeg].front()->iAcol;
3403 dipoles.push_back(
new ColourDipole(newCol1, -( iAntiJun * 10 + 10),
3404 iAcol1real, dip1->colReconnection,
false,
true,
false,
true));
3405 int iReal1 = dipoles.size() - 1;
3406 particles[iAcol1].dips[dip1->iAcolLeg].front() = dipoles.back();
3408 dipoles.push_back(
new ColourDipole(newCol1, -( iAntiJun * 10 + 10),
3409 iAcol1, dip1->colReconnection,
false,
true));
3410 dipoles.back()->iAcolLeg = dip1->iAcolLeg;
3411 int iActive1 = dipoles.size() - 1;
3416 = particles[iAcol2].dips[dip2->iAcolLeg].front()->iAcol;
3417 dipoles.push_back(
new ColourDipole(newCol2, -( iAntiJun * 10 + 10 + 1),
3418 iAcol2real, dip2->colReconnection,
false,
true,
false,
true));
3419 int iReal2 = dipoles.size() - 1;
3420 particles[iAcol2].dips[dip2->iAcolLeg].front() = dipoles.back();
3422 dipoles.push_back(
new ColourDipole(newCol2, -( iAntiJun * 10 + 10 + 1),
3423 iAcol2, dip2->colReconnection,
false,
true));
3424 dipoles.back()->iAcolLeg = dip2->iAcolLeg;
3425 int iActive2 = dipoles.size() - 1;
3430 = particles[iAcol3].dips[dip3->iAcolLeg].front()->iAcol;
3431 dipoles.push_back(
new ColourDipole(newCol3, -( iAntiJun * 10 + 10 + 2),
3432 iAcol3real, dip3->colReconnection,
false,
true,
false,
true));
3433 int iReal3 = dipoles.size() - 1;
3434 particles[iAcol3].dips[dip3->iAcolLeg].front() = dipoles.back();
3436 dipoles.push_back(
new ColourDipole(newCol3, -( iAntiJun * 10 + 10 + 2),
3437 iAcol3, dip3->colReconnection,
false,
true));
3438 dipoles.back()->iAcolLeg = dip3->iAcolLeg;
3439 int iActive3 = dipoles.size() - 1;
3444 particles[iCol1].dips[dip1->iColLeg].back()->iAcol = - (iJun * 10 + 10);
3445 particles[iCol2].dips[dip2->iColLeg].back()->iAcol = - (iJun * 10 + 10 + 1);
3446 particles[iCol3].dips[dip3->iColLeg].back()->iAcol = - (iJun * 10 + 10 + 2);
3447 particles[iCol1].dips[dip1->iColLeg].back()->isJun =
true;
3448 particles[iCol2].dips[dip2->iColLeg].back()->isJun =
true;
3449 particles[iCol3].dips[dip3->iColLeg].back()->isJun =
true;
3455 dip1->iAcol = - (iJun * 10 + 10);
3456 dip2->iAcol = - (iJun * 10 + 10 + 1);
3457 dip3->iAcol = - (iJun * 10 + 10 + 2);
3463 for (
int i = 0; i < int(particles[iAcol1].activeDips.size()); ++i)
3464 if (particles[iAcol1].activeDips[i] == dip1)
3465 particles[iAcol1].activeDips[i] = dipoles[iActive1];
3466 for (
int i = 0; i < int(particles[iAcol2].activeDips.size()); ++i)
3467 if (particles[iAcol2].activeDips[i] == dip2)
3468 particles[iAcol2].activeDips[i] = dipoles[iActive2];
3469 for (
int i = 0; i < int(particles[iAcol3].activeDips.size()); ++i)
3470 if (particles[iAcol3].activeDips[i] == dip3)
3471 particles[iAcol3].activeDips[i] = dipoles[iActive3];
3474 junctions.push_back(Junction(1, oldCol1, oldCol2, oldCol3));
3475 junctions.push_back(Junction(2, newCol1, newCol3, newCol3));
3478 junctions[iJun].dipsOrig[0] =
3479 particles[iCol1].dips[dip1->iColLeg].back();
3480 junctions[iJun].dipsOrig[1] =
3481 particles[iCol2].dips[dip2->iColLeg].back();
3482 junctions[iJun].dipsOrig[2] =
3483 particles[iCol3].dips[dip3->iColLeg].back();
3484 junctions[iJun].dips[0] = dip1;
3485 junctions[iJun].dips[1] = dip2;
3486 junctions[iJun].dips[2] = dip3;
3489 junctions[iAntiJun].dips[0] = dipoles[iActive1];
3490 junctions[iAntiJun].dips[1] = dipoles[iActive2];
3491 junctions[iAntiJun].dips[2] = dipoles[iActive3];
3492 junctions[iAntiJun].dipsOrig[0] = dipoles[iReal1];
3493 junctions[iAntiJun].dipsOrig[1] = dipoles[iReal2];
3494 junctions[iAntiJun].dipsOrig[2] = dipoles[iReal3];
3497 if (dip1->isActive && mDip(dip1) < m0)
3498 makePseudoParticle(dip1, 110,
true);
3499 if (dip2->isActive && mDip(dip2) < m0)
3500 makePseudoParticle(dip2, 110,
true);
3501 if (dip3->isActive && mDip(dip3) < m0)
3502 makePseudoParticle(dip3, 110,
true);
3504 if (dipoles[iActive1]->isActive && mDip(dipoles[iActive1]) < m0)
3505 makePseudoParticle(dipoles[iActive1], 110,
true);
3506 if (dipoles[iActive2]->isActive && mDip(dipoles[iActive2]) < m0)
3507 makePseudoParticle(dipoles[iActive2], 110,
true);
3508 if (dipoles[iActive3]->isActive && mDip(dipoles[iActive3]) < m0)
3509 makePseudoParticle(dipoles[iActive3], 110,
true);
3512 usedDipoles.push_back(dipoles[iActive1]);
3513 usedDipoles.push_back(dipoles[iActive2]);
3514 usedDipoles.push_back(dipoles[iActive3]);
3524 bool ColourReconnection::reconnectMove(
Event& event,
int oldSize) {
3528 iReduceCol.resize( event.size() );
3530 map<int, int> colMap, acolMap;
3531 map<int, int>::iterator colM, acolM;
3532 vector<InfoGluonMove> infoGM;
3543 double lambdaRefNow = 0.;
3544 double dLambdaNow = 0.;
3547 for (
int i = oldSize; i <
event.size(); ++i)
if (event[i].isFinal()) {
3548 if (flipMode < 3 && event[i].
id() == 21 && rndmPtr->flat() < fracGluon)
3552 if (event[i].col() > 0 || event[i].acol() > 0) {
3553 iReduceCol[i] = iExpandCol.size();
3554 iExpandCol.push_back(i);
3555 if (event[i].col() > 0) colMap[
event[i].col()] = i;
3556 if (event[i].acol() > 0) acolMap[
event[i].acol()] = i;
3561 for (
int iJun = 0; iJun <
event.sizeJunction(); ++iJun) {
3562 if (event.kindJunction(iJun) == 1) {
3563 for (
int j = 0; j < 3; ++j) {
3564 int jCol =
event.colJunction( iJun, j);
3565 for (colM = colMap.begin(); colM != colMap.end(); ++colM)
3566 if (colM->first == jCol) {
3567 colMap.erase( colM);
3570 for (
int iG = 0; iG < int(iGlu.size()); ++iG)
3571 if (event[iGlu[iG]].col() == jCol) {
3572 iGlu.erase(iGlu.begin() + iG);
3576 }
else if (event.kindJunction(iJun) == 2) {
3577 for (
int j = 0; j < 3; ++j) {
3578 int jCol =
event.colJunction( iJun, j);
3579 for (acolM = acolMap.begin(); acolM != acolMap.end(); ++acolM)
3580 if (acolM->first == jCol) {
3581 acolMap.erase( acolM);
3584 for (
int iG = 0; iG < int(iGlu.size()); ++iG)
3585 if (event[iGlu[iG]].acol() == jCol) {
3586 iGlu.erase(iGlu.begin() + iG);
3594 int nGlu = iGlu.size();
3595 int nCol = colMap.size();
3596 if (
int(acolMap.size()) != nCol) {
3597 infoPtr->errorMsg(
"Error in MBReconUserHooks: map sizes do not match");
3600 colM = colMap.begin();
3601 acolM = acolMap.begin();
3602 for (
int iCol = 0; iCol < nCol; ++iCol) {
3603 if (colM->first != acolM->first) {
3604 infoPtr->errorMsg(
"Error in MBReconUserHooks: map elements"
3613 nColMove = iExpandCol.size();
3614 lambdaijMove.resize( pow2(nColMove) );
3615 for (
int iAC = 0; iAC < nColMove - 1; ++iAC) {
3616 int i = iExpandCol[iAC];
3617 for (
int jAC = iAC + 1; jAC < nColMove; ++jAC) {
3618 int j = iExpandCol[jAC];
3619 lambdaijMove[nColMove * iAC + jAC]
3620 = log(1. + m2( event[i], event[j]) / m2Lambda);
3625 for (
int iG = 0; iG < nGlu; ++iG) {
3629 colNow =
event[iNow].col();
3630 acolNow =
event[iNow].acol();
3631 iColNow = acolMap[colNow];
3632 iAcolNow = colMap[acolNow];
3635 lambdaRefNow = lambda123Move( iNow, iColNow, iAcolNow);
3638 for (colM = colMap.begin(); colM != colMap.end(); ++colM) {
3639 col2Now = colM->first;
3640 iCol2Now = colMap[col2Now];
3641 iAcol2Now = acolMap[col2Now];
3644 dLambdaNow = (iCol2Now == iNow || iAcol2Now == iNow
3645 || iColNow == iAcolNow) ? 2e4
3646 : lambda123Move( iNow, iCol2Now, iAcol2Now) - lambdaRefNow;
3649 infoGM.push_back( InfoGluonMove( iNow, colNow, acolNow, iColNow,
3650 iAcolNow, col2Now, iCol2Now, iAcol2Now, lambdaRefNow, dLambdaNow ));
3653 int nPair = infoGM.size();
3656 for (
int iMove = 0; iMove < nGlu; ++iMove) {
3658 double dLambdaMin = 1e4;
3661 for (
int iPair = 0; iPair < nPair; ++iPair)
3662 if (infoGM[iPair].dLambda < dLambdaMin) {
3664 dLambdaMin = infoGM[iPair].dLambda;
3668 if (dLambdaMin > -dLambdaCut)
break;
3671 InfoGluonMove& selSM = infoGM[iPairMin];
3672 int i1Sel = selSM.i1;
3673 int iCol1Sel = selSM.iCol1;
3674 int iAcol1Sel = selSM.iAcol1;
3675 int iCol2Sel = selSM.iCol2;
3676 int iAcol2Sel = selSM.iAcol2;
3677 int iCol2Mod[3] = { iAcol1Sel , i1Sel , iCol2Sel };
3678 int col2Mod[3] = { selSM.col1, selSM.col2, selSM.acol1};
3681 for (
int i = 0; i < 3; ++i) {
3682 event[ iCol2Mod[i] ].col( col2Mod[i] );
3683 colMap[ col2Mod[i] ] = iCol2Mod[i];
3688 bool doUpdate =
false;
3689 for (
int iPair = 0; iPair < nPair; ++iPair) {
3690 InfoGluonMove& tmpSM = infoGM[iPair];
3691 if (tmpSM.i1 != i1Now) {
3694 if (i1Now == i1Sel || i1Now == iCol1Sel || i1Now == iAcol1Sel
3695 || i1Now == iCol2Sel || i1Now == iAcol2Sel) {
3696 colNow =
event[i1Now].col();
3697 acolNow =
event[i1Now].acol();
3698 iColNow = acolMap[colNow];
3699 iAcolNow = colMap[acolNow];
3700 lambdaRefNow = lambda123Move( i1Now, iColNow, iAcolNow);
3705 tmpSM.col1 = colNow;
3706 tmpSM.acol1 = acolNow;
3707 tmpSM.iCol1 = iColNow;
3708 tmpSM.iAcol1 = iAcolNow;
3709 tmpSM.lambdaRef = lambdaRefNow;
3714 for (
int iPair = 0; iPair < nPair; ++iPair) {
3715 InfoGluonMove& tmpSM = infoGM[iPair];
3717 for (
int i = 0; i < 3; ++i)
if (tmpSM.col2 == col2Mod[i]) iMod = i;
3718 if (iMod > -1) tmpSM.iCol2 = iCol2Mod[iMod];
3719 if (tmpSM.i1 == i1Sel || tmpSM.i1 == iCol1Sel || tmpSM.i1 == iAcol1Sel
3720 || tmpSM.i1 == iCol2Sel || tmpSM.i1 == iAcol2Sel || iMod > -1)
3721 tmpSM.dLambda = (tmpSM.iCol2 == tmpSM.i1 || tmpSM.iAcol2 == tmpSM.i1
3722 || tmpSM.iCol1 == tmpSM.iAcol1) ? 2e4
3723 : lambda123Move( tmpSM.i1, tmpSM.iCol2, tmpSM.iAcol2)
3731 if (flipMode == 0)
return true;
3734 vector<int> iTmpFlip, iVecFlip, iBegFlip, iEndFlip;
3737 int i1c, i1a, i2c, i2a, i1cMin, i1aMin, i2cMin, i2aMin, iSMin;
3738 double dLambdaFlip, dLambdaFlipMin;
3739 vector<InfoGluonMove> flipMin;
3742 for (
int i = oldSize; i <
event.size(); ++i)
3743 if (event[i].isFinal() &&
event[i].col() > 0 &&
event[i].acol() == 0) {
3745 iTmpFlip.push_back( i);
3749 acolM = acolMap.find( event[iNow].col() );
3750 bool foundEnd =
false;
3751 while (acolM != acolMap.end()) {
3752 iNow = acolM->second;
3753 iTmpFlip.push_back( iNow);
3754 if (event[iNow].col() == 0) {
3758 acolM = acolMap.find( event[iNow].col() );
3762 if (foundEnd || flipMode == 2 || flipMode == 4) {
3763 iBegFlip.push_back( iVecFlip.size());
3764 for (
int j = 0; j < int(iTmpFlip.size()); ++j)
3765 iVecFlip.push_back( iTmpFlip[j]);
3766 iEndFlip.push_back( iVecFlip.size());
3771 if (flipMode == 2 || flipMode == 4)
3772 for (
int i = oldSize; i <
event.size(); ++i)
3773 if (event[i].isFinal() &&
event[i].acol() > 0 &&
event[i].col() == 0) {
3775 iTmpFlip.push_back( i);
3779 colM = colMap.find( event[iNow].acol() );
3780 bool foundEnd =
false;
3781 while (colM != colMap.end()) {
3782 iNow = colM->second;
3783 iTmpFlip.push_back( iNow);
3784 if (event[iNow].acol() == 0) {
3788 colM = colMap.find( event[iNow].acol() );
3793 iBegFlip.push_back( iVecFlip.size());
3794 for (
int j = 0; j < int(iTmpFlip.size()); ++j)
3795 iVecFlip.push_back( iTmpFlip[j]);
3796 iEndFlip.push_back( iVecFlip.size());
3801 int nSysFlip = iBegFlip.size();
3802 for (
int iSys1 = 0; iSys1 < nSysFlip - 1; ++iSys1)
3803 if (iBegFlip[iSys1] >= 0)
3804 for (
int iSys2 = iSys1 + 1; iSys2 < nSysFlip; ++iSys2)
3805 if (iBegFlip[iSys2] >= 0) {
3810 dLambdaFlipMin = 1e4;
3813 for (
int j1 = iBegFlip[iSys1]; j1 < iEndFlip[iSys1] - 1; ++j1)
3814 for (
int j2 = iBegFlip[iSys2]; j2 < iEndFlip[iSys2] - 1; ++j2) {
3816 i1a = iVecFlip[j1 + 1];
3818 i2a = iVecFlip[j2 + 1];
3819 dLambdaFlip = lambda12Move( i1c, i2a) + lambda12Move( i2c, i1a)
3820 - lambda12Move( i1c, i1a) - lambda12Move( i2c, i2a);
3821 if (dLambdaFlip < dLambdaFlipMin) {
3826 dLambdaFlipMin = dLambdaFlip;
3831 if (dLambdaFlipMin < -dLambdaCut) flipMin.push_back( InfoGluonMove(
3832 iSys1, iSys2, i1cMin, i1aMin, i2cMin, i2aMin, dLambdaFlipMin) );
3834 int flipSize = flipMin.size();
3837 for (
int iFlip = 0; iFlip < min( nSysFlip / 2, flipSize); ++iFlip) {
3839 dLambdaFlipMin = 1e4;
3840 for (
int iSys12 = 0; iSys12 < flipSize; ++iSys12)
3841 if (flipMin[iSys12].i1 >= 0 && flipMin[iSys12].dLambda < dLambdaFlipMin) {
3843 dLambdaFlipMin = flipMin[iSys12].dLambda;
3848 InfoGluonMove& flipNow = flipMin[iSMin];
3849 int iS1 = flipNow.i1;
3850 int iS2 = flipNow.i2;
3851 event[ flipNow.iAcol1 ].acol( event[flipNow.iCol2].col() );
3852 event[ flipNow.iAcol2 ].acol( event[flipNow.iCol1].col() );
3853 for (
int iSys12 = 0; iSys12 < flipSize; ++iSys12)
3854 if ( flipMin[iSys12].i1 == iS1 || flipMin[iSys12].i1 == iS2
3855 || flipMin[iSys12].i2 == iS1 || flipMin[iSys12].i2 == iS2)
3856 flipMin[iSys12].i1 = -1;
3870 bool ColourReconnection::reconnectTypeCommon(
Event& event,
int ) {
3873 vector<vector< ColourDipole> > dips;
3876 if (partonSystemsPtr->sizeSys() < 2) {
3877 infoPtr->errorMsg(
"Error in ColourReconnection::reconnectTypeCommon: "
3878 "expect at least two parton systems");
3883 for (
int i = 0; i < 2; ++i) {
3884 dips.push_back(vector<ColourDipole>());
3885 int iSys = partonSystemsPtr->sizeSys() - i - 1;
3886 for (
int j = 0; j < partonSystemsPtr->sizeOut(iSys); ++j) {
3887 int iPar = partonSystemsPtr->getOut(iSys, j);
3891 int iMot =
event[iPar].mother1();
3892 while (iMot != 0 && event[iMot].idAbs() != 23
3893 && event[iMot].idAbs() != 24) iMot =
event[iMot].mother1();
3895 infoPtr->errorMsg(
"Error in ColourReconnection::reconnectTypeCommon:"
3896 " Not a resonance decay of a W/Z");
3903 int col =
event[iPar].col();
3904 if (col == 0)
continue;
3905 for (
int k = 0; k < partonSystemsPtr->sizeOut(iSys); ++k) {
3906 int iAntiPar = partonSystemsPtr->getOut(iSys, k);
3907 if (event[iAntiPar].acol() == col) {
3908 dips.back().push_back(ColourDipole(col, iPar, iAntiPar));
3916 Vec4 boost =
event[iBosons[0]].p() +
event[iBosons[1]].p();
3917 for (
int i = 1; i <
event.size(); ++i) event[i].bstback(boost);
3920 for (
int i = 0; i < 2; ++i) {
3921 int iBoson = iBosons[i];
3922 double mBoson = particleDataPtr->m0(event[iBoson].idAbs());
3923 double gammaBoson = particleDataPtr->mWidth(event[iBoson].idAbs());
3924 double mReal =
event[iBoson].mCalc();
3925 decays[i][0] = -HBAR * log(rndmPtr->flat()) * event[iBoson].e() /
3926 sqrt(pow2(pow2(mBoson) - pow2(mReal)) + pow2(gammaBoson * pow2(mReal)
3928 for (
int j = 1; j < 4; ++j)
3929 decays[i][j] = event[iBoson].p()[j]/
event[iBoson].e() * decays[i][0];
3933 map<double,pair<int,int> > reconnections;
3934 if (reconnectMode == 3)
3935 reconnections = reconnectTypeI(event, dips, decays);
3936 else if (reconnectMode == 4)
3937 reconnections = reconnectTypeII(event, dips, decays);
3940 vector<bool> used1(dips[0].size(),
false), used2(dips[1].size(),
false);
3941 for (map<
double,pair<int,int> >::iterator it=reconnections.begin();
3942 it != reconnections.end(); ++it) {
3945 if (used1[it->second.first] || used2[it->second.second])
continue;
3948 int iAcol1 = dips[0][it->second.first].iAcol;
3949 int iAcol2 = dips[1][it->second.second].iAcol;
3950 event.copy(iAcol1, 79);
3951 event.back().acol(event[iAcol2].acol());
3952 event.copy(iAcol2, 79);
3953 event.back().acol(event[iAcol1].acol());
3956 used1[it->second.first] =
true;
3957 used2[it->second.second] =
true;
3960 if (singleReconOnly)
break;
3964 for (
int i = 1; i <
event.size(); ++i) event[i].bst(boost);
3974 map<double,pair<int,int> > ColourReconnection::reconnectTypeI(
Event& event,
3975 vector<vector<ColourDipole> > &dips, Vec4 decays[2]) {
3978 multimap<double,pair<int,int> > reconnections;
3981 vector<vector<Vec4> > vel;
3983 vector<vector<Vec4> > dir;
3986 for (
int i = 0; i < 2; ++i) {
3987 vel.push_back(vector<Vec4>(dips[i].size(),Vec4()));
3988 dir.push_back(vector<Vec4>(dips[i].size(),Vec4()));
3989 for (
int j = 0; j < int(dips[i].size()); ++j) {
3992 double pSumCol =
event[dips[i][j].iCol].pAbs();
3993 double pSumAcol =
event[dips[i][j].iAcol].pAbs();
3996 for (
int k = 1; k < 4; ++k) {
3997 vel[i][j][k] = 0.5 *(
event[dips[i][j].iCol].p()[k] / pSumCol
3998 +
event[dips[i][j].iAcol].p()[k] / pSumAcol);
3999 dir[i][j][k] =
event[dips[i][j].iCol].p()[k] / pSumCol
4000 -
event[dips[i][j].iAcol].p()[k] / pSumAcol;
4002 vel[i][j][0] = 1/sqrt(1 - vel[i][j].pAbs2());
4003 dir[i][j] /= dir[i][j].pAbs();
4011 for (
int i = 0; i < nPoints; ++i) {
4013 double r = sqrt(- log(rndmPtr->flat()));
4014 double phi = 2 * M_PI * rndmPtr->flat();
4015 x[1] = blowR * rHadron * r * cos(phi);
4016 x[2] = blowR * rHadron * r * sin(phi);
4017 r = sqrt(- log(rndmPtr->flat()));
4018 phi = 2 * M_PI * rndmPtr->flat();
4019 x[3] = blowR * rHadron * r * cos(phi);
4020 x[0] = max(decays[0][0], decays[1][0])
4021 + blowT * sqrt(0.5) * tfrag * r * abs(sin(phi));
4022 if (x.m2Calc() < 0)
continue;
4025 double weightTrial = exp(-x.pAbs2() / pow2(blowR*rHadron))
4026 * exp( -2. * pow2(x[0] - max(decays[0][0],decays[1][0]))
4027 / pow2(blowT * tfrag) );
4030 double maxWeights[2] = {0,0};
4031 int maxIndices[2] = {-1,-1};
4034 for (
int j = 0;j < 2;++j) {
4037 Vec4 xd = x - decays[j];
4040 for (
int k = 0; k < int(dips[j].size()); ++k) {
4043 double gam = vel[j][k][0];
4044 double dotProd = dot3(xd,vel[j][k]);
4045 double xBoost = gam * (gam * dotProd/ (1. + gam) - xd[0]);
4046 Vec4 xb = xd + xBoost * vel[j][k];
4047 xb[0] = gam * (xd[0] - dotProd);
4050 if (xb.m2Calc() < 0)
continue;
4053 double weight = exp( -(xb.pAbs2() - pow2(dot3(xb,dir[j][k])))
4054 / (2 * pow2(rHadron)) )
4055 * exp( -(pow2(xb[0]) - pow2(dot3(xb, dir[j][k]))) / pow2(tfrag) );
4056 if (weight > maxWeights[j]) {
4057 maxWeights[j] = weight;
4064 if (maxIndices[0] != -1 && maxIndices[1] != -1) {
4067 if (lowerLambdaOnly) {
4068 double oldLambda = stringLength.getStringLength(event,
4069 dips[0][maxIndices[0]].iCol, dips[0][maxIndices[0]].iAcol) +
4070 stringLength.getStringLength(event, dips[1][maxIndices[1]].iCol,
4071 dips[1][maxIndices[1]].iAcol);
4072 double newLambda = stringLength.getStringLength(event,
4073 dips[0][maxIndices[0]].iCol, dips[1][maxIndices[1]].iAcol) +
4074 stringLength.getStringLength(event, dips[1][maxIndices[1]].iCol,
4075 dips[0][maxIndices[0]].iAcol);
4076 if (oldLambda < newLambda)
continue;
4080 double weight = maxWeights[0] * maxWeights[1] / weightTrial;
4081 reconnections.insert(make_pair(weight,
4082 make_pair(maxIndices[0], maxIndices[1])));
4089 map<double,pair<int,int> > singleRecon;
4090 double result = pow3(blowR) * blowT * sumW/nPoints;
4092 if (1 - exp(-kI * result) < rndmPtr->flat()) {
4093 singleRecon.clear();
4097 double rSum = sumW * rndmPtr->flat();
4098 for (map<
double,pair<int,int> >::iterator it = reconnections.begin();
4099 it != reconnections.end(); ++it) {
4102 singleRecon.insert(make_pair(1., it->second));
4108 singleRecon.clear();
4117 map<double,pair<int,int> > ColourReconnection::reconnectTypeII(
Event& event,
4118 vector<vector<ColourDipole> > &dips, Vec4 decays[2]) {
4121 map<double,pair<int,int> > reconnections;
4124 for (
int i = 0;i < int(dips[0].size()); ++i) {
4125 for (
int j = 0;j < int(dips[1].size()); ++j) {
4127 v1 =
event[dips[0][i].iCol].p() /
event[dips[0][i].iCol].e();
4128 v2 =
event[dips[0][i].iAcol].p() /
event[dips[0][i].iAcol].e();
4129 u1 =
event[dips[1][j].iCol].p() /
event[dips[1][j].iCol].e();
4130 u2 =
event[dips[1][j].iAcol].p() /
event[dips[1][j].iAcol].e();
4133 vector<vector<double> > matUpper, matLower;
4134 for (
int k = 0; k < 3; ++k) {
4135 matUpper.push_back(vector<double>(3,0));
4136 matLower.push_back(vector<double>(3,0));
4140 for (
int k = 0;k < 3; ++k) {
4141 matUpper[0][k] = matLower[0][k] = v2[k+1]-v1[k+1];
4142 matUpper[1][k] = matLower[1][k] = -(u2[k+1]-u1[k+1]);
4143 matUpper[2][k] = decays[0][k+1] - decays[1][k+1]
4144 - decays[0][0] * v1[k+1] + decays[1][0] * u1[k+1];
4145 matLower[2][k] = v1[k+1] - u1[k+1];
4147 double t = -determinant3(matUpper) / determinant3(matLower);
4150 double s11 = matUpper[0][0]*(t - decays[0][0]);
4151 double s12 = matUpper[1][0]*(t - decays[1][0]);
4152 double s13 = matUpper[2][0] + matLower[2][0]*t;
4153 double s21 = matUpper[0][1]*(t - decays[0][0]);
4154 double s22 = matUpper[1][1]*(t - decays[1][0]);
4155 double s23 = matUpper[2][1] + matLower[2][1]*t;
4156 double den = s11*s22 - s12*s21;
4157 double alpha = (s12*s23 - s22*s13)/den;
4158 double beta = (s21*s13 - s11*s23)/den;
4161 if (alpha < 0 || alpha > 1)
continue;
4162 if (beta < 0 || beta > 1)
continue;
4163 if (t < max(decays[0][0], decays[1][0]))
continue;
4167 x1 = decays[0] + (alpha * v2 + (1 - alpha) * v1) * (t - decays[0][0]);
4168 x2 = decays[1] + (beta * u2 + (1 - beta) * u1) * (t - decays[1][0]);
4172 if (dot3(x1-x2,x1-x2) > 1E-4 * (x1.pAbs2() + x2.pAbs2()))
continue;
4175 double tauPlus = (x1 - decays[0]).mCalc();
4176 double tauMinus = (x2 - decays[1]).mCalc();
4179 if (rndmPtr->flat() > exp( -(pow2(tauPlus) + pow2(tauMinus))
4180 / pow2(tfrag)))
continue;
4183 if (lowerLambdaOnly) {
4184 double oldLambda = stringLength.getStringLength(event,
4185 dips[0][i].iCol, dips[0][i].iAcol) +
4186 stringLength.getStringLength(event, dips[1][j].iCol,
4188 double newLambda = stringLength.getStringLength(event,
4189 dips[0][i].iCol, dips[1][j].iAcol) +
4190 stringLength.getStringLength(event, dips[1][j].iCol,
4192 if (oldLambda < newLambda)
continue;
4196 reconnections.insert(make_pair(t,make_pair(i,j)));
4200 return reconnections;
4208 double ColourReconnection::determinant3(vector<vector< double> >& vec) {
4209 return vec[0][0]*vec[1][1]*vec[2][2] + vec[0][1]*vec[1][2]*vec[2][0]
4210 + vec[0][2]*vec[1][0]*vec[2][1] - vec[0][0]*vec[2][1]*vec[1][2]
4211 - vec[0][1]*vec[1][0]*vec[2][2] - vec[0][2]*vec[1][1]*vec[2][0];