8 #include "Pythia8/HadronLevel.h"
22 const double HadronLevel::JJSTRINGM2MAX = 25.;
23 const double HadronLevel::JJSTRINGM2FRAC = 0.1;
26 const double HadronLevel::CONVJNREST = 1e-5;
27 const int HadronLevel::NTRYJNREST = 20;
30 const double HadronLevel::MTHAD = 0.9;
36 bool HadronLevel::init(Info* infoPtrIn, Settings& settings,
37 ParticleData* particleDataPtrIn, Rndm* rndmPtrIn,
38 Couplings* couplingsPtrIn, TimeShower* timesDecPtr,
39 RHadrons* rHadronsPtrIn, DecayHandler* decayHandlePtr,
40 vector<int> handledParticles) {
44 particleDataPtr = particleDataPtrIn;
46 couplingsPtr = couplingsPtrIn;
47 rHadronsPtr = rHadronsPtrIn;
50 doHadronize = settings.flag(
"HadronLevel:Hadronize");
51 doDecay = settings.flag(
"HadronLevel:Decay");
52 doBoseEinstein = settings.flag(
"HadronLevel:BoseEinstein");
55 mStringMin = settings.parm(
"HadronLevel:mStringMin");
58 eNormJunction = settings.parm(
"StringFragmentation:eNormJunction");
61 allowRH = settings.flag(
"RHadrons:allow");
64 widthSepBE = settings.parm(
"BoseEinstein:widthSep");
67 doHadronScatter = settings.flag(
"HadronScatter:scatter");
68 hsAfterDecay = settings.flag(
"HadronScatter:afterDecay");
71 flavSel.init(settings, rndmPtr);
72 pTSel.init(settings, *particleDataPtr, rndmPtr);
73 zSel.init(settings, *particleDataPtr, rndmPtr);
76 colConfig.init(infoPtr, settings, &flavSel);
79 stringFrag.init(infoPtr, settings, particleDataPtr, rndmPtr,
80 &flavSel, &pTSel, &zSel);
81 ministringFrag.init(infoPtr, settings, particleDataPtr, rndmPtr,
82 &flavSel, &pTSel, &zSel);
85 decays.init(infoPtr, settings, particleDataPtr, rndmPtr, couplingsPtr,
86 timesDecPtr, &flavSel, decayHandlePtr, handledParticles);
89 boseEinstein.init(infoPtr, settings, *particleDataPtr);
93 hadronScatter.init(infoPtr, settings, rndmPtr, particleDataPtr);
96 useHiddenValley = hiddenvalleyFrag.init(infoPtr, settings,
97 particleDataPtr, rndmPtr);
100 rHadronsPtr->fragPtrs( &flavSel, &zSel);
111 bool HadronLevel::next(
Event& event) {
114 if (useHiddenValley) hiddenvalleyFrag.fragment(event);
117 if (!decayOctetOnia(event))
return false;
121 bool moreToDo, firstPass =
true;
122 bool doBoseEinsteinNow = doBoseEinstein;
130 if (!findSinglets( event))
return false;
133 if (allowRH && !rHadronsPtr->produce( colConfig, event))
137 for (
int iSub = 0; iSub < colConfig.size(); ++iSub) {
140 colConfig.collect(iSub, event);
143 if ( colConfig[iSub].massExcess > mStringMin ) {
144 if (!stringFrag.fragment( iSub, colConfig, event))
return false;
148 bool isDiff = infoPtr->isDiffractiveA()
149 || infoPtr->isDiffractiveB();
150 if (!ministringFrag.fragment( iSub, colConfig, event, isDiff))
157 if (doHadronScatter && !hsAfterDecay && firstPass)
158 hadronScatter.scatter(event);
166 Particle& decayer =
event[iDec];
167 if ( decayer.isFinal() && decayer.canDecay() && decayer.mayDecay()
168 && (decayer.mWidth() > widthSepBE || decayer.idAbs() == 311) ) {
169 decays.decay( iDec, event);
170 if (decays.moreToDo()) moreToDo =
true;
172 }
while (++iDec < event.size());
176 if (doHadronScatter && hsAfterDecay && firstPass)
177 hadronScatter.scatter(event);
180 if (doBoseEinsteinNow) {
181 if (!boseEinstein.shiftEvent(event))
return false;
182 doBoseEinsteinNow =
false;
191 Particle& decayer =
event[iDec];
192 if ( decayer.isFinal() && decayer.canDecay() && decayer.mayDecay() ) {
193 decays.decay( iDec, event);
194 if (decays.moreToDo()) moreToDo =
true;
196 }
while (++iDec < event.size());
212 bool HadronLevel::moreDecays(
Event& event) {
215 if (!decayOctetOnia(event))
return false;
220 if ( event[iDec].isFinal() && event[iDec].canDecay()
221 && event[iDec].mayDecay() ) decays.decay( iDec, event);
222 }
while (++iDec < event.size());
233 bool HadronLevel::decayOctetOnia(
Event& event) {
236 for (
int iDec = 0; iDec <
event.size(); ++iDec)
237 if (event[iDec].isFinal()
238 && particleDataPtr->isOctetHadron(event[iDec].
id())) {
239 if (!decays.decay( iDec, event))
return false;
242 int iGlu =
event.size() - 1;
243 event[iGlu].cols( event[iDec].col(), event[iDec].acol() );
255 bool HadronLevel::findSinglets(
Event& event) {
260 iColAndAcol.resize(0);
261 for (
int i = 0; i <
event.size(); ++i)
if (event[i].isFinal()) {
262 if (event[i].col() > 0 &&
event[i].acol() > 0) iColAndAcol.push_back(i);
263 else if (event[i].col() > 0) iColEnd.push_back(i);
264 else if (event[i].acol() > 0) iAcolEnd.push_back(i);
269 iPartonJun.resize(0);
270 iPartonAntiJun.resize(0);
273 if (iColEnd.size() == 0 && iAcolEnd.size() == 0
274 && iColAndAcol.size() == 0)
return true;
277 for (
int iJun = 0; iJun <
event.sizeJunction(); ++iJun)
278 if (event.remainsJunction(iJun)) {
279 event.remainsJunction(iJun,
false);
280 int kindJun =
event.kindJunction(iJun);
284 for (
int iCol = 0; iCol < 3; ++iCol) {
285 int indxCol =
event.colJunction(iJun, iCol);
286 iParton.push_back( -(10 + 10 * iJun + iCol) );
288 if (kindJun % 2 == 1 && !traceFromAcol(indxCol, event, iJun, iCol))
291 if (kindJun % 2 == 0 && !traceFromCol(indxCol, event, iJun, iCol))
297 for (
int i = 0; i < int(iParton.size()); ++i)
298 if (iParton[i] < 0 && abs(iParton[i]) / 10 != iJun + 1) {
299 if (otherJun == 0) otherJun = abs(iParton[i]) / 10;
300 else if (abs(iParton[i]) / 10 != otherJun) {
301 infoPtr->errorMsg(
"Error in HadronLevel::findSinglets: "
302 "too many junction-junction connections");
310 for (
int i = 0; i < int(iParton.size()); ++i)
if (iParton[i] < 0)
312 if (nNeg > 3 && kindJun % 2 == 1) {
313 iPartonJun.push_back(iParton);
314 }
else if (nNeg > 3 && kindJun % 2 == 0) {
315 iPartonAntiJun.push_back(iParton);
318 int nJunOld =
event.sizeJunction();
319 if (!colConfig.insert(iParton, event))
return false;
320 if (event.sizeJunction() < nJunOld) {
323 for (
int i = 0;i < int(iPartonJun.size());++i)
324 for (
int j = 0;j < int(iPartonJun[i].size()); ++j)
325 if (iPartonJun[i][j] < -(10 + 10 * iJun)) iPartonJun[i][j] += 10;
326 for (
int i = 0;i < int(iPartonAntiJun.size());++i)
327 for (
int j = 0;j < int(iPartonAntiJun[i].size()); ++j)
328 if (iPartonAntiJun[i][j] < -(10 + 10 * iJun))
329 iPartonAntiJun[i][j] += 10;
339 if (iPartonJun.size() > 0 && iPartonAntiJun.size() > 0) {
340 if (!splitJunctionPair(event))
return false;
341 for (
int i = 0; i < int(iPartonJun.size()); ++i)
342 if (iPartonJun[i].size() > 0)
343 if (!colConfig.insert(iPartonJun[i], event))
return false;
345 for (
int i = 0; i < int(iPartonAntiJun.size()); ++i)
346 if (iPartonAntiJun[i].size() > 0)
347 if (!colConfig.insert(iPartonAntiJun[i], event))
return false;
351 if ( iPartonJun.size() != iPartonAntiJun.size() ) {
352 infoPtr->errorMsg(
"Error in HadronLevel::findSinglets: "
353 "unmatched (anti)junction");
358 for (
int iEnd = 0; iEnd < int(iColEnd.size()); ++iEnd) {
360 iParton.push_back( iColEnd[iEnd] );
361 int indxCol =
event[ iColEnd[iEnd] ].col();
362 if (!traceFromCol(indxCol, event))
return false;
365 if (!colConfig.insert(iParton, event))
return false;
369 while (iColAndAcol.size() > 0) {
371 iParton.push_back( iColAndAcol[0] );
372 int indxCol =
event[ iColAndAcol[0] ].col();
373 int indxAcol =
event[ iColAndAcol[0] ].acol();
374 iColAndAcol[0] = iColAndAcol.back();
375 iColAndAcol.pop_back();
376 if (!traceInLoop(indxCol, indxAcol, event))
return false;
379 if (!colConfig.insert(iParton, event))
return false;
391 bool HadronLevel::traceFromCol(
int indxCol,
Event& event,
int iJun,
395 int kindJun = (iJun >= 0) ? event.kindJunction(iJun) : 0;
399 int loopMax = iColAndAcol.size() + 2;
400 bool hasFound =
false;
406 for (
int i = 0; i < int(iAcolEnd.size()); ++i)
407 if (event[ iAcolEnd[i] ].acol() == indxCol) {
408 iParton.push_back( iAcolEnd[i] );
410 iAcolEnd[i] = iAcolEnd.back();
418 for (
int i = 0; i < int(iColAndAcol.size()); ++i)
419 if (event[ iColAndAcol[i] ].acol() == indxCol) {
420 iParton.push_back( iColAndAcol[i] );
423 indxCol =
event[ iColAndAcol[i] ].col();
424 if (kindJun > 0)
event.endColJunction(iJun, iCol, indxCol);
425 iColAndAcol[i] = iColAndAcol.back();
426 iColAndAcol.pop_back();
433 for (
int iAntiJun = 0; iAntiJun <
event.sizeJunction(); ++iAntiJun)
434 if (iAntiJun != iJun && event.kindJunction(iAntiJun) %2 == 1)
435 for (
int iColAnti = 0; iColAnti < 3; ++iColAnti)
436 if (event.colJunction(iAntiJun, iColAnti) == indxCol) {
437 iParton.push_back( -(10 + 10 * iAntiJun + iColAnti) );
445 if (!hasFound && kindJun % 2 == 0 && event.sizeJunction() > 1)
446 for (
int iAntiJun = 0; iAntiJun <
event.sizeJunction(); ++iAntiJun)
447 if (iAntiJun != iJun && event.kindJunction(iAntiJun) %2 == 1)
448 for (
int iColAnti = 0; iColAnti < 3; ++iColAnti)
449 if (event.endColJunction(iAntiJun, iColAnti) == indxCol) {
450 iParton.push_back( -(10 + 10 * iAntiJun + iColAnti) );
457 }
while (hasFound && indxCol > 0 && loop < loopMax);
460 if (!hasFound || loop == loopMax) {
461 infoPtr->errorMsg(
"Error in HadronLevel::traceFromCol: "
462 "colour tracing failed");
475 bool HadronLevel::traceFromAcol(
int indxCol,
Event& event,
int iJun,
479 int kindJun = (iJun >= 0) ? event.kindJunction(iJun) : 0;
483 int loopMax = iColAndAcol.size() + 2;
484 bool hasFound =
false;
490 for (
int i = 0; i < int(iColEnd.size()); ++i)
491 if (event[ iColEnd[i] ].col() == indxCol) {
492 iParton.push_back( iColEnd[i] );
494 iColEnd[i] = iColEnd.back();
502 for (
int i = 0; i < int(iColAndAcol.size()); ++i)
503 if (event[ iColAndAcol[i] ].col() == indxCol) {
504 iParton.push_back( iColAndAcol[i] );
506 indxCol =
event[ iColAndAcol[i] ].acol();
507 if (kindJun > 0)
event.endColJunction(iJun, iCol, indxCol);
508 iColAndAcol[i] = iColAndAcol.back();
509 iColAndAcol.pop_back();
516 for (
int iAntiJun = 0; iAntiJun <
event.sizeJunction(); ++iAntiJun)
517 if (iAntiJun != iJun && event.kindJunction(iAntiJun) % 2 == 0)
518 for (
int iColAnti = 0; iColAnti < 3; ++iColAnti)
519 if (event.colJunction(iAntiJun, iColAnti) == indxCol) {
520 iParton.push_back( -(10 + 10 * iAntiJun + iColAnti) );
528 if (!hasFound && kindJun % 2 == 1 && event.sizeJunction() > 1)
529 for (
int iAntiJun = 0; iAntiJun <
event.sizeJunction(); ++iAntiJun)
530 if (iAntiJun != iJun && event.kindJunction(iAntiJun) % 2 == 0)
531 for (
int iColAnti = 0; iColAnti < 3; ++iColAnti)
532 if (event.endColJunction(iAntiJun, iColAnti) == indxCol) {
533 iParton.push_back( -(10 + 10 * iAntiJun + iColAnti) );
540 }
while (hasFound && indxCol > 0 && loop < loopMax);
543 if (!hasFound || loop == loopMax) {
544 infoPtr->errorMsg(
"Error in HadronLevel::traceFromAcol: "
545 "colour tracing failed");
558 bool HadronLevel::traceInLoop(
int indxCol,
int indxAcol,
Event& event) {
562 int loopMax = iColAndAcol.size() + 2;
563 bool hasFound =
false;
569 for (
int i = 0; i < int(iColAndAcol.size()); ++i)
570 if (event[ iColAndAcol[i] ].acol() == indxCol) {
571 iParton.push_back( iColAndAcol[i] );
572 indxCol =
event[ iColAndAcol[i] ].col();
573 iColAndAcol[i] = iColAndAcol.back();
574 iColAndAcol.pop_back();
578 }
while (hasFound && indxCol != indxAcol && loop < loopMax);
581 if (!hasFound || loop == loopMax) {
582 infoPtr->errorMsg(
"Error in HadronLevel::traceInLoop: "
583 "colour tracing failed");
596 bool HadronLevel::splitJunctionPair(
Event& event) {
598 for(
int iJun = 0;iJun < int(iPartonJun.size());++iJun) {
599 int identJun = (-iPartonJun[iJun][0])/10;
602 int identAntiJun = 500;
603 for (
int i = 0;i < int(iPartonJun[iJun].size()); ++i) {
604 if (iPartonJun[iJun][i] < 0 && (-iPartonJun[iJun][i])/10 != identJun) {
605 identAntiJun = (-iPartonJun[iJun][i])/10;
610 for (
int i = 0; i < int(iPartonAntiJun.size());i++)
611 if ( (-iPartonAntiJun[i][0])/10 == identAntiJun) {
624 for (
int i = 0; i < int(iPartonJun[iJun].size()); ++ i) {
625 if ( (-iPartonJun[iJun][i])/10 == identJun) ++leg;
626 if (leg == 0) iJunLegA.push_back( iPartonJun[iJun][i] );
627 else if (leg == 1) iJunLegB.push_back( iPartonJun[iJun][i] );
628 else iJunLegC.push_back( iPartonJun[iJun][i] );
632 int identAnti = (-iPartonAntiJun[iAntiJun][0])/10;
637 for (
int i = 0; i < int(iPartonAntiJun[iAntiJun].size()); ++ i) {
638 if ( (-iPartonAntiJun[iAntiJun][i])/10 == identAnti) ++leg;
639 if (leg == 0) iAntiLegA.push_back( iPartonAntiJun[iAntiJun][i] );
640 else if (leg == 1) iAntiLegB.push_back( iPartonAntiJun[iAntiJun][i] );
641 else iAntiLegC.push_back( iPartonAntiJun[iAntiJun][i] );
646 int legJun[3], legAnti[3], nGluLeg[3];
647 if (iJunLegA.back() < 0) { legJun[nMatch] = 0;
648 legAnti[nMatch] = (-iJunLegA.back())%10; ++nMatch;}
649 if (iJunLegB.back() < 0) { legJun[nMatch] = 1;
650 legAnti[nMatch] = (-iJunLegB.back())%10; ++nMatch;}
651 if (iJunLegC.back() < 0) { legJun[nMatch] = 2;
652 legAnti[nMatch] = (-iJunLegC.back())%10; ++nMatch;}
655 for (
int iMatch = 0; iMatch < nMatch; ++iMatch) {
656 vector<int>& iJunLeg = (legJun[iMatch] == 0) ? iJunLegA
657 : ( (legJun[iMatch] == 1) ? iJunLegB : iJunLegC );
658 vector<int>& iAntiLeg = (legAnti[iMatch] == 0) ? iAntiLegA
659 : ( (legAnti[iMatch] == 1) ? iAntiLegB : iAntiLegC );
662 nGluLeg[iMatch] = iJunLeg.size() + iAntiLeg.size() - 4;
663 if (nGluLeg[iMatch] == 0)
continue;
667 for (
int i = 1; i < int(iJunLeg.size()) - 1; ++i)
668 iGluLeg.push_back( iJunLeg[i] );
669 for (
int i =
int(iAntiLeg.size()) - 2; i > 0; --i)
670 iGluLeg.push_back( iAntiLeg[i] );
677 int idQ = flavSel.pickLightQ();
681 if (iGluLeg.size() == 1) {
684 colQ =
event[ iGluLeg[0] ].col();
685 acolQ =
event[ iGluLeg[0] ].acol();
686 Vec4 pQ = 0.5 *
event[ iGluLeg[0] ].p();
687 double mQ = 0.5 *
event[ iGluLeg[0] ].m();
688 int iQ =
event.append( idQ, 75, iGluLeg[0], 0, 0, 0, colQ, 0, pQ, mQ );
689 int iQbar =
event.append( -idQ, 75, iGluLeg[0], 0, 0, 0, 0, acolQ,
693 event[ iGluLeg[0] ].statusNeg();
694 event[ iGluLeg[0] ].daughters( iQ, iQbar);
695 iJunLeg.push_back(iQ);
696 iAntiLeg.push_back(iQbar);
704 for (
int i = 0; i < int(iGluLeg.size()) - 1; ++i) {
705 double m2Now = 0.5 *
event[ iGluLeg[i] ].p()
706 *
event[ iGluLeg[i + 1] ].p();
707 m2Pair.push_back(m2Now);
712 double m2Reg = m2Sum * rndmPtr->flat();
714 do m2Reg -= m2Pair[++iReg];
715 while (m2Reg > 0. && iReg <
int(iGluLeg.size()) - 1);
716 m2Reg = m2Pair[iReg];
719 double m2Temp = min( JJSTRINGM2MAX, JJSTRINGM2FRAC * m2Reg);
723 double zTemp = zSel.zFrag( idQ, 0, m2Temp);
725 xNeg = m2Temp / (zTemp * m2Reg);
727 if (rndmPtr->flat() > 0.5) swap(xPos, xNeg);
730 Particle& gJun =
event[ iGluLeg[iReg] ];
731 Particle& gAnti =
event[ iGluLeg[iReg + 1] ];
734 int dau1 =
event.size();
735 gJun.daughters(dau1, dau1 + 3);
736 gAnti.daughters(dau1, dau1 + 3);
737 int mother1 = min( iGluLeg[iReg], iGluLeg[iReg + 1]);
738 int mother2 = max( iGluLeg[iReg], iGluLeg[iReg + 1]);
742 int gJunCol = gJun.col();
743 int gJunAcol = gJun.acol();
744 int gAntiAcol = gAnti.acol();
745 Vec4 gJunP = gJun.p();
746 Vec4 gAntiP = gAnti.p();
747 double gJunM = gJun.m();
748 double gAntiM = gAnti.m();
752 acolQ =
event.nextColTag();
755 int iGjun =
event.append( 21, 75, mother1, mother2, 0, 0,
756 gJunCol, gJunAcol, (1. - 0.5 * xPos) * gJunP,
757 (1. - 0.5 * xPos) * gJunM);
758 int iGanti =
event.append( 21, 75, mother1, mother2, 0, 0,
759 acolQ, gAntiAcol, (1. - 0.5 * xNeg) * gAntiP,
760 (1. - 0.5 * xNeg) * gAntiM);
763 int iQ =
event.append( idQ, 75, mother1, mother2, 0, 0,
764 colQ, 0, 0.5 * xNeg * gAntiP, 0.5 * xNeg * gAntiM );
765 int iQbar =
event.append( -idQ, 75, mother1, mother2, 0, 0,
766 0, acolQ, 0.5 * xPos * gJunP, 0.5 * xPos * gJunM );
769 for (
int i = 0; i < iReg; ++i)
770 iJunLeg.push_back( iGluLeg[i] );
771 iJunLeg.push_back(iGjun);
772 iJunLeg.push_back(iQ);
773 for (
int i =
int(iGluLeg.size()) - 1; i > iReg + 1; --i)
774 iAntiLeg.push_back( iGluLeg[i] );
775 iAntiLeg.push_back(iGanti);
776 iAntiLeg.push_back(iQbar);
780 event.endColJunction(identJun - 1, legJun[iMatch], colQ);
781 event.endColJunction(identAnti - 1, legAnti[iMatch], acolQ);
786 while (iMatchUp < nMatch) {
787 if (nGluLeg[iMatchUp] > 0) {
788 for (
int i = iMatchUp; i < nMatch - 1; ++i) {
789 legJun[i] = legJun[i + 1];
790 legAnti[i] = legAnti[i + 1];
791 nGluLeg[i] = nGluLeg[i + 1];
798 infoPtr->errorMsg(
"Error in HadronLevel::splitJunctionPair: "
799 "three empty junction-junction legs");
805 int legJunLeft = 3 - legJun[0] - legJun[1];
806 int legAntiLeft = 3 - legAnti[0] - legAnti[1];
807 vector<int>& iJunLeg = (legJunLeft == 0) ? iJunLegA
808 : ( (legJunLeft == 1) ? iJunLegB : iJunLegC );
809 vector<int>& iAntiLeg = (legAntiLeft == 0) ? iAntiLegA
810 : ( (legAntiLeft == 1) ? iAntiLegB : iAntiLegC );
811 iPartonJun[iJun].resize(0);
812 for (
int i =
int(iJunLeg.size()) - 1; i > 0; --i)
813 iPartonJun[iJun].push_back( iJunLeg[i] );
814 for (
int i = 1; i < int(iAntiLeg.size()); ++i)
815 iPartonJun[iJun].push_back( iAntiLeg[i] );
818 int iColJoin = iJunLeg[1];
819 int iAcolJoin = iAntiLeg[1];
820 event[iAcolJoin].acol( event[iColJoin].col() );
823 iPartonAntiJun[iAntiJun].resize(0);
824 event.eraseJunction( max(identJun, identAnti) - 1);
825 event.eraseJunction( min(identJun, identAnti) - 1);
835 vector<int>& iJunLeg0 = (legJun[0] == 0) ? iJunLegB : iJunLegA;
836 vector<int>& iJunLeg1 = (legJun[0] == 2) ? iJunLegB : iJunLegC;
837 vector<int>& iAntiLeg0 = (legAnti[0] == 0) ? iAntiLegB : iAntiLegA;
838 vector<int>& iAntiLeg1 = (legAnti[0] == 2) ? iAntiLegB : iAntiLegC;
841 Vec4 pJunLeg0 =
event[ iJunLeg0[1] ].p();
842 Vec4 pJunLeg1 =
event[ iJunLeg1[1] ].p();
843 Vec4 pAntiLeg0 =
event[ iAntiLeg0[1] ].p();
844 Vec4 pAntiLeg1 =
event[ iAntiLeg1[1] ].p();
847 Vec4 pStart = pJunLeg0 / pJunLeg0.e() + pJunLeg1 / pJunLeg1.e()
848 + pAntiLeg0 / pAntiLeg0.e() + pAntiLeg1 / pAntiLeg1.e();
851 RotBstMatrix MtoJRF, MtoARF;
852 Vec4 pInJRF[3], pInARF[3];
853 for (
int iJunLocal = 0; iJunLocal < 2; ++iJunLocal) {
854 int offset = (iJunLocal == 0) ? 0 : 2;
857 RotBstMatrix MtoRF, Mstep;
858 MtoRF.bstback(pStart);
866 pInRF[0 + offset] = pJunLeg0;
867 pInRF[1 + offset] = pJunLeg1;
868 pInRF[2 - offset] = pAntiLeg0;
869 pInRF[3 - offset] = pAntiLeg1;
870 for (
int i = 0; i < 4; ++i) pInRF[i].rotbst(MtoRF);
873 double wt2 = 1. - exp( -pInRF[2].e() / eNormJunction);
874 double wt3 = 1. - exp( -pInRF[3].e() / eNormJunction);
875 pInRF[2] = wt2 * pInRF[2] + wt3 * pInRF[3];
878 Mstep = stringFrag.junctionRestFrame( pInRF[0], pInRF[1], pInRF[2]);
879 MtoRF.rotbst( Mstep );
880 }
while (iter < 3 || (Mstep.deviation() > CONVJNREST
881 && iter < NTRYJNREST) );
884 if (iJunLocal == 0) {
886 for (
int i = 0; i < 3; ++i) pInJRF[i] = pInRF[i];
889 for (
int i = 0; i < 3; ++i) pInARF[i] = pInRF[i];
894 RotBstMatrix MfromJRF = MtoJRF;
896 RotBstMatrix MfromARF = MtoARF;
900 Vec4 vJun(0., 0., 0., 1.);
901 vJun.rotbst(MfromJRF);
902 Vec4 vAnti(0., 0., 0., 1.);
903 vAnti.rotbst(MfromARF);
904 Vec4 pLabJ[3], pLabA[3];
905 for (
int i = 0; i < 3; ++i) {
906 pLabJ[i] = pInJRF[i];
907 pLabJ[i].rotbst(MfromJRF);
908 pLabA[i] = pInARF[i];
909 pLabA[i].rotbst(MfromARF);
913 double vJvA = vJun * vAnti;
914 double vJvAe2y = vJvA + sqrt(vJvA*vJvA - 1.);
915 double LambdaJA = (2. * pInJRF[0].e()) * (2. * pInJRF[1].e())
916 * (2. * pInARF[0].e()) * (2. * pInARF[1].e()) * vJvAe2y;
917 double Lambda00 = (2. * pLabJ[0] * pLabA[0])
918 * (2. * pLabJ[1] * pLabA[1]);
919 double Lambda01 = (2. * pLabJ[0] * pLabA[1])
920 * (2. * pLabJ[1] * pLabA[0]);
923 if (LambdaJA > min( Lambda00, Lambda01)) {
924 vector<int>& iAntiMatch0 = (Lambda00 < Lambda01)
925 ? iAntiLeg0 : iAntiLeg1;
926 vector<int>& iAntiMatch1 = (Lambda00 < Lambda01)
927 ? iAntiLeg1 : iAntiLeg0;
930 iPartonJun[iJun].resize(0);
931 for (
int i =
int(iJunLeg0.size()) - 1; i > 0; --i)
932 iPartonJun[iJun].push_back( iJunLeg0[i] );
933 for (
int i = 1; i < int(iAntiMatch0.size()); ++i)
934 iPartonJun[iJun].push_back( iAntiMatch0[i] );
935 iPartonAntiJun[iAntiJun].resize(0);
936 for (
int i =
int(iJunLeg1.size()) - 1; i > 0; --i)
937 iPartonAntiJun[iAntiJun].push_back( iJunLeg1[i] );
938 for (
int i = 1; i < int(iAntiMatch1.size()); ++i)
939 iPartonAntiJun[iAntiJun].push_back( iAntiMatch1[i] );
942 int iColJoin = iJunLeg0[1];
943 int iAcolJoin = iAntiMatch0[1];
944 event[iAcolJoin].acol( event[iColJoin].col() );
945 iColJoin = iJunLeg1[1];
946 iAcolJoin = iAntiMatch1[1];
947 event[iAcolJoin].acol( event[iColJoin].col() );
950 event.eraseJunction( max(identJun, identAnti) - 1);
951 event.eraseJunction( min(identJun, identAnti) - 1);
960 double eShift = MTHAD / (3. * sqrt(vJvAe2y));
961 double fracJ0 = min(0.5, eShift / pInJRF[0].e());
962 double fracJ1 = min(0.5, eShift / pInJRF[0].e());
963 Vec4 pFromJun = fracJ0 * pJunLeg0 + fracJ1 * pJunLeg1;
964 double fracA0 = min(0.5, eShift / pInARF[0].e());
965 double fracA1 = min(0.5, eShift / pInARF[0].e());
966 Vec4 pFromAnti = fracA0 * pAntiLeg0 + fracA1 * pAntiLeg1;
969 int idQ = flavSel.pickLightQ();
972 int mother1 = min(iJunLeg0[1], iJunLeg1[1]);
973 int mother2 = max(iJunLeg0[1], iJunLeg1[1]);
974 int iNew1 =
event.copy(iJunLeg0[1], 76);
975 event[iNew1].rescale5(1. - fracJ0);
977 int iNew2 =
event.copy(iJunLeg1[1], 76);
978 event[iNew2].rescale5(1. - fracJ1);
983 int colQ =
event.nextColTag();
984 event.endColJunction(identJun - 1, legJun[0], colQ);
985 int iNewJ =
event.append( idQ, 76, mother1, mother2, 0, 0,
986 colQ, 0, pFromAnti, pFromAnti.mCalc() );
987 event[mother1].daughters( iNew1, iNewJ);
988 event[mother2].daughters( iNew1, iNewJ);
989 event[iNew1].mothers( mother1, mother2);
990 event[iNew2].mothers( mother1, mother2);
993 mother1 = min(iAntiLeg0[1], iAntiLeg1[1]);
994 mother2 = max(iAntiLeg0[1], iAntiLeg1[1]);
995 iNew1 =
event.copy(iAntiLeg0[1], 76);
996 event[iNew1].rescale5(1. - fracA0);
997 iAntiLeg0[1] = iNew1;
998 iNew2 =
event.copy(iAntiLeg1[1], 76);
999 event[iNew2].rescale5(1. - fracA1);
1000 iAntiLeg1[1] = iNew2;
1004 int acolQ =
event.nextColTag();
1005 event.endColJunction(identAnti - 1, legAnti[0], acolQ);
1006 int iNewA =
event.append( -idQ, 76, mother1, mother2, 0, 0,
1007 0, acolQ, pFromJun, pFromJun.mCalc() );
1008 event[mother1].daughters( iNew1, iNewA);
1009 event[mother2].daughters( iNew1, iNewA);
1010 event[iNew1].mothers( mother1, mother2);
1011 event[iNew2].mothers( mother1, mother2);
1014 if (legJun[0] == 0) iJunLegA[1] = iNewJ;
1015 else if (legJun[0] == 1) iJunLegB[1] = iNewJ;
1016 else iJunLegC[1] = iNewJ;
1017 if (legAnti[0] == 0) iAntiLegA[1] = iNewA;
1018 else if (legAnti[0] == 1) iAntiLegB[1] = iNewA;
1019 else iAntiLegC[1] = iNewA;
1025 iPartonJun[iJun].resize(0);
1026 for (
int i = 0; i < int(iJunLegA.size()); ++i)
1027 iPartonJun[iJun].push_back( iJunLegA[i] );
1028 for (
int i = 0; i < int(iJunLegB.size()); ++i)
1029 iPartonJun[iJun].push_back( iJunLegB[i] );
1030 for (
int i = 0; i < int(iJunLegC.size()); ++i)
1031 iPartonJun[iJun].push_back( iJunLegC[i] );
1034 iPartonAntiJun[iAntiJun].resize(0);
1035 for (
int i = 0; i < int(iAntiLegA.size()); ++i)
1036 iPartonAntiJun[iAntiJun].push_back( iAntiLegA[i] );
1037 for (
int i = 0; i < int(iAntiLegB.size()); ++i)
1038 iPartonAntiJun[iAntiJun].push_back( iAntiLegB[i] );
1039 for (
int i = 0; i < int(iAntiLegC.size()); ++i)
1040 iPartonAntiJun[iAntiJun].push_back( iAntiLegC[i] );