9 #include "Pythia8/BeamParticle.h"
24 ColState() : nTotal(0.) {}
25 vector< pair<int,int> > lastSteps;
40 const double BeamParticle::XMINUNRESOLVED = 1. - 1e-10;
43 const double BeamParticle::POMERONMASS = 1.;
46 const double BeamParticle::XMAXCOMPANION = 0.99;
49 const double BeamParticle::TINYZREL = 1e-8;
52 const int BeamParticle::NMAX = 1000;
56 const int BeamParticle::NRANDOMTRIES = 1000;
62 void BeamParticle::init(
int idIn,
double pzIn,
double eIn,
double mIn,
63 PDFPtr pdfInPtr, PDFPtr pdfHardInPtr,
bool isUnresolvedIn,
64 StringFlav* flavSelPtrIn) {
67 pdfBeamPtr = pdfInPtr;
68 pdfHardBeamPtr = pdfHardInPtr;
69 isUnresolvedBeam = isUnresolvedIn;
70 flavSelPtr = flavSelPtrIn;
74 pdfBeamPtrSave = pdfInPtr;
75 pdfHardBeamPtrSave = pdfHardInPtr;
78 maxValQuark = mode(
"BeamRemnants:maxValQuark");
81 valencePowerMeson = parm(
"BeamRemnants:valencePowerMeson");
82 valencePowerUinP = parm(
"BeamRemnants:valencePowerUinP");
83 valencePowerDinP = parm(
"BeamRemnants:valencePowerDinP");
86 valenceDiqEnhance = parm(
"BeamRemnants:valenceDiqEnhance");
89 companionPower = mode(
"BeamRemnants:companionPower");
92 gluonPower = parm(
"BeamRemnants:gluonPower");
93 xGluonCutoff = parm(
"BeamRemnants:xGluonCutoff");
96 allowJunction = flag(
"BeamRemnants:allowJunction");
100 beamJunction = flag(
"beamRemnants:beamJunction");
103 allowBeamJunctions = flag(
"beamRemnants:allowBeamJunction");
106 pickQuarkNorm = parm(
"Diffraction:pickQuarkNorm");
107 pickQuarkPower = parm(
"Diffraction:pickQuarkPower");
110 beamSat = parm(
"BeamRemnants:saturation");
113 diffPrimKTwidth = parm(
"Diffraction:primKTwidth");
116 diffLargeMassSuppress = parm(
"Diffraction:largeMassSuppress");
119 doND = flag(
"SoftQCD:nonDiffractive");
120 doISR = flag(
"PartonLevel:ISR");
121 doMPI = flag(
"PartonLevel:MPI");
122 pTminISR = parm(
"SpaceShower:pTmin");
127 pBeam = Vec4( 0., 0., pzIn, eIn);
131 hasResGammaInBeam =
false;
135 resetGammaInLepton();
147 void BeamParticle::initBeamKind() {
150 idBeamAbs = abs(idBeam);
151 isLeptonBeam =
false;
152 isHadronBeam =
false;
154 isBaryonBeam =
false;
163 if ( (idBeamAbs > 10 && idBeamAbs < 17)
164 || (idBeamAbs > 50 && idBeamAbs < 60) ) {
172 if (idBeamAbs == 22) {
182 if (idBeamAbs < 101 || idBeamAbs > 9999)
return;
185 if (idBeamAbs == 990) {
193 }
else if (idBeamAbs < 1000) {
194 int id1 = idBeamAbs/100;
195 int id2 = (idBeamAbs/10)%10;
196 if ( id1 > maxValQuark || id2 > maxValQuark )
return;
214 int id1 = idBeamAbs/1000;
215 int id2 = (idBeamAbs/100)%10;
216 int id3 = (idBeamAbs/10)%10;
217 if ( id1 > maxValQuark || id2 > maxValQuark || id3 > maxValQuark)
return;
218 if (id2 > id1 || id3 > id1)
return;
222 nValKinds = 1; idVal[0] = id1; nVal[0] = 1;
223 if (id2 == id1) ++nVal[0];
229 if (id3 == id1) ++nVal[0];
230 else if (id3 == id2) ++nVal[1];
232 idVal[nValKinds] = id3;
239 if (idBeam < 0)
for (
int i = 0; i < nValKinds; ++i) idVal[i] = -idVal[i];
249 void BeamParticle::initUnres(PDFPtr pdfUnresInPtr) {
252 pdfUnresBeamPtr = pdfUnresInPtr;
253 isResUnres = (pdfUnresBeamPtr != 0 ) ?
true :
false;
261 void BeamParticle::newValenceContent() {
264 if (idBeam == 111 || idBeam == 113 || idBeam == 223) {
265 idVal[0] = (rndmPtr->flat() < 0.5) ? 1 : 2;
266 idVal[1] = -idVal[0];
269 }
else if (idBeam == 130 || idBeam == 310) {
270 idVal[0] = (rndmPtr->flat() < 0.5) ? 1 : 3;
271 idVal[1] = (idVal[0] == 1) ? -3 : -1;
274 }
else if (idBeam == 990) {
275 idVal[0] = (rndmPtr->flat() < 0.5) ? 1 : 2;
276 idVal[1] = -idVal[0];
279 }
else if (idBeam == 22) {
283 if (idTmp == 113 || idTmp == 223) {
284 idVal[0] = (rndmPtr->flat() < 0.5) ? 1 : 2;
285 idVal[1] = -idVal[0];
287 }
else if (idTmp == 333) {
291 }
else if (idTmp == 443) {
299 idVal[1] = -idVal[0];
303 }
else if (idBeam == 333) {
305 idVal[1] = -idVal[0];
308 }
else if (idBeam == 443) {
310 idVal[1] = -idVal[0];
316 pdfBeamPtr->newValenceContent( idVal[0], idVal[1]);
317 if (pdfHardBeamPtr != pdfBeamPtr && pdfHardBeamPtr != 0)
318 pdfHardBeamPtr->newValenceContent( idVal[0], idVal[1]);
324 double BeamParticle::xMax(
int iSkip) {
328 if (idBeam == 990) xLeft -= POMERONMASS / e();
329 else if (isHadron()) xLeft -= m() / e();
330 if (size() == 0)
return xLeft;
333 for (
int i = 0; i < size(); ++i)
334 if (i != iSkip && resolved[i].isFromBeam()) xLeft -= resolved[i].x();
343 xfModPrepData BeamParticle::xfModPrep(
int iSkip,
double Q2) {
346 xfModPrepData xfData = {0., 0., 0., 0., 0.};
349 for (
int i = 0; i < nValKinds; ++i) {
350 nValLeft[i] = nVal[i];
351 for (
int j = 0; j < size(); ++j)
352 if (j != iSkip && resolved[j].isValence()
353 && resolved[j].id() == idVal[i]) --nValLeft[i];
354 double xValNow = xValFrac(i, Q2);
355 xfData.xValTot += nVal[i] * xValNow;
356 xfData.xValLeft += nValLeft[i] * xValNow;
361 for (
int i = 0; i < size(); ++i)
if (i != iSkip) xUsed += resolved[i].x();
362 xfData.xLeft = 1. - xUsed;
365 for (
int i = 0; i < size(); ++i) {
366 if (i != iSkip && resolved[i].isUnmatched()) xfData.xCompAdded
367 += xCompFrac( resolved[i].x() / (xfData.xLeft + resolved[i].x()) )
370 * (1. + resolved[i].x() / xfData.xLeft);
374 xfData.rescaleGS = max( 0., (1. - xfData.xValLeft - xfData.xCompAdded)
375 / (1. - xfData.xValTot) );
387 double BeamParticle::xfModified(
int iSkip,
int idIn,
double x,
double Q2,
388 xfModPrepData& xfData ) {
396 const int rsize = size();
399 if (rsize == 0)
return xfModified0(iSkip, idIn, x, Q2);
403 if (x >= xfData.xLeft)
return 0.;
404 double xRescaled = x / xfData.xLeft;
407 for (
int i = nValKinds - 1; i >= 0; --i) {
409 if (idIn == idVal[i] && nValLeft[i] > 0) {
410 xqVal = xfVal( idIn, xRescaled, Q2)
411 * double(nValLeft[i]) / double(nVal[i]);
417 for (
int i = 0; i < rsize; ++i) {
418 if (i != iSkip && resolved[i].isUnmatched() &&
419 resolved[i].
id() == -idIn) {
421 double xsRescaled = resolved[i].x() / (xfData.xLeft + resolved[i].x());
422 double xcRescaled = x / (xfData.xLeft + resolved[i].x());
423 double xqCompNow = xCompDist( xcRescaled, xsRescaled);
426 if ( isGamma() ) xqCompNow *= xIntegratedPDFs(Q2);
427 resolved[i].xqCompanion( xqCompNow);
428 xqCompSum += xqCompNow;
433 xqgSea = xfData.rescaleGS * xfSea( idIn, xRescaled, Q2);
436 xqgTot = xqVal + xqgSea + xqCompSum;
439 if (isGammaBeam && doISR)
return xqgTot;
443 if (resolved[iSkip].isValence())
return xqVal;
444 if (resolved[iSkip].isUnmatched())
return xqgSea + xqCompSum;
457 double BeamParticle::xfModified0(
int iSkip,
int idIn,
double x,
double Q2) {
460 if (x >= 1.)
return 0.;
461 bool canBeVal =
false;
462 for (
int i = 0; i < nValKinds; ++i)
if (idIn == idVal[i]) {
467 xqVal = xfVal( idIn, x, Q2);
468 xqgSea = xfSea( idIn, x, Q2);
471 xqgSea = xf( idIn, x, Q2);
475 xqgTot = xqVal + xqgSea + xqCompSum;
478 if (isGammaBeam && doISR)
return xqgTot;
482 if (resolved[iSkip].isValence())
return xqVal;
483 if (resolved[iSkip].isUnmatched())
return xqgSea + xqCompSum;
495 int BeamParticle::pickValSeaComp() {
498 int oldCompanion = resolved[iSkipSave].companion();
499 if (oldCompanion >= 0) resolved[oldCompanion].companion(-2);
505 if (idSave == 21 || idSave == 22) vsc = -1;
508 else if (isLeptonBeam && idSave == idBeam) vsc = -3;
513 double xqRndm = xqgTot * rndmPtr->flat();
514 if (xqRndm < xqVal && !isGammaBeam ) vsc = -3;
515 else if (xqRndm < xqVal + xqgSea) vsc = -2;
519 xqRndm -= xqVal + xqgSea;
520 for (
int i = 0; i < size(); ++i)
521 if (i != iSkipSave && resolved[i].
id() == -idSave
522 && resolved[i].isUnmatched()) {
523 xqRndm -= resolved[i].xqCompanion();
524 if (xqRndm < 0.) vsc = i;
531 resolved[iSkipSave].companion(vsc);
532 if (vsc >= 0) resolved[vsc].companion(iSkipSave);
544 double BeamParticle::xValFrac(
int j,
double Q2) {
547 if (Q2 != Q2ValFracSav) {
551 double llQ2 = log( log( max( 1., Q2) / 0.04 ));
554 uValInt = 0.48 / (1. + 1.56 * llQ2);
555 dValInt = 0.385 / (1. + 1.60 * llQ2);
559 if (isBaryonBeam && nValKinds == 3)
return (2. * uValInt + dValInt) / 3.;
562 if (isBaryonBeam && nVal[j] == 1)
return dValInt;
563 if (isBaryonBeam && nVal[j] == 2)
return uValInt;
566 return 0.5 * (2. * uValInt + dValInt);
576 inline double BeamParticle::xCompFrac(
double xs) {
579 if (xs > XMAXCOMPANION)
return 0.;
582 if (companionPower == cPowerCache && xs == xsCache)
return resCache;
585 double logxs = log(xs);
587 switch (companionPower) {
590 res = xs * ( 5. + xs * (-9. - 2. * xs * (-3. + xs)) + 3. * logxs )
591 / ( (-1. + xs) * (2. + xs * (-1. + 2. * xs)) );
594 res = -1. -3. * xs + ( 2. * pow2(-1. + xs) * (1. + xs + xs*xs))
595 / ( 2. + xs*xs * (xs - 3.) + 3. * xs * logxs );
598 res = xs * ( (1. - xs) * (19. + xs * (43. + 4. * xs))
599 + 6. * logxs * (1. + 6. * xs + 4.*xs*xs) ) /
600 ( 4. * ( (xs - 1.) * (1. + xs * (4. + xs) )
601 - 3. * xs * logxs * (1 + xs) ) );
604 res = 3. * xs * ( (xs - 1.) * (7. + xs * (28. + 13. * xs))
605 - 2. * logxs * (1. + xs * (9. + 2. * xs * (6. + xs))) )
606 / ( 4. + 27. * xs - 31. * pow3(xs)
607 + 6. * xs * logxs * (3. + 2. * xs * (3.+xs)) );
610 res = ( -9. * xs * (xs*xs - 1.) * (5. + xs * (24. + xs)) + 12. * xs
611 * logxs * (1. + 2. * xs) * (1. + 2. * xs * (5. + 2. * xs)) )
612 / ( 8. * (1. + 2. * xs) * ((xs - 1.) * (1. + xs * (10. + xs))
613 - 6. * xs * logxs * (1. + xs)) );
618 cPowerCache = companionPower;
630 double BeamParticle::xCompDist(
double xc,
double xs) {
633 if (xs > XMAXCOMPANION)
return 0.;
637 if (xg > 1.)
return 0.;
641 double fac = 3. * xc * xs * (xc*xc + xs*xs) / pow4(xg);
644 switch (companionPower) {
647 return fac / ( 2. - xs * (3. - xs * (3. - 2. * xs)) );
650 return fac * (1. - xg) / ( 2. + xs*xs * (-3. + xs) + 3. * xs * log(xs) );
653 return fac * pow2(1. - xg) / ( 2. * ((1. - xs) * (1. + xs * (4. + xs))
654 + 3. * xs * (1. + xs) * log(xs)) );
657 return fac * pow3(1. - xg) * 2. / ( 4. + 27. * xs - 31. * pow3(xs)
658 + 6. * xs * log(xs) * (3. + 2. * xs * (3. + xs)) );
661 return fac * pow4(1. - xg) / ( 2. * (1. + 2. * xs) * ((1. - xs)
662 * (1. + xs * (10. + xs)) + 6. * xs * log(xs) * (1. + xs)) );
671 void BeamParticle::setGammaMode(
int gammaModeIn) {
674 if ( !( initGammaBeam || isGamma() ) ) {
676 pdfBeamPtr = pdfBeamPtrSave;
677 pdfHardBeamPtr = pdfHardBeamPtrSave;
678 hasResGammaInBeam =
false;
679 isResolvedGamma =
false;
684 gammaMode = gammaModeIn;
687 if (gammaMode == 2 && isResUnres) {
688 pdfBeamPtr = pdfUnresBeamPtr;
689 pdfHardBeamPtr = pdfUnresBeamPtr;
690 isResolvedGamma =
false;
691 hasResGammaInBeam =
false;
694 if ( isGamma()) isUnresolvedBeam =
true;
698 pdfBeamPtr = pdfBeamPtrSave;
699 pdfHardBeamPtr = pdfHardBeamPtrSave;
700 isUnresolvedBeam =
false;
701 if ( isGamma()) isResolvedGamma =
true;
702 else isResolvedGamma =
false;
703 if ( initGammaBeam && gammaMode == 1 ) hasResGammaInBeam =
true;
704 else hasResGammaInBeam =
false;
713 bool BeamParticle::gammaInitiatorIsVal(
int iResolved,
double Q2) {
714 return gammaInitiatorIsVal( iResolved, resolved[iResolved].
id(),
715 resolved[iResolved].x(), Q2 );
723 bool BeamParticle::gammaInitiatorIsVal(
int iResolved,
int idInit,
724 double x,
double Q2) {
730 if ( idInit == 0 || abs(idInit) == 21 ) {
731 idVal[0] = pdfBeamPtr->sampleGammaValFlavor(Q2);
732 idVal[1] = -idVal[0];
740 pdfBeamPtr->newValenceContent( idVal[0], idVal[1]);
743 if ( iResolved == iGamVal ) {
748 }
else if ( Q2 < pdfBeamPtr->gammaPDFRefScale(idInit) ) {
754 double xVal = xfVal( idInit, x, Q2);
755 double xSea = xfSea( idInit, x, Q2);
756 if ( rndmPtr->flat() < xVal/( xVal + xSea ) ) {
762 idVal[0] = pdfBeamPtr->sampleGammaValFlavor(Q2);
763 idVal[1] = -idVal[0];
774 int BeamParticle::gammaValSeaComp(
int iResolved) {
780 if ( resolved[iResolved].
id() == 21 ||
781 resolved[iResolved].
id() == 22 ) vsc = -1;
784 else if (iResolved == iPosVal) vsc = -3;
785 resolved[iResolved].companion(vsc);
794 bool BeamParticle::remnantFlavours(
Event& event,
bool isDIS) {
797 if (isHadronBeam && isUnresolvedBeam) {
798 append( 0, idBeam, 0., -1);
799 resolved[1].m( particleDataPtr->m0( idBeamAbs ) );
804 hasJunctionBeam = (isBaryon());
808 if (isDIS && nInit != 1)
return false;
814 if (resolved[0].
id() == 22)
return true;
817 if ( doISR && !doMPI ) {
821 if ( isResolvedGamma ) {
822 gammaInitiatorIsVal(0, pow2(pTminISR));
828 }
else if ( doMPI || doND ) {
832 double pTmin = doISR ? pTminISR : pTminMPI;
836 if ( iGamVal >= 0 ) {
837 gammaInitiatorIsVal(iGamVal, pow2(pTmin));
838 int valComp = resolved[iGamVal].companion();
839 if ( valComp >= 0 ) resolved[valComp].companion(-3);
840 gammaValSeaComp(iGamVal);
846 for (
int i = 0; i < size(); ++i) {
847 bool isValence = gammaInitiatorIsVal(i, pow2(pTminISR));
848 int origComp = resolved[i].companion();
853 if ( origComp >= 0 ) resolved[origComp].companion(-3);
862 else if ( isLeptonBeam && gammaMode == 2)
return true;
865 for (
int i = 0; i < nValKinds; ++i) {
866 nValLeft[i] = nVal[i];
867 for (
int j = 0; j < nInit; ++j)
if (resolved[j].isValence()
868 && resolved[j].
id() == idVal[i]) --nValLeft[i];
870 if ( isGammaBeam && doISR && !isResolvedGamma && !doMPI ) nValLeft[i] = 0;
872 for (
int k = 0; k < nValLeft[i]; ++k) append(0, idVal[i], 0., -3);
876 int nInitPlusVal = size();
877 if (isBaryon() && nInitPlusVal - nInit >= 2) {
882 if (nInitPlusVal - nInit == 3) {
883 double pickDq = 3. * rndmPtr->flat();
884 if (pickDq > 1.) iQ2 = nInit + 2;
885 if (pickDq > 2.) iQ1 = nInit + 1;
889 int idDq = flavSelPtr->makeDiquark( resolved[iQ1].
id(),
890 resolved[iQ2].
id(), idBeam);
893 resolved[iQ1].id(idDq);
894 if (nInitPlusVal - nInit == 3 && iQ2 == nInit + 1)
895 resolved[nInit + 1].id( resolved[nInit + 2].
id() );
897 hasJunctionBeam =
false;
901 for (
int i = 0; i < nInit; ++i)
902 if (resolved[i].isUnmatched()) {
905 append(0, -resolved[i].
id(), 0., i);
906 resolved[i].companion(size() - 1);
911 if ( size() == nInit && !isUnresolvedBeam &&
912 (!isGammaBeam || isResolvedGamma || doMPI) ) {
913 int idRemnant = (isHadronBeam || isGammaBeam) ? 21 : 22;
914 append(0, idRemnant, 0., -1);
918 if (isHadronBeam && isDIS && size() > 2 && resolved[0].
id() != 21) {
920 infoPtr->errorMsg(
"Error in BeamParticle::remnantFlavours: "
921 "unexpected number of beam remnants for DIS");
926 int colTypeComp = particleDataPtr->colType( resolved[3].
id() );
927 int colType1 = particleDataPtr->colType( resolved[1].
id() );
928 int i12 = (colType1 == -colTypeComp) ? 1 : 2;
931 int idHad = flavSelPtr->combineId( resolved[i12].
id(), resolved[3].
id() );
933 infoPtr->errorMsg(
"Error in BeamParticle::remnantFlavours: "
934 "failed to combine hadron for DIS");
939 resolved[i12].id(idHad);
941 resolved[0].companion(-3);
945 for (
int i = 0; i < size(); ++i) {
946 if (i < nInit) resolved[i].m(0.);
947 else resolved[i].m( particleDataPtr->m0( resolved[i].id() ) );
951 if (hasJunctionBeam && !allowJunction)
return false;
954 for (
int i = nInit; i < size(); ++i) {
955 int colType = particleDataPtr->colType( resolved[i].
id() );
956 int col = (colType == 1 || colType == 2) ? event.nextColTag() : 0;
957 int acol = (colType == -1 || colType == 2) ? event.nextColTag() : 0;
958 resolved[i].cols( col, acol);
970 bool BeamParticle::remnantColours(
Event& event, vector<int>& colFrom,
971 vector<int>& colTo) {
974 if (isLeptonBeam)
return true;
977 for (
int i = 0; i < size(); ++i) {
978 int j = resolved[i].iPos();
979 resolved[i].cols( event[j].col(), event[j].acol());
987 for (
int i = 0; i < size(); ++i)
988 if (resolved[i].isFromBeam()) {
989 if ( resolved[i].isValence() ) iVal.push_back(i);
990 else if ( resolved[i].isCompanion() && resolved[i].companion() > i )
992 else if ( resolved[i].
id() == 21
993 && resolved[i].col() != resolved[i].acol() ) iGlu.push_back(i);
999 if (iVal.size() != 0) {
1001 if (iVal.size() == 2) {
1002 if ( abs(resolved[iValSel].
id()) > 10 ) iValSel = iVal[1];
1003 }
else if (iVal.size() >= 3) {
1004 double rndmValSel = 3. * rndmPtr->flat();
1005 if (rndmValSel > 1.) iValSel= iVal[1];
1006 if (rndmValSel > 2.) iValSel= iVal[2];
1012 bool hasCol = (resolved[iBeg].col() > 0);
1013 int begCol = (hasCol) ? resolved[iBeg].col() : resolved[iBeg].acol();
1016 vector<int> iGluRndm;
1017 for (
int i = 0; i < int(iGlu.size()); ++i)
1018 iGluRndm.push_back( iGlu[i] );
1019 for (
int iOrder = 0; iOrder < int(iGlu.size()); ++iOrder) {
1020 int iRndm = int(
double(iGluRndm.size()) * rndmPtr->flat());
1021 int iGluSel = iGluRndm[iRndm];
1022 iGluRndm[iRndm] = iGluRndm[iGluRndm.size() - 1];
1023 iGluRndm.pop_back();
1027 int endCol = (hasCol) ? resolved[iEnd].acol() : resolved[iEnd].col();
1030 iEnd = resolved[iEnd].companion();
1031 endCol = (hasCol) ? resolved[iEnd].acol() : resolved[iEnd].col();
1035 if (begCol < endCol) {
1036 if (hasCol) resolved[iEnd].acol(begCol);
1037 else resolved[iEnd].col(begCol);
1038 colFrom.push_back(endCol);
1039 colTo.push_back(begCol);
1041 if (hasCol) resolved[iBeg].col(endCol);
1042 else resolved[iBeg].acol(endCol);
1043 colFrom.push_back(begCol);
1044 colTo.push_back(endCol);
1049 begCol = (hasCol) ? resolved[iBeg].col() : resolved[iBeg].acol();
1052 iBeg = resolved[iBeg].companion();
1053 begCol = (hasCol) ? resolved[iBeg].col() : resolved[iBeg].acol();
1061 vector<int> colList;
1062 vector<int> acolList;
1063 for (
int i = 0; i < size(); ++i)
1064 if ( resolved[i].isFromBeam() )
1065 if ( resolved[i].col() != resolved[i].acol() ) {
1066 if (resolved[i].col() > 0) colList.push_back( resolved[i].col() );
1067 if (resolved[i].acol() > 0) acolList.push_back( resolved[i].acol() );
1071 bool foundPair =
true;
1072 while (foundPair && colList.size() > 0 && acolList.size() > 0) {
1074 for (
int iCol = 0; iCol < int(colList.size()); ++iCol) {
1075 for (
int iAcol = 0; iAcol < int(acolList.size()); ++iAcol) {
1076 if (acolList[iAcol] == colList[iCol]) {
1077 colList[iCol] = colList.back();
1079 acolList[iAcol] = acolList.back();
1080 acolList.pop_back();
1084 }
if (foundPair)
break;
1089 if (colList.size() == 1 && acolList.size() == 1) {
1090 int finalFrom = max( colList[0], acolList[0]);
1091 int finalTo = min( colList[0], acolList[0]);
1092 for (
int i = 0; i < size(); ++i)
1093 if ( resolved[i].isFromBeam() ) {
1094 if (resolved[i].col() == finalFrom) resolved[i].col(finalTo);
1095 if (resolved[i].acol() == finalFrom) resolved[i].acol(finalTo);
1097 colFrom.push_back(finalFrom);
1098 colTo.push_back(finalTo);
1101 }
else if (hasJunctionBeam && colList.size() == 3
1102 && acolList.size() == 0) {
1103 event.appendJunction( 1, colList[0], colList[1], colList[2]);
1104 junCol[0] = colList[0];
1105 junCol[1] = colList[1];
1106 junCol[2] = colList[2];
1107 }
else if (hasJunctionBeam && acolList.size() == 3
1108 && colList.size() == 0) {
1109 event.appendJunction( 2, acolList[0], acolList[1], acolList[2]);
1110 junCol[0] = acolList[0];
1111 junCol[1] = acolList[1];
1112 junCol[2] = acolList[2];
1115 }
else if (colList.size() > 0 || acolList.size() > 0) {
1116 infoPtr->errorMsg(
"Error in BeamParticle::remnantColours: "
1117 "leftover unmatched colours");
1122 for (
int i = nInit; i < size(); ++i)
1123 event[resolved[i].iPos()].cols( resolved[i].col(), resolved[i].acol() );
1134 double BeamParticle::xRemnant(
int i) {
1139 int idAbs = abs(resolved[i].
id());
1140 if (idAbs > 100 && (idAbs/10)%10 != 0) {
1144 }
else if (resolved[i].isValence()) {
1147 int id1 = resolved[i].id();
1149 if (abs(id1) > 1000) {
1150 id2 = (id1 > 0) ? (id1/100)%10 : -(((-id1)/100)%10);
1151 id1 = (id1 > 0) ? id1/1000 : -((-id1)/1000);
1155 for (
int iId = 0; iId < 2; ++iId) {
1156 int idNow = (iId == 0) ? id1 : id2;
1157 if (idNow == 0)
break;
1161 double xPow = valencePowerMeson;
1163 if (nValKinds == 3 || nValKinds == 1)
1164 xPow = (3. * rndmPtr->flat() < 2.)
1165 ? valencePowerUinP : valencePowerDinP ;
1166 else if (nValence(idNow) == 2) xPow = valencePowerUinP;
1167 else xPow = valencePowerDinP;
1169 do xPart = pow2( rndmPtr->flat() );
1170 while ( pow(1. - xPart, xPow) < rndmPtr->flat() );
1175 if (id2 != 0) x *= valenceDiqEnhance;
1178 }
else if (resolved[i].isCompanion()) {
1182 for (
int iInit = 0; iInit < nInit; ++iInit)
1183 if (resolved[iInit].isFromBeam()) xLeft -= resolved[iInit].x();
1184 double xCompanion = resolved[ resolved[i].companion() ].x();
1185 xCompanion /= (xLeft + xCompanion);
1188 do x = pow( xCompanion, rndmPtr->flat()) - xCompanion;
1189 while ( pow( (1. - x - xCompanion) / (1. - xCompanion), companionPower)
1190 * (pow2(x) + pow2(xCompanion)) / pow2(x + xCompanion)
1191 < rndmPtr->flat() );
1196 do x = pow(xGluonCutoff, 1 - rndmPtr->flat());
1197 while ( pow(1. - x, gluonPower) < rndmPtr->flat() );
1208 double BeamParticle::remnantMass(
int idIn) {
1214 double mRem = particleDataPtr->m0(
id());
1215 int valSign1 = (nValence(idIn) > 0) ? -1 : 1;
1216 mRem += valSign1 * particleDataPtr->m0(idIn);
1221 }
else if ( isGamma() ) {
1222 if ( isUnresolved() )
return 0.;
1223 double mRem = (idIn == 21) ? 2*( particleDataPtr->m0( idLight ) ) :
1224 particleDataPtr->m0( idIn );
1235 bool BeamParticle::roomFor1Remnant(
double eCM) {
1238 if (!isResolvedGamma)
return true;
1241 double x1 = resolved[0].x();
1242 int id1 = resolved[0].id();
1243 return roomFor1Remnant(id1, x1, eCM);
1250 bool BeamParticle::roomFor1Remnant(
int id1,
double x1,
double eCM) {
1257 double mRemnant = (id1 == 21) ? 2*( particleDataPtr->m0( idLight ) ) :
1258 particleDataPtr->m0( id1 );
1259 return ( mRemnant < eCM*( 1 - sqrt(x1) ) );
1266 bool BeamParticle::roomFor2Remnants(
int id1,
double x1,
double eCM) {
1270 double id2 = resolved[0].id();
1271 double x2 = resolved[0].x();
1275 double m1 = (id1 == 21) ? 2*( particleDataPtr->m0( idLight ) ) :
1276 particleDataPtr->m0( id1 );
1277 double m2 = (id2 == 21) ? 2*( particleDataPtr->m0( idLight ) ) :
1278 particleDataPtr->m0( id2 );
1279 return ( (m1 + m2) < eCM*sqrt( (1.0 - x1)*(1.0 - x2) ) );
1287 bool BeamParticle::roomForRemnants(BeamParticle beamOther) {
1290 double xLeftA = this->xMax(-1);
1291 double xLeftB = beamOther.xMax(-1);
1292 double eCM = infoPtr->eCM();
1293 double Wleft = eCM * sqrt(xLeftA * xLeftB);
1296 bool allGluonsA =
true;
1297 bool allGluonsB =
true;
1300 for (
int i = 0; i < this->size(); ++i)
1301 if ( resolved[i].
id() != 21 ) {
1304 if ( resolved[i].companion() < 0 && resolved[i].companion() != -3 )
1305 mRemA += particleDataPtr->m0( resolved[i].id() );
1307 for (
int i = 0; i < beamOther.size(); ++i)
1308 if ( beamOther[i].
id() != 21 ) {
1310 if ( beamOther[i].companion() < 0 && beamOther[i].companion() != -3 )
1311 mRemB += particleDataPtr->m0( beamOther[i].id() );
1316 if ( allGluonsA) mRemA = this->isGamma() ? 2*particleDataPtr->m0(2) : 0.;
1317 if ( allGluonsB) mRemB = beamOther.isGamma() ? 2*particleDataPtr->m0(2) : 0.;
1320 if ( Wleft < mRemA + mRemB )
return false;
1328 void BeamParticle::list()
const {
1331 cout <<
"\n -------- PYTHIA Partons resolved in beam -----------------"
1332 <<
"-------------------------------------------------------------\n"
1333 <<
"\n i iPos id x comp xqcomp pTfact "
1334 <<
"colours p_x p_y p_z e m \n";
1339 for (
int i = 0; i < size(); ++i) {
1340 ResolvedParton res = resolved[i];
1341 cout << fixed << setprecision(6) << setw(5) << i << setw(6) << res.iPos()
1342 << setw(8) << res.id() << setw(10) << res.x() << setw(6)
1343 << res.companion() << setw(10) << res.xqCompanion() << setw(10)
1344 << res.pTfactor() << setprecision(3) << setw(6) << res.col()
1345 << setw(6) << res.acol() << setw(11) << res.px() << setw(11)
1346 << res.py() << setw(11) << res.pz() << setw(11) << res.e()
1347 << setw(11) << res.m() <<
"\n";
1350 if (res.companion() != -10) {
1357 cout << setprecision(6) <<
" x sum:" << setw(10) << xSum
1358 << setprecision(3) <<
" p sum:"
1359 << setw(11) << pSum.px() << setw(11) << pSum.py() << setw(11)
1360 << pSum.pz() << setw(11) << pSum.e()
1361 <<
"\n\n -------- End PYTHIA Partons resolved in beam -----------"
1362 <<
"---------------------------------------------------------------"
1370 bool BeamParticle::isUnresolvedLepton() {
1373 if (!isLeptonBeam || resolved.size() > 2 || resolved[1].id() != 22
1374 || resolved[0].x() < XMINUNRESOLVED)
return false;
1383 bool BeamParticle::pickGluon(
double mDiff) {
1386 double probPickQuark = pickQuarkNorm / pow( mDiff, pickQuarkPower);
1387 return ( (1. + probPickQuark) * rndmPtr->flat() < 1. );
1395 int BeamParticle::pickValence() {
1398 int nTotVal = (isBaryonBeam) ? 3 : 2;
1399 double rnVal = rndmPtr->flat() * nTotVal;
1400 int iVal = (rnVal < 1.) ? 1 : ( (rnVal < 2.) ? 2 : 3 );
1407 for (
int i = 0; i < nValKinds; ++i)
1408 for (
int j = 0; j < nVal[i]; ++j) {
1410 if (iNow == iVal) idVal1 = idVal[i];
1411 else if ( idVal2 == 0) idVal2 = idVal[i];
1412 else idVal3 = idVal[i];
1416 if (idVal3 != 0) idVal2 = flavSelPtr->makeDiquark( idVal2, idVal3, idBeam);
1427 double BeamParticle::zShare(
double mDiff,
double m1,
double m2) {
1430 append(0, idVal1, 0., -3);
1431 append(0, idVal2, 0., -3);
1432 double m2Diff = mDiff*mDiff;
1437 double x1 = xRemnant(0);
1438 double x2 = xRemnant(0);
1439 zRel = max( TINYZREL, min( 1. - TINYZREL, x1 / (x1 + x2) ) );
1440 pair<double, double> gauss2 = rndmPtr->gauss2();
1441 pxRel = diffPrimKTwidth * gauss2.first;
1442 pyRel = diffPrimKTwidth * gauss2.second;
1445 double mTS1 = m1*m1 + pxRel*pxRel + pyRel*pyRel;
1446 double mTS2 = m2*m2 + pxRel*pxRel + pyRel*pyRel;
1447 double m2Sys = mTS1 / zRel + mTS2 / (1. - zRel);
1448 wtAcc = (m2Sys < m2Diff)
1449 ? pow( 1. - m2Sys / m2Diff, diffLargeMassSuppress) : 0.;
1450 }
while (wtAcc < rndmPtr->flat());
1462 void BeamParticle::findColSetup(
Event& event) {
1465 colSetup = make_pair(0,0);
1473 vector<vector <vector <ColState> > > colStates;
1474 colStates.resize(size() + 1);
1475 for (
int i = 0; i < size() + 1; ++i) {
1476 colStates[i].resize(2*(i + 1));
1477 for (
int j = 0; j < 2*(i+1); ++j)
1478 colStates[i][j].resize(2*(i+1));
1480 colStates[0][0][0].nTotal = 1.;
1482 bool noColouredParticles =
true;
1484 for (
int i = 0; i < size(); ++i) {
1485 for (
int j = 0; j < int(colStates[i].size()); ++j) {
1486 for (
int k = 0; k < int(colStates[i][j].size()); ++k) {
1487 if (colStates[i][j][k].nTotal < 0.5)
continue;
1488 int idParton = resolved[i].id();
1491 if (idParton > 0 && idParton < 9) {
1492 colStates[i+1][j+1][k].lastSteps.push_back(make_pair(j,k));
1493 colStates[i+1][j+1][k].nTotal += colStates[i][j][k].nTotal;
1495 colStates[i+1][j][k -1].lastSteps.push_back(make_pair(j,k));
1496 colStates[i+1][j][k -1].nTotal += colStates[i][j][k].nTotal;
1500 if (j > 0 && allowBeamJunctions) {
1501 colStates[i+1][j - 1][k + 1].lastSteps.push_back(make_pair(j,k));
1502 colStates[i+1][j - 1][k + 1].nTotal += colStates[i][j][k].nTotal;
1507 if (idParton < 0 && idParton > -9) {
1508 colStates[i+1][j][k + 1].lastSteps.push_back(make_pair(j,k));
1509 colStates[i+1][j][k + 1].nTotal += colStates[i][j][k].nTotal;
1511 colStates[i+1][j - 1][k].lastSteps.push_back(make_pair(j,k));
1512 colStates[i+1][j - 1][k].nTotal += colStates[i][j][k].nTotal;
1516 if (k > 0 && allowBeamJunctions) {
1517 colStates[i+1][j + 1][k - 1].lastSteps.push_back(make_pair(j,k));
1518 colStates[i+1][j + 1][k - 1].nTotal += colStates[i][j][k].nTotal;
1523 if (idParton == 21) {
1524 colStates[i+1][j + 1][k + 1].lastSteps.push_back(make_pair(j,k));
1525 colStates[i+1][j + 1][k + 1].nTotal += colStates[i][j][k].nTotal;
1527 colStates[i+1][j][k].lastSteps.push_back(make_pair(j,k));
1528 colStates[i+1][j][k].nTotal += colStates[i][j][k].nTotal;
1531 colStates[i+1][j][k].lastSteps.push_back(make_pair(j,k));
1532 colStates[i+1][j][k].nTotal += colStates[i][j][k].nTotal;
1534 if (j > 0 && k > 0) {
1535 colStates[i+1][j - 1][k - 1].lastSteps.push_back(make_pair(j,k));
1536 colStates[i+1][j - 1][k - 1].nTotal += colStates[i][j][k].nTotal;
1540 if (k > 0 && allowBeamJunctions) {
1541 colStates[i+1][j + 2][k - 1].lastSteps.push_back(make_pair(j,k));
1542 colStates[i+1][j + 2][k - 1].nTotal += colStates[i][j][k].nTotal;
1544 if (j > 0 && allowBeamJunctions) {
1545 colStates[i+1][j - 1][k + 2].lastSteps.push_back(make_pair(j,k));
1546 colStates[i+1][j - 1][k + 2].nTotal += colStates[i][j][k].nTotal;
1548 if (j > 1 && allowBeamJunctions) {
1549 colStates[i+1][j - 2][k + 1].lastSteps.push_back(make_pair(j,k));
1550 colStates[i+1][j - 2][k + 1].nTotal += colStates[i][j][k].nTotal;
1552 if (k > 1 && allowBeamJunctions) {
1553 colStates[i+1][j + 1][k - 2].lastSteps.push_back(make_pair(j,k));
1554 colStates[i+1][j + 1][k - 2].nTotal += colStates[i][j][k].nTotal;
1558 if (idParton != 21 && abs(idParton) > 9) {
1559 colStates[i+1][j][k].lastSteps.push_back(make_pair(j,k));
1560 colStates[i+1][j][k].nTotal += colStates[i][j][k].nTotal;
1562 noColouredParticles =
false;
1569 double totalSize = 0;
1570 for (
int i = 0;i < int(colStates[size()].size()); ++i) {
1571 for (
int j = 0;j < int(colStates[size()][i].size()); ++j) {
1574 if (i == 0 && j == 0 && !noColouredParticles)
continue;
1576 double multipletSize = (i + 1) * (j + 1) * (i + j + 2) / 2.;
1577 totalSize += colStates[size()][i][j].nTotal *
1578 multipletSize * exp(-multipletSize / beamSat);
1584 double chosenSize = rndmPtr->flat() * totalSize;
1585 for (
int i = 0;i < int(colStates[size()].size()); ++i) {
1586 for (
int j = 0;j < int(colStates[size()][i].size()); ++j) {
1589 if (i == 0 && j == 0 && !noColouredParticles)
continue;
1592 double multipletSize = (i + 1) * (j + 1) * (i + j + 2) / 2.;
1593 curSize += colStates[size()][i][j].nTotal *
1594 multipletSize * exp(-multipletSize / beamSat);
1595 if (curSize > chosenSize) {
1597 colSetup.second = j;
1601 if (curSize > chosenSize)
break;
1605 vector<pair<int, int> > colSetupChain;
1606 colSetupChain.resize(size() + 1);
1607 pair<int,int> curColSetup = make_pair(colSetup.first, colSetup.second);
1608 for (
int i = size(); i > 0; --i) {
1609 colSetupChain[i] = curColSetup;
1610 int curColSize = colStates[i][curColSetup.first][curColSetup.second].
1612 int iCurCol = int(rndmPtr->flat() * curColSize);
1613 curColSetup = colStates[i][curColSetup.first][curColSetup.second].
1616 colSetupChain[0] = curColSetup;
1620 for (
int i = 0; i < size() ; ++i) {
1623 if (resolved[i].
id() > 0 && resolved[i].id() < 9) {
1625 if (colSetupChain[i].first + 1 == colSetupChain[i + 1].first)
1626 cols.push_back(resolved[i].col());
1629 else if (colSetupChain[i].second - 1 == colSetupChain[i + 1].second) {
1630 int iAcol = int(acols.size() * rndmPtr->flat());
1631 int acol = acols[iAcol];
1632 acols.erase(acols.begin() + iAcol);
1633 updateSingleCol(acol, resolved[i].col());
1638 int iCol = int(cols.size() * rndmPtr->flat());
1639 int juncCol =
event.nextColTag();
1640 event.appendJunction(1, cols[iCol], resolved[i].col(), juncCol);
1641 event.saveJunctionSize();
1642 acols.push_back(juncCol);
1643 cols.erase(cols.begin() + iCol);
1649 if (resolved[i].
id() < 0 && resolved[i].id() > -9) {
1651 if (colSetupChain[i].second + 1 == colSetupChain[i + 1].second)
1652 acols.push_back(resolved[i].acol());
1655 else if (colSetupChain[i].first - 1 == colSetupChain[i + 1].first) {
1656 int iCol = int(cols.size() * rndmPtr->flat());
1657 int col = cols[iCol];
1658 cols.erase(cols.begin() + iCol);
1659 updateSingleCol(col, resolved[i].acol());
1664 int iAcol = int(acols.size() * rndmPtr->flat());
1665 int juncCol =
event.nextColTag();
1666 event.appendJunction(2, acols[iAcol], resolved[i].acol(), juncCol);
1667 event.saveJunctionSize();
1668 cols.push_back(juncCol);
1669 acols.erase(acols.begin() + iAcol);
1675 if (resolved[i].
id() == 21) {
1677 if (colSetupChain[i].first + 1 == colSetupChain[i + 1].first &&
1678 colSetupChain[i].second + 1 == colSetupChain[i + 1].second ) {
1679 acols.push_back(resolved[i].acol());
1680 cols.push_back(resolved[i].col());
1684 if (colSetupChain[i].first - 1 == colSetupChain[i + 1].first &&
1685 colSetupChain[i].second - 1 == colSetupChain[i + 1].second ) {
1687 int iCol = int(cols.size() * rndmPtr->flat());
1688 int col = cols[iCol];
1689 cols.erase(cols.begin() + iCol);
1690 updateSingleCol(col, resolved[i].acol());
1692 int iAcol = int(acols.size() * rndmPtr->flat());
1693 int acol = acols[iAcol];
1694 acols.erase(acols.begin() + iAcol);
1695 updateSingleCol(acol, resolved[i].col());
1700 if (colSetupChain[i].first == colSetupChain[i + 1].first &&
1701 colSetupChain[i].second == colSetupChain[i + 1].second ) {
1702 bool removeColour =
true;
1703 if (cols.size() > 0 && acols.size() > 0)
1704 removeColour = (rndmPtr->flat() > 0.5);
1705 else if (acols.size() > 0)
1706 removeColour =
false;
1709 int iCol = int(cols.size() * rndmPtr->flat());
1710 int col = cols[iCol];
1711 cols.erase(cols.begin() + iCol);
1712 cols.push_back(resolved[i].col());
1713 updateSingleCol(col, resolved[i].acol());
1717 int iAcol = int(acols.size() * rndmPtr->flat());
1718 int acol = acols[iAcol];
1719 acols.erase(acols.begin() + iAcol);
1720 acols.push_back(resolved[i].acol());
1721 updateSingleCol(acol, resolved[i].col());
1728 if (colSetupChain[i].first + 2 == colSetupChain[i + 1].first &&
1729 colSetupChain[i].second - 1 == colSetupChain[i + 1].second ) {
1730 int iAcol = int(acols.size() * rndmPtr->flat());
1731 int acol = acols[iAcol];
1732 acols.erase(acols.begin() + iAcol);
1733 int acol3 =
event.nextColTag();
1734 event.appendJunction(2,acol,resolved[i].acol(),acol3);
1735 cols.push_back(resolved[i].col());
1736 cols.push_back(acol3);
1741 if (colSetupChain[i].first - 1 == colSetupChain[i + 1].first &&
1742 colSetupChain[i].second + 2 == colSetupChain[i + 1].second ) {
1743 int iCol = int(cols.size() * rndmPtr->flat());
1744 int col = cols[iCol];
1745 cols.erase(cols.begin() + iCol);
1746 int col3 =
event.nextColTag();
1747 event.appendJunction(1,col,resolved[i].col(),col3);
1748 acols.push_back(resolved[i].acol());
1749 acols.push_back(col3);
1754 if (colSetupChain[i].first + 1 == colSetupChain[i + 1].first &&
1755 colSetupChain[i].second - 2 == colSetupChain[i + 1].second ) {
1756 int iAcol = int(acols.size() * rndmPtr->flat());
1757 int acol = acols[iAcol];
1758 acols.erase(acols.begin() + iAcol);
1759 int iAcol2 = int(acols.size() * rndmPtr->flat());
1760 int acol2 = acols[iAcol2];
1761 acols.erase(acols.begin() + iAcol2);
1762 event.appendJunction(2,acol,resolved[i].acol(),acol2);
1763 cols.push_back(resolved[i].col());
1768 if (colSetupChain[i].first - 2 == colSetupChain[i + 1].first &&
1769 colSetupChain[i].second + 1 == colSetupChain[i + 1].second ) {
1770 int iCol = int(cols.size() * rndmPtr->flat());
1771 int col = cols[iCol];
1772 cols.erase(cols.begin() + iCol);
1773 int iCol2 = int(cols.size() * rndmPtr->flat());
1774 int col2 = cols[iCol2];
1775 cols.erase(cols.begin() + iCol2);
1776 event.appendJunction(1,col,resolved[i].col(),col2);
1777 acols.push_back(resolved[i].acol());
1790 bool BeamParticle::remnantFlavoursNew(
Event& event) {
1793 hasJunctionBeam = (isBaryon());
1799 for (
int i = 0; i < nValKinds; ++i) {
1800 nValLeft[i] = nVal[i];
1801 for (
int j = 0; j < nInit; ++j)
if (resolved[j].isValence()
1802 && resolved[j].
id() == idVal[i]) --nValLeft[i];
1804 for (
int k = 0; k < nValLeft[i]; ++k) append(0, idVal[i], 0., -3);
1806 int nInitPlusVal = size();
1809 for (
int i = 0; i < nInit; ++i)
1810 if (resolved[i].isUnmatched()) {
1813 append(0, -resolved[i].
id(), 0., i);
1814 resolved[i].companion(size() - 1);
1817 if (isBaryon()) beamJunc = 1;
1818 if (
id() < 0) beamJunc = -beamJunc;
1821 int nGluons = (colSetup.first + colSetup.second - (size() - nInit)
1822 +abs( (nJuncs - nAjuncs) - beamJunc)) / 2;
1823 for (
int i = 0; i < nGluons; i++) append(0,21,0.,-1);
1827 if (size() == nInit) {
1829 append(0, 22, 0., -1);
1831 int idRemnant = int(3*rndmPtr->flat())+1;
1832 append(0, -idRemnant, 0., -1);
1833 append(0, idRemnant, 0., -1);
1834 resolved[size()-2].companion(size() - 1);
1835 resolved[size()-1].companion(size() - 2);
1839 usedCol = vector<bool>(size(),
false);
1840 usedAcol = vector<bool>(size(),
false);
1844 nDiffJuncs = nJuncs - nAjuncs - beamJunc;
1845 if (isBaryon() && nInitPlusVal - nInit >= 2 && (
1846 (nDiffJuncs > 0 && beamJunc < 0) ||
1847 (nDiffJuncs < 0 && beamJunc > 0)) ) {
1851 int iQ2 = nInit + 1;
1852 if (nInitPlusVal - nInit == 3) {
1853 double pickDq = 3. * rndmPtr->flat();
1854 if (pickDq > 1.) iQ2 = nInit + 2;
1855 if (pickDq > 2.) iQ1 = nInit + 1;
1861 if (resolved[iQ1].
id() < 0) {
1864 usedAcol[iQ1] =
true;
1865 usedAcol[iQ2] =
true;
1868 int acol = findSingleCol(event,
true,
true);
1869 if ( acol == 0)
return false;
1872 int newCol1 =
event.nextColTag();
1873 int newCol2 =
event.nextColTag();
1874 resolved[iQ1].acol(newCol1);
1875 resolved[iQ2].acol(newCol2);
1876 event.appendJunction(2, resolved[iQ1].acol(), resolved[iQ2].acol(),
1884 usedCol[iQ1] =
true;
1885 usedCol[iQ2] =
true;
1888 int col = findSingleCol(event,
false,
true);
1889 if (col == 0)
return false;
1892 int newCol1 =
event.nextColTag();
1893 int newCol2 =
event.nextColTag();
1894 resolved[iQ1].col(newCol1);
1895 resolved[iQ2].col(newCol2);
1896 event.appendJunction(1,resolved[iQ1].col(),resolved[iQ2].col(),col);
1904 int idDq = flavSelPtr->makeDiquark( resolved[iQ1].
id(),
1905 resolved[iQ2].
id(), idBeam);
1908 if (nInitPlusVal - nInit == 3)
1909 resolved[nInit + 2].id( resolved[3 * nInit + 3 - iQ2 - iQ1].
id() );
1910 resolved[nInit].id(idDq);
1911 resolved.erase(resolved.begin() + nInit + 1);
1912 hasJunctionBeam =
false;
1915 if (idDq > 0) nDiffJuncs++;
1921 while (nDiffJuncs > 0) {
1922 int acol1 = findSingleCol(event,
true,
false);
1923 int acol2 = findSingleCol(event,
true,
false);
1924 int acol3 = findSingleCol(event,
true,
true);
1925 event.appendJunction(2,acol1,acol2,acol3);
1929 while (nDiffJuncs < 0) {
1930 int col1 = findSingleCol(event,
false,
false);
1931 int col2 = findSingleCol(event,
false,
false);
1932 int col3 = findSingleCol(event,
false,
true);
1933 event.appendJunction(1,col1,col2,col3);
1938 for (
int j = 0;j < NRANDOMTRIES; ++j) {
1939 int i = int(rndmPtr->flat() * (size() - nInit) + nInit );
1941 if ( resolved[i].hasCol() && !usedCol[i]) {
1943 int acol = findSingleCol(event,
true,
true);
1944 if ( acol == 0)
return false;
1945 resolved[i].col(acol);
1948 if ( resolved[i].hasAcol() && !usedAcol[i]) {
1950 int col = findSingleCol(event,
false,
true);
1951 if (col == 0)
return false;
1952 resolved[i].acol(col);
1957 for (
int i = nInit;i < size();i++) {
1959 if ( resolved[i].hasCol() && !usedCol[i]) {
1961 int acol = findSingleCol(event,
true,
true);
1962 if ( acol == 0)
return false;
1963 resolved[i].col(acol);
1966 if ( resolved[i].hasAcol() && !usedAcol[i]) {
1968 int col = findSingleCol(event,
false,
true);
1969 if (col == 0)
return false;
1970 resolved[i].acol(col);
1975 if (cols.size() != 0 || acols.size() != 0) {
1976 infoPtr->errorMsg(
"Error in BeamParticle::RemnantFlavours: "
1977 "Colour not conserved in beamRemnants");
1982 for (
int i = 0; i < size(); ++i) {
1983 if (i < nInit) resolved[i].m(0.);
1984 else resolved[i].m( particleDataPtr->m0( resolved[i].id() ) );
1988 if (hasJunctionBeam && !allowJunction)
return false;
1999 void BeamParticle::setInitialCol(
Event& event) {
2002 for (
int i = 0;i < size(); ++i) {
2003 if (event[resolved[i].iPos()].col() != 0)
2004 resolved[i].col(event[resolved[i].iPos()].col());
2005 if (event[resolved[i].iPos()].acol() != 0)
2006 resolved[i].acol(event[resolved[i].iPos()].acol());
2015 int BeamParticle::findSingleCol(
Event& event,
bool isAcol,
2016 bool useHardScatters) {
2019 if (useHardScatters) {
2021 if (acols.size() > 0) {
2022 int iAcol = int(acols.size() * rndmPtr->flat());
2023 int acol = acols[iAcol];
2024 acols.erase(acols.begin() + iAcol);
2028 if (
int(cols.size()) > 0) {
2029 int iCol = int(cols.size() * rndmPtr->flat());
2030 int col = cols[iCol];
2031 cols.erase(cols.begin() + iCol);
2039 for (
int i = 0;i < NMAX; ++i) {
2040 int iBeam = int((size() - nInit) * rndmPtr->flat()) + nInit;
2041 if (resolved[iBeam].hasAcol() && !usedAcol[iBeam]) {
2042 int acol =
event.nextColTag();
2043 resolved[iBeam].acol(acol);
2044 usedAcol[iBeam] =
true;
2049 for (
int i = 0; i < NMAX; ++i) {
2050 int iBeam = int((size() - nInit) * rndmPtr->flat()) + nInit;
2051 if (resolved[iBeam].hasCol() && !usedCol[iBeam]) {
2052 int col =
event.nextColTag();
2053 resolved[iBeam].col(col);
2054 usedCol[iBeam] =
true;
2061 infoPtr->errorMsg(
"Error in BeamParticle::findSingleCol: "
2062 "could not find matching anti colour");
2070 void BeamParticle::updateCol(vector<pair<int,int> > colourChanges) {
2072 for (
int iCol = 0;iCol < int(colourChanges.size()); ++iCol) {
2073 int oldCol = colourChanges[iCol].first;
2074 int newCol = colourChanges[iCol].second;
2077 for (
int i = 0;i < int(cols.size()); ++i)
2078 if (cols[i] == oldCol) cols[i] = newCol;
2079 for (
int i = 0;i < int(acols.size()); ++i)
2080 if (acols[i] == oldCol) acols[i] = newCol;
2083 for (
int i = 0;i < int(resolved.size()); ++i) {
2084 if (resolved[i].acol() == oldCol) resolved[i].acol(newCol);
2085 if (resolved[i].col() == oldCol) resolved[i].col(newCol);
2093 void BeamParticle::updateSingleCol(
int oldCol,
int newCol) {
2096 for (
int i = 0; i < int(cols.size()); ++i)
2097 if (cols[i] == oldCol) cols[i] = newCol;
2099 for (
int i = 0; i < int(acols.size()); ++i)
2100 if (acols[i] == oldCol) acols[i] = newCol;
2103 for (
int i = 0; i < int(resolved.size()); ++i) {
2104 if (resolved[i].acol() == oldCol) resolved[i].acol(newCol);
2105 if (resolved[i].col() == oldCol) resolved[i].col(newCol);
2108 colUpdates.push_back(make_pair(oldCol,newCol));