StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
HadronLevel.cc
1 // HadronLevel.cc is a part of the PYTHIA event generator.
2 // Copyright (C) 2018 Torbjorn Sjostrand.
3 // PYTHIA is licenced under the GNU GPL v2 or later, see COPYING for details.
4 // Please respect the MCnet Guidelines, see GUIDELINES for details.
5 
6 // Function definitions (not found in the header) for the HadronLevel class.
7 
8 #include "Pythia8/HadronLevel.h"
9 
10 namespace Pythia8 {
11 
12 //==========================================================================
13 
14 // The HadronLevel class.
15 
16 //--------------------------------------------------------------------------
17 
18 // Constants: could be changed here if desired, but normally should not.
19 
20 // Small safety mass used in string-end rapidity calculations.
21 const double HadronLevel::MTINY = 0.1;
22 
23 //--------------------------------------------------------------------------
24 
25 // Find settings. Initialize HadronLevel classes as required.
26 
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) {
32 
33  // Save pointers.
34  infoPtr = infoPtrIn;
35  particleDataPtr = particleDataPtrIn;
36  rndmPtr = rndmPtrIn;
37  couplingsPtr = couplingsPtrIn;
38  rHadronsPtr = rHadronsPtrIn;
39  userHooksPtr = userHooksPtrIn;
40 
41  // Main flags.
42  doHadronize = settings.flag("HadronLevel:Hadronize");
43  doHadronScatter = settings.flag("hadronLevel:HadronScatter");
44  doDecay = settings.flag("HadronLevel:Decay");
45  doBoseEinstein = settings.flag("HadronLevel:BoseEinstein");
46 
47  // Boundary mass between string and ministring handling.
48  mStringMin = settings.parm("HadronLevel:mStringMin");
49 
50  // For junction processing.
51  eNormJunction = settings.parm("StringFragmentation:eNormJunction");
52 
53  // Allow R-hadron formation.
54  allowRH = settings.flag("RHadrons:allow");
55 
56  // Particles that should decay or not before Bose-Einstein stage.
57  widthSepBE = settings.parm("BoseEinstein:widthSep");
58 
59  // Need string density information be collected?
60  closePacking = settings.flag("StringPT:closePacking");
61 
62  // Hadron scattering.
63  hadronScatMode = settings.mode("HadronScatter:mode");
64  hsAfterDecay = settings.flag("HadronScatter:afterDecay");
65 
66  // Rope hadronization. Setting of partonic production vertices.
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");
72 
73  // Initialize Ropewalk and Flavour Ropes.
74  if (doRopes) {
75  if (!ropewalk.init(infoPtr, settings, rndmPtr)) return false;
76  flavourRope.init(&settings, rndmPtr, particleDataPtr, infoPtr, &ropewalk);
77  }
78 
79  // Initialize auxiliary fragmentation classes.
80  flavSel.init(settings, particleDataPtr, rndmPtr, infoPtr);
81  pTSel.init( settings, particleDataPtr, rndmPtr, infoPtr);
82  zSel.init( settings, *particleDataPtr, rndmPtr, infoPtr);
83 
84  // Initialize auxiliary administrative class.
85  colConfig.init(infoPtr, settings, &flavSel);
86 
87  // Initialize string and ministring fragmentation.
88  stringFrag.init(infoPtr, settings, particleDataPtr, rndmPtr,
89  &flavSel, &pTSel, &zSel, &flavourRope, userHooksPtr);
90  ministringFrag.init(infoPtr, settings, particleDataPtr, rndmPtr,
91  &flavSel, &pTSel, &zSel);
92 
93  // Initialize particle decays.
94  decays.init(infoPtr, settings, particleDataPtr, rndmPtr, couplingsPtr,
95  timesDecPtr, &flavSel, decayHandlePtr, handledParticles);
96 
97  // Initialize BoseEinstein.
98  boseEinstein.init(infoPtr, settings, *particleDataPtr);
99 
100  // Initialize HadronScatter.
101  if (doHadronScatter)
102  hadronScatter.init(infoPtr, settings, rndmPtr, particleDataPtr);
103 
104  // Initialize Hidden-Valley fragmentation, if necessary.
105  useHiddenValley = hiddenvalleyFrag.init(infoPtr, settings,
106  particleDataPtr, rndmPtr);
107 
108  // Send flavour and z selection pointers to R-hadron machinery.
109  rHadronsPtr->fragPtrs( &flavSel, &zSel);
110 
111  // Initialize the colour tracing class.
112  colTrace.init(infoPtr);
113 
114  // Initialize the junction splitting class.
115  junctionSplitting.init(infoPtr, settings, rndmPtr, particleDataPtr);
116 
117  // Done.
118  return true;
119 
120 }
121 
122 //--------------------------------------------------------------------------
123 
124 // Hadronize and decay the next parton-level.
125 
126 bool HadronLevel::next( Event& event) {
127 
128  // Store current event size to mark Parton Level content.
129  event.savePartonLevelSize();
130 
131  // Do Hidden-Valley fragmentation, if necessary.
132  if (useHiddenValley) hiddenvalleyFrag.fragment(event);
133 
134  // Colour-octet onia states must be decayed to singlet + gluon.
135  if (!decayOctetOnia(event)) return false;
136 
137  // Set lifetimes for already existing hadrons, like onia.
138  for (int i = 0; i < event.size(); ++i) if (event[i].isHadron())
139  event[i].tau( event[i].tau0() * rndmPtr->exp() );
140 
141  // Remove junction structures.
142  if (!junctionSplitting.checkColours(event)) {
143  infoPtr->errorMsg("Error in HadronLevel::next: "
144  "failed colour/junction check");
145  return false;
146  }
147 
148  // Possibility of hadronization inside decay, but then no BE second time.
149  // Hadron scattering, first pass only --rjc
150  bool moreToDo, firstPass = true;
151  bool doBoseEinsteinNow = doBoseEinstein;
152  do {
153  moreToDo = false;
154 
155  // First part: string fragmentation.
156  if (doHadronize) {
157 
158  // Find the complete colour singlet configuration of the event.
159  // Keep junctions if we do shoving.
160  if (!findSinglets( event, (doRopes && doShoving) )) return false;
161 
162  // Fragment off R-hadrons, if necessary.
163  if (allowRH && !rHadronsPtr->produce( colConfig, event))
164  return false;
165 
166  // Save list with rapidity pairs of the different string pieces.
167  if (closePacking) {
168  vector< vector< pair<double,double> > > rapPairs =
169  rapidityPairs(event);
170  colConfig.rapPairs = rapPairs;
171  }
172 
173  // Let strings interact in rope hadronization treatment.
174  if (doRopes) {
175 
176  // Do the shoving treatment.
177  if (doShoving) {
178  // For shoving we need explicit vertex information.
179  if (!doVertex) {
180  infoPtr->errorMsg("Error in HadronLevel::next: "
181  "shoving enabled, but no vertex info.");
182  return false;
183  }
184  // Extract all string segments from the event.
185  ropewalk.extractDipoles(event, colConfig);
186  // String shoving.
187  ropewalk.shoveTheDipoles(event);
188  // Find singlets again.
189  iParton.resize(0);
190  colConfig.clear();
191  if (!findSinglets( event)) {
192  infoPtr->errorMsg("Error in HadronLevel::next: "
193  "ropes: failed 2nd singlet tracing.");
194  return false;
195  }
196  }
197 
198  // Prepare for flavour ropes.
199  if (doFlavour) {
200  if (doVertex && !doBuffon) {
201  ropewalk.extractDipoles(event, colConfig);
202  ropewalk.calculateOverlaps();
203  }
204  // Else default to Buffon treatment which
205  // does not need dipole extraction and overlaps.
206  else {
207  infoPtr->errorMsg("Error in HadronLevel::next: "
208  "ropes: Flavour enabled, but no space time information.");
209  }
210  }
211  }
212 
213  // Process all colour singlet (sub)systems.
214  for (int iSub = 0; iSub < colConfig.size(); ++iSub) {
215 
216  // Collect sequentially all partons in a colour singlet subsystem.
217  colConfig.collect(iSub, event);
218 
219  // String fragmentation of each colour singlet (sub)system.
220  if ( colConfig[iSub].massExcess > mStringMin ) {
221  if (!stringFrag.fragment( iSub, colConfig, event)) return false;
222 
223  // Low-mass string treated separately. Tell if diffractive system.
224  } else {
225  bool isDiff = infoPtr->isDiffractiveA() || infoPtr->isDiffractiveB();
226  if (!ministringFrag.fragment( iSub, colConfig, event, isDiff))
227  return false;
228  }
229  }
230  }
231 
232  // Hadron scattering.
233  if (doHadronScatter) {
234  // New model.
235  if (hadronScatMode < 2) hadronScatter.scatter(event);
236  // Old model, before dacys.
237  else if ((hadronScatMode == 2) && !hsAfterDecay && firstPass)
238  hadronScatter.scatterOld(event);
239  }
240 
241  // Second part: sequential decays of short-lived particles (incl. K0).
242  if (doDecay) {
243 
244  // Loop through all entries to find those that should decay.
245  int iDec = 0;
246  do {
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;
252  }
253  } while (++iDec < event.size());
254  }
255 
256  // Hadron scattering, old model, after decays.
257  if (doHadronScatter && (hadronScatMode == 2) && hsAfterDecay && firstPass)
258  hadronScatter.scatterOld(event);
259 
260  // Third part: include Bose-Einstein effects among current particles.
261  if (doBoseEinsteinNow) {
262  if (!boseEinstein.shiftEvent(event)) return false;
263  doBoseEinsteinNow = false;
264  }
265 
266  // Fourth part: sequential decays also of long-lived particles.
267  if (doDecay) {
268 
269  // Loop through all entries to find those that should decay.
270  int iDec = 0;
271  do {
272  Particle& decayer = event[iDec];
273  if ( decayer.isFinal() && decayer.canDecay() && decayer.mayDecay() ) {
274  decays.decay( iDec, event);
275  if (decays.moreToDo()) moreToDo = true;
276  }
277  } while (++iDec < event.size());
278  }
279 
280  // Normally done first time around, but sometimes not (e.g. Upsilon).
281  } while (moreToDo);
282 
283  // Done.
284  return true;
285 
286 }
287 
288 //--------------------------------------------------------------------------
289 
290 // Allow more decays if on/off switches changed.
291 // Note: does not do sequential hadronization, e.g. for Upsilon.
292 
293 bool HadronLevel::moreDecays( Event& event) {
294 
295  // Colour-octet onia states must be decayed to singlet + gluon.
296  if (!decayOctetOnia(event)) return false;
297 
298  // Loop through all entries to find those that should decay.
299  int iDec = 0;
300  do {
301  if ( event[iDec].isFinal() && event[iDec].canDecay()
302  && event[iDec].mayDecay() ) decays.decay( iDec, event);
303  } while (++iDec < event.size());
304 
305  // Done.
306  return true;
307 
308 }
309 
310 //--------------------------------------------------------------------------
311 
312 // Decay colour-octet onium states.
313 
314 bool HadronLevel::decayOctetOnia(Event& event) {
315 
316  // Loop over particles and decay any onia encountered.
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;
321 
322  // Set colour flow by hand: gluon inherits octet-onium state.
323  int iGlu = event.size() - 1;
324  event[iGlu].cols( event[iDec].col(), event[iDec].acol() );
325  }
326 
327  // Done.
328  return true;
329 
330 }
331 
332 //--------------------------------------------------------------------------
333 
334 // Trace colour flow in the event to form colour singlet subsystems.
335 // Option will keep junctions in the remainsJunction list,
336 // and not eliminate any junctions by insertion.
337 
338 bool HadronLevel::findSinglets(Event& event, bool keepJunctions) {
339 
340  // Clear up storage.
341  colConfig.clear();
342 
343  // Find a list of final partons and of all colour ends and gluons.
344  if (colTrace.setupColList(event)) return true;
345 
346  // Begin arrange the partons into separate colour singlets.
347 
348  // Junctions: loop over them, and identify kind.
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);
353  iParton.resize(0);
354 
355  // Loop over junction legs.
356  for (int iCol = 0; iCol < 3; ++iCol) {
357  int indxCol = event.colJunction(iJun, iCol);
358  iParton.push_back( -(10 + 10 * iJun + iCol) );
359  // Junctions: find color ends.
360  if (kindJun % 2 == 1 && !colTrace.traceFromAcol(indxCol, event, iJun,
361  iCol, iParton)) return false;
362  // Antijunctions: find anticolor ends.
363  if (kindJun % 2 == 0 && !colTrace.traceFromCol(indxCol, event, iJun,
364  iCol, iParton)) return false;
365  }
366 
367  // A junction may be eliminated by insert if two quarks are nearby.
368  if (!keepJunctions) {
369  int nJunOld = event.sizeJunction();
370  if (!colConfig.insert(iParton, event)) return false;
371  if (event.sizeJunction() < nJunOld) --iJun;
372  }
373  }
374 
375  // Open strings: pick up each colour end and trace to its anticolor end.
376  while (!colTrace.colFinished()) {
377  iParton.resize(0);
378  if (!colTrace.traceFromCol( -1, event, -1, -1, iParton)) return false;
379 
380  // Store found open string system. Analyze its properties.
381  if (!colConfig.insert(iParton, event)) return false;
382  }
383 
384  // Closed strings : begin at any gluon and trace until back at it.
385  while (!colTrace.finished()) {
386  iParton.resize(0);
387  if (!colTrace.traceInLoop(event, iParton)) return false;
388 
389  // Store found closed string system. Analyze its properties.
390  if (!colConfig.insert(iParton, event)) return false;
391  }
392 
393  // Done.
394  return true;
395 
396 }
397 
398 //--------------------------------------------------------------------------
399 
400 // Extract rapidity pairs of string pieces.
401 
402 vector< vector< pair<double,double> > > HadronLevel::rapidityPairs(
403  Event& event) {
404 
405  // Loop over all string systems in the event.
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;
410 
411  // Special treatment for junction systems.
412  if (colConfig[iSub].hasJunction) {
413  // Pick smallest and largest rapidity parton.
414  double ymi = 1e10;
415  double yma = -1e10;
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;
423  }
424  rapsNow.push_back( make_pair(ymi, yma) );
425 
426  // Normal strings. For closed gluon loop include first-last pair.
427  } else {
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) );
438  }
439  }
440  rapPairs.push_back(rapsNow);
441  }
442  // Done.
443  return rapPairs;
444 }
445 
446 //==========================================================================
447 
448 } // end namespace Pythia8
Definition: AgUStep.h:26