1 // BeamParticle.cc is a part of the PYTHIA event generator.
2 // Copyright (C) 2008 Torbjorn Sjostrand.
3 // PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
4 // Please respect the MCnet Guidelines, see GUIDELINES for details.
6 // Function definitions (not found in the header) for the
9 #include "BeamParticle.h"
13 //**************************************************************************
15 // The BeamParticle class.
19 // Constants: could be changed here if desired, but normally should not.
20 // These are of technical nature, as described for each.
22 // A lepton that takes (almost) the full beam energy does not leave a remnant.
23 const double BeamParticle::XMINUNRESOLVED = 1. - 1e-10;
27 // Initialize data on a beam particle and save pointers.
29 void BeamParticle::init( int idIn, double pzIn, double eIn, double mIn,
30 Info* infoPtrIn, PDF* pdfInPtr, PDF* pdfHardInPtr,
31 bool isUnresolvedIn, StringFlav* flavSelPtrIn) {
33 // Store input pointers (and one bool) for future use.
35 pdfBeamPtr = pdfInPtr;
36 pdfHardBeamPtr = pdfHardInPtr;
37 isUnresolvedBeam = isUnresolvedIn;
38 flavSelPtr = flavSelPtrIn;
40 // Maximum quark kind in allowed incoming beam hadrons.
41 maxValQuark = Settings::mode("BeamRemnants:maxValQuark");
43 // Power of (1-x)^power/sqrt(x) for remnant valence quark distribution.
44 valencePowerMeson = Settings::parm("BeamRemnants:valencePowerMeson");
45 valencePowerUinP = Settings::parm("BeamRemnants:valencePowerUinP");
46 valencePowerDinP = Settings::parm("BeamRemnants:valencePowerDinP");
48 // Enhancement factor of x of diquark.
49 valenceDiqEnhance = Settings::parm("BeamRemnants:valenceDiqEnhance");
51 // Assume g(x) ~ (1-x)^power/x to constrain companion to sea quark.
52 companionPower = Settings::mode("BeamRemnants:companionPower");
54 // Assume g(x) ~ (1-x)^power/x to constrain companion to sea quark.
55 companionPower = Settings::mode("BeamRemnants:companionPower");
57 // Allow or not more than one valence quark to be kicked out.
58 allowJunction = Settings::flag("BeamRemnants:allowJunction");
60 // For diffractive system kick out q/g = norm / mass^power.
61 pickQuarkNorm = Settings::parm("BeamRemnants:pickQuarkNorm");
62 pickQuarkPower = Settings::parm("BeamRemnants:pickQuarkPower");
64 // Width of primordial kT distribution in diffractive systems.
65 diffPrimKTwidth = Settings::parm("BeamRemnants:diffPrimKTwidth");
67 // Suppress large masses of beam remnant in diffractive systems.
68 diffLargeMassSuppress = Settings::parm("BeamRemnants:diffLargeMassSuppress");
70 // Store info on the incoming beam.
73 pBeam = Vec4( 0., 0., pzIn, eIn);
80 // Initialize kind and valence flavour content of incoming beam.
81 // For recognized hadrons one can generate multiple interactions.
82 // So far we do not handle diagonal mesons or K0S/K0L (or photons),
83 // for which flavour content is only known after first interaction.
85 void BeamParticle::initBeamKind() {
88 idBeamAbs = abs(idBeam);
96 if (idBeamAbs > 10 && idBeamAbs < 17) {
103 // Done if cannot be lowest-lying hadron state.
104 if (idBeamAbs < 101 || idBeamAbs > 9999) return;
106 // Resolve valence content for assumed meson. Flunk unallowed codes.
107 if (idBeamAbs < 1000) {
108 int id1 = idBeamAbs/100;
109 int id2 = (idBeamAbs/10)%10;
110 if ( id1 < 1 || id1 > maxValQuark
111 || id2 < 1 || id2 > maxValQuark ) return;
112 if (id2 == id1 || idBeamAbs == 130 || idBeamAbs == 310) return;
115 // Store valence content of a confirmed meson.
127 // Resolve valence content for assumed baryon. Flunk unallowed codes.
129 int id1 = idBeamAbs/1000;
130 int id2 = (idBeamAbs/100)%10;
131 int id3 = (idBeamAbs/10)%10;
132 if ( id1 < 1 || id1 > maxValQuark || id2 < 1 || id2 > maxValQuark
133 || id3 < 1 || id3 > maxValQuark) return;
134 if (id2 > id1 || id3 > id1) return;
137 // Store valence content of a confirmed baryon.
138 nValKinds = 1; idVal[0] = id1; nVal[0] = 1;
139 if (id2 == id1) ++nVal[0];
145 if (id3 == id1) ++nVal[0];
146 else if (id3 == id2) ++nVal[1];
148 idVal[nValKinds] = id3;
154 // Flip flavours for antimeson or antibaryon, and then done.
155 if (idBeam < 0) for (int i = 0; i < nValKinds; ++i) idVal[i] = -idVal[i];
163 double BeamParticle::xMax(int iSkip) {
165 // Minimum requirement on remaining energy > nominal mass for hadron.
167 if (isHadron()) xLeft -= m() / e();
168 if (size() == 0) return xLeft;
170 // Subtract what was carried away by initiators (to date).
171 for (int i = 0; i < size(); ++i)
172 if (i != iSkip) xLeft -= resolved[i].x();
179 // Parton distributions, reshaped to take into account previous
180 // multiple interactions. By picking a non-negative iSkip value,
181 // one particular interaction is skipped, as needed for ISR
183 double BeamParticle::xfModified(int iSkip, int idIn, double x, double Q2) {
192 // Fast procedure for first interaction.
194 if (x >= 1.) return 0.;
195 bool canBeVal = false;
196 for (int i = 0; i < nValKinds; ++i)
197 if (idIn == idVal[i]) canBeVal = true;
199 xqVal = xfVal( idIn, x, Q2);
200 xqgSea = xfSea( idIn, x, Q2);
202 else xqgSea = xf( idIn, x, Q2);
204 // More complicated procedure for non-first interaction.
207 // Sum up the x already removed, and check that remaining x is enough.
209 for (int i = 0; i < size(); ++i)
210 if (i != iSkip) xUsed += resolved[i].x();
211 double xLeft = 1. - xUsed;
212 if (x >= xLeft) return 0.;
213 double xRescaled = x / xLeft;
215 // Calculate total and remaining amount of x carried by valence quarks.
217 double xValLeft = 0.;
218 for (int i = 0; i < nValKinds; ++i) {
219 nValLeft[i] = nVal[i];
220 for (int j = 0; j < size(); ++j)
221 if (j != iSkip && resolved[j].isValence()
222 && resolved[j].id() == idVal[i]) --nValLeft[i];
223 double xValNow = xValFrac(i, Q2);
224 xValTot += nVal[i] * xValNow;
225 xValLeft += nValLeft[i] * xValNow;
228 // Calculate total amount of x carried by unmatched companion quarks.
229 double xCompAdded = 0.;
230 for (int i = 0; i < size(); ++i)
231 if (i != iSkip && resolved[i].isUnmatched()) xCompAdded
232 += xCompFrac( resolved[i].x() / (xLeft + resolved[i].x()) )
233 // Typo warning: extrafactor missing in Skands&Sjostrand article;
234 // <x> for companion refers to fraction of x left INCLUDING sea quark.
235 // To be modified further??
236 * (1. + resolved[i].x() / xLeft);
238 // Calculate total rescaling factor and pdf for sea and gluon.
239 double rescaleGS = max( 0., (1. - xValLeft - xCompAdded)
241 xqgSea = rescaleGS * xfSea( idIn, xRescaled, Q2);
243 // Find valence part and rescale it to remaining number of quarks.
244 for (int i = 0; i < nValKinds; ++i)
245 if (idIn == idVal[i] && nValLeft[i] > 0)
246 xqVal = xfVal( idIn, xRescaled, Q2)
247 * double(nValLeft[i]) / double(nVal[i]);
249 // Find companion part, by adding all companion contributions.
250 for (int i = 0; i < size(); ++i)
251 if (i != iSkip && resolved[i].id() == -idIn
252 && resolved[i].isUnmatched()) {
253 double xsRescaled = resolved[i].x() / (xLeft + resolved[i].x());
254 double xcRescaled = x / (xLeft + resolved[i].x());
255 double xqCompNow = xCompDist( xcRescaled, xsRescaled);
256 resolved[i].xqCompanion( xqCompNow);
257 xqCompSum += xqCompNow;
261 // Add total, but only return relevant part for ISR. More cases??
262 // Watch out, e.g. g can come from either kind of quark.??
263 xqgTot = xqVal + xqgSea + xqCompSum;
265 if (resolved[iSkip].isValence()) return xqVal;
266 if (resolved[iSkip].isUnmatched()) return xqgSea + xqCompSum;
274 // Decide whether a quark extracted from the beam is of valence, sea or
275 // companion kind; in the latter case also pick its companion.
276 // Assumes xfModified has already been called.
278 int BeamParticle::pickValSeaComp() {
280 // If parton already has a companion than reset code for this.
281 int oldCompanion = resolved[iSkipSave].companion();
282 if (oldCompanion >= 0) resolved[oldCompanion].companion(-2);
284 // Default assignment is sea.
287 // For gluons or photons no sense of valence or sea.
288 if (idSave == 21 || idSave == 22) vsc = -1;
290 // For lepton beam assume same-kind lepton inside is valence.
291 else if (isLeptonBeam && idSave == idBeam) vsc = -3;
293 // Decide if valence or sea quark.
295 double xqRndm = xqgTot * Rndm::flat();
296 if (xqRndm < xqVal) vsc = -3;
297 else if (xqRndm < xqVal + xqgSea) vsc = -2;
299 // If not either, loop over all possible companion quarks.
301 xqRndm -= xqVal + xqgSea;
302 for (int i = 0; i < size(); ++i)
303 if (i != iSkipSave && resolved[i].id() == -idSave
304 && resolved[i].isUnmatched()) {
305 xqRndm -= resolved[i].xqCompanion();
306 if (xqRndm < 0.) vsc = i;
312 // Bookkeep assignment; for sea--companion pair both ways.
313 resolved[iSkipSave].companion(vsc);
314 if (vsc >= 0) resolved[vsc].companion(iSkipSave);
316 // Done; return code for choice (to distinguish valence/sea in Info).
323 // Fraction of hadron momentum sitting in a valence quark distribution.
324 // Based on hardcoded parametrizations of CTEQ 5L numbers.
326 double BeamParticle::xValFrac(int j, double Q2) {
328 // Only recalculate when required.
329 if (Q2 != Q2ValFracSav) {
332 // Q2-dependence of log-log form; assume fixed Lambda = 0.2.
333 double llQ2 = log( log( max( 1., Q2) / 0.04 ));
335 // Fractions carried by u and d in proton.
336 uValInt = 0.48 / (1. + 1.56 * llQ2);
337 dValInt = 0.385 / (1. + 1.60 * llQ2);
340 // Baryon with three different quark kinds: (2 * u + d) / 3 of proton.
341 if (isBaryonBeam && nValKinds == 3) return (2. * uValInt + dValInt) / 3.;
343 // Baryon with one or two identical: like d or u of proton.
344 if (isBaryonBeam && nVal[j] == 1) return dValInt;
345 if (isBaryonBeam && nVal[j] == 2) return uValInt;
347 // Meson: (2 * u + d) / 2 of proton so same total valence quark fraction.
348 return 0.5 * (2. * uValInt + dValInt);
354 // The momentum integral of a companion quark, with its partner at x_s,
355 // using an approximate gluon density like (1 - x_g)^power / x_g.
356 // The value corresponds to an unrescaled range between 0 and 1 - x_s.
358 double BeamParticle::xCompFrac(double xs) {
360 // Select case by power of gluon (1-x_g) shape.
361 switch (companionPower) {
364 return xs * ( 5. + xs * (-9. - 2. * xs * (-3. + xs)) + 3. * log(xs) )
365 / ( (-1. + xs) * (2. + xs * (-1. + 2. * xs)) );
368 return -1. -3. * xs + ( 2. * pow2(-1. + xs) * (1. + xs + xs*xs))
369 / ( 2. + xs*xs * (xs - 3.) + 3. * xs * log(xs) );
372 return xs * ( (1. - xs) * (19. + xs * (43. + 4. * xs))
373 + 6. * log(xs) * (1. + 6. * xs + 4.*xs*xs) ) /
374 ( 4. * ( (xs - 1.) * (1. + xs * (4. + xs) )
375 - 3. * xs * log(xs) * (1 + xs) ) );
378 return 3. * xs * ( (xs - 1.) * (7. + xs * (28. + 13. * xs))
379 - 2. * log(xs) * (1. + xs * (9. + 2. * xs * (6. + xs))) )
380 / ( 4. + 27. * xs - 31. * pow3(xs)
381 + 6. * xs * log(xs) * (3. + 2. * xs * (3.+xs)) );
384 return ( -9. * xs * (xs*xs - 1.) * (5. + xs * (24. + xs)) + 12. * xs
385 * log(xs) * (1. + 2. * xs) * (1. + 2. * xs * (5. + 2. * xs)) )
386 / ( 8. * (1. + 2. * xs) * ((xs - 1.) * (1. + xs * (10. + xs))
387 - 6. * xs * log(xs) * (1. + xs)) );
394 // The x*f pdf of a companion quark at x_c, with its sea partner at x_s,
395 // using an approximate gluon density like (1 - x_g)^power / x_g.
396 // The value corresponds to an unrescaled range between 0 and 1 - x_s.
398 double BeamParticle::xCompDist(double xc, double xs) {
400 // Mother gluon momentum fraction. Check physical limit.
402 if (xg > 1.) return 0.;
404 // Common factor, including splitting kernel and part of gluon density
405 // (and that it is x_c * f that is coded).
406 double fac = 3. * xc * xs * (xc*xc + xs*xs) / pow4(xg);
408 // Select case by power of gluon (1-x_g) shape.
409 switch (companionPower) {
412 return fac / ( 2. - xs * (3. - xs * (3. - 2. * xs)) );
415 return fac * (1. - xg) / ( 2. + xs*xs * (-3. + xs) + 3. * xs * log(xs) );
418 return fac * pow2(1. - xg) / ( 2. * ((1. - xs) * (1. + xs * (4. + xs))
419 + 3. * xs * (1. + xs) * log(xs)) );
422 return fac * pow3(1. - xg) * 2. / ( 4. + 27. * xs - 31. * pow3(xs)
423 + 6. * xs * log(xs) * (3. + 2. * xs * (3. + xs)) );
426 return fac * pow4(1. - xg) / ( 2. * (1. + 2. * xs) * ((1. - xs)
427 * (1. + xs * (10. + xs)) + 6. * xs * log(xs) * (1. + xs)) );
434 // Add required extra remnant flavour content. Also initial colours.
436 bool BeamParticle::remnantFlavours(Event& event) {
438 // A baryon will have a junction, unless a diquark is formed later.
439 hasJunctionBeam = (isBaryon());
441 // Store how many hard-scattering partons were removed from beam.
444 // Find remaining valence quarks.
445 for (int i = 0; i < nValKinds; ++i) {
446 nValLeft[i] = nVal[i];
447 for (int j = 0; j < nInit; ++j) if (resolved[j].isValence()
448 && resolved[j].id() == idVal[i]) --nValLeft[i];
449 // Add remaining valence quarks to record. Partly temporary values.
450 for (int k = 0; k < nValLeft[i]; ++k) append(0, idVal[i], 0., -3);
453 // If at least two valence quarks left in baryon remnant then form diquark.
454 int nInitPlusVal = size();
455 if (isBaryon() && nInitPlusVal - nInit >= 2) {
457 // If three, pick two at random to form diquark, else trivial.
460 if (nInitPlusVal - nInit == 3) {
461 double pickDq = 3. * Rndm::flat();
462 if (pickDq > 1.) iQ2 = nInit + 2;
463 if (pickDq > 2.) iQ1 = nInit + 1;
466 // Pick spin 0 or 1 according to SU(6) wave function factors.
467 int idDq = flavSelPtr->makeDiquark( resolved[iQ1].id(),
468 resolved[iQ2].id(), idBeam);
470 // Overwrite with diquark flavour and remove one slot. No more junction.
471 resolved[iQ1].id(idDq);
472 if (nInitPlusVal - nInit == 3 && iQ2 == nInit + 1)
473 resolved[nInit + 1].id( resolved[nInit + 2].id() );
475 hasJunctionBeam = false;
478 // Find companion quarks to unmatched sea quarks.
479 for (int i = 0; i < nInit; ++i)
480 if (resolved[i].isUnmatched()) {
482 // Add companion quark to record; and bookkeep both ways.
483 append(0, -resolved[i].id(), 0., i);
484 resolved[i].companion(size() - 1);
487 // If no other remnants found, add a gluon or photon to carry momentum.
488 if (size() == nInit) {
489 int idRemnant = (isHadronBeam) ? 21 : 22;
490 append(0, idRemnant, 1., -1);
493 // Set initiator and remnant masses.
494 for (int i = 0; i < size(); ++i) {
495 if (i < nInit) resolved[i].m(0.);
496 else resolved[i].m( ParticleDataTable::m0( resolved[i].id() ) );
499 // For debug purposes: reject beams with resolved junction topology.
500 if (hasJunctionBeam && !allowJunction) return false;
502 // Pick initial colours for remnants.
503 for (int i = nInit; i < size(); ++i) {
504 int colType = ParticleDataTable::colType( resolved[i].id() );
505 int col = (colType == 1 || colType == 2) ? event.nextColTag() : 0;
506 int acol = (colType == -1 || colType == 2) ? event.nextColTag() : 0;
507 resolved[i].cols( col, acol);
517 // Correlate all initiators and remnants to make a colour singlet.
519 bool BeamParticle::remnantColours(Event& event, vector<int>& colFrom,
520 vector<int>& colTo) {
522 // No colours in lepton beams so no need to do anything.
523 if (isLeptonBeam) return true;
525 // Copy initiator colour info from the event record to the beam.
526 for (int i = 0; i < size(); ++i) {
527 int j = resolved[i].iPos();
528 resolved[i].cols( event[j].col(), event[j].acol());
531 // Find number and position of valence quarks, of gluons, and
532 // of sea-companion pairs (counted as gluons) in the beam remnants.
533 // Skip gluons with same colour as anticolour.
536 for (int i = 0; i < size(); ++i) {
537 if ( resolved[i].isValence() ) iVal.push_back(i);
538 else if ( resolved[i].isCompanion() && resolved[i].companion() > i )
540 else if ( resolved[i].id() == 21
541 && resolved[i].col() != resolved[i].acol() ) iGlu.push_back(i);
544 // Pick a valence quark to which gluons are attached.
545 // Do not resolve quarks in diquark. (More sophisticated??)
546 int iValSel= iVal[0];
547 if (iVal.size() == 2) {
548 if ( abs(resolved[iValSel].id()) > 10 ) iValSel = iVal[1];
550 double rndmValSel = 3. * Rndm::flat();
551 if (rndmValSel > 1.) iValSel= iVal[1];
552 if (rndmValSel > 2.) iValSel= iVal[2];
555 // This valence quark defines initial (anti)colour.
557 bool hasCol = (resolved[iBeg].col() > 0);
558 int begCol = (hasCol) ? resolved[iBeg].col() : resolved[iBeg].acol();
560 // Do random stepping through gluon/(sea+companion) list.
561 vector<int> iGluRndm;
562 for (int i = 0; i < int(iGlu.size()); ++i)
563 iGluRndm.push_back( iGlu[i] );
564 for (int iOrder = 0; iOrder < int(iGlu.size()); ++iOrder) {
565 int iRndm = int( double(iGluRndm.size()) * Rndm::flat());
566 int iGluSel = iGluRndm[iRndm];
567 iGluRndm[iRndm] = iGluRndm[iGluRndm.size() - 1];
570 // Find matching anticolour/colour to current colour/anticolour.
572 int endCol = (hasCol) ? resolved[iEnd].acol() : resolved[iEnd].col();
573 // Not gluon but sea+companion pair: go to other.
575 iEnd = resolved[iEnd].companion();
576 endCol = (hasCol) ? resolved[iEnd].acol() : resolved[iEnd].col();
579 // Collapse this colour-anticolour pair to the lowest one.
580 if (begCol < endCol) {
581 if (hasCol) resolved[iEnd].acol(begCol);
582 else resolved[iEnd].col(begCol);
583 colFrom.push_back(endCol);
584 colTo.push_back(begCol);
586 if (hasCol) resolved[iBeg].col(endCol);
587 else resolved[iBeg].acol(endCol);
588 colFrom.push_back(begCol);
589 colTo.push_back(endCol);
592 // Pick up the other colour of the recent gluon and repeat.
594 begCol = (hasCol) ? resolved[iBeg].col() : resolved[iBeg].acol();
595 // Not gluon but sea+companion pair: go to other.
597 iBeg = resolved[iBeg].companion();
598 begCol = (hasCol) ? resolved[iBeg].col() : resolved[iBeg].acol();
601 // At end of gluon/(sea+companion) list.
604 // Now begin checks, and also finding junction information.
605 // Loop through remnant partons; isolate all colours and anticolours.
607 vector<int> acolList;
608 for (int i = 0; i < size(); ++i)
609 if ( resolved[i].col() != resolved[i].acol() ) {
610 if (resolved[i].col() > 0) colList.push_back( resolved[i].col() );
611 if (resolved[i].acol() > 0) acolList.push_back( resolved[i].acol() );
614 // Remove all matching colour-anticolour pairs.
615 bool foundPair = true;
616 while (foundPair && colList.size() > 0 && acolList.size() > 0) {
618 for (int iCol = 0; iCol < int(colList.size()); ++iCol) {
619 for (int iAcol = 0; iAcol < int(acolList.size()); ++iAcol) {
620 if (acolList[iAcol] == colList[iCol]) {
621 colList[iCol] = colList.back(); colList.pop_back();
622 acolList[iAcol] = acolList.back(); acolList.pop_back();
623 foundPair = true; break;
625 } if (foundPair) break;
629 // Usually one unmatched pair left to collapse.
630 if (colList.size() == 1 && acolList.size() == 1) {
631 int finalFrom = max( colList[0], acolList[0]);
632 int finalTo = min( colList[0], acolList[0]);
633 for (int i = 0; i < size(); ++i) {
634 if (resolved[i].col() == finalFrom) resolved[i].col(finalTo);
635 if (resolved[i].acol() == finalFrom) resolved[i].acol(finalTo);
637 colFrom.push_back(finalFrom);
638 colTo.push_back(finalTo);
640 // Store an (anti)junction when three (anti)coloured daughters.
641 } else if (hasJunctionBeam && colList.size() == 3
642 && acolList.size() == 0) {
643 event.appendJunction( 1, colList[0], colList[1], colList[2]);
644 junCol[0] = colList[0];
645 junCol[1] = colList[1];
646 junCol[2] = colList[2];
647 } else if (hasJunctionBeam && acolList.size() == 3
648 && colList.size() == 0) {
649 event.appendJunction( 2, acolList[0], acolList[1], acolList[2]);
650 junCol[0] = acolList[0];
651 junCol[1] = acolList[1];
652 junCol[2] = acolList[2];
654 // Any other nonvanishing values indicate failure.
655 } else if (colList.size() > 0 || acolList.size() > 0) {
656 infoPtr->errorMsg("Error in BeamParticle::remnantColours: "
657 "leftover unmatched colours");
661 // Store colour assignment of beam particles.
662 for (int i = nInit; i < size(); ++i)
663 event[resolved[i].iPos()].cols( resolved[i].col(), resolved[i].acol() );
672 // Pick unrescaled x values for beam remnant sharing.
674 double BeamParticle::xRemnant( int i) {
678 // Calculation of x of valence quark or diquark, for latter as sum.
679 if (resolved[i].isValence()) {
681 // Resolve diquark into sum of two quarks.
682 int id1 = resolved[i].id();
685 id2 = (id1 > 0) ? (id1/100)%10 : -(((-id1)/100)%10);
686 id1 = (id1 > 0) ? id1/1000 : -((-id1)/1000);
689 // Loop over (up to) two quarks; add their contributions.
690 for (int iId = 0; iId < 2; ++iId) {
691 int idNow = (iId == 0) ? id1 : id2;
692 if (idNow == 0) break;
695 // Assume form (1-x)^a / sqrt(x).
696 double xPow = valencePowerMeson;
698 if (nValKinds == 3 || nValKinds == 1)
699 xPow = (3. * Rndm::flat() < 2.)
700 ? valencePowerUinP : valencePowerDinP ;
701 else if (nValence(idNow) == 2) xPow = valencePowerUinP;
702 else xPow = valencePowerDinP;
704 do xPart = pow2( Rndm::flat() );
705 while ( pow(1. - xPart, xPow) < Rndm::flat() );
707 // End loop over (up to) two quarks. Possibly enhancement for diquarks.
710 if (id2 != 0) x *= valenceDiqEnhance;
712 // Calculation of x of sea quark, based on companion association.
713 } else if (resolved[i].isCompanion()) {
715 // Find rescaled x value of companion.
717 for (int iInit = 0; iInit < nInit; ++iInit)
718 xLeft -= resolved[iInit].x();
719 double xCompanion = resolved[ resolved[i].companion() ].x();
720 xCompanion /= (xLeft + xCompanion);
722 // Now use ansatz q(x; x_c) < N/(x +x_c) to pick x.
723 do x = pow( xCompanion, Rndm::flat()) - xCompanion;
724 while ( pow( (1. - x - xCompanion) / (1. - xCompanion), companionPower)
725 * (pow2(x) + pow2(xCompanion)) / pow2(x + xCompanion) < Rndm::flat() );
727 // Else, rarely, a single gluon remnant, so value does not matter.
735 // Print the list of resolved partons in a beam.
737 void BeamParticle::list(ostream& os) {
740 os << "\n -------- PYTHIA Partons resolved in beam ------------"
741 << "--------------------------------------------------------\n"
742 << "\n i iPos id x comp xqcomp colours"
743 << " p_x p_y p_z e m \n";
745 // Loop over list of removed partons and print it.
748 for (int i = 0; i < size(); ++i) {
749 ResolvedParton res = resolved[i];
750 os << fixed << setprecision(6) << setw(5) << i << setw(6) << res.iPos()
751 << setw(8) << res.id() << setw(10) << res.x() << setw(6)
752 << res.companion() << setw(10) << res.xqCompanion()
753 << setprecision(3) << setw(6) << res.col() << setw(6) << res.acol()
754 << setw(11) << res.px() << setw(11) << res.py() << setw(11)
755 << res.pz() << setw(11) << res.e() << setw(11) << res.m() << "\n";
757 // Also find and print sum of x and p values. Endline.
761 os << setprecision(6) << " x sum:" << setw(10) << xSum
762 << setprecision(3) << " p sum:" << setw(11)
763 << pSum.px() << setw(11) << pSum.py() << setw(11) << pSum.pz()
764 << setw(11) << pSum.e()
765 << "\n\n -------- End PYTHIA Partons resolved in beam ------"
766 << "----------------------------------------------------------"
772 // Test whether a lepton is to be considered as unresolved.
774 bool BeamParticle::isUnresolvedLepton() {
776 // Require record to consist of lepton with full energy plus a photon.
777 if (!isLeptonBeam || resolved.size() > 2 || resolved[1].id() != 22
778 || resolved[0].x() < XMINUNRESOLVED) return false;
785 // For a diffractive system, decide whether to kick out gluon or quark.
787 bool BeamParticle::pickGluon(double mDiff) {
789 // Relative weight to pick a quark, assumed falling with energy.
790 double probPickQuark = pickQuarkNorm / pow( mDiff, pickQuarkPower);
791 return ( (1. + probPickQuark) * Rndm::flat() < 1. );
797 // Pick a valence quark at random. (Used for diffractive systems.)
799 int BeamParticle::pickValence() {
801 // Pick one valence quark at random.
802 int nTotVal = (isBaryonBeam) ? 3 : 2;
803 double rnVal = Rndm::flat() * nTotVal;
804 int iVal = (rnVal < 1.) ? 1 : ( (rnVal < 2.) ? 2 : 3 );
806 // This valence in slot 1, the rest thereafter.
811 for (int i = 0; i < nValKinds; ++i)
812 for (int j = 0; j < nVal[i]; ++j) {
814 if (iNow == iVal) idVal1 = idVal[i];
815 else if ( idVal2 == 0) idVal2 = idVal[i];
816 else idVal3 = idVal[i];
819 // Construct diquark if baryon.
820 if (idVal3 != 0) idVal2 = flavSelPtr->makeDiquark( idVal2, idVal3);
829 // Share lightcone momentum between two remnants in a diffractive system.
831 double BeamParticle::zShare( double mDiff, double m1, double m2) {
833 // Set up as valence in normal beam so can use xRemnant code.
834 append(0, idVal1, 0., -3);
835 append(0, idVal2, 0., -3);
836 double m2Diff = mDiff*mDiff;
838 // Begin to generate z and pT until acceptable solution.
841 double x1 = xRemnant(0);
842 double x2 = xRemnant(0);
843 zRel = x1 / (x1 + x2);
844 pxRel = diffPrimKTwidth * Rndm::gauss();
845 pyRel = diffPrimKTwidth * Rndm::gauss();
847 // Suppress large invariant masses of remnant system.
848 double mTS1 = m1*m1 + pxRel*pxRel + pyRel*pyRel;
849 double mTS2 = m2*m2 + pxRel*pxRel + pyRel*pyRel;
850 double m2Sys = mTS1 / zRel + mTS2 / (1. - zRel);
851 wtAcc = (m2Sys < m2Diff)
852 ? pow( 1. - m2Sys / m2Diff, diffLargeMassSuppress) : 0.;
853 } while (wtAcc < Rndm::flat());
860 //**************************************************************************
862 } // end namespace Pythia8