9 #include "Pythia8/ColourReconnection.h"
21 BeamDipole(
int colIn = 0,
int iColIn = 0,
int iAcolIn = 0)
22 : col(colIn), iCol(iColIn), iAcol(iAcolIn), p1p2() {}
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::TINYP1P2 = 1e-20;
169 const int ColourReconnection::MAXRECONNECTIONS = 1000;
175 bool cmpTrials(TrialReconnection j1, TrialReconnection j2) {
176 return (j1.lambdaDiff < j2.lambdaDiff);
183 bool ColourReconnection::init() {
186 eCM = infoPtr->eCM();
190 reconnectMode = mode(
"ColourReconnection:mode");
193 pT0Ref = parm(
"MultipartonInteractions:pT0Ref");
194 ecmRef = parm(
"MultipartonInteractions:ecmRef");
195 ecmPow = parm(
"MultipartonInteractions:ecmPow");
196 pT0 = pT0Ref * pow(eCM / ecmRef, ecmPow);
199 reconnectRange = parm(
"ColourReconnection:range");
200 pT20Rec = pow2(reconnectRange * pT0);
203 m0 = parm(
"ColourReconnection:m0");
205 allowJunctions = flag(
"ColourReconnection:allowJunctions");
206 nReconCols = mode(
"ColourReconnection:nColours");
207 sameNeighbourCol = flag(
"ColourReconnection:sameNeighbourColours");
208 timeDilationMode = mode(
"ColourReconnection:timeDilationMode");
209 timeDilationPar = parm(
"ColourReconnection:timeDilationPar");
210 timeDilationParGeV = timeDilationPar / HBARC;
213 m2Lambda = parm(
"ColourReconnection:m2Lambda");
214 fracGluon = parm(
"ColourReconnection:fracGluon");
215 dLambdaCut = parm(
"ColourReconnection:dLambdaCut");
216 flipMode = mode(
"ColourReconnection:flipMode");
219 singleReconOnly = flag(
"ColourReconnection:singleReconnection");
220 lowerLambdaOnly = flag(
"ColourReconnection:lowerLambdaOnly");
221 tfrag = parm(
"ColourReconnection:fragmentationTime");
222 blowR = parm(
"ColourReconnection:blowR");
223 blowT = parm(
"ColourReconnection:blowT");
224 rHadron = parm(
"ColourReconnection:rHadron");
225 kI = parm(
"ColourReconnection:kI");
228 stringLength.init(infoPtr, *settingsPtr);
239 bool ColourReconnection::next(
Event& event,
int iFirst) {
242 if (reconnectMode == 0)
return reconnectMPIs(event, iFirst);
245 else if (reconnectMode == 1)
return nextNew(event, iFirst);
248 else if (reconnectMode == 2)
return reconnectMove(event, iFirst);
251 else if (reconnectMode == 3 || reconnectMode == 4)
252 return reconnectTypeCommon(event, iFirst);
256 infoPtr->errorMsg(
"Warning in ColourReconnection::next: "
257 "Colour reconnecion mode not found");
267 bool ColourReconnection::nextNew(
Event& event,
int iFirst) {
270 while (!dipoles.empty()) {
271 delete dipoles.back();
278 formationTimes.clear();
281 setupDipoles(event, iFirst);
282 if (dipoles.size() == 0)
return true;
283 makeAllPseudoParticles(event, iFirst);
287 vector<vector<int> > iDips;
288 iDips.resize(nReconCols);
289 for (
int i = 0; i < int(iDips.size()); ++i)
290 iDips[i] = vector<int>();
292 for (
int i = 0; i < int(dipoles.size()); ++i)
293 if (dipoles[i]->isActive)
294 iDips[dipoles[i]->colReconnection].push_back(i);
297 for (
int i = 0;i < int(iDips.size()); ++i)
298 for (
int j = 0; j < int(iDips[i].size()); ++j)
299 for (
int k = j + 1; k < int(iDips[i].size()); ++k)
300 singleReconnection(dipoles[iDips[i][j]], dipoles[iDips[i][k]]);
303 bool alreadyWarned =
false;
306 for (
int iOuterLoop = 0; iOuterLoop < 20; ++iOuterLoop) {
307 bool finished =
true;
310 for (
int iInnerLoop = 0;dipTrials.size() > 0; ++iInnerLoop) {
313 if (iInnerLoop > MAXRECONNECTIONS) {
315 infoPtr->errorMsg(
"Warning in ColourReconnection::nextNew:"
316 "Too many reconnections, stopping before minimum reached.");
317 alreadyWarned =
true;
323 storeUsedDips(dipTrials.back());
326 doDipoleTrial(dipTrials.back());
329 sort(usedDipoles.begin(), usedDipoles.end());
330 for (
int i = 0;i < int(usedDipoles.size() - 1); ++i)
331 if (usedDipoles[i] == usedDipoles[i + 1]) {
332 usedDipoles.erase(usedDipoles.begin() + i);
337 updateDipoleTrials();
341 if (allowJunctions) {
346 for (
int i = 0; i < int(iDips.size()); ++i)
347 iDips[i] = vector<int>();
349 for (
int i = 0; i < int(dipoles.size()); ++i)
350 if (dipoles[i]->isActive)
351 iDips[dipoles[i]->colReconnection % 3].push_back(i);
354 for (
int i = 0;i < int(iDips.size()); ++i)
355 for (
int j = 0; j < int(iDips[i].size()); ++j)
356 for (
int k = j + 1; k < int(iDips[i].size()); ++k)
357 singleJunction(dipoles[iDips[i][j]], dipoles[iDips[i][k]]);
361 for (
int i = 0;i < int(iDips.size()); ++i)
362 for (
int j = 0; j < int(iDips[i].size()); ++j)
363 for (
int k = j + 1; k < int(iDips[i].size()); ++k)
364 for (
int l = k + 1; l < int(iDips[i].size()); ++l)
365 singleJunction(dipoles[iDips[i][j]], dipoles[iDips[i][k]],
366 dipoles[iDips[i][l]]);
369 for (
int iInnerLoop = 0;junTrials.size() > 0; ++iInnerLoop) {
372 if (iInnerLoop > MAXRECONNECTIONS) {
374 infoPtr->errorMsg(
"Warning in ColourReconnection::nextNew:"
375 "Too many reconnections, stopping before minimum reached.");
376 alreadyWarned =
true;
382 storeUsedDips(junTrials.back());
385 doJunctionTrial(event, junTrials.back());
388 sort(usedDipoles.begin(), usedDipoles.end());
389 for (
int i = 0;i < int(usedDipoles.size() - 1); ++i)
390 if (usedDipoles[i] == usedDipoles[i + 1]) {
391 usedDipoles.erase(usedDipoles.begin() + i);
396 updateJunctionTrials();
397 updateDipoleTrials();
408 updateEvent(event, iFirst);
420 void ColourReconnection::setupDipoles(
Event& event,
int iFirst) {
423 vector< vector<int > > chains;
425 vector<bool> isAntiJun;
426 vector<bool> isGluonLoop;
427 vector<bool> inChain(event.size(),
false);
430 for (
int i = iFirst; i <
event.size(); ++i) {
431 if ( (event[i].isFinal() && !inChain[i]
432 && event[i].isQuark() && event[i].
id() > 0)
433 || (
event[i].isFinal() && !inChain[i]
434 &&
event[i].isDiquark() &&
event[i].id() < 0) ) {
435 int curCol =
event[i].col();
439 isAntiJun.push_back(
false);
440 isJun.push_back(
false);
441 isGluonLoop.push_back(
false);
442 for (
int iSteps = 0; curCol != 0 && iSteps < 1000; ++iSteps) {
445 for (
int j = iFirst; j <
event.size(); j++) {
446 if (event[j].isFinal() && !inChain[j] &&
event[j].acol() == curCol) {
449 curCol =
event[j].col();
455 for (
int iJun = 0; iJun <
event.sizeJunction(); ++iJun) {
456 for (
int j = 0; j < 3; ++j) {
457 if (event.colJunction(iJun,j) == curCol) {
458 isJun[isJun.size() -1] =
true;
460 chain.push_back( -(10 + 10 * iJun + j) );
465 chains.push_back(chain);
470 for (
int i = 0; i <
event.sizeJunction(); ++i) {
473 int checkCol =
event.colJunction(i,0);
474 bool wrongSystem =
false;
475 for (
int j = 0; j < iFirst; ++j)
476 if (event[j].isFinal() && event[j].acol() == checkCol)
482 if (event.kindJunction(i) == 2)
483 for (
int jCol = 0; jCol < 3; ++jCol) {
484 int curCol =
event.colJunction(i,jCol);
486 chain.push_back( -(10 + 10 * i + jCol));
487 isAntiJun.push_back(
true);
488 isJun.push_back(
false);
489 isGluonLoop.push_back(
false);
490 for (
int iSteps = 0; curCol != 0 && iSteps < 1000; ++iSteps) {
493 for (
int j = iFirst; j <
event.size(); ++j)
494 if (event[j].isFinal() && !inChain[j] &&
495 event[j].acol() == curCol) {
498 curCol =
event[j].col();
503 for (
int iJun = 0; iJun <
event.sizeJunction(); ++iJun)
504 if (event.kindJunction(iJun) == 1)
505 for (
int j = 0; j < 3; ++j)
506 if (event.colJunction(iJun,j) == curCol) {
507 isJun[isJun.size() - 1] =
true;
509 chain.push_back( -(10 + 10 * iJun + j));
512 chains.push_back(chain);
517 for (
int i = iFirst; i <
event.size(); ++i)
518 if (event[i].isFinal() && !inChain[i] &&
event[i].col() != 0) {
519 int curCol =
event[i].col();
523 isAntiJun.push_back(
false);
524 isJun.push_back(
false);
525 isGluonLoop.push_back(
true);
526 for (
int iSteps = 0; curCol != 0 && iSteps < 1000; ++iSteps) {
527 bool foundNext =
false;
528 for (
int j = iFirst; j <
event.size(); ++j)
529 if (event[j].isFinal() && !inChain[j] &&
event[j].acol() == curCol) {
532 curCol =
event[j].col();
540 chains.push_back(chain);
544 for (
int i = 0; i < int(chains.size()); ++i) {
545 if (chains[i].size() == 1)
continue;
551 for (
int j = 0; j < int(chains[i].size()); ++j) {
552 if (j !=
int(chains[i].size() - 1)) {
555 int newCol = int(rndmPtr->flat() * nReconCols);
556 while (newCol == lastCol && !sameNeighbourCol) {
557 newCol = int(rndmPtr->flat() * nReconCols);
563 if (j == 0 && !isAntiJun[i] && !isGluonLoop[i]) {
565 int iMother =
event[
event[ chains[i][j] ].iTopCopy()].mother1();
566 if ( event[iMother].idAbs() == 21) {
567 vector<int> sisters =
event[ chains[i][j] ].sisterList(
true);
569 if (sisters.size() == 1 &&
event[ chains[i][j] ].id()
570 == -
event[ sisters[0] ].id()) {
574 for (
int k = 0; k < int(dipoles.size()); ++k)
575 if (dipoles[k]->iAcol == sisters[0]) {
576 colSis = dipoles[k]->colReconnection;
581 while (colSis == newCol && !sameNeighbourCol)
582 newCol = int(rndmPtr->flat() * nReconCols);
589 if (j ==
int(chains[i].size() - 2) && !isJun[i] && !isGluonLoop[i]) {
591 int iMother =
event[
event[chains[i][j + 1]].iTopCopy()].mother1();
592 if (event[iMother].idAbs() == 21) {
593 vector<int> sisters =
event[ chains[i][j + 1] ].sisterList(
true);
595 if (sisters.size() == 1 &&
event[ chains[i][j + 1] ].id()
596 == -
event[ sisters[0] ].id()) {
600 for (
int k = 0; k < int(dipoles.size()); ++k)
601 if (dipoles[k]->iCol == sisters[0]) {
602 colSis = dipoles[k]->colReconnection;
607 while ((colSis == newCol || newCol == lastCol)
608 && !sameNeighbourCol)
609 newCol =
int(rndmPtr->flat() * nReconCols);
616 if ((chains[i][j] > 0 && event[chains[i][j]].status() == 75) ||
617 (chains[i][j + 1] > 0 &&
618 event[ chains[i][j + 1] ].status() == 75) ) {
622 if (chains[i][j] > 0 && event[ chains[i][j] ].status() == 75)
623 sisters = event[ chains[i][j] ].sisterList();
625 sisters =
event[ chains[i][j + 1] ].sisterList();
627 if (sisters.size() == 3 ) {
630 int acolSis1 = -1, acolSis2 = -1, acolSis3 = -1;
631 int colSis1 = -1, colSis2 = -1, colSis3 = -1;
632 for (
int k = 0;k < int(dipoles.size()); ++k) {
633 if (dipoles[k]->iAcol == sisters[0])
634 acolSis1 = dipoles[k]->colReconnection;
636 if (dipoles[k]->iAcol == sisters[1])
637 acolSis2 = dipoles[k]->colReconnection;
639 if (dipoles[k]->iAcol == sisters[2])
640 acolSis3 = dipoles[k]->colReconnection;
642 if (dipoles[k]->iCol == sisters[0])
643 colSis1 = dipoles[k]->colReconnection;
645 if (dipoles[k]->iCol == sisters[1])
646 colSis2 = dipoles[k]->colReconnection;
648 if (dipoles[k]->iCol == sisters[2])
649 colSis3 = dipoles[k]->colReconnection;
653 while ((colSis1 == newCol || colSis2 == newCol ||
654 colSis3 == newCol || acolSis1 == newCol ||
655 acolSis2 == newCol || acolSis3 == newCol)
656 && !sameNeighbourCol)
657 newCol =
int(rndmPtr->flat() * nReconCols);
662 if (j == 0) firstCol = newCol;
666 if (j == 0 && isAntiJun[i]) {
667 int col =
event.colJunction( -
int(chains[i][j]/10) - 1,
669 dipoles.push_back(
new ColourDipole(col, chains[i][j],
670 chains[i][j+1], newCol));
671 dipoles.back()->isAntiJun =
true;
675 else dipoles.push_back(
new ColourDipole(event[ chains[i][j] ].col(),
676 chains[i][j], chains[i][j+1], newCol));
679 if (j ==
int(chains[i].size() - 2) && isJun[i])
680 dipoles.back()->isJun =
true;
684 dipoles[dipoles.size() - 1]->leftDip = dipoles[dipoles.size() - 2];
685 dipoles[dipoles.size() - 2]->rightDip = dipoles[dipoles.size() - 1];
693 if (event[ chains[i][j] ].col() == event[ chains[i][0] ].acol()) {
694 int newCol = int(rndmPtr->flat() * nReconCols);
695 while ( (newCol == lastCol || newCol == firstCol)
696 && !sameNeighbourCol) {
697 newCol = int(rndmPtr->flat() * nReconCols);
699 dipoles.push_back(
new ColourDipole(event[ chains[i][j] ].col(),
700 chains[i][j], chains[i][0], newCol));
703 dipoles[dipoles.size() - 1]->leftDip = dipoles[dipoles.size() - 2];
704 dipoles[dipoles.size() - 2]->rightDip = dipoles[dipoles.size() - 1];
705 dipoles[dipoles.size() - chains[i].size()]->leftDip =
706 dipoles[dipoles.size() -1];
707 dipoles[dipoles.size() - 1]->rightDip =
708 dipoles[dipoles.size() - chains[i].size()];
716 iColJun.resize(event.sizeJunction());
717 for (
int i = 0; i < int(iColJun.size()); ++i) iColJun[i] = vector<int>(3,0);
720 for (
int i = iFirst; i <
event.size(); ++i)
721 if (event[i].isFinal())
722 for (
int j = 0; j <
event.sizeJunction(); ++j)
723 for (
int jLeg = 0; jLeg < 3; ++jLeg)
724 if (event[i].col() ==
event.colJunction(j,jLeg) ||
725 event[i].acol() ==
event.colJunction(j,jLeg))
726 iColJun[j][jLeg] = i;
729 for (
int i = 0;i <
event.sizeJunction(); ++i)
730 for (
int iLeg = 0; iLeg < 3; ++iLeg)
731 for (
int j = i + 1;j <
event.sizeJunction(); ++j)
732 for (
int jLeg = 0; jLeg < 3; ++jLeg)
733 if (event.colJunction(i, iLeg) ==
event.colJunction(j, jLeg)) {
734 iColJun[i][iLeg] = -(10*j + 10 + jLeg);
735 iColJun[j][jLeg] = -(10*i + 10 + iLeg);
739 setupFormationTimes(event);
748 double ColourReconnection::calculateStringLength(ColourDipole * dip,
749 vector<ColourDipole *> &dips) {
752 for (
int i = 0; i < int(dips.size()); ++i)
753 if (dips[i] == dip)
return 0.;
756 if (!dip->isJun && !dip->isAntiJun) {
757 return calculateStringLength(dip->iCol, dip->iAcol);
762 vector<int> iParticles;
763 vector<bool> usedJuns(junctions.size(),
false);
766 if (!findJunctionParticles( -
int(dip->iAcol/10) - 1, iParticles,
767 usedJuns, nJuns, dips))
return 1e9;
769 if (!findJunctionParticles(-
int(dip->iCol/10) - 1, iParticles,
770 usedJuns, nJuns, dips))
return 1e9;
773 if (
int(iParticles.size()) == 3)
774 return calculateJunctionLength(iParticles[0], iParticles[1],
778 else if (
int(iParticles.size()) == 4) {
779 return calculateDoubleJunctionLength(iParticles[0], iParticles[1],
780 iParticles[2], iParticles[3]);
791 void ColourReconnection::updateEvent(
Event& event,
int iFirst) {
794 int oldSize =
event.size();
795 for (
int i = iFirst; i < oldSize;++i)
796 if (event[i].isFinal())
event.copy(i, 79);
799 event.clearJunctions();
800 for (
int i = 0; i < int(junctions.size()); ++i) {
801 for (
int j = 0; j < 3; ++j) {
802 if ( junctions[i].dipsOrig[j] != 0) {
803 junctions[i].col(j, junctions[i].dipsOrig[j]->col);
806 event.appendJunction(Junction(junctions[i]));
810 for (
int i = 0; i < int(dipoles.size()); ++i)
811 if (dipoles[i]->isReal) {
812 if (dipoles[i]->iCol >= 0)
813 event[
event[ dipoles[i]->iCol ].daughter1() ].col(dipoles[i]->col);
815 event.colJunction(-(dipoles[i]->iCol/10 + 1), -dipoles[i]->iCol % 10,
817 if (dipoles[i]->iAcol >= 0)
818 event[
event[ dipoles[i]->iAcol ].daughter1() ].acol(dipoles[i]->col);
820 event.colJunction(-(dipoles[i]->iAcol/10 + 1), -dipoles[i]->iAcol % 10,
831 bool ColourReconnection::findJunctionParticles(
int iJun,
832 vector<int>& iParticles, vector<bool> &usedJuns,
int &nJuns,
833 vector<ColourDipole*> &dips ) {
836 usedJuns[iJun] =
true;
844 if (junctions[iJun].kind() % 2 == 1)
845 for (
int i = 0; i < 3; ++i)
846 iParticles.push_back(junctions[iJun].dips[i]->iCol);
848 for (
int i = 0; i < 3; ++i)
849 iParticles.push_back(junctions[iJun].dips[i]->iAcol);
852 for (
int i = 0; i < 3; ++i) {
854 for (
int j = 0; j < int(dips.size()); ++j) {
855 if (dips[j] == junctions[iJun].dips[i]) {
860 if (addDip) dips.push_back(junctions[iJun].dips[i]);
864 for (
int i = 0; i < int(iParticles.size()); ++i)
865 if (iParticles[i] < 0) {
866 int iNewJun = - int(iParticles[i] / 10) -1;
867 iParticles.erase(iParticles.begin() + i);
869 if (!usedJuns[iNewJun] && !findJunctionParticles( iNewJun, iParticles,
870 usedJuns, nJuns, dips) )
882 double ColourReconnection::calculateStringLength(
int i,
int j) {
883 return stringLength.getStringLength(particles[i].p(), particles[j].p());
890 double ColourReconnection::calculateJunctionLength(
int i,
894 if ( i == j || i == k || j == k)
return 1e9;
896 Vec4 p1 = particles[i].p();
897 Vec4 p2 = particles[j].p();
898 Vec4 p3 = particles[k].p();
900 return stringLength.getJuncLength(p1, p2, p3);
909 double ColourReconnection::calculateDoubleJunctionLength(
int i,
int j,
913 if (i == j || i == k || i == l || j == k || j == l || k == l)
return 1e9;
915 Vec4 p1 = particles[i].p();
916 Vec4 p2 = particles[j].p();
917 Vec4 p3 = particles[k].p();
918 Vec4 p4 = particles[l].p();
920 return stringLength.getJuncLength(p1, p2, p3, p4);
928 void ColourReconnection::singleReconnection(ColourDipole* dip1,
929 ColourDipole* dip2) {
932 if (dip1 == dip2)
return;
935 if (dip1->colReconnection != dip2->colReconnection)
return;
938 if (!dip1->isActive || !dip2->isActive)
return;
941 if (dip1->iCol == dip2->iAcol || dip1->iAcol == dip2->iCol)
return;
944 if (!checkTimeDilation(dip1, dip2))
return;
947 double lambdaDiff = getLambdaDiff(dip1, dip2);
950 if (lambdaDiff > MINIMUMGAIN) {
951 TrialReconnection dipTrial(dip1, dip2, 0, 0, 5, lambdaDiff);
952 dipTrials.insert(lower_bound(dipTrials.begin(), dipTrials.end(),
953 dipTrial, cmpTrials), dipTrial);
962 void ColourReconnection::swapDipoles(ColourDipole* dip1,
963 ColourDipole* dip2,
bool back) {
966 swap(dip1->iAcol, dip2->iAcol);
967 swap(dip1->isJun, dip2->isJun);
968 swap(dip1->iAcolLeg, dip2->iAcolLeg);
972 if (dip1->iAcol != dip2->iAcol) {
974 if (dip1->iAcol >= 0)
975 for (
int i = 0; i < int(particles[dip1->iAcol].activeDips.size()); ++i)
976 if (particles[dip1->iAcol].activeDips[i] == dip2) {
977 particles[dip1->iAcol].activeDips[i] = dip1;
981 if (dip2->iAcol >= 0)
982 for (
int i = 0; i < int(particles[dip2->iAcol].activeDips.size()); ++i)
983 if (particles[dip2->iAcol].activeDips[i] == dip1) {
984 particles[dip2->iAcol].activeDips[i] = dip2;
989 if (dip1->iAcol >= 0) particles[dip1->iAcol].activeDips[swap2] = dip1;
990 if (dip2->iAcol >= 0) particles[dip2->iAcol].activeDips[swap1] = dip2;
995 for (
int i = 0; i < int(junctions.size()); ++i)
996 if (junctions[i].kind() % 2 == 1)
997 for (
int iLeg = 0; iLeg < 3; ++iLeg) {
998 if (junctions[i].dips[iLeg] == dip1) {
999 junctions[i].dips[iLeg] = dip2;
1002 if (junctions[i].dips[iLeg] == dip2) {
1003 junctions[i].dips[iLeg] = dip1;
1015 void ColourReconnection::singleJunction(ColourDipole* dip1,
1016 ColourDipole* dip2) {
1022 int iCol1 = dip1->iCol;
1023 int iCol2 = dip2->iCol;
1024 int iAcol1 = dip1->iAcol;
1025 int iAcol2 = dip2->iAcol;
1028 if (iCol1 == iCol2)
return;
1029 if (iAcol1 == iAcol2)
return;
1032 if (!dip1->isActive || !dip2->isActive)
return;
1035 if (dip1->isJun || dip1->isAntiJun)
return;
1036 if (dip2->isJun || dip2->isAntiJun)
return;
1040 if (
int(particles[iCol1].dips.size()) != 1 ||
1041 int(particles[iAcol1].dips.size()) != 1 ||
1042 int(particles[iCol2].dips.size()) != 1 ||
1043 int(particles[iAcol2].dips.size()) != 1)
1047 if ( (dip1->colReconnection) % 3 !=
1048 dip2->colReconnection % 3)
return;
1050 if ( (dip1->colReconnection) ==
1051 dip2->colReconnection)
return;
1054 if (!checkTimeDilation(dip1, dip2))
return;
1057 int junCol = (3 - (dip1->colReconnection / 3)
1058 - (dip2->colReconnection / 3) ) * 3
1059 + (dip1->colReconnection % 3);
1062 if (nReconCols != 9) {
1063 while (junCol < 0 || junCol % 3 != dip1->colReconnection % 3 ||
1064 junCol == dip1->colReconnection || junCol == dip2->colReconnection)
1065 junCol = int(nReconCols * rndmPtr->flat());
1069 ColourDipole* dip3 = dip1;
1070 ColourDipole* dip4 = dip2;
1072 double lambdaDiff = getLambdaDiff(dip1, dip2, dip3, dip4, 0);
1073 if (lambdaDiff > MINIMUMGAINJUN) {
1074 TrialReconnection junTrial(dip1, dip2, dip3, dip4, 0, lambdaDiff);
1075 junTrials.insert(lower_bound(junTrials.begin(), junTrials.end(),
1076 junTrial, cmpTrials), junTrial);
1085 if (dip3->colReconnection == junCol)
1088 if (dip4->colReconnection == dip2->colReconnection)
1089 if (checkTimeDilation(dip1, dip2, dip3, dip4)) {
1092 lambdaDiff = getLambdaDiff(dip1, dip2, dip3, dip4, 1);
1094 if (lambdaDiff > MINIMUMGAINJUN) {
1096 TrialReconnection junTrial(dip1, dip2, dip3, dip4, 1, lambdaDiff);
1097 junTrials.insert(lower_bound(junTrials.begin(), junTrials.end(),
1098 junTrial, cmpTrials), junTrial);
1104 if (!findAntiNeighbour(dip4))
1108 if (dip4 == dip2 || dip4 == dip1)
1117 if (dip3->colReconnection == dip1->colReconnection)
1120 if (dip4->colReconnection == junCol)
1121 if (checkTimeDilation(dip1, dip2, dip3, dip4)) {
1124 lambdaDiff = getLambdaDiff(dip1, dip2, dip3, dip4, 2);
1126 if (lambdaDiff > MINIMUMGAINJUN) {
1128 TrialReconnection junTrial(dip1, dip2, dip3, dip4, 2, lambdaDiff);
1129 junTrials.insert(lower_bound(junTrials.begin(), junTrials.end(),
1130 junTrial, cmpTrials), junTrial);
1135 if (!findAntiNeighbour(dip4))
1139 if (dip4 == dip2 || dip4 == dip1)
1145 if (!findAntiNeighbour(dip3))
1149 if (dip3 == dip1 || dip3 == dip2)
1161 void ColourReconnection::singleJunction(ColourDipole* dip1,
1162 ColourDipole* dip2, ColourDipole* dip3) {
1165 if (dip1->isJun || dip1->isAntiJun)
return;
1166 if (dip2->isJun || dip2->isAntiJun)
return;
1167 if (dip3->isJun || dip3->isAntiJun)
return;
1171 if (!dip1->isActive || !dip2->isActive || !dip3->isActive)
return;
1174 if ( dip1->colReconnection % 3 != dip2->colReconnection % 3
1175 || dip1->colReconnection % 3 != dip3->colReconnection % 3)
return;
1177 if ( !(dip1->colReconnection != dip2->colReconnection
1178 && dip1->colReconnection != dip3->colReconnection
1179 && dip2->colReconnection != dip3->colReconnection) )
1183 if (
int(particles[dip1->iCol].dips.size()) != 1 ||
1184 int(particles[dip1->iAcol].dips.size()) != 1 ||
1185 int(particles[dip2->iCol].dips.size()) != 1 ||
1186 int(particles[dip2->iAcol].dips.size()) != 1 ||
1187 int(particles[dip3->iCol].dips.size()) != 1 ||
1188 int(particles[dip3->iAcol].dips.size()) != 1 )
1192 if (!checkTimeDilation(dip1, dip2, dip3))
return;
1194 double lambdaDiff = getLambdaDiff(dip1, dip2, dip3, 0, 3);
1196 if (lambdaDiff > MINIMUMGAINJUN) {
1197 TrialReconnection junTrial(dip1, dip2, dip3, 0, 3, lambdaDiff);
1198 junTrials.insert(lower_bound(junTrials.begin(), junTrials.end(), junTrial,
1199 cmpTrials), junTrial);
1210 void ColourReconnection::makePseudoParticle(ColourDipole* dip ,
int status,
1214 if (!dip->isJun && !dip->isAntiJun) {
1217 int iCol = dip->iCol;
1218 int iAcol = dip->iAcol;
1219 int iColLeg = dip->iColLeg;
1220 int iAcolLeg = dip->iAcolLeg;
1223 int iNew = particles.size();
1224 particles.push_back(particles[iCol]);
1225 particles[iNew].acol(particles[iCol].acol());
1226 particles[iNew].col(particles[iAcol].col());
1227 particles[iNew].mother1(iCol);
1228 particles[iNew].mother2(iAcol);
1229 particles[iNew].id(99);
1230 particles[iNew].status(status);
1231 particles[iNew].isJun =
false;
1232 particles[iAcol].statusNeg();
1233 particles[iAcol].daughter1(iNew);
1234 particles[iCol].statusNeg();
1235 particles[iCol].daughter1(iNew);
1237 particles[iNew].p(particles[iCol].p() + particles[iAcol].p());
1239 particles[iNew].p(particles[iCol].p());
1243 particles[iNew].dips = particles[dip->iCol].dips;
1244 particles[iNew].colEndIncluded = particles[dip->iCol].colEndIncluded;
1245 particles[iNew].acolEndIncluded = particles[dip->iCol].acolEndIncluded;
1248 if (iCol != iAcol) {
1249 for (
int i = 0; i < int(particles[dip->iAcol].dips.size()); ++i) {
1250 if (i != dip->iAcolLeg) {
1252 particles[iNew].dips.push_back(particles[dip->iAcol].dips[i]);
1253 particles[iNew].colEndIncluded.push_back(
1254 particles[dip->iAcol].colEndIncluded[i]);
1255 particles[iNew].acolEndIncluded.push_back(
1256 particles[dip->iAcol].acolEndIncluded[i]);
1259 particles[iNew].acolEndIncluded[iColLeg] =
1260 particles[iAcol].acolEndIncluded[i];
1261 particles[iNew].dips[iColLeg].pop_back();
1262 particles[iNew].dips[iColLeg].insert(
1263 particles[iNew].dips[iColLeg].end(),
1264 particles[iAcol].dips[i].begin(), particles[iAcol].dips[i].end() );
1269 for (
int i = 0; i < int(particles[iAcol].activeDips.size()); ++i) {
1270 if ( particles[iAcol].activeDips[i]->iAcol == iAcol) {
1271 if (particles[iAcol].activeDips[i]->iAcolLeg < iAcolLeg)
1272 particles[iAcol].activeDips[i]->iAcolLeg +=
1273 particles[iCol].dips.size();
1274 else if (particles[iAcol].activeDips[i]->iAcolLeg == iAcolLeg)
1275 particles[iAcol].activeDips[i]->iAcolLeg = iColLeg;
1276 else if (particles[iAcol].activeDips[i]->iAcolLeg > iAcolLeg)
1277 particles[iAcol].activeDips[i]->iAcolLeg +=
1278 particles[iCol].dips.size() - 1;
1280 if (particles[iAcol].activeDips[i]->iCol == iAcol) {
1281 if (particles[iAcol].activeDips[i]->iColLeg < iAcolLeg)
1282 particles[iAcol].activeDips[i]->iColLeg +=
1283 particles[iCol].dips.size();
1284 else if (particles[iAcol].activeDips[i]->iColLeg == iAcolLeg)
1285 particles[iAcol].activeDips[i]->iColLeg = iColLeg;
1286 else if (particles[iAcol].activeDips[i]->iColLeg > iAcolLeg)
1287 particles[iAcol].activeDips[i]->iColLeg +=
1288 particles[iCol].dips.size() - 1;
1294 particles[iNew].activeDips.clear();
1295 particles[iNew].activeDips.insert(particles[iNew].activeDips.end(),
1296 particles[iCol].activeDips.begin(), particles[iCol].activeDips.end());
1298 particles[iNew].activeDips.insert(particles[iNew].activeDips.end(),
1299 particles[iAcol].activeDips.begin(), particles[iAcol].activeDips.end());
1302 for (
int i = 0; i < int(particles[iNew].activeDips.size()); ++i)
1303 if (particles[iNew].activeDips[i] == dip) {
1304 particles[iNew].activeDips.erase(
1305 particles[iNew].activeDips.begin() + i);
1310 for (
int i = 0; i < int(particles[iNew].activeDips.size()); ++i) {
1311 if (particles[iNew].activeDips[i]->iCol == iAcol)
1312 particles[iNew].activeDips[i]->iCol = iNew;
1313 if (particles[iNew].activeDips[i]->iCol == iCol)
1314 particles[iNew].activeDips[i]->iCol = iNew;
1315 if (particles[iNew].activeDips[i]->iAcol == iAcol)
1316 particles[iNew].activeDips[i]->iAcol = iNew;
1317 if (particles[iNew].activeDips[i]->iAcol == iCol)
1318 particles[iNew].activeDips[i]->iAcol = iNew;
1319 particles[iNew].activeDips[i]->p1p2
1320 = mDip(particles[iNew].activeDips[i]);
1326 for (
int i = 0; i < int(particles[iNew].activeDips.size()); ++i)
1327 for (
int j = i + 1; j < int(particles[iNew].activeDips.size()); ++j)
1328 if (particles[iNew].activeDips[i] == particles[iNew].activeDips[j]) {
1329 particles[iNew].activeDips.erase(particles[iNew].activeDips.begin() + j);
1334 for (
int i = 0; i < int(particles[iNew].activeDips.size()); ++i) {
1335 if (particles[iNew].activeDips[i]->iCol >= 0)
1336 usedDipoles.push_back(particles[iNew].activeDips[i]);
1338 for (
int j = 0;j < 3; ++j)
1339 usedDipoles.push_back(junctions[-(particles[iNew].
1340 activeDips[i]->iCol / 10 + 1)].getColDip(j));
1342 if (particles[iNew].activeDips[i]->iAcol >= 0)
1343 usedDipoles.push_back(particles[iNew].activeDips[i]);
1345 for (
int j = 0;j < 3; ++j)
1346 usedDipoles.push_back(junctions[-(particles[iNew].
1347 activeDips[i]->iAcol / 10 + 1)].getColDip(j));
1351 dip->isActive =
false;
1358 else if (dip->isJun && dip->isAntiJun) {
1364 int iJun, i0, i1, i2, junLeg0, junLeg1, junLeg2;
1365 getJunctionIndices(dip, iJun, i0, i1, i2, junLeg0, junLeg1, junLeg2);
1366 ColourDipole* dip2 = junctions[iJun].dips[junLeg1];
1367 ColourDipole* dip3 = junctions[iJun].dips[junLeg2];
1370 int iNew = particles.size();
1371 particles.push_back(ColourParticle( Particle( 99, status, i0, i1, 0, 0, 0,
1372 0, particles[i0].p() + particles[i1].p() ) ) );
1373 particles[iNew].isJun =
true;
1374 particles[iNew].junKind = junctions[iJun].kind();
1375 if (i0 == i1) particles[iNew].p(particles[i0].p());
1378 particles[i0].statusNeg();
1379 particles[i0].daughter1(iNew);
1380 particles[i1].statusNeg();
1381 particles[i1].daughter1(iNew);
1384 particles[iNew].dips.clear();
1385 particles[iNew].dips.insert(particles[iNew].dips.end(),
1386 particles[i0].dips.begin(),particles[i0].dips.end());
1388 particles[iNew].dips.insert(particles[iNew].dips.end(),
1389 particles[i1].dips.begin(),particles[i1].dips.end());
1392 particles[iNew].colEndIncluded.clear();
1393 particles[iNew].colEndIncluded.insert(
1394 particles[iNew].colEndIncluded.end(),
1395 particles[i0].colEndIncluded.begin(),
1396 particles[i0].colEndIncluded.end() );
1398 particles[iNew].colEndIncluded.insert(
1399 particles[iNew].colEndIncluded.end(),
1400 particles[i1].colEndIncluded.begin(),
1401 particles[i1].colEndIncluded.end() );
1404 particles[iNew].acolEndIncluded.clear();
1405 particles[iNew].acolEndIncluded.insert(
1406 particles[iNew].acolEndIncluded.end(),
1407 particles[i0].acolEndIncluded.begin(),
1408 particles[i0].acolEndIncluded.end() );
1410 particles[iNew].acolEndIncluded.insert(
1411 particles[iNew].acolEndIncluded.end(),
1412 particles[i1].acolEndIncluded.begin(),
1413 particles[i1].acolEndIncluded.end() );
1416 if (dip->isJun && i2 >= 0 && i2 != i0 && i2 != i1) {
1417 particles[iNew].dips.push_back(particles[i2].dips[dip3->iColLeg]);
1418 particles[iNew].dips.back().erase(particles[iNew].dips.back().begin(),
1419 particles[iNew].dips.back().end() - 1);
1422 if (dip->isAntiJun && i2 >= 0 && i2 != i0 && i2 != i1) {
1423 particles[iNew].dips.push_back(particles[i2].dips[dip3->iAcolLeg]);
1424 particles[iNew].dips.back().erase(
1425 particles[iNew].dips.back().begin() + 1,
1426 particles[iNew].dips.back().end() );
1430 if (i2 != i0 && i2 != i1) {
1431 particles[iNew].acolEndIncluded.push_back(
false);
1432 particles[iNew].colEndIncluded.push_back(
false);
1437 particles[iNew].dips.push_back(vector<ColourDipole *>());
1440 for (
int i = 0; i < int(dipoles.size()); ++i)
1441 if (dipoles[i]->isReal && dipoles[i]->iCol == dip3->iCol &&
1442 dipoles[i]->iAcol == dip3->iAcol)
1443 particles[iNew].dips.back().push_back(dipoles[i]);
1446 particles[iNew].acolEndIncluded.back() =
true;
1447 particles[iNew].colEndIncluded.back() =
true;
1452 for (
int i = 0; i < int(particles[iNew].acolEndIncluded.size()); ++i)
1453 particles[iNew].acolEndIncluded[i] =
true;
1455 for (
int i = 0; i < int(particles[iNew].colEndIncluded.size()); ++i)
1456 particles[iNew].colEndIncluded[i] =
true;
1460 dip->isActive =
false;
1461 dip2->isActive =
false;
1462 dip3->isActive =
true;
1468 for (
int i = 0; i < int(particles[i1].activeDips.size()); ++i) {
1469 if (particles[i1].activeDips[i]->iAcol == i1)
1470 particles[i1].activeDips[i]->iAcolLeg += particles[i0].dips.size();
1471 if (particles[i1].activeDips[i]->iCol == i1)
1472 particles[i1].activeDips[i]->iColLeg += particles[i0].dips.size();
1476 particles[iNew].activeDips.clear();
1477 particles[iNew].activeDips.insert(particles[iNew].activeDips.end(),
1478 particles[i0].activeDips.begin(), particles[i0].activeDips.end());
1480 particles[iNew].activeDips.insert(particles[iNew].activeDips.end(),
1481 particles[i1].activeDips.begin(), particles[i1].activeDips.end());
1482 if (i2 != i0 && i2 != i1)
1483 particles[iNew].activeDips.push_back(dip3);
1486 for (
int i = 0; i < int(particles[iNew].activeDips.size()); ++i) {
1487 if (particles[iNew].activeDips[i] == dip) {
1488 particles[iNew].activeDips.erase(
1489 particles[iNew].activeDips.begin() + i);
1493 if (particles[iNew].activeDips[i] == dip2) {
1494 particles[iNew].activeDips.erase(
1495 particles[iNew].activeDips.begin() + i);
1502 for (
int i = 0; i < int(particles[iNew].activeDips.size()); ++i) {
1503 if (particles[iNew].activeDips[i]->iCol == i1)
1504 particles[iNew].activeDips[i]->iCol = iNew;
1505 if (particles[iNew].activeDips[i]->iCol == i0)
1506 particles[iNew].activeDips[i]->iCol = iNew;
1507 if (particles[iNew].activeDips[i]->iAcol == i1)
1508 particles[iNew].activeDips[i]->iAcol = iNew;
1509 if (particles[iNew].activeDips[i]->iAcol == i0)
1510 particles[iNew].activeDips[i]->iAcol = iNew;
1511 particles[iNew].activeDips[i]->p1p2
1512 = mDip(particles[iNew].activeDips[i]);
1517 dip3->isJun =
false;
1519 if (i2 != i0 && i2 != i1)
1520 dip3->iAcolLeg = particles[iNew].dips.size() - 1;
1523 dip3->isAntiJun =
false;
1525 if (i2 != i0 && i2 != i1)
1526 dip3->iColLeg = particles[iNew].dips.size() - 1;
1530 for (
int i = 0; i < int(particles[iNew].activeDips.size()); ++i) {
1532 for (
int j = 0;j < int(usedDipoles.size()); ++j)
1533 if (particles[iNew].activeDips[i] == usedDipoles[j]) {
1537 if (!added) usedDipoles.push_back(particles[iNew].activeDips[i]);
1539 usedDipoles.push_back(dip);
1540 usedDipoles.push_back(dip2);
1541 usedDipoles.push_back(dip3);
1545 if (setupDone && mDip(dip3) < m0)
1546 makePseudoParticle(dip3, status,
true);
1557 bool sortFunc(ColourDipole* a, ColourDipole* b) {
1558 return (a->p1p2 < b->p1p2);
1565 void ColourReconnection::makeAllPseudoParticles(
Event & event,
int iFirst) {
1568 for (
int i = 0; i <
event.sizeJunction(); ++i)
1569 junctions.push_back(event.getJunction(i));
1572 int oldSize = int(dipoles.size());
1573 for (
int i = 0; i < oldSize; ++i) {
1574 dipoles.push_back(
new ColourDipole(*dipoles[i]));
1575 dipoles[i + oldSize]->iColLeg = 0;
1576 dipoles[i + oldSize]->iAcolLeg = 0;
1577 dipoles[i]->iColLeg = 0;
1578 dipoles[i]->iAcolLeg = 0;
1579 dipoles[i]->isActive =
false;
1580 dipoles[i]->isReal =
true;
1581 dipoles[i + oldSize]->isReal =
false;
1586 if (dipoles[i]->iCol < 0) {
1587 junctions[-(dipoles[i]->iCol / 10 + 1)].dipsOrig
1588 [min(2, (-dipoles[i]->iCol) % 10)] = dipoles[i];
1590 if (dipoles[i]->iAcol < 0) {
1591 junctions[-(dipoles[i]->iAcol / 10 + 1)].dipsOrig
1592 [min(2, -(dipoles[i]->iAcol % 10))] = dipoles[i];
1597 for (
int i = 0; i < oldSize; ++i) {
1598 if (dipoles[i]->leftDip != 0)
1599 for (
int j = 0; j < oldSize; ++j)
1600 if (dipoles[i]->leftDip == dipoles[j]) {
1601 dipoles[i + oldSize]->colDips.push_back(dipoles[j + oldSize]);
1605 if (dipoles[i]->rightDip != 0)
1606 for (
int j = 0; j < oldSize; ++j)
1607 if (dipoles[i]->rightDip == dipoles[j]) {
1608 dipoles[i + oldSize]->acolDips.push_back(dipoles[j + oldSize]);
1615 for (
int i = iFirst; i <
event.size(); ++i)
1616 if (event[i].isFinal()) {
1617 particles.push_back(ColourParticle(event[i]));
1618 particles.back().dips.resize(1,vector<ColourDipole *>());
1621 for (
int j = 0; j < int(dipoles.size()); ++j) {
1622 if (dipoles[j]->iCol == i) {
1623 if (dipoles[j]->isActive) {
1624 dipoles[j]->iCol = particles.size() - 1;
1625 particles.back().activeDips.push_back(dipoles[j]);
1627 else particles.back().dips[0].push_back(dipoles[j]);
1630 if (dipoles[j]->iAcol == i) {
1631 if (dipoles[j]->isActive) {
1632 dipoles[j]->iAcol = particles.size() - 1;
1633 particles.back().activeDips.push_back(dipoles[j]);
1635 else particles.back().dips[0].insert(particles.back().dips[0].begin(),
1641 if (event[i].isQuark() &&
event[i].id() > 0)
1642 particles.back().colEndIncluded.push_back(
true);
1643 else particles.back().colEndIncluded.push_back(
false);
1645 if (event[i].isQuark() && event[i].
id() < 0)
1646 particles.back().acolEndIncluded.push_back(
true);
1647 else particles.back().acolEndIncluded.push_back(
false);
1656 for (
int i = 0; i < int(dipoles.size()); ++i) {
1657 if (dipoles[i]->iCol < 0) {
1658 int j = (- dipoles[i]->iCol / 10) - 1;
1659 int jLeg = - dipoles[i]->iCol % 10;
1660 junctions[j].setColDip(jLeg, dipoles[i]);
1662 if (dipoles[i]->iAcol < 0) {
1663 int j = (- dipoles[i]->iAcol / 10) - 1;
1664 int jLeg = - dipoles[i]->iAcol % 10;
1665 junctions[j].setColDip(jLeg, dipoles[i]);
1670 for (
int i = 0; i < int(dipoles.size()); ++i) {
1671 if (dipoles[i]->isActive)
1672 dipoles[i]->p1p2 = mDip(dipoles[i]);
1674 dipoles[i]->p1p2 = 1e9;
1679 sort(dipoles.begin(), dipoles.end(), sortFunc);
1680 bool finished =
true;
1681 for (
int i = 0; i < int(dipoles.size()); ++i) {
1682 if (!dipoles[i]->isActive)
continue;
1683 if (dipoles[i]->p1p2 < m0) {
1684 makePseudoParticle( dipoles[i], 110);
1690 if (finished)
break;
1694 sort(dipoles.begin(), dipoles.end(), sortFunc);
1706 void ColourReconnection::checkRealDipoles(
Event& event,
int iFirst) {
1707 vector<int> dipConnections(event.size(),0);
1708 for (
int i = 0;i < int(dipoles.size()); ++i)
1709 if (dipoles[i]->isReal) {
1710 if (dipoles[i]->iCol >= 0)
1711 dipConnections[dipoles[i]->iCol]++;
1712 if (dipoles[i]->iAcol >= 0)
1713 dipConnections[dipoles[i]->iAcol]++;
1715 bool working =
true;
1716 for (
int i = iFirst ;i <
event.size(); ++i) {
1717 if (event[i].isFinal()) {
1718 if (event[i].isQuark() && dipConnections[i] != 1) {
1719 cout <<
"quark " << i <<
" is wrong!!" << endl;
1722 else if (event[i].idAbs() == 21 && dipConnections[i] != 2) {
1723 cout <<
"gluon " << i <<
" is wrong!!" << endl;
1729 infoPtr->errorMsg(
"Error in ColourReconnection::checkRealDipoles:"
1730 "Real dipoles not setup properply");
1740 void ColourReconnection::checkDipoles() {
1742 for (
int i = 0;i < int(dipoles.size()); ++i) {
1743 if (dipoles[i] == 0) { cout <<
"dipole empty" << endl;}
1744 if (dipoles[i]->isActive) {
1745 if (dipoles[i]->iCol >= 0) {
1746 bool foundMyself =
false;
1747 for (
int j = 0; j < int(particles[ dipoles[i]->iCol ].
1748 activeDips.size()); ++j) {
1749 if (!particles[dipoles[i]->iCol].activeDips[j]->isActive) {
1750 infoPtr->errorMsg(
"Error in ColourReconnection::checkDipoles:"
1751 "Found inactive dipole, where only active was expected");
1753 if (particles[dipoles[i]->iCol].activeDips[j] == dipoles[i])
1758 infoPtr->errorMsg(
"Error in ColourReconnection::checkDipoles:"
1759 "Linking between active dipoles and particles is wrong");
1761 if (dipoles[i]->iColLeg
1762 >=
int(particles[dipoles[i]->iCol].dips.size())) {
1763 infoPtr->errorMsg(
"Error in ColourReconnection::checkDipoles:"
1764 "Original dipoles not stored correct");
1768 if (dipoles[i]->col !=
1769 particles[dipoles[i]->iCol].dips[dipoles[i]->iColLeg].back()->col) {
1770 infoPtr->errorMsg(
"Error in ColourReconnection::checkDipoles:"
1771 "Original dipoles do not match in");
1775 if (dipoles[i]->iAcol >= 0) {
1776 bool foundMyself =
false;
1777 for (
int j = 0;j < int(particles[ dipoles[i]->iAcol ].
1778 activeDips.size()); ++j) {
1780 if (!particles[dipoles[i]->iAcol].activeDips[j]->isActive) {
1781 infoPtr->errorMsg(
"Error in ColourReconnection::checkDipoles:"
1782 "Found inactive dipole, where only active was expected");
1784 if (particles[dipoles[i]->iAcol].activeDips[j] == dipoles[i])
1789 infoPtr->errorMsg(
"Error in ColourReconnection::checkDipoles:"
1790 "Linking between active dipoles and particles is wrong");
1792 if (dipoles[i]->iAcolLeg >=
int(particles[dipoles[i]->iAcol].
1794 infoPtr->errorMsg(
"Error in ColourReconnection::checkDipoles:"
1795 "Original dipoles not stored correct");
1799 if (dipoles[i]->col != particles[dipoles[i]->iAcol].
1800 dips[dipoles[i]->iAcolLeg].front()->col) {
1801 infoPtr->errorMsg(
"Error in ColourReconnection::checkDipoles:"
1802 "Original dipoles do not match in");
1813 void ColourReconnection::listAllChains() {
1815 cout <<
" ----- PRINTING CHAINS ----- " << dipoles.size() << endl;
1816 for (
int i = 0; i < int(dipoles.size()); ++i)
1817 dipoles[i]->printed =
false;
1819 for (
int i = 0;i < int(dipoles.size()); ++i)
1820 if (!dipoles[i]->printed)
1821 listChain(dipoles[i]);
1822 cout <<
" ----- PRINTED CHAINS ----- " << endl;
1830 void ColourReconnection::listChain(ColourDipole *dip) {
1833 if (dip == 0)
return;
1836 if (!dip->isActive) {
1840 ColourDipole * colDip = dip;
1843 while (particles[colDip->iCol].dips.size() == 1 && findColNeighbour(colDip))
1847 ColourDipole * endDip = colDip;
1849 cout << colDip->iCol <<
" (" << colDip->p1p2 <<
", " << colDip->col
1850 <<
") (" << colDip->isActive <<
") ";
1851 colDip->printed =
true;
1854 while (particles[colDip->iAcol].dips.size() == 1 && findAntiNeighbour(colDip)
1855 && colDip != endDip);
1858 cout << colDip->iAcol<< endl;
1867 bool ColourReconnection::getJunctionIndices(ColourDipole * dip,
int &iJun,
1868 int &i0,
int &i1,
int &i2,
int &junLeg0,
int &junLeg1,
int &junLeg2) {
1871 int indxJun = dip->iCol;
1873 indxJun = dip->iAcol;
1874 iJun = (- indxJun / 10) - 1;
1875 junLeg0 = -(indxJun % 10);
1878 if (junLeg0 == 1) junLeg1 = 0;
1879 else if (junLeg0 == 2) junLeg2 = 0;
1881 if (dip->iCol < 0) {
1883 i1 = junctions[iJun].dips[junLeg1]->iAcol;
1884 i2 = junctions[iJun].dips[junLeg2]->iAcol;
1888 i1 = junctions[iJun].dips[junLeg1]->iCol;
1889 i2 = junctions[iJun].dips[junLeg2]->iCol;
1894 if (i1 < 0 && i2 < 0)
return false;
1897 double m1 = 1e9, m2 = 1e9;
1899 m1 = m(particles[i0].p(),particles[i1].p());
1901 m2 = m(particles[i0].p(),particles[i2].p());
1905 swap(junLeg1,junLeg2);
1910 swap(junLeg1,junLeg2);
1921 bool ColourReconnection::checkTimeDilation(ColourDipole * dip1,
1922 ColourDipole * dip2, ColourDipole * dip3, ColourDipole * dip4) {
1924 if (timeDilationMode == 0)
return true;
1928 Vec4 p1 = getDipoleMomentum(dip1);
1929 Vec4 p2 = getDipoleMomentum(dip2);
1930 double t1 = formationTimes[dip1->col];
1931 double t2 = formationTimes[dip2->col];
1932 if (dip1 == dip2)
return true;
1933 else return checkTimeDilation(p1, p2, t1, t2);
1936 }
else if (dip4 == 0) {
1937 Vec4 p1 = getDipoleMomentum(dip1);
1938 Vec4 p2 = getDipoleMomentum(dip2);
1939 Vec4 p3 = getDipoleMomentum(dip3);
1940 double t1 = formationTimes[dip1->col];
1941 double t2 = formationTimes[dip2->col];
1942 double t3 = formationTimes[dip3->col];
1944 if (timeDilationMode == 1 || timeDilationMode == 2 ||
1945 timeDilationMode == 4) {
1946 if (dip1 != dip2 && !checkTimeDilation(p1, p2, t1, t2))
return false;
1947 if (dip1 != dip3 && !checkTimeDilation(p1, p3, t1, t3))
return false;
1948 if (dip2 != dip3 && !checkTimeDilation(p2, p3, t2, t3))
return false;
1952 if (dip1 != dip2 && checkTimeDilation(p1, p2, t1, t2))
return true;
1953 if (dip1 != dip3 && checkTimeDilation(p1, p3, t1, t3))
return true;
1954 if (dip2 != dip3 && checkTimeDilation(p2, p3, t2, t3))
return true;
1960 Vec4 p1 = getDipoleMomentum(dip1);
1961 Vec4 p2 = getDipoleMomentum(dip2);
1962 Vec4 p3 = getDipoleMomentum(dip3);
1963 Vec4 p4 = getDipoleMomentum(dip4);
1964 double t1 = formationTimes[dip1->col];
1965 double t2 = formationTimes[dip2->col];
1966 double t3 = formationTimes[dip3->col];
1967 double t4 = formationTimes[dip4->col];
1969 if (timeDilationMode == 1 || timeDilationMode == 2 ||
1970 timeDilationMode == 4) {
1971 if (dip1 != dip2 && !checkTimeDilation(p1, p2, t1, t2))
return false;
1972 if (dip1 != dip3 && !checkTimeDilation(p1, p3, t1, t3))
return false;
1973 if (dip1 != dip4 && !checkTimeDilation(p1, p4, t1, t4))
return false;
1974 if (dip2 != dip3 && !checkTimeDilation(p2, p3, t2, t3))
return false;
1975 if (dip2 != dip4 && !checkTimeDilation(p2, p4, t2, t4))
return false;
1976 if (dip3 != dip4 && !checkTimeDilation(p3, p4, t3, t4))
return false;
1980 if (dip1 != dip2 && checkTimeDilation(p1, p2, t1, t2))
return true;
1981 if (dip1 != dip3 && checkTimeDilation(p1, p3, t1, t3))
return true;
1982 if (dip1 != dip4 && checkTimeDilation(p1, p4, t1, t4))
return true;
1983 if (dip2 != dip3 && checkTimeDilation(p2, p3, t2, t3))
return true;
1984 if (dip2 != dip4 && checkTimeDilation(p2, p4, t2, t4))
return true;
1985 if (dip3 != dip4 && checkTimeDilation(p3, p4, t3, t4))
return true;
1997 Vec4 ColourReconnection::getDipoleMomentum(ColourDipole * dip) {
1998 vector<int> iPar, usedJuncs;
1999 if (!dip->isJun) iPar.push_back(dip->iAcol);
2000 else addJunctionIndices(dip->iAcol, iPar, usedJuncs);
2001 if (!dip->isAntiJun) iPar.push_back(dip->iCol);
2002 else addJunctionIndices(dip->iCol, iPar, usedJuncs);
2005 sort(iPar.begin(),iPar.end());
2006 for (
int i = 0;i < int(iPar.size()) - 1; ++i)
2007 if (iPar[i] == iPar[i+1]) {
2008 iPar.erase(iPar.begin()+i);
2012 if (iPar.size() == 0) {
2013 infoPtr->errorMsg(
"Error in ColourReconnection::getDipoleMomentum: "
2014 "No particles connected to junction.");
2015 return Vec4(0,0,0,0);
2018 Vec4 p = particles[iPar[0]].p();
2019 for (
int i = 1;i < int(iPar.size()); ++i)
2020 p += particles[iPar[i]].p();
2029 bool ColourReconnection::checkTimeDilation(Vec4 p1,
2030 Vec4 p2,
double t1,
double t2) {
2032 if (timeDilationMode == 0)
return true;
2035 else if (timeDilationMode == 1) {
2037 if (p2.e() / p2.mCalc() > timeDilationPar)
return false;
2041 }
else if (timeDilationMode == 2) {
2044 if (p2.e() / p2.mCalc() > timeDilationParGeV * p2.mCalc()) part1 =
false;
2048 if (p1.e() / p1.mCalc() > timeDilationParGeV * p1.mCalc()) part2 =
false;
2050 if (part1 && part2)
return true;
2054 }
else if (timeDilationMode == 3) {
2057 if (p2.e() / p2.mCalc() > timeDilationParGeV * p2.mCalc()) part1 =
false;
2061 if (p1.e() / p1.mCalc() > timeDilationParGeV * p1.mCalc()) part2 =
false;
2063 if (part1 || part2)
return true;
2067 }
else if (timeDilationMode == 4) {
2069 if (p2.e() / p2.mCalc() < timeDilationParGeV * min(t1,t2))
return true;
2073 }
else if (timeDilationMode == 5) {
2075 if (p2.e() / p2.mCalc() < timeDilationParGeV * max(t1,t2))
return true;
2086 void ColourReconnection::setupFormationTimes(
Event & event) {
2088 for (
int i = 0;i <
event.size(); ++i) {
2090 if (event[i].col() != 0 && formationTimes.count(event[i].col()) == 0) {
2091 int col =
event[i].col();
2093 bool foundCol =
false;
2095 for (
int j = i;j <
event.size(); ++j) {
2096 if (event[j].acol() == col) {
2105 formationTimes[col] = max( m0,
2106 (event[i].p() + event[iAcol].p()).mCalc() );
2109 formationTimes[col] = max(m0, getJunctionMass(event, col));
2114 if (event[i].acol() != 0 && formationTimes.count(event[i].acol()) == 0) {
2115 int acol =
event[i].acol();
2117 bool foundCol =
false;
2119 for (
int j = i;j <
event.size(); ++j) {
2120 if (event[j].col() == acol) {
2129 formationTimes[acol] = max(m0, (event[i].p() + event[iCol].p())
2133 formationTimes[acol] = max(m0, getJunctionMass(event, acol));
2139 for (
int i = 0; i <
event.sizeJunction(); ++i)
2140 for (
int j = 0; j < 3; ++j)
2141 if (formationTimes.count(event.colJunction(i,j)) == 0)
2142 formationTimes[
event.colJunction(i,j)] = max(m0,
2143 getJunctionMass(event, event.colJunction(i,j)));
2152 double ColourReconnection::getJunctionMass(
Event & event,
int col) {
2155 vector<int> iPar, usedJuncs;
2156 addJunctionIndices(event, col, iPar, usedJuncs);
2159 sort(iPar.begin(), iPar.end());
2160 for (
int i = 0;i < int(iPar.size() -1); ++i) {
2161 if (iPar[i] == iPar[i + 1]) {
2162 iPar.erase(iPar.begin() + i);
2169 if (
int(iPar.size()) == 0)
return 0;
2171 Vec4 p =
event[iPar[0]].p();
2172 for (
int i = 1; i < int(iPar.size()); ++i)
2173 p += event[iPar[i]].p();
2184 void ColourReconnection::addJunctionIndices(
Event & event,
int col,
2185 vector<int> &iPar, vector<int> &usedJuncs) {
2189 for (
int j = 0;j <
event.sizeJunction(); ++j) {
2190 for (
int k = 0; k < 3; ++k) {
2191 if (event.colJunction(j,k) == col) {
2199 for (
int i = 0;i < int(juncs.size()); ++i) {
2200 for (
int j = 0;j < int(usedJuncs.size()); ++j) {
2201 if (juncs[i] == usedJuncs[j]) {
2202 juncs.erase(juncs.begin() + i);
2210 if (juncs.size() == 0)
return;
2213 for (
int i = 0;i < int(juncs.size()); ++i)
2214 usedJuncs.push_back(juncs[i]);
2217 for (
int iJunc = 0; iJunc < int(juncs.size()); ++iJunc) {
2218 int iTempPars[3] = {-1,-1,-1};
2219 int cols[3] = {
event.colJunction(juncs[iJunc],0),
2220 event.colJunction(juncs[iJunc],1),
event.colJunction(juncs[iJunc],2)};
2223 for (
int i = 0;i <
event.size(); ++i) {
2224 for (
int j = 0;j < 3; ++j) {
2225 if (iTempPars[j] == -1 && event.kindJunction(juncs[iJunc]) % 2 == 1 &&
2226 event[i].col() == cols[j]) iTempPars[j] = i;
2227 if (iTempPars[j] == -1 && event.kindJunction(juncs[iJunc]) % 2 == 0 &&
2228 event[i].acol() == cols[j]) iTempPars[j] = i;
2232 for (
int i = 0;i < 3;++i) {
2233 if (iTempPars[i] >= 0) iPar.push_back(iTempPars[i]);
2234 else addJunctionIndices(event, cols[i], iPar, usedJuncs);
2245 void ColourReconnection::addJunctionIndices(
int iSinglePar, vector<int> &iPar,
2246 vector<int> &usedJuncs) {
2249 int iJun = -(1 + iSinglePar/10);
2250 for (
int i = 0;i < int(usedJuncs.size()); ++i)
2251 if (iJun == usedJuncs[i])
return;
2254 usedJuncs.push_back(iJun);
2255 for (
int i = 0; i < 3; ++i)
2256 if (junctions[iJun].kind() % 2 == 1) {
2257 int iCol = junctions[iJun].dips[i]->iCol;
2258 if (iCol >= 0) iPar.push_back(iCol);
2259 else addJunctionIndices(iCol, iPar, usedJuncs);
2261 int iAcol = junctions[iJun].dips[i]->iAcol;
2262 if (iAcol >= 0) iPar.push_back(iAcol);
2263 else addJunctionIndices(iAcol, iPar, usedJuncs);
2271 double ColourReconnection::mDip(ColourDipole* dip) {
2274 if (dip->isJun && dip->isAntiJun)
return 1e9;
2276 else if (dip->isJun || dip->isAntiJun) {
2277 int iJun, i0, i1, i2, junLeg0, junLeg1, junLeg2;
2278 getJunctionIndices(dip, iJun, i0, i1, i2, junLeg0, junLeg1, junLeg2);
2280 return particles[i0].m();
2283 return m(particles[i0].p(),particles[i1].p());
2286 if (dip->iCol == dip->iAcol)
2287 return particles[dip->iCol].m();
2289 return m(particles[dip->iCol].p(),particles[dip->iAcol].p());
2298 void ColourReconnection::listDipoles(
bool onlyActive,
bool onlyReal) {
2300 cout <<
" --- listing dipoles ---" << endl;
2301 for (
int i = 0; i < int(dipoles.size()); ++i) {
2302 if (onlyActive && !dipoles[i]->isActive)
2304 if (onlyReal && !dipoles[i]->isReal)
2308 cout <<
" --- finished listing ---" << endl;
2316 void ColourReconnection::listParticles() {
2318 for (
int i = 0; i < int(particles.size()); ++i) {
2319 const ColourParticle& pt = particles[i];
2322 cout << setw(6) << i << setw(10) << pt.id() <<
" " << left
2323 << setw(18) << pt.nameWithStatus(18) << right << setw(4)
2324 << pt.status() << setw(6) << pt.mother1() << setw(6)
2325 << pt.mother2() << setw(6) << pt.daughter1() << setw(6)
2326 << pt.daughter2() << setw(6) << pt.col() << setw(6) << pt.acol()
2328 << setw(11) << pt.px() << setw(11) << pt.py() << setw(11)
2329 << pt.pz() << setw(11) << pt.e() << setw(11) << pt.m();
2330 for (
int j = 0;j < int(pt.activeDips.size());++j)
2331 cout << setw(10) << pt.activeDips[j];
2341 void ColourReconnection::listJunctions() {
2343 cout <<
" --- listing junctions ---" << endl;
2344 for (
int i = 0; i < int(junctions.size()); ++i)
2345 junctions[i].list();
2346 cout <<
" --- finished listing ---" << endl;
2359 bool ColourReconnection::reconnectMPIs(
Event& event,
int oldSize) {
2362 BeamParticle& beamA = *beamAPtr;
2363 BeamParticle& beamB = *beamBPtr;
2367 nSys = partonSystemsPtr->sizeSys();
2368 vector<int> iMerge(nSys);
2369 vector<bool> hasColour(nSys);
2370 for (
int iSys = 0; iSys < nSys; ++iSys) {
2371 iMerge[iSys] = iSys;
2372 bool hasCol =
false;
2373 for (
int iMem = 0; iMem < partonSystemsPtr->sizeOut(iSys); ++iMem) {
2374 int iNow = partonSystemsPtr->getOut( iSys, iMem);
2375 if (event[iNow].isFinal() && (event[iNow].col() > 0
2376 || event[iNow].acol() > 0) ) {
2381 hasColour[iSys] = hasCol;
2385 for (
int iRec = nSys - 1; iRec > 0; --iRec) {
2388 double pT2Rec = pow2( partonSystemsPtr->getPTHat(iRec) );
2389 double probRec = pT20Rec / (pT20Rec + pT2Rec);
2393 for (
int iSys = iRec - 1; iSys >= 0; --iSys)
2394 if (hasColour[iSys] && probRec > rndmPtr->flat()) {
2397 iMerge[iRec] = iSys;
2398 for (
int iRec2 = iRec + 1; iRec2 < nSys; ++iRec2)
2399 if (iMerge[iRec2] == iRec) iMerge[iRec2] = iSys;
2407 for (
int iSys = 0; iSys < nSys; ++iSys) {
2409 for (
int iRec = iSys + 1; iRec < nSys; ++iRec)
2410 if (iMerge[iRec] == iSys) ++nMerge;
2411 if (nMerge == 0)
continue;
2414 int iInASys = partonSystemsPtr->getInA(iSys);
2415 bool hasInA = (beamA[iSys].isFromBeam());
2416 int iInBSys = partonSystemsPtr->getInB(iSys);
2417 bool hasInB = (beamB[iSys].isFromBeam());
2420 vector<BeamDipole> bmdipoles;
2421 int sizeOut = partonSystemsPtr->sizeOut(iSys);
2422 for (
int iMem = 0; iMem < sizeOut; ++iMem) {
2425 int iNow = partonSystemsPtr->getOut( iSys, iMem);
2426 if (!event[iNow].isFinal())
continue;
2427 int col =
event[iNow].col();
2429 if (hasInA && event[iInASys].col() == col)
2430 bmdipoles.push_back( BeamDipole( col, iNow, iInASys ) );
2431 else if (hasInB && event[iInBSys].col() == col)
2432 bmdipoles.push_back( BeamDipole( col, iNow, iInBSys ) );
2435 else for (
int iMem2 = 0; iMem2 < sizeOut; ++iMem2)
2436 if (iMem2 != iMem) {
2437 int iNow2 = partonSystemsPtr->getOut( iSys, iMem2);
2438 if (!event[iNow2].isFinal())
continue;
2439 if (event[iNow2].acol() == col) {
2440 bmdipoles.push_back( BeamDipole( col, iNow, iNow2) );
2447 int acol =
event[iNow].acol();
2449 if (hasInA && event[iInASys].acol() == acol)
2450 bmdipoles.push_back( BeamDipole( acol, iInASys, iNow ) );
2451 else if (hasInB && event[iInBSys].acol() == acol)
2452 bmdipoles.push_back( BeamDipole( acol, iInBSys, iNow ) );
2457 if (bmdipoles.size() == 0)
continue;
2460 for (
int iDip = 0; iDip < int(bmdipoles.size()); ++iDip)
2461 bmdipoles[iDip].p1p2 = event[bmdipoles[iDip].iCol].p()
2462 *
event[bmdipoles[iDip].iAcol].p();
2465 for (
int iRec = iSys + 1; iRec < nSys; ++iRec) {
2466 if (iMerge[iRec] != iSys)
continue;
2469 int sizeRec = partonSystemsPtr->sizeOut(iRec);
2470 int iInARec = partonSystemsPtr->getInA(iRec);
2471 int iInBRec = partonSystemsPtr->getInB(iRec);
2473 vector<int> iGluRec;
2474 vector<double> pT2GluRec;
2476 vector<int> iAnyRec;
2477 vector<bool> freeAnyRec;
2480 for (
int iMem = 0; iMem < sizeRec; ++iMem) {
2481 int iNow = partonSystemsPtr->getOut( iRec, iMem);
2482 if (!event[iNow].isFinal())
continue;
2483 if (event[iNow].isGluon()) {
2485 iGluRec.push_back( iNow );
2486 pT2GluRec.push_back( event[iNow].pT2() );
2487 for (
int i = nGluRec - 1; i > 1; --i) {
2488 if (pT2GluRec[i - 1] > pT2GluRec[i])
break;
2489 swap( iGluRec[i - 1], iGluRec[i] );
2490 swap( pT2GluRec[i - 1], pT2GluRec[i] );
2495 iAnyRec.push_back( iNow );
2496 freeAnyRec.push_back(
true );
2502 for (
int iGRec = 0; iGRec < nGluRec; ++iGRec) {
2503 int iGlu = iGluRec[iGRec];
2504 Vec4 pGlu =
event[iGlu].p();
2506 double pT2DipMin = sCM;
2507 for (
int iDip = 0; iDip < int(bmdipoles.size()); ++iDip)
2508 if (bmdipoles[iDip].p1p2 > TINYP1P2) {
2509 double pT2Dip = (pGlu *
event[bmdipoles[iDip].iCol].p())
2510 * (pGlu * event[bmdipoles[iDip].iAcol].p()) / bmdipoles[iDip].p1p2;
2511 if (pT2Dip < pT2DipMin) {
2518 int colGlu =
event[iGlu].col();
2519 int acolGlu =
event[iGlu].acol();
2520 int colDip = bmdipoles[iDipMin].col;
2521 int iColDip = bmdipoles[iDipMin].iCol;
2522 int iAcolDip = bmdipoles[iDipMin].iAcol;
2523 event[iGlu].acol( colDip );
2524 if (event[iAcolDip].acol() == colDip)
2525 event[iAcolDip].acol( colGlu );
2526 else event[iAcolDip].col( colGlu );
2527 bmdipoles[iDipMin].iAcol = iGlu;
2528 bmdipoles[iDipMin].p1p2 =
event[iColDip].p() * pGlu;
2529 bmdipoles.push_back( BeamDipole( colGlu, iGlu, iAcolDip ) );
2530 bmdipoles.back().p1p2 = pGlu *
event[iAcolDip].p();
2533 for (
int i = oldSize; i <
event.size(); ++i)
2534 if (i != iGlu && i != iAcolDip) {
2535 if (event[i].isFinal()) {
2536 if (event[i].acol() == colGlu) event[i].acol( acolGlu );
2538 if (event[i].col() == colGlu) event[i].col( acolGlu );
2543 for (
int iJun = 0; iJun <
event.sizeJunction(); ++iJun) {
2546 if (event.kindJunction(iJun) % 2 == 0)
continue;
2547 for (
int leg = 0; leg < 3; ++leg) {
2548 int col =
event.colJunction(iJun, leg);
2550 event.colJunction(iJun, leg, colGlu);
2557 for (
int iQRec = 0; iQRec < nAnyRec; ++iQRec) {
2558 int iQ = iAnyRec[iQRec];
2559 int idQ =
event[iQ].id();
2560 if (freeAnyRec[iQRec] && idQ > 0 && idQ < 6)
2561 for (
int iQbarRec = 0; iQbarRec < nAnyRec; ++iQbarRec) {
2562 int iQbar = iAnyRec[iQbarRec];
2563 if (freeAnyRec[iQbarRec] && event[iQbar].
id() == -idQ) {
2567 int iTopQ =
event[iQ].iTopCopyId();
2568 int iTopQbar =
event[iQbar].iTopCopyId();
2569 int iMother =
event[iTopQ].mother1();
2570 if (event[iTopQbar].mother1() == iMother
2571 && event[iMother].isGluon() && event[iMother].status() != -34
2572 && event[iMother + 1].status() != -34 ) {
2576 Vec4 pGlu =
event[iQ].p() +
event[iQbar].p();
2578 double pT2DipMin = sCM;
2579 for (
int iDip = 0; iDip < int(bmdipoles.size()); ++iDip) {
2580 double pT2Dip = (pGlu *
event[bmdipoles[iDip].iCol].p())
2581 * (pGlu * event[bmdipoles[iDip].iAcol].p())
2582 / bmdipoles[iDip].p1p2;
2583 if (pT2Dip < pT2DipMin) {
2590 int colGlu =
event[iQ].col();
2591 int acolGlu =
event[iQbar].acol();
2592 int colDip = bmdipoles[iDipMin].col;
2593 int iColDip = bmdipoles[iDipMin].iCol;
2594 int iAcolDip = bmdipoles[iDipMin].iAcol;
2595 event[iQbar].acol( colDip );
2596 if (event[iAcolDip].acol() == colDip)
2597 event[iAcolDip].acol( colGlu );
2598 else event[iAcolDip].col( colGlu );
2599 bmdipoles[iDipMin].iAcol = iQbar;
2600 bmdipoles[iDipMin].p1p2 =
event[iColDip].p() *
event[iQbar].p();
2601 bmdipoles.push_back( BeamDipole( colGlu, iQ, iAcolDip ) );
2602 bmdipoles.back().p1p2 =
event[iQ].p() *
event[iAcolDip].p();
2605 freeAnyRec[iQRec] =
false;
2606 freeAnyRec[iQbarRec] =
false;
2607 for (
int i = oldSize; i <
event.size(); ++i)
2608 if (i != iQRec && i != iQbarRec && i != iColDip
2610 if (event[i].isFinal()) {
2611 if (event[i].acol() == colGlu) event[i].acol( acolGlu );
2613 if (event[i].col() == colGlu) event[i].col( acolGlu );
2618 for (
int iJun = 0; iJun <
event.sizeJunction(); ++iJun) {
2621 if (event.kindJunction(iJun) % 2 == 0)
continue;
2622 for (
int leg = 0; leg < 3; ++leg) {
2623 int col =
event.colJunction(iJun, leg);
2625 event.colJunction(iJun, leg, colGlu);
2637 if ( event[iInARec].isGluon() && !event[iInARec].isRescatteredIncoming()
2638 && event[iInBRec].isGluon() && !event[iInBRec].isRescatteredIncoming()
2639 && event[iInARec].col() == event[iInBRec].acol()
2640 && event[iInARec].acol() == event[iInBRec].col() ) {
2641 event[iInARec].acol( event[iInARec].col() );
2642 event[iInBRec].acol( event[iInBRec].col() );
2658 bool ColourReconnection::findAntiNeighbour(ColourDipole*& dip) {
2660 if (
int(particles[dip->iAcol].activeDips.size()) == 1)
2664 if (
int(particles[dip->iAcol].activeDips.size()) != 2) {
2665 infoPtr->errorMsg(
"Warning in ColourReconnection::findAntiNeighbour: "
2666 "Wrong number of active dipoles");
2671 if (dip == particles[dip->iAcol].activeDips[0])
2672 dip = particles[dip->iAcol].activeDips[1];
2673 else dip = particles[dip->iAcol].activeDips[0];
2676 if (dip->isAntiJun || dip->isJun)
2681 if (
int(particles[dip->iAcol].dips.size()) != 1)
2691 bool ColourReconnection::checkJunctionTrials() {
2692 for (
int i = 0;i < int(junTrials.size());++i) {
2694 if (junTrials[i].mode == 3)
2696 for (
int j = 0;j < int(junTrials[i].dips.size()) - minus; ++j) {
2697 ColourDipole* dip = junTrials[i].dips[j];
2698 if (dip->isJun || dip->isAntiJun) {
2699 junTrials[i].list();
2702 if (particles[dip->iCol].dips.size() != 1 ||
2703 particles[dip->iAcol].dips.size() != 1) {
2704 junTrials[i].list();
2718 bool ColourReconnection::findColNeighbour(ColourDipole*& dip) {
2720 if (
int(particles[dip->iCol].activeDips.size()) == 1)
2724 if (
int(particles[dip->iCol].activeDips.size()) != 2) {
2725 infoPtr->errorMsg(
"Warning in ColourReconnection::findAntiNeighbour: "
2726 "Wrong number of active dipoles");
2730 if (dip == particles[dip->iCol].activeDips[0])
2731 dip = particles[dip->iCol].activeDips[1];
2732 else dip = particles[dip->iCol].activeDips[0];
2735 if (dip->isJun || dip->isAntiJun)
2740 if (
int(particles[dip->iCol].dips.size()) != 1)
2750 void ColourReconnection::storeUsedDips(TrialReconnection& trial) {
2752 if (trial.mode == 5) {
2754 for (
int i = 0;i < 2; ++i) {
2755 ColourDipole* dip = trial.dips[i];
2757 for (
int j = 0;j < 3; ++j)
2758 usedDipoles.push_back(junctions[-(dip->iCol / 10 + 1)].getColDip(j));
2760 for (
int j = 0;j < 3; ++j)
2761 usedDipoles.push_back(junctions[-(dip->iAcol / 10 + 1)].getColDip(j));
2763 usedDipoles.push_back(dip);
2768 for (
int i = 0;i < 4; ++i) {
2769 if (trial.mode == 3 && i == 3)
2771 usedDipoles.push_back(trial.dips[i]);
2772 ColourDipole* dip = trial.dips[i];
2775 while (findAntiNeighbour(dip) && dip != trial.dips[i])
2776 usedDipoles.push_back(dip);
2778 dip = trial.dips[i];
2779 while (findColNeighbour(dip) && dip != trial.dips[i])
2780 usedDipoles.push_back(dip);
2789 double ColourReconnection::getLambdaDiff(ColourDipole* dip1,
2790 ColourDipole* dip2) {
2793 vector<ColourDipole*> oldDips, newDips;
2796 double oldLambda = calculateStringLength(dip1, oldDips)
2797 + calculateStringLength( dip2, oldDips);
2800 swapDipoles(dip1,dip2);
2803 double newLambda = calculateStringLength(dip1, newDips)
2804 + calculateStringLength(dip2, newDips);
2807 swapDipoles(dip1, dip2,
true);
2810 if (newLambda >= 0.5E9)
return -1e9;
2813 return oldLambda - newLambda;
2820 double ColourReconnection::getLambdaDiff(ColourDipole* dip1,
2821 ColourDipole* dip2, ColourDipole* dip3, ColourDipole* dip4,
int modeIn) {
2825 double oldLambda = calculateStringLength(dip1->iCol, dip1->iAcol)
2826 + calculateStringLength(dip2->iCol, dip2->iAcol);
2828 oldLambda += calculateStringLength(dip3->iCol, dip3->iAcol);
2829 if (dip4 != 0 && dip4 != dip2)
2830 oldLambda += calculateStringLength(dip4->iCol, dip4->iAcol);
2833 double newLambda = 0;
2836 newLambda = calculateDoubleJunctionLength(dip1->iCol, dip2->iCol,
2837 dip1->iAcol, dip2->iAcol);
2838 else if (modeIn == 1) {
2840 newLambda = calculateJunctionLength(dip1->iCol, dip2->iCol, dip3->iCol)
2841 + calculateJunctionLength(dip1->iAcol, dip2->iAcol, dip3->iAcol);
2843 newLambda = calculateJunctionLength(dip1->iCol, dip2->iCol, dip3->iCol)
2844 + calculateJunctionLength(dip2->iAcol, dip3->iAcol, dip4->iAcol)
2845 + calculateStringLength(dip4->iCol, dip1->iAcol);
2848 else if (modeIn == 2) {
2850 newLambda = calculateJunctionLength(dip1->iCol, dip2->iCol, dip4->iCol)
2851 + calculateJunctionLength(dip1->iAcol, dip2->iAcol, dip4->iAcol);
2853 newLambda = calculateJunctionLength(dip1->iCol, dip2->iCol, dip4->iCol)
2854 + calculateJunctionLength(dip1->iAcol, dip3->iAcol, dip4->iAcol)
2855 + calculateStringLength(dip3->iCol, dip2->iAcol);
2859 else if (modeIn == 3)
2860 newLambda = calculateJunctionLength(dip1->iCol, dip2->iCol, dip3->iCol)
2861 + calculateJunctionLength(dip1->iAcol, dip2->iAcol, dip3->iAcol);
2864 if (newLambda >= 0.5E9)
return -1e9;
2867 return oldLambda - newLambda;
2875 void ColourReconnection::doDipoleTrial(TrialReconnection& trial) {
2878 ColourDipole* dip1 = trial.dips[0];
2879 ColourDipole* dip2 = trial.dips[1];
2882 if (dip1->iAcol >= 0 && dip2->iAcol >= 0) {
2883 swap(particles[dip1->iAcol].dips[dip1->iAcolLeg].front()->iAcol,
2884 particles[dip2->iAcol].dips[dip2->iAcolLeg].front()->iAcol);
2885 swap(particles[dip1->iAcol].dips[dip1->iAcolLeg].front(),
2886 particles[dip2->iAcol].dips[dip2->iAcolLeg].front());
2890 }
else if (dip1->iAcol >= 0) {
2891 swap(particles[dip1->iAcol].dips[dip1->iAcolLeg].front()->iAcol,
2892 junctions[-(dip2->iAcol / 10 + 1)].dipsOrig
2893 [min(2, -dip2->iAcol % 10)]->iAcol);
2894 swap(particles[dip1->iAcol].dips[dip1->iAcolLeg].front(),
2895 junctions[-(dip2->iAcol / 10 + 1)].dipsOrig
2896 [min(2, -dip2->iAcol % 10)]);
2898 }
else if (dip2->iAcol >= 0) {
2899 swap(particles[dip2->iAcol].dips[dip2->iAcolLeg].front()->iAcol,
2900 junctions[-(dip1->iAcol / 10 + 1)].dipsOrig
2901 [min(2, -dip1->iAcol % 10)]->iAcol);
2902 swap(particles[dip2->iAcol].dips[dip2->iAcolLeg].front(),
2903 junctions[-(dip1->iAcol / 10 + 1)].dipsOrig
2904 [min(2, -dip1->iAcol % 10)]);
2907 swap(junctions[ -(dip1->iAcol / 10 + 1) ].dipsOrig
2908 [min(2, -dip1->iAcol % 10)]->iAcol,
2909 junctions[ -(dip2->iAcol / 10 + 1) ].dipsOrig
2910 [min(2, -dip2->iAcol % 10)]->iAcol);
2911 swap(junctions[ -(dip1->iAcol / 10 + 1) ].dipsOrig
2912 [min(2, -dip1->iAcol % 10)],
2913 junctions[ -(dip2->iAcol / 10 + 1) ].dipsOrig
2914 [min(2, -dip2->iAcol % 10)]);
2918 swapDipoles(dip1, dip2);
2921 if (mDip(dip1) < m0) makePseudoParticle(dip1, 110,
true);
2922 if (mDip(dip2) < m0) makePseudoParticle(dip2, 110,
true);
2932 void ColourReconnection::updateDipoleTrials() {
2935 for (
int i = 0; i < int(dipTrials.size()); ++i)
2936 for (
int j = 0;j < 2; ++j) {
2937 if (binary_search(usedDipoles.begin(), usedDipoles.end(),
2938 dipTrials[i].dips[j]) ) {
2939 dipTrials.erase(dipTrials.begin() + i);
2946 vector<ColourDipole*> activeDipoles;
2947 for (
int i = 0;i < int(dipoles.size()); ++i)
2948 if (dipoles[i]->isActive)
2949 activeDipoles.push_back(dipoles[i]);
2952 for (
int i = 0;i < int(usedDipoles.size()); ++i)
2953 if (usedDipoles[i]->isActive)
2954 for (
int j = 0; j < int(activeDipoles.size()); ++j)
2955 singleReconnection(usedDipoles[i], activeDipoles[j]);
2963 void ColourReconnection::updateJunctionTrials() {
2966 for (
int i = 0; i < int(junTrials.size()); ++i)
2967 for (
int j = 0; j < 4; ++j) {
2968 if (binary_search(usedDipoles.begin(), usedDipoles.end(),
2969 junTrials[i].dips[j]) ) {
2970 junTrials.erase(junTrials.begin() + i);
2977 vector<ColourDipole*> activeDipoles;
2978 for (
int i = 0;i < int(dipoles.size()); ++i)
2979 if (dipoles[i]->isActive)
2980 activeDipoles.push_back(dipoles[i]);
2983 for (
int i = 0;i < int(usedDipoles.size()); ++i)
2984 if (usedDipoles[i]->isActive)
2985 for (
int j = 0; j < int(activeDipoles.size()); ++j)
2986 singleJunction(usedDipoles[i], activeDipoles[j]);
2989 for (
int i = 0;i < int(usedDipoles.size()); ++i)
2990 if (usedDipoles[i]->isActive)
2991 for (
int j = 0; j < int(activeDipoles.size()); ++j)
2992 for (
int k = j + 1; k < int(activeDipoles.size()); ++k)
2993 singleJunction(usedDipoles[i], activeDipoles[j], activeDipoles[k]);
3001 void ColourReconnection::doJunctionTrial(
Event& event,
3002 TrialReconnection& juncTrial) {
3004 int jtMode = juncTrial.mode;
3007 doTripleJunctionTrial(event, juncTrial);
3012 ColourDipole* dip1 = juncTrial.dips[0];
3013 ColourDipole* dip2 = juncTrial.dips[1];
3014 ColourDipole* dip3 = juncTrial.dips[2];
3015 ColourDipole* dip4 = juncTrial.dips[3];
3017 int iCol1 = dip1->iCol;
3018 int iCol2 = dip2->iCol;
3019 int iCol3 = dip3->iCol;
3020 int iCol4 = dip4->iCol;
3021 int iAcol1 = dip1->iAcol;
3022 int iAcol2 = dip2->iAcol;
3023 int iAcol3 = dip3->iAcol;
3024 int iAcol4 = dip4->iAcol;
3026 int oldCol1 = dip1->col;
3027 int oldCol2 = dip2->col;
3028 int oldCol3 = dip3->col;
3029 int oldCol4 = dip4->col;
3032 int newCol1 =
event.nextColTag();
3033 int newCol2 =
event.nextColTag();
3034 int newCol3 =
event.nextColTag();
3037 double mCalc = (particles[iCol1].p() + particles[iAcol1].p() +
3038 particles[iCol2].p() + particles[iAcol2].p() +
3039 particles[iCol3].p() + particles[iAcol3].p() +
3040 particles[iCol4].p() + particles[iAcol4].p()).mCalc();
3041 formationTimes[newCol1] = mCalc;
3042 formationTimes[newCol2] = mCalc;
3043 formationTimes[newCol3] = mCalc;
3050 int junCol = 3 * (3 - (dip1->colReconnection / 3)
3051 - (dip2->colReconnection / 3) ) + dip1->colReconnection % 3;
3054 if (nReconCols != 9) {
3055 while (junCol < 0 || junCol % 3 != dip1->colReconnection % 3 ||
3056 junCol == dip1->colReconnection || junCol == dip2->colReconnection)
3057 junCol = int(nReconCols * rndmPtr->flat());
3060 int iJun = junctions.size();
3061 int iAntiJun = junctions.size() + 1;
3064 ColourDipole* dip3real = particles[iCol3].dips[dip3->iColLeg].back();
3065 ColourDipole* dip4real = particles[iCol4].dips[dip4->iColLeg].back();
3068 int iActive1 = 0, iReal1 = 0;
3070 dipoles.push_back(
new ColourDipole(newCol1, -( iAntiJun * 10 + 10 + 2) ,
3071 -( iJun * 10 + 10 + 2), junCol,
true,
true,
false,
true));
3072 iReal1 = dipoles.size() - 1;
3073 dipoles.push_back(
new ColourDipole(newCol1, -( iAntiJun * 10 + 10 + 2) ,
3074 -( iJun * 10 + 10 + 2), junCol,
true,
true));
3075 iActive1 = dipoles.size() - 1;
3076 }
else if (jtMode == 1) {
3077 int iCol3real = particles[iCol3].dips[dip3->iColLeg].back()->iCol;
3078 dipoles.push_back(
new ColourDipole(newCol1, iCol3real ,
3079 -( iJun * 10 + 10 + 2), junCol,
true,
false,
false,
true));
3080 iReal1 = dipoles.size() - 1;
3081 particles[iCol3].dips[dip3->iColLeg].back() = dipoles.back();
3082 dipoles.push_back(
new ColourDipole(newCol1, dip3->iCol,
3083 -( iJun * 10 + 10 + 2), junCol,
true,
false));
3084 iActive1 = dipoles.size() - 1;
3085 }
else if (jtMode == 2) {
3086 int iCol4real = particles[iCol4].dips[dip4->iColLeg].back()->iCol;
3087 dipoles.push_back(
new ColourDipole(newCol1, iCol4real,
3088 -( iJun * 10 + 10 + 2), junCol,
true,
false,
false,
true));
3089 iReal1 = dipoles.size() - 1;
3090 particles[iCol4].dips[dip4->iColLeg].back() = dipoles.back();
3091 dipoles.push_back(
new ColourDipole(newCol1, dip4->iCol,
3092 -( iJun * 10 + 10 + 2), junCol,
true,
false));
3093 iActive1 = dipoles.size() - 1;
3098 int iAcol3real = particles[iAcol3].dips[dip3->iAcolLeg].front()->iAcol;
3099 dipoles.push_back(
new ColourDipole(newCol2, -( iAntiJun * 10 + 10),
3100 iAcol3real, dip3->colReconnection,
false,
true,
false,
true));
3101 int iReal2 = dipoles.size() - 1;
3102 particles[iAcol3].dips[dip3->iAcolLeg].front() = dipoles.back();
3104 dipoles.push_back(
new ColourDipole(newCol2, -( iAntiJun * 10 + 10),
3105 iAcol3, dip3->colReconnection,
false,
true));
3106 dipoles.back()->iAcolLeg = dip3->iAcolLeg;
3107 int iActive2 = dipoles.size() - 1;
3111 int iAcol4real = particles[iAcol4].dips[dip4->iAcolLeg].front()->iAcol;
3112 dipoles.push_back(
new ColourDipole(newCol3, -( iAntiJun * 10 + 10 + 1),
3113 iAcol4real, dip4->colReconnection,
false,
true,
false,
true));
3114 int iReal3 = dipoles.size() - 1;
3115 particles[iAcol4].dips[dip4->iAcolLeg].front() = dipoles.back();
3117 dipoles.push_back(
new ColourDipole(newCol3, -( iAntiJun * 10 + 10 + 1),
3118 iAcol4, dip4->colReconnection,
false,
true));
3119 dipoles.back()->iAcolLeg = dip4->iAcolLeg;
3120 int iActive3 = dipoles.size() - 1;
3129 dip3real->iAcol = particles[dip1->iAcol].dips[dip1->iAcolLeg].
3131 dip3real->iCol = -( iAntiJun * 10 + 10 + 2);
3132 dip3real->isAntiJun =
true;
3135 dip3->iAcol = dip1->iAcol;
3136 dip3->iAcolLeg = dip1->iAcolLeg;
3137 dip3->isAntiJun =
true;
3138 dip3->iCol = -( iAntiJun * 10 + 10 + 2);
3142 particles[dip3->iAcol].dips[dip3->iAcolLeg].front() = dip3real;
3147 dip3real->iAcol = particles[dip2->iAcol].dips[dip2->iAcolLeg].
3149 dip3real->iCol = -( iAntiJun * 10 + 10 + 2);
3150 dip3real->isAntiJun =
true;
3151 dip4real->iAcol = particles[dip1->iAcol].dips[dip1->iAcolLeg].
3155 dip3->iAcol = dip2->iAcol;
3156 dip3->iAcolLeg = dip2->iAcolLeg;
3157 dip3->isAntiJun =
true;
3158 dip3->iCol = -( iAntiJun * 10 + 10 + 2);
3162 dip4->iAcol = dip1->iAcol;
3163 dip4->iAcolLeg = dip1->iAcolLeg;
3166 particles[dip3->iAcol].dips[dip3->iAcolLeg].front() = dip3real;
3167 particles[dip4->iAcol].dips[dip4->iAcolLeg].front() = dip4real;
3170 }
else if (jtMode == 2) {
3174 dip4real->iAcol = particles[dip2->iAcol].dips[dip2->iAcolLeg].
3176 dip4real->iCol = -( iAntiJun * 10 + 10 + 2);
3177 dip4real->isAntiJun =
true;
3180 dip4->iAcol = dip2->iAcol;
3181 dip4->iAcolLeg = dip2->iAcolLeg;
3182 dip4->isAntiJun =
true;
3183 dip4->iCol = -( iAntiJun * 10 + 10 + 2);
3187 particles[dip4->iAcol].dips[dip4->iAcolLeg].front() = dip4real;
3192 dip4real->iAcol = particles[dip1->iAcol].dips[dip1->iAcolLeg].
3194 dip4real->iCol = -( iAntiJun * 10 + 10 + 2);
3195 dip4real->isAntiJun =
true;
3196 dip3real->iAcol = particles[dip2->iAcol].dips[dip2->iAcolLeg].
3200 dip4->iAcol = dip1->iAcol;
3201 dip4->iAcolLeg = dip1->iAcolLeg;
3202 dip4->isAntiJun =
true;
3203 dip4->iCol = -( iAntiJun * 10 + 10 + 2);
3207 dip3->iAcol = dip2->iAcol;
3208 dip3->iAcolLeg = dip2->iAcolLeg;
3211 particles[dip3->iAcol].dips[dip3->iAcolLeg].front() = dip3real;
3212 particles[dip4->iAcol].dips[dip4->iAcolLeg].front() = dip4real;
3218 particles[iCol1].dips[dip1->iColLeg].back()->iAcol = - (iJun * 10 + 10);
3219 particles[iCol2].dips[dip2->iColLeg].back()->iAcol = - (iJun * 10 + 10 + 1);
3220 particles[iCol1].dips[dip1->iColLeg].back()->isJun =
true;
3221 particles[iCol2].dips[dip2->iColLeg].back()->isJun =
true;
3226 dip1->iAcol = - (iJun * 10 + 10);
3227 dip2->iAcol = - (iJun * 10 + 10 + 1);
3235 for (
int i = 0; i < int(particles[iAcol3].activeDips.size()); ++i)
3236 if (particles[iAcol3].activeDips[i] == dip3) {
3237 particles[iAcol3].activeDips[i] = dipoles[iActive2];
3241 for (
int i = 0; i < int(particles[iAcol4].activeDips.size()); ++i)
3242 if (particles[iAcol4].activeDips[i] == dip4) {
3243 particles[iAcol4].activeDips[i] = dipoles[iActive3];
3249 for (
int i = 0; i < int(particles[iCol3].activeDips.size()); ++i)
3250 if (particles[iCol3].activeDips[i] == dip3) {
3251 particles[iCol3].activeDips[i] = dipoles[iActive1];
3256 for (
int i = 0; i < int(particles[iAcol1].activeDips.size()); ++i)
3257 if (particles[iAcol1].activeDips[i] == dip1) {
3258 particles[iAcol1].activeDips[i] = dip3;
3262 for (
int i = 0; i < int(particles[iAcol2].activeDips.size()); ++i)
3263 if (particles[iAcol2].activeDips[i] == dip2) {
3264 particles[iAcol2].activeDips[i] = dip3;
3268 for (
int i = 0; i < int(particles[iAcol1].activeDips.size()); ++i)
3269 if (particles[iAcol1].activeDips[i] == dip1) {
3270 particles[iAcol1].activeDips[i] = dip4;
3274 }
else if (jtMode == 2) {
3275 for (
int i = 0; i < int(particles[iCol4].activeDips.size()); ++i)
3276 if (particles[iCol4].activeDips[i] == dip4) {
3277 particles[iCol4].activeDips[i] = dipoles[iActive1];
3282 for (
int i = 0; i < int(particles[iAcol2].activeDips.size()); ++i)
3283 if (particles[iAcol2].activeDips[i] == dip2) {
3284 particles[iAcol2].activeDips[i] = dip4;
3288 for (
int i = 0; i < int(particles[iAcol1].activeDips.size()); ++i)
3289 if (particles[iAcol1].activeDips[i] == dip1) {
3290 particles[iAcol1].activeDips[i] = dip4;
3294 for (
int i = 0; i < int(particles[iAcol2].activeDips.size()); ++i)
3295 if (particles[iAcol2].activeDips[i] == dip2) {
3296 particles[iAcol2].activeDips[i] = dip3;
3303 junctions.push_back(Junction(1, oldCol1, oldCol2, newCol1));
3304 if (jtMode == 0) junctions.push_back(Junction(2, newCol2, newCol3, newCol1));
3305 else if (jtMode == 1)
3306 junctions.push_back(Junction(2, newCol2, newCol3, oldCol3));
3307 else if (jtMode == 2)
3308 junctions.push_back(Junction(2, newCol2, newCol3, oldCol4));
3311 junctions[iJun].dipsOrig[0] =
3312 particles[iCol1].dips[dip1->iColLeg].back();
3313 junctions[iJun].dipsOrig[1] =
3314 particles[iCol2].dips[dip2->iColLeg].back();
3315 junctions[iJun].dipsOrig[2] = dipoles[iReal1];
3316 junctions[iJun].dips[0] = dip1;
3317 junctions[iJun].dips[1] = dip2;
3318 junctions[iJun].dips[2] = dipoles[iActive1];
3321 junctions[iAntiJun].dips[0] = dipoles[iActive2];
3322 junctions[iAntiJun].dips[1] = dipoles[iActive3];
3323 junctions[iAntiJun].dipsOrig[0] = dipoles[iReal2];
3324 junctions[iAntiJun].dipsOrig[1] = dipoles[iReal3];
3327 junctions[iAntiJun].dips[2] = dipoles[iActive1];
3328 junctions[iAntiJun].dipsOrig[2] = dipoles[iReal1];
3329 }
else if (jtMode == 1) {
3330 junctions[iAntiJun].dips[2] = dip3;
3331 junctions[iAntiJun].dipsOrig[2] =
3332 particles[dip3->iAcol].dips[dip3->iAcolLeg].front();
3333 }
else if (jtMode == 2) {
3334 junctions[iAntiJun].dips[2] = dip4;
3335 junctions[iAntiJun].dipsOrig[2] =
3336 particles[dip4->iAcol].dips[dip4->iAcolLeg].front();
3340 if (dip1->isActive && mDip(dip1) < m0)
3341 makePseudoParticle(dip1, 110,
true);
3342 if (dip2->isActive && mDip(dip2) < m0)
3343 makePseudoParticle(dip2, 110,
true);
3344 if (dip3->isActive && mDip(dip3) < m0)
3345 makePseudoParticle(dip3, 110,
true);
3346 if (dip4->isActive && mDip(dip4) < m0)
3347 makePseudoParticle(dip4, 110,
true);
3349 if (dipoles[iActive1]->isActive && mDip(dipoles[iActive1]) < m0)
3350 makePseudoParticle(dipoles[iActive1], 110,
true);
3351 if (dipoles[iActive2]->isActive && mDip(dipoles[iActive2]) < m0)
3352 makePseudoParticle(dipoles[iActive2], 110,
true);
3353 if (dipoles[iActive3]->isActive && mDip(dipoles[iActive3]) < m0)
3354 makePseudoParticle(dipoles[iActive3], 110,
true);
3357 usedDipoles.push_back(dipoles[iActive1]);
3358 usedDipoles.push_back(dipoles[iActive2]);
3359 usedDipoles.push_back(dipoles[iActive3]);
3368 void ColourReconnection::doTripleJunctionTrial(
Event& event,
3369 TrialReconnection& juncTrial) {
3372 ColourDipole* dip1 = juncTrial.dips[0];
3373 ColourDipole* dip2 = juncTrial.dips[1];
3374 ColourDipole* dip3 = juncTrial.dips[2];
3377 int iCol1 = dip1->iCol;
3378 int iCol2 = dip2->iCol;
3379 int iCol3 = dip3->iCol;
3380 int iAcol1 = dip1->iAcol;
3381 int iAcol2 = dip2->iAcol;
3382 int iAcol3 = dip3->iAcol;
3385 int oldCol1 = dip1->col;
3386 int oldCol2 = dip2->col;
3387 int oldCol3 = dip3->col;
3388 int newCol1 =
event.nextColTag();
3389 int newCol2 =
event.nextColTag();
3390 int newCol3 =
event.nextColTag();
3393 int iJun = junctions.size();
3394 int iAntiJun = junctions.size() + 1;
3399 = particles[iAcol1].dips[dip1->iAcolLeg].front()->iAcol;
3400 dipoles.push_back(
new ColourDipole(newCol1, -( iAntiJun * 10 + 10),
3401 iAcol1real, dip1->colReconnection,
false,
true,
false,
true));
3402 int iReal1 = dipoles.size() - 1;
3403 particles[iAcol1].dips[dip1->iAcolLeg].front() = dipoles.back();
3405 dipoles.push_back(
new ColourDipole(newCol1, -( iAntiJun * 10 + 10),
3406 iAcol1, dip1->colReconnection,
false,
true));
3407 dipoles.back()->iAcolLeg = dip1->iAcolLeg;
3408 int iActive1 = dipoles.size() - 1;
3413 = particles[iAcol2].dips[dip2->iAcolLeg].front()->iAcol;
3414 dipoles.push_back(
new ColourDipole(newCol2, -( iAntiJun * 10 + 10 + 1),
3415 iAcol2real, dip2->colReconnection,
false,
true,
false,
true));
3416 int iReal2 = dipoles.size() - 1;
3417 particles[iAcol2].dips[dip2->iAcolLeg].front() = dipoles.back();
3419 dipoles.push_back(
new ColourDipole(newCol2, -( iAntiJun * 10 + 10 + 1),
3420 iAcol2, dip2->colReconnection,
false,
true));
3421 dipoles.back()->iAcolLeg = dip2->iAcolLeg;
3422 int iActive2 = dipoles.size() - 1;
3427 = particles[iAcol3].dips[dip3->iAcolLeg].front()->iAcol;
3428 dipoles.push_back(
new ColourDipole(newCol3, -( iAntiJun * 10 + 10 + 2),
3429 iAcol3real, dip3->colReconnection,
false,
true,
false,
true));
3430 int iReal3 = dipoles.size() - 1;
3431 particles[iAcol3].dips[dip3->iAcolLeg].front() = dipoles.back();
3433 dipoles.push_back(
new ColourDipole(newCol3, -( iAntiJun * 10 + 10 + 2),
3434 iAcol3, dip3->colReconnection,
false,
true));
3435 dipoles.back()->iAcolLeg = dip3->iAcolLeg;
3436 int iActive3 = dipoles.size() - 1;
3441 particles[iCol1].dips[dip1->iColLeg].back()->iAcol = - (iJun * 10 + 10);
3442 particles[iCol2].dips[dip2->iColLeg].back()->iAcol = - (iJun * 10 + 10 + 1);
3443 particles[iCol3].dips[dip3->iColLeg].back()->iAcol = - (iJun * 10 + 10 + 2);
3444 particles[iCol1].dips[dip1->iColLeg].back()->isJun =
true;
3445 particles[iCol2].dips[dip2->iColLeg].back()->isJun =
true;
3446 particles[iCol3].dips[dip3->iColLeg].back()->isJun =
true;
3452 dip1->iAcol = - (iJun * 10 + 10);
3453 dip2->iAcol = - (iJun * 10 + 10 + 1);
3454 dip3->iAcol = - (iJun * 10 + 10 + 2);
3460 for (
int i = 0; i < int(particles[iAcol1].activeDips.size()); ++i)
3461 if (particles[iAcol1].activeDips[i] == dip1)
3462 particles[iAcol1].activeDips[i] = dipoles[iActive1];
3463 for (
int i = 0; i < int(particles[iAcol2].activeDips.size()); ++i)
3464 if (particles[iAcol2].activeDips[i] == dip2)
3465 particles[iAcol2].activeDips[i] = dipoles[iActive2];
3466 for (
int i = 0; i < int(particles[iAcol3].activeDips.size()); ++i)
3467 if (particles[iAcol3].activeDips[i] == dip3)
3468 particles[iAcol3].activeDips[i] = dipoles[iActive3];
3471 junctions.push_back(Junction(1, oldCol1, oldCol2, oldCol3));
3472 junctions.push_back(Junction(2, newCol1, newCol3, newCol3));
3475 junctions[iJun].dipsOrig[0] =
3476 particles[iCol1].dips[dip1->iColLeg].back();
3477 junctions[iJun].dipsOrig[1] =
3478 particles[iCol2].dips[dip2->iColLeg].back();
3479 junctions[iJun].dipsOrig[2] =
3480 particles[iCol3].dips[dip3->iColLeg].back();
3481 junctions[iJun].dips[0] = dip1;
3482 junctions[iJun].dips[1] = dip2;
3483 junctions[iJun].dips[2] = dip3;
3486 junctions[iAntiJun].dips[0] = dipoles[iActive1];
3487 junctions[iAntiJun].dips[1] = dipoles[iActive2];
3488 junctions[iAntiJun].dips[2] = dipoles[iActive3];
3489 junctions[iAntiJun].dipsOrig[0] = dipoles[iReal1];
3490 junctions[iAntiJun].dipsOrig[1] = dipoles[iReal2];
3491 junctions[iAntiJun].dipsOrig[2] = dipoles[iReal3];
3494 if (dip1->isActive && mDip(dip1) < m0)
3495 makePseudoParticle(dip1, 110,
true);
3496 if (dip2->isActive && mDip(dip2) < m0)
3497 makePseudoParticle(dip2, 110,
true);
3498 if (dip3->isActive && mDip(dip3) < m0)
3499 makePseudoParticle(dip3, 110,
true);
3501 if (dipoles[iActive1]->isActive && mDip(dipoles[iActive1]) < m0)
3502 makePseudoParticle(dipoles[iActive1], 110,
true);
3503 if (dipoles[iActive2]->isActive && mDip(dipoles[iActive2]) < m0)
3504 makePseudoParticle(dipoles[iActive2], 110,
true);
3505 if (dipoles[iActive3]->isActive && mDip(dipoles[iActive3]) < m0)
3506 makePseudoParticle(dipoles[iActive3], 110,
true);
3509 usedDipoles.push_back(dipoles[iActive1]);
3510 usedDipoles.push_back(dipoles[iActive2]);
3511 usedDipoles.push_back(dipoles[iActive3]);
3521 bool ColourReconnection::reconnectMove(
Event& event,
int oldSize) {
3525 iReduceCol.resize( event.size() );
3527 map<int, int> colMap, acolMap;
3528 map<int, int>::iterator colM, acolM;
3529 vector<InfoGluonMove> infoGM;
3540 double lambdaRefNow = 0.;
3541 double dLambdaNow = 0.;
3544 for (
int i = oldSize; i <
event.size(); ++i)
if (event[i].isFinal()) {
3545 if (flipMode < 3 && event[i].
id() == 21 && rndmPtr->flat() < fracGluon)
3549 if (event[i].col() > 0 || event[i].acol() > 0) {
3550 iReduceCol[i] = iExpandCol.size();
3551 iExpandCol.push_back(i);
3552 if (event[i].col() > 0) colMap[
event[i].col()] = i;
3553 if (event[i].acol() > 0) acolMap[
event[i].acol()] = i;
3558 for (
int iJun = 0; iJun <
event.sizeJunction(); ++iJun) {
3559 if (event.kindJunction(iJun) == 1) {
3560 for (
int j = 0; j < 3; ++j) {
3561 int jCol =
event.colJunction( iJun, j);
3562 for (colM = colMap.begin(); colM != colMap.end(); ++colM)
3563 if (colM->first == jCol) {
3564 colMap.erase( colM);
3567 for (
int iG = 0; iG < int(iGlu.size()); ++iG)
3568 if (event[iGlu[iG]].col() == jCol) {
3569 iGlu.erase(iGlu.begin() + iG);
3573 }
else if (event.kindJunction(iJun) == 2) {
3574 for (
int j = 0; j < 3; ++j) {
3575 int jCol =
event.colJunction( iJun, j);
3576 for (acolM = acolMap.begin(); acolM != acolMap.end(); ++acolM)
3577 if (acolM->first == jCol) {
3578 acolMap.erase( acolM);
3581 for (
int iG = 0; iG < int(iGlu.size()); ++iG)
3582 if (event[iGlu[iG]].acol() == jCol) {
3583 iGlu.erase(iGlu.begin() + iG);
3591 int nGlu = iGlu.size();
3592 int nCol = colMap.size();
3593 if (
int(acolMap.size()) != nCol) {
3594 infoPtr->errorMsg(
"Error in MBReconUserHooks: map sizes do not match");
3597 colM = colMap.begin();
3598 acolM = acolMap.begin();
3599 for (
int iCol = 0; iCol < nCol; ++iCol) {
3600 if (colM->first != acolM->first) {
3601 infoPtr->errorMsg(
"Error in MBReconUserHooks: map elements"
3610 nColMove = iExpandCol.size();
3611 lambdaijMove.resize( pow2(nColMove) );
3612 for (
int iAC = 0; iAC < nColMove - 1; ++iAC) {
3613 int i = iExpandCol[iAC];
3614 for (
int jAC = iAC + 1; jAC < nColMove; ++jAC) {
3615 int j = iExpandCol[jAC];
3616 lambdaijMove[nColMove * iAC + jAC]
3617 = log(1. + m2( event[i], event[j]) / m2Lambda);
3622 for (
int iG = 0; iG < nGlu; ++iG) {
3626 colNow =
event[iNow].col();
3627 acolNow =
event[iNow].acol();
3628 iColNow = acolMap[colNow];
3629 iAcolNow = colMap[acolNow];
3632 lambdaRefNow = lambda123Move( iNow, iColNow, iAcolNow);
3635 for (colM = colMap.begin(); colM != colMap.end(); ++colM) {
3636 col2Now = colM->first;
3637 iCol2Now = colMap[col2Now];
3638 iAcol2Now = acolMap[col2Now];
3641 dLambdaNow = (iCol2Now == iNow || iAcol2Now == iNow
3642 || iColNow == iAcolNow) ? 2e4
3643 : lambda123Move( iNow, iCol2Now, iAcol2Now) - lambdaRefNow;
3646 infoGM.push_back( InfoGluonMove( iNow, colNow, acolNow, iColNow,
3647 iAcolNow, col2Now, iCol2Now, iAcol2Now, lambdaRefNow, dLambdaNow ));
3650 int nPair = infoGM.size();
3653 for (
int iMove = 0; iMove < nGlu; ++iMove) {
3655 double dLambdaMin = 1e4;
3658 for (
int iPair = 0; iPair < nPair; ++iPair)
3659 if (infoGM[iPair].dLambda < dLambdaMin) {
3661 dLambdaMin = infoGM[iPair].dLambda;
3665 if (dLambdaMin > -dLambdaCut)
break;
3668 InfoGluonMove& selSM = infoGM[iPairMin];
3669 int i1Sel = selSM.i1;
3670 int iCol1Sel = selSM.iCol1;
3671 int iAcol1Sel = selSM.iAcol1;
3672 int iCol2Sel = selSM.iCol2;
3673 int iAcol2Sel = selSM.iAcol2;
3674 int iCol2Mod[3] = { iAcol1Sel , i1Sel , iCol2Sel };
3675 int col2Mod[3] = { selSM.col1, selSM.col2, selSM.acol1};
3678 for (
int i = 0; i < 3; ++i) {
3679 event[ iCol2Mod[i] ].col( col2Mod[i] );
3680 colMap[ col2Mod[i] ] = iCol2Mod[i];
3685 bool doUpdate =
false;
3686 for (
int iPair = 0; iPair < nPair; ++iPair) {
3687 InfoGluonMove& tmpSM = infoGM[iPair];
3688 if (tmpSM.i1 != i1Now) {
3691 if (i1Now == i1Sel || i1Now == iCol1Sel || i1Now == iAcol1Sel
3692 || i1Now == iCol2Sel || i1Now == iAcol2Sel) {
3693 colNow =
event[i1Now].col();
3694 acolNow =
event[i1Now].acol();
3695 iColNow = acolMap[colNow];
3696 iAcolNow = colMap[acolNow];
3697 lambdaRefNow = lambda123Move( i1Now, iColNow, iAcolNow);
3702 tmpSM.col1 = colNow;
3703 tmpSM.acol1 = acolNow;
3704 tmpSM.iCol1 = iColNow;
3705 tmpSM.iAcol1 = iAcolNow;
3706 tmpSM.lambdaRef = lambdaRefNow;
3711 for (
int iPair = 0; iPair < nPair; ++iPair) {
3712 InfoGluonMove& tmpSM = infoGM[iPair];
3714 for (
int i = 0; i < 3; ++i)
if (tmpSM.col2 == col2Mod[i]) iMod = i;
3715 if (iMod > -1) tmpSM.iCol2 = iCol2Mod[iMod];
3716 if (tmpSM.i1 == i1Sel || tmpSM.i1 == iCol1Sel || tmpSM.i1 == iAcol1Sel
3717 || tmpSM.i1 == iCol2Sel || tmpSM.i1 == iAcol2Sel || iMod > -1)
3718 tmpSM.dLambda = (tmpSM.iCol2 == tmpSM.i1 || tmpSM.iAcol2 == tmpSM.i1
3719 || tmpSM.iCol1 == tmpSM.iAcol1) ? 2e4
3720 : lambda123Move( tmpSM.i1, tmpSM.iCol2, tmpSM.iAcol2)
3728 if (flipMode == 0)
return true;
3731 vector<int> iTmpFlip, iVecFlip, iBegFlip, iEndFlip;
3734 int i1c, i1a, i2c, i2a, i1cMin, i1aMin, i2cMin, i2aMin, iSMin;
3735 double dLambdaFlip, dLambdaFlipMin;
3736 vector<InfoGluonMove> flipMin;
3739 for (
int i = oldSize; i <
event.size(); ++i)
3740 if (event[i].isFinal() &&
event[i].col() > 0 &&
event[i].acol() == 0) {
3742 iTmpFlip.push_back( i);
3746 acolM = acolMap.find( event[iNow].col() );
3747 bool foundEnd =
false;
3748 while (acolM != acolMap.end()) {
3749 iNow = acolM->second;
3750 iTmpFlip.push_back( iNow);
3751 if (event[iNow].col() == 0) {
3755 acolM = acolMap.find( event[iNow].col() );
3759 if (foundEnd || flipMode == 2 || flipMode == 4) {
3760 iBegFlip.push_back( iVecFlip.size());
3761 for (
int j = 0; j < int(iTmpFlip.size()); ++j)
3762 iVecFlip.push_back( iTmpFlip[j]);
3763 iEndFlip.push_back( iVecFlip.size());
3768 if (flipMode == 2 || flipMode == 4)
3769 for (
int i = oldSize; i <
event.size(); ++i)
3770 if (event[i].isFinal() &&
event[i].acol() > 0 &&
event[i].col() == 0) {
3772 iTmpFlip.push_back( i);
3776 colM = colMap.find( event[iNow].acol() );
3777 bool foundEnd =
false;
3778 while (colM != colMap.end()) {
3779 iNow = colM->second;
3780 iTmpFlip.push_back( iNow);
3781 if (event[iNow].acol() == 0) {
3785 colM = colMap.find( event[iNow].acol() );
3790 iBegFlip.push_back( iVecFlip.size());
3791 for (
int j = 0; j < int(iTmpFlip.size()); ++j)
3792 iVecFlip.push_back( iTmpFlip[j]);
3793 iEndFlip.push_back( iVecFlip.size());
3798 int nSysFlip = iBegFlip.size();
3799 for (
int iSys1 = 0; iSys1 < nSysFlip - 1; ++iSys1)
3800 if (iBegFlip[iSys1] >= 0)
3801 for (
int iSys2 = iSys1 + 1; iSys2 < nSysFlip; ++iSys2)
3802 if (iBegFlip[iSys2] >= 0) {
3807 dLambdaFlipMin = 1e4;
3810 for (
int j1 = iBegFlip[iSys1]; j1 < iEndFlip[iSys1] - 1; ++j1)
3811 for (
int j2 = iBegFlip[iSys2]; j2 < iEndFlip[iSys2] - 1; ++j2) {
3813 i1a = iVecFlip[j1 + 1];
3815 i2a = iVecFlip[j2 + 1];
3816 dLambdaFlip = lambda12Move( i1c, i2a) + lambda12Move( i2c, i1a)
3817 - lambda12Move( i1c, i1a) - lambda12Move( i2c, i2a);
3818 if (dLambdaFlip < dLambdaFlipMin) {
3823 dLambdaFlipMin = dLambdaFlip;
3828 if (dLambdaFlipMin < -dLambdaCut) flipMin.push_back( InfoGluonMove(
3829 iSys1, iSys2, i1cMin, i1aMin, i2cMin, i2aMin, dLambdaFlipMin) );
3831 int flipSize = flipMin.size();
3834 for (
int iFlip = 0; iFlip < min( nSysFlip / 2, flipSize); ++iFlip) {
3836 dLambdaFlipMin = 1e4;
3837 for (
int iSys12 = 0; iSys12 < flipSize; ++iSys12)
3838 if (flipMin[iSys12].i1 >= 0 && flipMin[iSys12].dLambda < dLambdaFlipMin) {
3840 dLambdaFlipMin = flipMin[iSys12].dLambda;
3845 InfoGluonMove& flipNow = flipMin[iSMin];
3846 int iS1 = flipNow.i1;
3847 int iS2 = flipNow.i2;
3848 event[ flipNow.iAcol1 ].acol( event[flipNow.iCol2].col() );
3849 event[ flipNow.iAcol2 ].acol( event[flipNow.iCol1].col() );
3850 for (
int iSys12 = 0; iSys12 < flipSize; ++iSys12)
3851 if ( flipMin[iSys12].i1 == iS1 || flipMin[iSys12].i1 == iS2
3852 || flipMin[iSys12].i2 == iS1 || flipMin[iSys12].i2 == iS2)
3853 flipMin[iSys12].i1 = -1;
3867 bool ColourReconnection::reconnectTypeCommon(
Event& event,
int ) {
3870 int sizeSys = partonSystemsPtr->sizeSys();
3871 if (sizeSys < 2 || partonSystemsPtr->hasInAB(sizeSys - 2)
3872 || partonSystemsPtr->hasInAB(sizeSys - 1) )
return true;
3875 vector<vector< ColourDipole> > dips;
3880 for (
int i = 0; i < 2; ++i) {
3881 dips.push_back(vector<ColourDipole>());
3882 int iSys = sizeSys - i - 1;
3883 for (
int j = 0; j < partonSystemsPtr->sizeOut(iSys); ++j) {
3884 int iPar = partonSystemsPtr->getOut(iSys, j);
3888 int iMot =
event[iPar].mother1();
3889 while (iMot != 0 && event[iMot].idAbs() != 23
3890 && event[iMot].idAbs() != 24) iMot =
event[iMot].mother1();
3892 infoPtr->errorMsg(
"Error in ColourReconnection::reconnectType"
3893 "Common: Not a resonance decay of a W/Z");
3900 int col =
event[iPar].col();
3901 if (col == 0)
continue;
3902 for (
int k = 0; k < partonSystemsPtr->sizeOut(iSys); ++k) {
3903 int iAntiPar = partonSystemsPtr->getOut(iSys, k);
3904 if (event[iAntiPar].acol() == col) {
3905 dips.back().push_back(ColourDipole(col, iPar, iAntiPar));
3912 if (dips.back().size() == 0)
return true;
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] = -HBARC * 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];