StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
BeamParticle.cc
1 // BeamParticle.cc is a part of the PYTHIA event generator.
2 // Copyright (C) 2020 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
7 // BeamParticle class.
8 
9 #include "Pythia8/BeamParticle.h"
10 
11 namespace Pythia8 {
12 
13 //==========================================================================
14 
15 // The ColState class.
16 
17 //--------------------------------------------------------------------------
18 
19 // Small storage class needed to find the full colour state
20 // of all the scattered partons.
21 
22 class ColState {
23 public:
24  ColState() : nTotal(0.) {}
25  vector< pair<int,int> > lastSteps;
26  // nTotal is integer but can become extremely big.
27  double nTotal;
28 };
29 
30 //==========================================================================
31 
32 // The BeamParticle class.
33 
34 //--------------------------------------------------------------------------
35 
36 // Constants: could be changed here if desired, but normally should not.
37 // These are of technical nature, as described for each.
38 
39 // A lepton that takes (almost) the full beam energy does not leave a remnant.
40 const double BeamParticle::XMINUNRESOLVED = 1. - 1e-10;
41 
42 // Fictitious Pomeron mass to leave some room for beam remnant.
43 const double BeamParticle::POMERONMASS = 1.;
44 
45 // Avoid numerical instability in the x -> 1 limit for companion quark.
46 const double BeamParticle::XMAXCOMPANION = 0.99;
47 
48 // Avoid too extremely uneven momentum sharing.
49 const double BeamParticle::TINYZREL = 1e-8;
50 
51 // Maximum number of tries to find a suitable colour.
52 const int BeamParticle::NMAX = 1000;
53 
54 // Maximum number of tries to randomly assign colours to beam remnant.
55 // After this number is reached, a systematic approach is used.
56 const int BeamParticle::NRANDOMTRIES = 1000;
57 
58 //--------------------------------------------------------------------------
59 
60 // Initialize data on a beam particle and save pointers.
61 
62 void BeamParticle::init( int idIn, double pzIn, double eIn, double mIn,
63  PDFPtr pdfInPtr, PDFPtr pdfHardInPtr, bool isUnresolvedIn,
64  StringFlav* flavSelPtrIn) {
65 
66  // Store input pointers (and one bool) for future use.
67  pdfBeamPtr = pdfInPtr;
68  pdfHardBeamPtr = pdfHardInPtr;
69  isUnresolvedBeam = isUnresolvedIn;
70  flavSelPtr = flavSelPtrIn;
71 
72  // Save the usual PDF pointers as the normal ones may be overwritten
73  // with unresolved PDFs when mixing different photoproduction modes.
74  pdfBeamPtrSave = pdfInPtr;
75  pdfHardBeamPtrSave = pdfHardInPtr;
76 
77  // Maximum quark kind in allowed incoming beam hadrons.
78  maxValQuark = mode("BeamRemnants:maxValQuark");
79 
80  // Power of (1-x)^power/sqrt(x) for remnant valence quark distribution.
81  valencePowerMeson = parm("BeamRemnants:valencePowerMeson");
82  valencePowerUinP = parm("BeamRemnants:valencePowerUinP");
83  valencePowerDinP = parm("BeamRemnants:valencePowerDinP");
84 
85  // Enhancement factor of x of diquark.
86  valenceDiqEnhance = parm("BeamRemnants:valenceDiqEnhance");
87 
88  // Assume g(x) ~ (1-x)^power/x to constrain companion to sea quark.
89  companionPower = mode("BeamRemnants:companionPower");
90 
91  // Assume g(x) ~ (1-x)^power/x with a cut-off for low x.
92  gluonPower = parm("BeamRemnants:gluonPower");
93  xGluonCutoff = parm("BeamRemnants:xGluonCutoff");
94 
95  // Allow or not more than one valence quark to be kicked out.
96  allowJunction = flag("BeamRemnants:allowJunction");
97 
98  // Choose whether to form a di-quark or
99  // a junction with new colur reconnection scheme.
100  beamJunction = flag("beamRemnants:beamJunction");
101 
102  // Allow junctions in the outgoing colour state.
103  allowBeamJunctions = flag("beamRemnants:allowBeamJunction");
104 
105  // For low-mass diffractive system kick out q/g = norm / mass^power.
106  pickQuarkNorm = parm("Diffraction:pickQuarkNorm");
107  pickQuarkPower = parm("Diffraction:pickQuarkPower");
108 
109  // Controls the amount of saturation in the new model.
110  beamSat = parm("BeamRemnants:saturation");
111 
112  // Width of primordial kT distribution in low-mass diffractive systems.
113  diffPrimKTwidth = parm("Diffraction:primKTwidth");
114 
115  // Suppress large masses of beam remnant in low-mass diffractive systems.
116  diffLargeMassSuppress = parm("Diffraction:largeMassSuppress");
117 
118  // Check if ISR for photon collisions is applied and set pTmin.
119  doND = flag("SoftQCD:nonDiffractive");
120  doISR = flag("PartonLevel:ISR");
121  doMPI = flag("PartonLevel:MPI");
122  pTminISR = parm("SpaceShower:pTmin");
123 
124  // Store info on the incoming beam.
125  idBeam = idIn;
126  initBeamKind();
127  pBeam = Vec4( 0., 0., pzIn, eIn);
128  mBeam = mIn;
129 
130  // To be set process by process so start with false.
131  hasResGammaInBeam = false;
132 
133  // Initialize parameters related to photon beams.
134  resetGamma();
135  resetGammaInLepton();
136 
137  clear();
138 
139 }
140 
141 //--------------------------------------------------------------------------
142 
143 // Initialize kind and valence flavour content of incoming beam.
144 // For recognized hadrons one can generate multiparton interactions.
145 // Dynamic choice of meson valence flavours in newValenceContent below.
146 
147 void BeamParticle::initBeamKind() {
148 
149  // Reset.
150  idBeamAbs = abs(idBeam);
151  isLeptonBeam = false;
152  isHadronBeam = false;
153  isMesonBeam = false;
154  isBaryonBeam = false;
155  isGammaBeam = false;
156  nValKinds = 0;
157 
158  // To be modified according to the process.
159  gammaMode = 0;
160  isResUnres = false;
161 
162  // Check for leptons or DM beams.
163  if ( (idBeamAbs > 10 && idBeamAbs < 17)
164  || (idBeamAbs > 50 && idBeamAbs < 60) ) {
165  nValKinds = 1;
166  nVal[0] = 1;
167  idVal[0] = idBeam;
168  isLeptonBeam = true;
169  }
170 
171  // Valence content for photons.
172  if (idBeamAbs == 22) {
173  isGammaBeam = true;
174  nValKinds = 2;
175  nVal[0] = 1;
176  nVal[1] = 1;
177  newValenceContent();
178  iPosVal = -1;
179  }
180 
181  // Done if cannot be lowest-lying hadron state.
182  if (idBeamAbs < 101 || idBeamAbs > 9999) return;
183 
184  // Resolve valence content for assumed Pomeron.
185  if (idBeamAbs == 990) {
186  isMesonBeam = true;
187  nValKinds = 2;
188  nVal[0] = 1 ;
189  nVal[1] = 1 ;
190  newValenceContent();
191 
192  // Resolve valence content for assumed meson. Flunk unallowed codes.
193  } else if (idBeamAbs < 1000) {
194  int id1 = idBeamAbs/100;
195  int id2 = (idBeamAbs/10)%10;
196  if ( id1 > maxValQuark || id2 > maxValQuark ) return;
197  isMesonBeam = true;
198 
199  // Store valence content of a confirmed meson.
200  nValKinds = 2;
201  nVal[0] = 1 ;
202  nVal[1] = 1;
203  if (id1%2 == 0) {
204  idVal[0] = id1;
205  idVal[1] = -id2;
206  } else {
207  idVal[0] = id2;
208  idVal[1] = -id1;
209  }
210  newValenceContent();
211 
212  // Resolve valence content for assumed baryon. Flunk unallowed codes.
213  } else {
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;
219  isBaryonBeam = true;
220 
221  // Store valence content of a confirmed baryon.
222  nValKinds = 1; idVal[0] = id1; nVal[0] = 1;
223  if (id2 == id1) ++nVal[0];
224  else {
225  nValKinds = 2;
226  idVal[1] = id2;
227  nVal[1] = 1;
228  }
229  if (id3 == id1) ++nVal[0];
230  else if (id3 == id2) ++nVal[1];
231  else {
232  idVal[nValKinds] = id3;
233  nVal[nValKinds] = 1;
234  ++nValKinds;
235  }
236  }
237 
238  // Flip flavours for antimeson or antibaryon, and then done.
239  if (idBeam < 0) for (int i = 0; i < nValKinds; ++i) idVal[i] = -idVal[i];
240  isHadronBeam = true;
241  Q2ValFracSav = -1.;
242 
243 }
244 
245 //--------------------------------------------------------------------------
246 
247 // Initialize the photon beam with additional unresolved PDF pointer.
248 
249 void BeamParticle::initUnres(PDFPtr pdfUnresInPtr) {
250 
251  // Set the pointer and check that pointer exists.
252  pdfUnresBeamPtr = pdfUnresInPtr;
253  isResUnres = (pdfUnresBeamPtr != 0 ) ? true : false;
254 
255 }
256 
257 //--------------------------------------------------------------------------
258 
259 // Dynamic choice of meson valence flavours for pi0, K0S, K0L, Pomeron.
260 
261 void BeamParticle::newValenceContent() {
262 
263  // A pi0, rho and omega oscillates between d dbar and u ubar.
264  if (idBeam == 111 || idBeam == 113 || idBeam == 223) {
265  idVal[0] = (rndmPtr->flat() < 0.5) ? 1 : 2;
266  idVal[1] = -idVal[0];
267 
268  // A K0S or K0L oscillates between d sbar and s dbar.
269  } else if (idBeam == 130 || idBeam == 310) {
270  idVal[0] = (rndmPtr->flat() < 0.5) ? 1 : 3;
271  idVal[1] = (idVal[0] == 1) ? -3 : -1;
272 
273  // For a Pomeron split gluon remnant into d dbar or u ubar.
274  } else if (idBeam == 990) {
275  idVal[0] = (rndmPtr->flat() < 0.5) ? 1 : 2;
276  idVal[1] = -idVal[0];
277 
278  // For photons a VMD content may be chosen, or the choice may be delayed.
279  } else if (idBeam == 22) {
280  if (hasVMDstate()) {
281  int idTmp = idVMD();
282  // A rho and omega oscillates between a uubar and ddbar.
283  if (idTmp == 113 || idTmp == 223) {
284  idVal[0] = (rndmPtr->flat() < 0.5) ? 1 : 2;
285  idVal[1] = -idVal[0];
286  // A phi is an ssbar system.
287  } else if (idTmp == 333) {
288  idVal[0] = 3;
289  idVal[1] = -3;
290  // COR: A J/psi is an ccbar system.
291  } else if (idTmp == 443) {
292  idVal[0] = 4;
293  idVal[1] = -4;
294  } else return;
295  // For non-VMD photons set an usused code to indicate that the flavour
296  // is not chosen yet but will be done later.
297  } else {
298  idVal[0] = 10;
299  idVal[1] = -idVal[0];
300  }
301 
302  // If phi meson set content to s sbar.
303  } else if (idBeam == 333) {
304  idVal[0] = 3;
305  idVal[1] = -idVal[0];
306 
307  // COR: If J/Psi meson set content to c cbar.
308  } else if (idBeam == 443) {
309  idVal[0] = 4;
310  idVal[1] = -idVal[0];
311 
312  // Other hadrons so far do not require any event-by-event change.
313  } else return;
314 
315  // Propagate change to PDF routine(s).
316  pdfBeamPtr->newValenceContent( idVal[0], idVal[1]);
317  if (pdfHardBeamPtr != pdfBeamPtr && pdfHardBeamPtr != 0)
318  pdfHardBeamPtr->newValenceContent( idVal[0], idVal[1]);
319 
320 }
321 
322 //--------------------------------------------------------------------------
323 
324 double BeamParticle::xMax(int iSkip) {
325 
326  // Minimum requirement on remaining energy > nominal mass for hadron.
327  double xLeft = 1.;
328  if (idBeam == 990) xLeft -= POMERONMASS / e();
329  else if (isHadron()) xLeft -= m() / e();
330  if (size() == 0) return xLeft;
331 
332  // Subtract what was carried away by initiators (to date).
333  for (int i = 0; i < size(); ++i)
334  if (i != iSkip && resolved[i].isFromBeam()) xLeft -= resolved[i].x();
335  return xLeft;
336 
337 }
338 
339 //--------------------------------------------------------------------------
340 
341 // Caclulate used and left x fractions in total and of a few kinds.
342 
343 xfModPrepData BeamParticle::xfModPrep(int iSkip, double Q2) {
344 
345  // Initial value.
346  xfModPrepData xfData = {0., 0., 0., 0., 0.};
347 
348  // Calculate total and remaining amount of x carried by valence quarks.
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;
357  }
358 
359  // Calculate how much x is left overall.
360  double xUsed = 0.;
361  for (int i = 0; i < size(); ++i) if (i != iSkip) xUsed += resolved[i].x();
362  xfData.xLeft = 1. - xUsed;
363 
364  // Calculate total amount of x carried by unmatched companion quarks.
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()) )
368  // Typo warning: extrafactor missing in Skands&Sjostrand article;
369  // <x> for companion refers to fraction of x left INCLUDING sea quark.
370  * (1. + resolved[i].x() / xfData.xLeft);
371  }
372 
373  // Calculate total rescaling factor and pdf for sea and gluon.
374  xfData.rescaleGS = max( 0., (1. - xfData.xValLeft - xfData.xCompAdded)
375  / (1. - xfData.xValTot) );
376 
377  // Done.
378  return xfData;
379 }
380 
381 //--------------------------------------------------------------------------
382 
383 // Parton distributions, reshaped to take into account previous
384 // multiparton interactions. By picking a non-negative iSkip value,
385 // one particular interaction is skipped, as needed for ISR.
386 
387 double BeamParticle::xfModified(int iSkip, int idIn, double x, double Q2,
388  xfModPrepData& xfData ) {
389 
390  // Initial values.
391  idSave = idIn;
392  iSkipSave = iSkip;
393  xqVal = 0.;
394  xqgSea = 0.;
395  xqCompSum = 0.;
396  const int rsize = size();
397 
398  // Fast procedure for first interaction.
399  if (rsize == 0) return xfModified0(iSkip, idIn, x, Q2);
400 
401  // More complicated procedure for non-first interaction.
402  // Sum up the x already removed, and check that remaining x is enough.
403  if (x >= xfData.xLeft) return 0.;
404  double xRescaled = x / xfData.xLeft;
405 
406  // Calculate total and remaining amount of x carried by valence quarks.
407  for (int i = nValKinds - 1; i >= 0; --i) {
408  // Find valence part and rescale it to remaining number of quarks.
409  if (idIn == idVal[i] && nValLeft[i] > 0) {
410  xqVal = xfVal( idIn, xRescaled, Q2)
411  * double(nValLeft[i]) / double(nVal[i]);
412  break;
413  }
414  }
415 
416  // Calculate total amount of x carried by unmatched companion quarks.
417  for (int i = 0; i < rsize; ++i) {
418  if (i != iSkip && resolved[i].isUnmatched() &&
419  resolved[i].id() == -idIn) {
420  // Find companion part, by adding all companion contributions.
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);
424  // Normalize the companion quark PDF to the total momentum carried
425  // by the partons in case of photon beam at given scale Q^2.
426  if ( isGamma() ) xqCompNow *= xIntegratedPDFs(Q2);
427  resolved[i].xqCompanion( xqCompNow);
428  xqCompSum += xqCompNow;
429  }
430  }
431 
432  // Calculate total rescaling factor and pdf for sea and gluon.
433  xqgSea = xfData.rescaleGS * xfSea( idIn, xRescaled, Q2);
434 
435  // Add total, but only return relevant part for ISR.
436  xqgTot = xqVal + xqgSea + xqCompSum;
437 
438  // If ISR with photon beams no distinction between valence and sea.
439  if (isGammaBeam && doISR) return xqgTot;
440 
441  // Return result depending on case.
442  if (iSkip >= 0) {
443  if (resolved[iSkip].isValence()) return xqVal;
444  if (resolved[iSkip].isUnmatched()) return xqgSea + xqCompSum;
445  }
446  return xqgTot;
447 
448 }
449 
450 //--------------------------------------------------------------------------
451 
452 // Parton distributions, reshaped to take into account previous
453 // multiparton interactions. By picking a non-negative iSkip value,
454 // one particular interaction is skipped, as needed for ISR
455 // when resolved.size() == 0.
456 
457 double BeamParticle::xfModified0(int iSkip, int idIn, double x, double Q2) {
458 
459  // If parton can be valence quark then separate valence and sea.
460  if (x >= 1.) return 0.;
461  bool canBeVal = false;
462  for (int i = 0; i < nValKinds; ++i) if (idIn == idVal[i]) {
463  canBeVal = true;
464  break;
465  }
466  if (canBeVal) {
467  xqVal = xfVal( idIn, x, Q2);
468  xqgSea = xfSea( idIn, x, Q2);
469  } else {
470  xqVal = 0.;
471  xqgSea = xf( idIn, x, Q2);
472  }
473 
474  // Add total, but only return relevant part for ISR.
475  xqgTot = xqVal + xqgSea + xqCompSum;
476 
477  // If ISR with photon beams no distinction between valence and sea.
478  if (isGammaBeam && doISR) return xqgTot;
479 
480  // Return result depending on case.
481  if (iSkip >= 0) {
482  if (resolved[iSkip].isValence()) return xqVal;
483  if (resolved[iSkip].isUnmatched()) return xqgSea + xqCompSum;
484  }
485  return xqgTot;
486 
487 }
488 
489 //--------------------------------------------------------------------------
490 
491 // Decide whether a quark extracted from the beam is of valence, sea or
492 // companion kind; in the latter case also pick its companion.
493 // Assumes xfModified has already been called.
494 
495 int BeamParticle::pickValSeaComp() {
496 
497  // If parton already has a companion than reset code for this.
498  int oldCompanion = resolved[iSkipSave].companion();
499  if (oldCompanion >= 0) resolved[oldCompanion].companion(-2);
500 
501  // Default assignment is sea.
502  int vsc = -2;
503 
504  // For gluons or photons no sense of valence or sea.
505  if (idSave == 21 || idSave == 22) vsc = -1;
506 
507  // For lepton beam assume same-kind lepton inside is valence.
508  else if (isLeptonBeam && idSave == idBeam) vsc = -3;
509 
510  // Decide if valence or sea quark.
511  // For photons, consider all partons as sea until valence content fixed.
512  else {
513  double xqRndm = xqgTot * rndmPtr->flat();
514  if (xqRndm < xqVal && !isGammaBeam ) vsc = -3;
515  else if (xqRndm < xqVal + xqgSea) vsc = -2;
516 
517  // If not either, loop over all possible companion quarks.
518  else {
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;
525  break;
526  }
527  }
528  }
529 
530  // Bookkeep assignment; for sea--companion pair both ways.
531  resolved[iSkipSave].companion(vsc);
532  if (vsc >= 0) resolved[vsc].companion(iSkipSave);
533 
534  // Done; return code for choice (to distinguish valence/sea in Info).
535  return vsc;
536 
537 }
538 
539 //--------------------------------------------------------------------------
540 
541 // Fraction of hadron momentum sitting in a valence quark distribution.
542 // Based on hardcoded parametrizations of CTEQ 5L numbers.
543 
544 double BeamParticle::xValFrac(int j, double Q2) {
545 
546  // Only recalculate when required.
547  if (Q2 != Q2ValFracSav) {
548  Q2ValFracSav = Q2;
549 
550  // Q2-dependence of log-log form; assume fixed Lambda = 0.2.
551  double llQ2 = log( log( max( 1., Q2) / 0.04 ));
552 
553  // Fractions carried by u and d in proton.
554  uValInt = 0.48 / (1. + 1.56 * llQ2);
555  dValInt = 0.385 / (1. + 1.60 * llQ2);
556  }
557 
558  // Baryon with three different quark kinds: (2 * u + d) / 3 of proton.
559  if (isBaryonBeam && nValKinds == 3) return (2. * uValInt + dValInt) / 3.;
560 
561  // Baryon with one or two identical: like d or u of proton.
562  if (isBaryonBeam && nVal[j] == 1) return dValInt;
563  if (isBaryonBeam && nVal[j] == 2) return uValInt;
564 
565  // Meson: (2 * u + d) / 2 of proton so same total valence quark fraction.
566  return 0.5 * (2. * uValInt + dValInt);
567 
568 }
569 
570 //--------------------------------------------------------------------------
571 
572 // The momentum integral of a companion quark, with its partner at x_s,
573 // using an approximate gluon density like (1 - x_g)^power / x_g.
574 // The value corresponds to an unrescaled range between 0 and 1 - x_s.
575 
576 inline double BeamParticle::xCompFrac(double xs) {
577 
578  // Tiny answer for xs -> 1 is numerically unstable, so set = 0.
579  if (xs > XMAXCOMPANION) return 0.;
580 
581  // Cached result can be returned straight away.
582  if (companionPower == cPowerCache && xs == xsCache) return resCache;
583 
584  // Select case by power of gluon (1-x_g) shape.
585  double logxs = log(xs);
586  double res;
587  switch (companionPower) {
588 
589  case 0:
590  res = xs * ( 5. + xs * (-9. - 2. * xs * (-3. + xs)) + 3. * logxs )
591  / ( (-1. + xs) * (2. + xs * (-1. + 2. * xs)) );
592  break;
593  case 1:
594  res = -1. -3. * xs + ( 2. * pow2(-1. + xs) * (1. + xs + xs*xs))
595  / ( 2. + xs*xs * (xs - 3.) + 3. * xs * logxs );
596  break;
597  case 2:
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) ) );
602  break;
603  case 3:
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)) );
608  break;
609  default:
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)) );
614 
615  }
616 
617  // Cache new result and return it.
618  cPowerCache = companionPower;
619  xsCache = xs;
620  resCache = res;
621  return res;
622 }
623 
624 //--------------------------------------------------------------------------
625 
626 // The x*f pdf of a companion quark at x_c, with its sea partner at x_s,
627 // using an approximate gluon density like (1 - x_g)^power / x_g.
628 // The value corresponds to an unrescaled range between 0 and 1 - x_s.
629 
630 double BeamParticle::xCompDist(double xc, double xs) {
631 
632  // Tiny answer for xs -> 1 is numerically unstable, so set = 0.
633  if (xs > XMAXCOMPANION) return 0.;
634 
635  // Mother gluon momentum fraction. Check physical limit.
636  double xg = xc + xs;
637  if (xg > 1.) return 0.;
638 
639  // Common factor, including splitting kernel and part of gluon density
640  // (and that it is x_c * f that is coded).
641  double fac = 3. * xc * xs * (xc*xc + xs*xs) / pow4(xg);
642 
643  // Select case by power of gluon (1-x_g) shape.
644  switch (companionPower) {
645 
646  case 0:
647  return fac / ( 2. - xs * (3. - xs * (3. - 2. * xs)) );
648 
649  case 1:
650  return fac * (1. - xg) / ( 2. + xs*xs * (-3. + xs) + 3. * xs * log(xs) );
651 
652  case 2:
653  return fac * pow2(1. - xg) / ( 2. * ((1. - xs) * (1. + xs * (4. + xs))
654  + 3. * xs * (1. + xs) * log(xs)) );
655 
656  case 3:
657  return fac * pow3(1. - xg) * 2. / ( 4. + 27. * xs - 31. * pow3(xs)
658  + 6. * xs * log(xs) * (3. + 2. * xs * (3. + xs)) );
659 
660  default:
661  return fac * pow4(1. - xg) / ( 2. * (1. + 2. * xs) * ((1. - xs)
662  * (1. + xs * (10. + xs)) + 6. * xs * log(xs) * (1. + xs)) );
663 
664  }
665 }
666 
667 //--------------------------------------------------------------------------
668 
669 // Set the photon mode (none (0), resolved (1), unresolved (2)) of the beam.
670 
671 void BeamParticle::setGammaMode(int gammaModeIn) {
672 
673  // For hadrons mode always 0.
674  if ( !( initGammaBeam || isGamma() ) ) {
675  gammaMode = 0;
676  pdfBeamPtr = pdfBeamPtrSave;
677  pdfHardBeamPtr = pdfHardBeamPtrSave;
678  hasResGammaInBeam = false;
679  isResolvedGamma = false;
680  return;
681  }
682 
683  // Save the mode of the photon beam.
684  gammaMode = gammaModeIn;
685 
686  // Set the beam and PDF pointers to unresolved mode.
687  if (gammaMode == 2 && isResUnres) {
688  pdfBeamPtr = pdfUnresBeamPtr;
689  pdfHardBeamPtr = pdfUnresBeamPtr;
690  isResolvedGamma = false;
691  hasResGammaInBeam = false;
692 
693  // Only a photon beam can be unresolved with gammaMode == 2.
694  if ( isGamma()) isUnresolvedBeam = true;
695 
696  // Set the beam and PDF pointers to resolved mode.
697  } else {
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;
705  }
706 
707 }
708 
709 //--------------------------------------------------------------------------
710 
711 // Check whether parton iResolved with given Q^2 is a valence quark.
712 
713 bool BeamParticle::gammaInitiatorIsVal(int iResolved, double Q2) {
714  return gammaInitiatorIsVal( iResolved, resolved[iResolved].id(),
715  resolved[iResolved].x(), Q2 );
716 }
717 
718 //--------------------------------------------------------------------------
719 
720 // Check whether initiator parton is a valence quark using the PDFs.
721 // Set the position of the valence quark to iGamVal.
722 
723 bool BeamParticle::gammaInitiatorIsVal(int iResolved, int idInit,
724  double x, double Q2) {
725 
726  // Reset the valence quark position.
727  iPosVal = -1;
728 
729  // Gluon is not a valence parton. Sample content accordingly.
730  if ( idInit == 0 || abs(idInit) == 21 ) {
731  idVal[0] = pdfBeamPtr->sampleGammaValFlavor(Q2);
732  idVal[1] = -idVal[0];
733  return false;
734  } else {
735 
736  // Set the valence content to match with the hard process to get the
737  // correct PDFs and to store the choice. Changed by sampleGammaValFlavor.
738  idVal[0] = idInit;
739  idVal[1] = -idInit;
740  pdfBeamPtr->newValenceContent( idVal[0], idVal[1]);
741 
742  // If initiator from gamma->qqbar splitting then it is a valence quark.
743  if ( iResolved == iGamVal ) {
744  iPosVal = iResolved;
745  return true;
746 
747  // If Q^2 is smaller than mass of quark set to valence.
748  } else if ( Q2 < pdfBeamPtr->gammaPDFRefScale(idInit) ) {
749  iPosVal = iResolved;
750  return true;
751 
752  // Use PDFs to decide if valence parton.
753  } else {
754  double xVal = xfVal( idInit, x, Q2);
755  double xSea = xfSea( idInit, x, Q2);
756  if ( rndmPtr->flat() < xVal/( xVal + xSea ) ) {
757  iPosVal = iResolved;
758  return true;
759 
760  // If the initiator not valence sample the flavour.
761  } else {
762  idVal[0] = pdfBeamPtr->sampleGammaValFlavor(Q2);
763  idVal[1] = -idVal[0];
764  return false;
765  }
766  }
767  }
768 }
769 
770 //--------------------------------------------------------------------------
771 
772 // Return the type of the hard parton from a photon beam.
773 
774 int BeamParticle::gammaValSeaComp(int iResolved) {
775 
776  // Default choice a sea quark.
777  int vsc = -2;
778 
779  // Gluons and photons -1.
780  if ( resolved[iResolved].id() == 21 ||
781  resolved[iResolved].id() == 22 ) vsc = -1;
782 
783  // Quarks are valence partons if decided so earlier.
784  else if (iResolved == iPosVal) vsc = -3;
785  resolved[iResolved].companion(vsc);
786 
787  return vsc;
788 }
789 
790 //--------------------------------------------------------------------------
791 
792 // Add required extra remnant flavour content. Also initial colours.
793 
794 bool BeamParticle::remnantFlavours(Event& event, bool isDIS) {
795 
796  // Elastically scattered beam, e.g. for coherent photon from proton.
797  if (isHadronBeam && isUnresolvedBeam) {
798  append( 0, idBeam, 0., -1);
799  resolved[1].m( particleDataPtr->m0( idBeamAbs ) );
800  return true;
801  }
802 
803  // A baryon will have a junction, unless a diquark is formed later.
804  hasJunctionBeam = (isBaryon());
805 
806  // Store how many hard-scattering partons were removed from beam.
807  nInit = size();
808  if (isDIS && nInit != 1) return false;
809 
810  // Decide the valence content of photon beam here if ISR is applied.
811  if ( isGammaBeam ) {
812 
813  // For direct-resolved processes no need for remnants on direct side.
814  if (resolved[0].id() == 22) return true;
815 
816  // If ISR but no MPIs check only for the one initiator.
817  if ( doISR && !doMPI ) {
818 
819  // If remnants are constructed fix the valence content using the
820  // scale where ISR have stopped.
821  if ( isResolvedGamma ) {
822  gammaInitiatorIsVal(0, pow2(pTminISR));
823  }
824 
825  // Set the initiator companion code after the valence content is fixed.
826  gammaValSeaComp(0);
827 
828  } else if ( doMPI || doND ) {
829 
830  // If ISR is applied, use the min. scale of evolution for the valence
831  // parton decision. Otherwise use the pT of latest MPI (set in scatter).
832  double pTmin = doISR ? pTminISR : pTminMPI;
833 
834  // If a quark from gamma->qqbar exists, this must be the valence so
835  // set it to valence and the possible companion to other valence.
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);
841  } else {
842 
843  // Loop through initiators starting from parton from the hardest
844  // interaction and check whether valence. When found, no need to
845  // check further.
846  for ( int i = 0; i < size(); ++i) {
847  bool isValence = gammaInitiatorIsVal(i, pow2(pTminISR));
848  int origComp = resolved[i].companion();
849  gammaValSeaComp(i);
850  if (isValence) {
851  // If the chosen valence parton has a companion, set this to be
852  // the other valence parton.
853  if ( origComp >= 0 ) resolved[origComp].companion(-3);
854  break;
855  }
856  }
857  }
858  }
859  }
860 
861  // No need for remnants with unresolved photon from leptons.
862  else if ( isLeptonBeam && gammaMode == 2) return true;
863 
864  // Find remaining valence quarks.
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];
869  // No valence quarks if ISR find the original beam photon.
870  if ( isGammaBeam && doISR && !isResolvedGamma && !doMPI ) nValLeft[i] = 0;
871  // Add remaining valence quarks to record. Partly temporary values.
872  for (int k = 0; k < nValLeft[i]; ++k) append(0, idVal[i], 0., -3);
873  }
874 
875  // If at least two valence quarks left in baryon remnant then form diquark.
876  int nInitPlusVal = size();
877  if (isBaryon() && nInitPlusVal - nInit >= 2) {
878 
879  // If three, pick two at random to form diquark, else trivial.
880  int iQ1 = nInit;
881  int iQ2 = nInit + 1;
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;
886  }
887 
888  // Pick spin 0 or 1 according to SU(6) wave function factors.
889  int idDq = flavSelPtr->makeDiquark( resolved[iQ1].id(),
890  resolved[iQ2].id(), idBeam);
891 
892  // Overwrite with diquark flavour and remove one slot. No more junction.
893  resolved[iQ1].id(idDq);
894  if (nInitPlusVal - nInit == 3 && iQ2 == nInit + 1)
895  resolved[nInit + 1].id( resolved[nInit + 2].id() );
896  resolved.pop_back();
897  hasJunctionBeam = false;
898  }
899 
900  // Find companion quarks to unmatched sea quarks.
901  for (int i = 0; i < nInit; ++i)
902  if (resolved[i].isUnmatched()) {
903 
904  // Add companion quark to record; and bookkeep both ways.
905  append(0, -resolved[i].id(), 0., i);
906  resolved[i].companion(size() - 1);
907  }
908 
909  // If no other remnants found, add a gluon or photon to carry momentum.
910  // Add partons for photons only if remnants needed.
911  if ( size() == nInit && !isUnresolvedBeam &&
912  (!isGammaBeam || isResolvedGamma || doMPI) ) {
913  int idRemnant = (isHadronBeam || isGammaBeam) ? 21 : 22;
914  append(0, idRemnant, 0., -1);
915  }
916 
917  // For DIS allow collapse to one colour singlet hadron.
918  if (isHadronBeam && isDIS && size() > 2 && resolved[0].id() != 21) {
919  if (size() != 4) {
920  infoPtr->errorMsg("Error in BeamParticle::remnantFlavours: "
921  "unexpected number of beam remnants for DIS");
922  return false;
923  }
924 
925  // Companion last; find parton with matching colour.
926  int colTypeComp = particleDataPtr->colType( resolved[3].id() );
927  int colType1 = particleDataPtr->colType( resolved[1].id() );
928  int i12 = (colType1 == -colTypeComp) ? 1 : 2;
929 
930  // Combine to new hadron flavour.
931  int idHad = flavSelPtr->combineId( resolved[i12].id(), resolved[3].id() );
932  if (idHad == 0) {
933  infoPtr->errorMsg("Error in BeamParticle::remnantFlavours: "
934  "failed to combine hadron for DIS");
935  return false;
936  }
937 
938  // Overwrite with hadron flavour and remove companion.
939  resolved[i12].id(idHad);
940  resolved.pop_back();
941  resolved[0].companion(-3);
942  }
943 
944  // Set initiator and remnant masses.
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() ) );
948  }
949 
950  // For debug purposes: reject beams with resolved junction topology.
951  if (hasJunctionBeam && !allowJunction) return false;
952 
953  // Pick initial colours for remnants.
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);
959  }
960 
961  // Done.
962  return true;
963 
964 }
965 
966 //--------------------------------------------------------------------------
967 
968 // Correlate all initiators and remnants to make a colour singlet.
969 
970 bool BeamParticle::remnantColours(Event& event, vector<int>& colFrom,
971  vector<int>& colTo) {
972 
973  // No colours in lepton beams so no need to do anything.
974  if (isLeptonBeam) return true;
975 
976  // Copy initiator colour info from the event record to the beam.
977  for (int i = 0; i < size(); ++i) {
978  int j = resolved[i].iPos();
979  resolved[i].cols( event[j].col(), event[j].acol());
980  }
981 
982  // Find number and position of valence quarks, of gluons, and
983  // of sea-companion pairs (counted as gluons) in the beam remnants.
984  // Skip gluons with same colour as anticolour and rescattering partons.
985  vector<int> iVal;
986  vector<int> iGlu;
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 )
991  iGlu.push_back(i);
992  else if ( resolved[i].id() == 21
993  && resolved[i].col() != resolved[i].acol() ) iGlu.push_back(i);
994  }
995 
996  // Pick a valence quark to which gluons are attached.
997  // Do not resolve quarks in diquark. (More sophisticated??)
998  int iValSel = 0;
999  if (iVal.size() != 0) {
1000  iValSel = iVal[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];
1007  }
1008  }
1009 
1010  // This valence quark defines initial (anti)colour.
1011  int iBeg = iValSel;
1012  bool hasCol = (resolved[iBeg].col() > 0);
1013  int begCol = (hasCol) ? resolved[iBeg].col() : resolved[iBeg].acol();
1014 
1015  // Do random stepping through gluon/(sea+companion) list.
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();
1024 
1025  // Find matching anticolour/colour to current colour/anticolour.
1026  int iEnd = iGluSel;
1027  int endCol = (hasCol) ? resolved[iEnd].acol() : resolved[iEnd].col();
1028  // Not gluon but sea+companion pair: go to other.
1029  if (endCol == 0) {
1030  iEnd = resolved[iEnd].companion();
1031  endCol = (hasCol) ? resolved[iEnd].acol() : resolved[iEnd].col();
1032  }
1033 
1034  // Collapse this colour-anticolour pair to the lowest one.
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);
1040  } else {
1041  if (hasCol) resolved[iBeg].col(endCol);
1042  else resolved[iBeg].acol(endCol);
1043  colFrom.push_back(begCol);
1044  colTo.push_back(endCol);
1045  }
1046 
1047  // Pick up the other colour of the recent gluon and repeat.
1048  iBeg = iEnd;
1049  begCol = (hasCol) ? resolved[iBeg].col() : resolved[iBeg].acol();
1050  // Not gluon but sea+companion pair: go to other.
1051  if (begCol == 0) {
1052  iBeg = resolved[iBeg].companion();
1053  begCol = (hasCol) ? resolved[iBeg].col() : resolved[iBeg].acol();
1054  }
1055 
1056  // At end of gluon/(sea+companion) list.
1057  }
1058 
1059  // Now begin checks, and also finding junction information.
1060  // Loop through remnant partons; isolate all colours and anticolours.
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() );
1068  }
1069 
1070  // Remove all matching colour-anticolour pairs.
1071  bool foundPair = true;
1072  while (foundPair && colList.size() > 0 && acolList.size() > 0) {
1073  foundPair = false;
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();
1078  colList.pop_back();
1079  acolList[iAcol] = acolList.back();
1080  acolList.pop_back();
1081  foundPair = true;
1082  break;
1083  }
1084  } if (foundPair) break;
1085  }
1086  }
1087 
1088  // Usually one unmatched pair left to collapse.
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);
1096  }
1097  colFrom.push_back(finalFrom);
1098  colTo.push_back(finalTo);
1099 
1100  // Store an (anti)junction when three (anti)coloured daughters.
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];
1113 
1114  // Any other nonvanishing values indicate failure.
1115  } else if (colList.size() > 0 || acolList.size() > 0) {
1116  infoPtr->errorMsg("Error in BeamParticle::remnantColours: "
1117  "leftover unmatched colours");
1118  return false;
1119  }
1120 
1121  // Store colour assignment of beam particles.
1122  for (int i = nInit; i < size(); ++i)
1123  event[resolved[i].iPos()].cols( resolved[i].col(), resolved[i].acol() );
1124 
1125  // Done.
1126  return true;
1127 }
1128 
1129 
1130 //--------------------------------------------------------------------------
1131 
1132 // Pick unrescaled x values for beam remnant sharing.
1133 
1134 double BeamParticle::xRemnant( int i) {
1135 
1136  double x = 0.;
1137 
1138  // Hadrons (only used for DIS) rather primitive for now (probably OK).
1139  int idAbs = abs(resolved[i].id());
1140  if (idAbs > 100 && (idAbs/10)%10 != 0) {
1141  x = 1.;
1142 
1143  // Calculation of x of valence quark or diquark, for latter as sum.
1144  } else if (resolved[i].isValence()) {
1145 
1146  // Resolve diquark into sum of two quarks.
1147  int id1 = resolved[i].id();
1148  int id2 = 0;
1149  if (abs(id1) > 1000) {
1150  id2 = (id1 > 0) ? (id1/100)%10 : -(((-id1)/100)%10);
1151  id1 = (id1 > 0) ? id1/1000 : -((-id1)/1000);
1152  }
1153 
1154  // Loop over (up to) two quarks; add their contributions.
1155  for (int iId = 0; iId < 2; ++iId) {
1156  int idNow = (iId == 0) ? id1 : id2;
1157  if (idNow == 0) break;
1158  double xPart = 0.;
1159 
1160  // Assume form (1-x)^a / sqrt(x).
1161  double xPow = valencePowerMeson;
1162  if (isBaryonBeam) {
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;
1168  }
1169  do xPart = pow2( rndmPtr->flat() );
1170  while ( pow(1. - xPart, xPow) < rndmPtr->flat() );
1171 
1172  // End loop over (up to) two quarks. Possibly enhancement for diquarks.
1173  x += xPart;
1174  }
1175  if (id2 != 0) x *= valenceDiqEnhance;
1176 
1177  // Calculation of x of sea quark, based on companion association.
1178  } else if (resolved[i].isCompanion()) {
1179 
1180  // Find rescaled x value of companion.
1181  double xLeft = 1.;
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);
1186 
1187  // Now use ansatz q(x; x_c) < N/(x +x_c) to pick x.
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() );
1192 
1193  // Else a gluon remnant.
1194  // Rarely it is a single gluon remnant, for that case value does not matter.
1195  } else {
1196  do x = pow(xGluonCutoff, 1 - rndmPtr->flat());
1197  while ( pow(1. - x, gluonPower) < rndmPtr->flat() );
1198  }
1199 
1200  return x;
1201 
1202 }
1203 
1204 //--------------------------------------------------------------------------
1205 
1206 // Approximate the remnant mass according to the initiator.
1207 
1208 double BeamParticle::remnantMass(int idIn) {
1209 
1210  int idLight = 2;
1211 
1212  // Hadrons: remove valence flavour masses from the hadron mass, add others.
1213  if ( isHadron() ) {
1214  double mRem = particleDataPtr->m0( id());
1215  int valSign1 = (nValence(idIn) > 0) ? -1 : 1;
1216  mRem += valSign1 * particleDataPtr->m0(idIn);
1217  return mRem;
1218 
1219  // Photons: For gluons, add two light partons to act as valence, otherwise
1220  // add mass of companion. No remnants for unresolved photons.
1221  } else if ( isGamma() ) {
1222  if ( isUnresolved() ) return 0.;
1223  double mRem = (idIn == 21) ? 2*( particleDataPtr->m0( idLight ) ) :
1224  particleDataPtr->m0( idIn );
1225  return mRem;
1226 
1227  } else return 0.;
1228 
1229 }
1230 
1231 //--------------------------------------------------------------------------
1232 
1233 // Check whether room for a one remnant system.
1234 
1235 bool BeamParticle::roomFor1Remnant(double eCM) {
1236 
1237  // If no remnants for the beam return true.
1238  if (!isResolvedGamma) return true;
1239 
1240  // Else check whether room with given kinematics.
1241  double x1 = resolved[0].x();
1242  int id1 = resolved[0].id();
1243  return roomFor1Remnant(id1, x1, eCM);
1244 }
1245 
1246 //--------------------------------------------------------------------------
1247 
1248 // Check whether room for a one remnant system.
1249 
1250 bool BeamParticle::roomFor1Remnant(int id1, double x1, double eCM) {
1251 
1252  // Use u-quark mass as a lower limit for the remnant mass.
1253  int idLight = 2;
1254 
1255  // For gluons minimum requirement two light quarks.
1256  // For quarks need room for one quark of same flavor.
1257  double mRemnant = (id1 == 21) ? 2*( particleDataPtr->m0( idLight ) ) :
1258  particleDataPtr->m0( id1 );
1259  return ( mRemnant < eCM*( 1 - sqrt(x1) ) );
1260 }
1261 
1262 //--------------------------------------------------------------------------
1263 
1264 // Check whether room for two remnants in the event.
1265 
1266 bool BeamParticle::roomFor2Remnants(int id1, double x1, double eCM) {
1267 
1268  // Use u-quark mass as a lower limit for the remnant mass.
1269  int idLight = 2;
1270  double id2 = resolved[0].id();
1271  double x2 = resolved[0].x();
1272 
1273  // For gluons minimum requirement two light quarks.
1274  // For quarks need room for one quark of same flavor.
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) ) );
1280 }
1281 
1282 
1283 //--------------------------------------------------------------------------
1284 
1285 // Check whether room for two remnants in the event. This used by MPI.
1286 
1287 bool BeamParticle::roomForRemnants(BeamParticle beamOther) {
1288 
1289  // Calculate the invariant mass remaining after MPIs.
1290  double xLeftA = this->xMax(-1);
1291  double xLeftB = beamOther.xMax(-1);
1292  double eCM = infoPtr->eCM();
1293  double Wleft = eCM * sqrt(xLeftA * xLeftB);
1294  double mRemA = 0;
1295  double mRemB = 0;
1296  bool allGluonsA = true;
1297  bool allGluonsB = true;
1298 
1299  // Calculate the total mass of each beam remnant.
1300  for (int i = 0; i < this->size(); ++i)
1301  if ( resolved[i].id() != 21 ) {
1302  allGluonsA = false;
1303  // If initiator a valence, no need for a companion remnant.
1304  if ( resolved[i].companion() < 0 && resolved[i].companion() != -3 )
1305  mRemA += particleDataPtr->m0( resolved[i].id() );
1306  }
1307  for (int i = 0; i < beamOther.size(); ++i)
1308  if ( beamOther[i].id() != 21 ) {
1309  allGluonsB = false;
1310  if ( beamOther[i].companion() < 0 && beamOther[i].companion() != -3 )
1311  mRemB += particleDataPtr->m0( beamOther[i].id() );
1312  }
1313 
1314  // If all initiators are gluons leave room for two light quarks.
1315  // In case of hadrons the mass is taken into account already in xMax().
1316  if ( allGluonsA) mRemA = this->isGamma() ? 2*particleDataPtr->m0(2) : 0.;
1317  if ( allGluonsB) mRemB = beamOther.isGamma() ? 2*particleDataPtr->m0(2) : 0.;
1318 
1319  // If not enough invariant mass left for remnants reject scattering.
1320  if ( Wleft < mRemA + mRemB ) return false;
1321  else return true;
1322 }
1323 
1324 //--------------------------------------------------------------------------
1325 
1326 // Print the list of resolved partons in a beam.
1327 
1328 void BeamParticle::list() const {
1329 
1330  // Header.
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";
1335 
1336  // Loop over list of removed partons and print it.
1337  double xSum = 0.;
1338  Vec4 pSum;
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";
1348 
1349  // Also find sum of x and p values.
1350  if (res.companion() != -10) {
1351  xSum += res.x();
1352  pSum += res.p();
1353  }
1354  }
1355 
1356  // Print sum and endline.
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  << "---------------------------------------------------------------"
1363  << endl;
1364 }
1365 
1366 //--------------------------------------------------------------------------
1367 
1368 // Test whether a lepton is to be considered as unresolved.
1369 
1370 bool BeamParticle::isUnresolvedLepton() {
1371 
1372  // Require record to consist of lepton with full energy plus a photon.
1373  if (!isLeptonBeam || resolved.size() > 2 || resolved[1].id() != 22
1374  || resolved[0].x() < XMINUNRESOLVED) return false;
1375  return true;
1376 
1377 }
1378 
1379 //--------------------------------------------------------------------------
1380 
1381 // For a diffractive system, decide whether to kick out gluon or quark.
1382 
1383 bool BeamParticle::pickGluon(double mDiff) {
1384 
1385  // Relative weight to pick a quark, assumed falling with energy.
1386  double probPickQuark = pickQuarkNorm / pow( mDiff, pickQuarkPower);
1387  return ( (1. + probPickQuark) * rndmPtr->flat() < 1. );
1388 
1389 }
1390 
1391 //--------------------------------------------------------------------------
1392 
1393 // Pick a valence quark at random. (Used for diffractive systems.)
1394 
1395 int BeamParticle::pickValence() {
1396 
1397  // Pick one valence quark at random.
1398  int nTotVal = (isBaryonBeam) ? 3 : 2;
1399  double rnVal = rndmPtr->flat() * nTotVal;
1400  int iVal = (rnVal < 1.) ? 1 : ( (rnVal < 2.) ? 2 : 3 );
1401 
1402  // This valence in slot 1, the rest thereafter.
1403  idVal1 = 0;
1404  idVal2 = 0;
1405  idVal3 = 0;
1406  int iNow = 0;
1407  for (int i = 0; i < nValKinds; ++i)
1408  for (int j = 0; j < nVal[i]; ++j) {
1409  ++iNow;
1410  if (iNow == iVal) idVal1 = idVal[i];
1411  else if ( idVal2 == 0) idVal2 = idVal[i];
1412  else idVal3 = idVal[i];
1413  }
1414 
1415  // Construct diquark if baryon.
1416  if (idVal3 != 0) idVal2 = flavSelPtr->makeDiquark( idVal2, idVal3, idBeam);
1417 
1418  // Done.
1419  return idVal1;
1420 
1421 }
1422 
1423 //--------------------------------------------------------------------------
1424 
1425 // Share lightcone momentum between two remnants in a diffractive system.
1426 
1427 double BeamParticle::zShare( double mDiff, double m1, double m2) {
1428 
1429  // Set up as valence in normal beam so can use xRemnant code.
1430  append(0, idVal1, 0., -3);
1431  append(0, idVal2, 0., -3);
1432  double m2Diff = mDiff*mDiff;
1433 
1434  // Begin to generate z and pT until acceptable solution.
1435  double wtAcc = 0.;
1436  do {
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;
1443 
1444  // Suppress large invariant masses of remnant system.
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());
1451 
1452  // Done.
1453  return zRel;
1454 
1455 }
1456 
1457 // -------------------------------------------------------------------------
1458 
1459 // Find the colour configuration of the scattered partons
1460 // and update the colour tags to match this configuration.
1461 
1462 void BeamParticle::findColSetup(Event& event) {
1463 
1464  // Reset current colour setup;
1465  colSetup = make_pair(0,0);
1466  cols.clear();
1467  acols.clear();
1468  colUpdates.clear();
1469  nJuncs = 0;
1470  nAjuncs = 0;
1471 
1472  // Setup colour states.
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));
1479  }
1480  colStates[0][0][0].nTotal = 1.;
1481 
1482  bool noColouredParticles = true;
1483  // Find all possible multiplets and their degeneracies.
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();
1489 
1490  // If particle is a quark.
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;
1494  if (k > 0) {
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;
1497  }
1498 
1499  // Junction combination.
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;
1503  }
1504  }
1505 
1506  // If particle is an anti quark.
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;
1510  if (j > 0) {
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;
1513  }
1514 
1515  // Junction combination.
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;
1519  }
1520  }
1521 
1522  // If particle is a gluon.
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;
1526  if (j > 0) {
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;
1529  }
1530  if (k > 0) {
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;
1533  }
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;
1537  }
1538 
1539  // Junction combinations.
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;
1543  }
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;
1547  }
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;
1551  }
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;
1555  }
1556  }
1557  // If the parton is not a quark or a gluon.
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;
1561  } else
1562  noColouredParticles = false;
1563  }
1564  }
1565  }
1566 
1567  // Pick a specific multiplet depending on colour weight and saturation.
1568  // Start by calculating the sum of all weights.
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) {
1572  // Do not allow colour singlet states, since this will overlap
1573  // with diffractive events described elsewhere in PYTHIA.
1574  if (i == 0 && j == 0 && !noColouredParticles) continue;
1575 
1576  double multipletSize = (i + 1) * (j + 1) * (i + j + 2) / 2.;
1577  totalSize += colStates[size()][i][j].nTotal *
1578  multipletSize * exp(-multipletSize / beamSat);
1579  }
1580  }
1581 
1582  // Choose one colour configuration.
1583  double curSize = 0;
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) {
1587 
1588  // Do not allow singlets.
1589  if (i == 0 && j == 0 && !noColouredParticles) continue;
1590 
1591  // Reweight according to multiplet size.
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) {
1596  colSetup.first = i;
1597  colSetup.second = j;
1598  break;
1599  }
1600  }
1601  if (curSize > chosenSize) break;
1602  }
1603 
1604  // Find the whole colour flow chain.
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].
1611  lastSteps.size();
1612  int iCurCol = int(rndmPtr->flat() * curColSize);
1613  curColSetup = colStates[i][curColSetup.first][curColSetup.second].
1614  lastSteps[iCurCol];
1615  }
1616  colSetupChain[0] = curColSetup;
1617 
1618  // Update scattered partons to reflect new colour configuration and
1619  // store still unconnected colours and anti-colours.
1620  for (int i = 0; i < size() ; ++i) {
1621 
1622  // If particle is a quark.
1623  if (resolved[i].id() > 0 && resolved[i].id() < 9) {
1624  // Add quark to list of colours.
1625  if (colSetupChain[i].first + 1 == colSetupChain[i + 1].first)
1626  cols.push_back(resolved[i].col());
1627 
1628  // Find anti colour that quark connects to and update event record.
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());
1634  }
1635 
1636  // Else must be junction:
1637  else {
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);
1644  nJuncs++;
1645  }
1646  }
1647 
1648  // If particle is an anti quark.
1649  if (resolved[i].id() < 0 && resolved[i].id() > -9) {
1650  // Add anti quark to list of anti colours
1651  if (colSetupChain[i].second + 1 == colSetupChain[i + 1].second)
1652  acols.push_back(resolved[i].acol());
1653 
1654  // Find colour that anti quark connects to and update event record.
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());
1660  }
1661 
1662  // Else it has to be a junction configuration:
1663  else {
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);
1670  nAjuncs++;
1671  }
1672  }
1673 
1674  // If particle is a gluon.
1675  if (resolved[i].id() == 21) {
1676  // Add gluon to list of colours.
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());
1681  }
1682 
1683  // Remove colour and anti colour.
1684  if (colSetupChain[i].first - 1 == colSetupChain[i + 1].first &&
1685  colSetupChain[i].second - 1 == colSetupChain[i + 1].second ) {
1686  // First remove colour.
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());
1691  // Then remove anti colour.
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());
1696  }
1697 
1698  // If the gluon connects to a single end.
1699  // If it is possible to both go to a colour or anti colour pick randomly.
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;
1707  // Remove colour and add new colour.
1708  if (removeColour) {
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());
1714  }
1715  // Else remove anti colour and add new anti colour.
1716  else {
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());
1722  }
1723  }
1724 
1725  // Junction configuratons.
1726 
1727  // Gluon anti-junction case.
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);
1737  nAjuncs++;
1738  }
1739 
1740  // Gluon junction case.
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);
1750  nJuncs++;
1751  }
1752 
1753  // Gluon anti-junction case.
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());
1764  nAjuncs++;
1765  }
1766 
1767  // Gluon junction case.
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());
1778  nJuncs++;
1779  }
1780  }
1781  }
1782 
1783  // Done updating event.
1784 }
1785 
1786 // -------------------------------------------------------------------------
1787 
1788 // Add required extra remnant flavour content. Also initial colours.
1789 
1790 bool BeamParticle::remnantFlavoursNew(Event& event) {
1791 
1792  // A baryon will have a junction, unless a diquark is formed later.
1793  hasJunctionBeam = (isBaryon());
1794 
1795  // Store how many hard-scattering partons were removed from beam.
1796  nInit = size();
1797 
1798  // Find remaining valence quarks.
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];
1803  // Add remaining valence quarks to record. Partly temporary values.
1804  for (int k = 0; k < nValLeft[i]; ++k) append(0, idVal[i], 0., -3);
1805  }
1806  int nInitPlusVal = size();
1807 
1808  // Find companion quarks to unmatched sea quarks.
1809  for (int i = 0; i < nInit; ++i)
1810  if (resolved[i].isUnmatched()) {
1811 
1812  // Add companion quark to record; and bookkeep both ways.
1813  append(0, -resolved[i].id(), 0., i);
1814  resolved[i].companion(size() - 1);
1815  }
1816  int beamJunc = 0;
1817  if (isBaryon()) beamJunc = 1;
1818  if (id() < 0) beamJunc = -beamJunc;
1819 
1820  // Count the number of gluons that needs to be added.
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);
1824 
1825  // If no other remnants found, add a light q-qbar pair or a photon
1826  // to carry momentum.
1827  if (size() == nInit) {
1828  if (!isHadron())
1829  append(0, 22, 0., -1);
1830  else {
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);
1836  }
1837  }
1838 
1839  usedCol = vector<bool>(size(),false);
1840  usedAcol = vector<bool>(size(),false);
1841 
1842  // If at least two valence quarks left in baryon and no junction formed.
1843  // First check if junction already was moved into beam.
1844  nDiffJuncs = nJuncs - nAjuncs - beamJunc;
1845  if (isBaryon() && nInitPlusVal - nInit >= 2 && (
1846  (nDiffJuncs > 0 && beamJunc < 0) ||
1847  (nDiffJuncs < 0 && beamJunc > 0)) ) {
1848 
1849  // If three, pick two at random to form junction, else trivial.
1850  int iQ1 = nInit;
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;
1856  }
1857 
1858  // Either form di-quark or (anti-)junction.
1859  if (beamJunction) {
1860  // Form antijunction.
1861  if (resolved[iQ1].id() < 0) {
1862 
1863  // Start by finding last colour in the out going particles.
1864  usedAcol[iQ1] = true;
1865  usedAcol[iQ2] = true;
1866 
1867  // Find matching anti-colour.
1868  int acol = findSingleCol(event, true, true);
1869  if ( acol == 0) return false;
1870 
1871  // Make the antijunction.
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(),
1877  acol);
1878  nDiffJuncs--;
1879  }
1880 
1881  // Form Junction.
1882  else {
1883  // Start by finding last colour in the out going particles.
1884  usedCol[iQ1] = true;
1885  usedCol[iQ2] = true;
1886 
1887  // Find matching colour.
1888  int col = findSingleCol(event, false, true);
1889  if (col == 0) return false;
1890 
1891  // Make the junction.
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);
1897  nDiffJuncs++;
1898  }
1899 
1900  // Form diquark.
1901  } else {
1902 
1903  // Pick spin 0 or 1 according to SU(6) wave function factors.
1904  int idDq = flavSelPtr->makeDiquark( resolved[iQ1].id(),
1905  resolved[iQ2].id(), idBeam);
1906 
1907  // Overwrite with diquark flavour and remove one slot. No more junction.
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;
1913 
1914  // Di-quark changes the baryon number.
1915  if (idDq > 0) nDiffJuncs++;
1916  else nDiffJuncs--;
1917  }
1918  }
1919 
1920  // Form anti-junction out of any beam remnants if needed.
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);
1926  nDiffJuncs--;
1927  }
1928  // Form junction out of any beam remnants if needed.
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);
1934  nDiffJuncs++;
1935  }
1936 
1937  // Set remaining colours first in random order.
1938  for (int j = 0;j < NRANDOMTRIES; ++j) {
1939  int i = int(rndmPtr->flat() * (size() - nInit) + nInit );
1940  // Check if resolved has colour.
1941  if ( resolved[i].hasCol() && !usedCol[i]) {
1942  usedCol[i] = true;
1943  int acol = findSingleCol(event,true,true);
1944  if ( acol == 0) return false;
1945  resolved[i].col(acol);
1946  }
1947  // Check if resolved has anti colour.
1948  if ( resolved[i].hasAcol() && !usedAcol[i]) {
1949  usedAcol[i] = true;
1950  int col = findSingleCol(event, false, true);
1951  if (col == 0) return false;
1952  resolved[i].acol(col);
1953  }
1954  }
1955 
1956  // Add all missed colours from the random assignment.
1957  for (int i = nInit;i < size();i++) {
1958  // Check if resolved has colour.
1959  if ( resolved[i].hasCol() && !usedCol[i]) {
1960  usedCol[i] = true;
1961  int acol = findSingleCol(event,true,true);
1962  if ( acol == 0) return false;
1963  resolved[i].col(acol);
1964  }
1965  // Check if resolved has anti colour.
1966  if ( resolved[i].hasAcol() && !usedAcol[i]) {
1967  usedAcol[i] = true;
1968  int col = findSingleCol(event, false, true);
1969  if (col == 0) return false;
1970  resolved[i].acol(col);
1971  }
1972  }
1973 
1974  // Need to end in a colour singlet.
1975  if (cols.size() != 0 || acols.size() != 0) {
1976  infoPtr->errorMsg("Error in BeamParticle::RemnantFlavours: "
1977  "Colour not conserved in beamRemnants");
1978  return false;
1979  }
1980 
1981  // Set initiator and remnant masses.
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() ) );
1985  }
1986 
1987  // For debug purposes: reject beams with resolved junction topology.
1988  if (hasJunctionBeam && !allowJunction) return false;
1989 
1990  // Done.
1991  return true;
1992 
1993 }
1994 
1995 //--------------------------------------------------------------------------
1996 
1997 // Set initial colours.
1998 
1999 void BeamParticle::setInitialCol(Event& event) {
2000 
2001  // Set beam colours equal to those in the event record.
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());
2007  }
2008 }
2009 
2010 //--------------------------------------------------------------------------
2011 
2012 // Find a single (anti-) colour in the beam, if it is a
2013 // beam remnant set the new colour.
2014 
2015 int BeamParticle::findSingleCol(Event& event, bool isAcol,
2016  bool useHardScatters) {
2017 
2018  // Look in the already scattered parton list.
2019  if (useHardScatters) {
2020  if (isAcol) {
2021  if (acols.size() > 0) {
2022  int iAcol = int(acols.size() * rndmPtr->flat());
2023  int acol = acols[iAcol];
2024  acols.erase(acols.begin() + iAcol);
2025  return acol;
2026  }
2027  } else {
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);
2032  return col;
2033  }
2034  }
2035  }
2036 
2037  // Look inside the beam remnants.
2038  if (isAcol) {
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;
2045  return acol;
2046  }
2047  }
2048  } else {
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;
2055  return col;
2056  }
2057  }
2058  }
2059 
2060  // Return 0 if no particle was found.
2061  infoPtr->errorMsg("Error in BeamParticle::findSingleCol: "
2062  "could not find matching anti colour");
2063  return 0;
2064 }
2065 
2066 //--------------------------------------------------------------------------
2067 
2068 // Update list of all colours in beam.
2069 
2070 void BeamParticle::updateCol(vector<pair<int,int> > colourChanges) {
2071 
2072  for (int iCol = 0;iCol < int(colourChanges.size()); ++iCol) {
2073  int oldCol = colourChanges[iCol].first;
2074  int newCol = colourChanges[iCol].second;
2075 
2076  // Update acols and cols.
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;
2081 
2082  // Update resolved partons colours.
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);
2086  }
2087  }
2088  return;
2089 }
2090 
2091 //--------------------------------------------------------------------------
2092 
2093 void BeamParticle::updateSingleCol(int oldCol, int newCol) {
2094 
2095  // Update acols and cols.
2096  for (int i = 0; i < int(cols.size()); ++i)
2097  if (cols[i] == oldCol) cols[i] = newCol;
2098 
2099  for ( int i = 0; i < int(acols.size()); ++i)
2100  if (acols[i] == oldCol) acols[i] = newCol;
2101 
2102  // Update resolved partons colours.
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);
2106  }
2107 
2108  colUpdates.push_back(make_pair(oldCol,newCol));
2109 }
2110 
2111 //==========================================================================
2112 
2113 } // end namespace Pythia8
Definition: AgUStep.h:26