8 #include "Pythia8/HadronLevel.h"
21 const double HadronLevel::MTINY = 0.1;
27 bool HadronLevel::init(Info* infoPtrIn, Settings& settings,
28 ParticleData* particleDataPtrIn, Rndm* rndmPtrIn,
29 Couplings* couplingsPtrIn, TimeShower* timesDecPtr,
30 RHadrons* rHadronsPtrIn, DecayHandler* decayHandlePtr,
31 vector<int> handledParticles, UserHooks* userHooksPtrIn) {
35 particleDataPtr = particleDataPtrIn;
37 couplingsPtr = couplingsPtrIn;
38 rHadronsPtr = rHadronsPtrIn;
39 userHooksPtr = userHooksPtrIn;
42 doHadronize = settings.flag(
"HadronLevel:Hadronize");
43 doHadronScatter = settings.flag(
"hadronLevel:HadronScatter");
44 doDecay = settings.flag(
"HadronLevel:Decay");
45 doBoseEinstein = settings.flag(
"HadronLevel:BoseEinstein");
48 mStringMin = settings.parm(
"HadronLevel:mStringMin");
51 eNormJunction = settings.parm(
"StringFragmentation:eNormJunction");
54 allowRH = settings.flag(
"RHadrons:allow");
57 widthSepBE = settings.parm(
"BoseEinstein:widthSep");
60 closePacking = settings.flag(
"StringPT:closePacking");
63 hadronScatMode = settings.mode(
"HadronScatter:mode");
64 hsAfterDecay = settings.flag(
"HadronScatter:afterDecay");
67 doRopes = settings.flag(
"Ropewalk:RopeHadronization");
68 doShoving = settings.flag(
"Ropewalk:doShoving");
69 doFlavour = settings.flag(
"Ropewalk:doFlavour");
70 doVertex = settings.flag(
"PartonVertex:setVertex");
71 doBuffon = settings.flag(
"Ropewalk:doBuffon");
75 if (!ropewalk.init(infoPtr, settings, rndmPtr))
return false;
76 flavourRope.init(&settings, rndmPtr, particleDataPtr, infoPtr, &ropewalk);
80 flavSel.init(settings, particleDataPtr, rndmPtr, infoPtr);
81 pTSel.init( settings, particleDataPtr, rndmPtr, infoPtr);
82 zSel.init( settings, *particleDataPtr, rndmPtr, infoPtr);
85 colConfig.init(infoPtr, settings, &flavSel);
88 stringFrag.init(infoPtr, settings, particleDataPtr, rndmPtr,
89 &flavSel, &pTSel, &zSel, &flavourRope, userHooksPtr);
90 ministringFrag.init(infoPtr, settings, particleDataPtr, rndmPtr,
91 &flavSel, &pTSel, &zSel);
94 decays.init(infoPtr, settings, particleDataPtr, rndmPtr, couplingsPtr,
95 timesDecPtr, &flavSel, decayHandlePtr, handledParticles);
98 boseEinstein.init(infoPtr, settings, *particleDataPtr);
102 hadronScatter.init(infoPtr, settings, rndmPtr, particleDataPtr);
105 useHiddenValley = hiddenvalleyFrag.init(infoPtr, settings,
106 particleDataPtr, rndmPtr);
109 rHadronsPtr->fragPtrs( &flavSel, &zSel);
112 colTrace.init(infoPtr);
115 junctionSplitting.init(infoPtr, settings, rndmPtr, particleDataPtr);
126 bool HadronLevel::next(
Event& event) {
129 event.savePartonLevelSize();
132 if (useHiddenValley) hiddenvalleyFrag.fragment(event);
135 if (!decayOctetOnia(event))
return false;
138 for (
int i = 0; i <
event.size(); ++i)
if (event[i].isHadron())
139 event[i].tau( event[i].tau0() * rndmPtr->exp() );
142 if (!junctionSplitting.checkColours(event)) {
143 infoPtr->errorMsg(
"Error in HadronLevel::next: "
144 "failed colour/junction check");
150 bool moreToDo, firstPass =
true;
151 bool doBoseEinsteinNow = doBoseEinstein;
160 if (!findSinglets( event, (doRopes && doShoving) ))
return false;
163 if (allowRH && !rHadronsPtr->produce( colConfig, event))
168 vector< vector< pair<double,double> > > rapPairs =
169 rapidityPairs(event);
170 colConfig.rapPairs = rapPairs;
180 infoPtr->errorMsg(
"Error in HadronLevel::next: "
181 "shoving enabled, but no vertex info.");
185 ropewalk.extractDipoles(event, colConfig);
187 ropewalk.shoveTheDipoles(event);
191 if (!findSinglets( event)) {
192 infoPtr->errorMsg(
"Error in HadronLevel::next: "
193 "ropes: failed 2nd singlet tracing.");
200 if (doVertex && !doBuffon) {
201 ropewalk.extractDipoles(event, colConfig);
202 ropewalk.calculateOverlaps();
207 infoPtr->errorMsg(
"Error in HadronLevel::next: "
208 "ropes: Flavour enabled, but no space time information.");
214 for (
int iSub = 0; iSub < colConfig.size(); ++iSub) {
217 colConfig.collect(iSub, event);
220 if ( colConfig[iSub].massExcess > mStringMin ) {
221 if (!stringFrag.fragment( iSub, colConfig, event))
return false;
225 bool isDiff = infoPtr->isDiffractiveA() || infoPtr->isDiffractiveB();
226 if (!ministringFrag.fragment( iSub, colConfig, event, isDiff))
233 if (doHadronScatter) {
235 if (hadronScatMode < 2) hadronScatter.scatter(event);
237 else if ((hadronScatMode == 2) && !hsAfterDecay && firstPass)
238 hadronScatter.scatterOld(event);
247 Particle& decayer =
event[iDec];
248 if ( decayer.isFinal() && decayer.canDecay() && decayer.mayDecay()
249 && (decayer.mWidth() > widthSepBE || decayer.idAbs() == 311) ) {
250 decays.decay( iDec, event);
251 if (decays.moreToDo()) moreToDo =
true;
253 }
while (++iDec < event.size());
257 if (doHadronScatter && (hadronScatMode == 2) && hsAfterDecay && firstPass)
258 hadronScatter.scatterOld(event);
261 if (doBoseEinsteinNow) {
262 if (!boseEinstein.shiftEvent(event))
return false;
263 doBoseEinsteinNow =
false;
272 Particle& decayer =
event[iDec];
273 if ( decayer.isFinal() && decayer.canDecay() && decayer.mayDecay() ) {
274 decays.decay( iDec, event);
275 if (decays.moreToDo()) moreToDo =
true;
277 }
while (++iDec < event.size());
293 bool HadronLevel::moreDecays(
Event& event) {
296 if (!decayOctetOnia(event))
return false;
301 if ( event[iDec].isFinal() && event[iDec].canDecay()
302 && event[iDec].mayDecay() ) decays.decay( iDec, event);
303 }
while (++iDec < event.size());
314 bool HadronLevel::decayOctetOnia(
Event& event) {
317 for (
int iDec = 0; iDec <
event.size(); ++iDec)
318 if (event[iDec].isFinal()
319 && particleDataPtr->isOctetHadron(event[iDec].
id())) {
320 if (!decays.decay( iDec, event))
return false;
323 int iGlu =
event.size() - 1;
324 event[iGlu].cols( event[iDec].col(), event[iDec].acol() );
338 bool HadronLevel::findSinglets(
Event& event,
bool keepJunctions) {
344 if (colTrace.setupColList(event))
return true;
349 for (
int iJun = 0; iJun <
event.sizeJunction(); ++iJun)
350 if (event.remainsJunction(iJun)) {
351 if (!keepJunctions)
event.remainsJunction(iJun,
false);
352 int kindJun =
event.kindJunction(iJun);
356 for (
int iCol = 0; iCol < 3; ++iCol) {
357 int indxCol =
event.colJunction(iJun, iCol);
358 iParton.push_back( -(10 + 10 * iJun + iCol) );
360 if (kindJun % 2 == 1 && !colTrace.traceFromAcol(indxCol, event, iJun,
361 iCol, iParton))
return false;
363 if (kindJun % 2 == 0 && !colTrace.traceFromCol(indxCol, event, iJun,
364 iCol, iParton))
return false;
368 if (!keepJunctions) {
369 int nJunOld =
event.sizeJunction();
370 if (!colConfig.insert(iParton, event))
return false;
371 if (event.sizeJunction() < nJunOld) --iJun;
376 while (!colTrace.colFinished()) {
378 if (!colTrace.traceFromCol( -1, event, -1, -1, iParton))
return false;
381 if (!colConfig.insert(iParton, event))
return false;
385 while (!colTrace.finished()) {
387 if (!colTrace.traceInLoop(event, iParton))
return false;
390 if (!colConfig.insert(iParton, event))
return false;
402 vector< vector< pair<double,double> > > HadronLevel::rapidityPairs(
406 vector< vector< pair<double,double> > > rapPairs;
407 for (
int iSub = 0; iSub < int(colConfig.size()); iSub++) {
408 vector< pair<double,double> > rapsNow;
409 vector<int> iPartons = colConfig[iSub].iParton;
412 if (colConfig[iSub].hasJunction) {
416 for (
int iP = 0; iP < int(iPartons.size()); iP++) {
417 int iQ = iPartons[iP];
418 if (iQ < 0)
continue;
419 if (event[iQ].
id() == 21)
continue;
420 double yNow = yMax(event[iQ], MTINY);
421 if (yNow > yma) yma = yNow;
422 if (yNow < ymi) ymi = yNow;
424 rapsNow.push_back( make_pair(ymi, yma) );
428 int size = int(iPartons.size());
429 int end = size - (colConfig[iSub].isClosed ? 0 : 1);
430 for (
int iP = 0; iP < end; iP++) {
431 int i1 = iPartons[iP];
432 int i2 = iPartons[(iP+1)%size];
433 double y1 = yMax(event[i1], MTINY);
434 double y2 = yMax(event[i2], MTINY);
435 double ymi = min(y1, y2);
436 double yma = max(y1, y2);
437 rapsNow.push_back( make_pair(ymi, yma) );
440 rapPairs.push_back(rapsNow);