1 // PartonLevel.cc is a part of the PYTHIA event generator.
2 // Copyright (C) 2010 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 PartonLevel class.
8 #include "PartonLevel.h"
12 //==========================================================================
14 // The PartonLevel class.
16 //--------------------------------------------------------------------------
18 // Constants: could be changed here if desired, but normally should not.
19 // These are of technical nature, as described for each.
21 // Maximum number of tries to produce parton level from given input.
22 const int PartonLevel::NTRY = 10;
24 //--------------------------------------------------------------------------
26 // Main routine to initialize the parton-level generation process.
28 bool PartonLevel::init( Info* infoPtrIn, Settings& settings,
29 ParticleData* particleDataPtrIn, Rndm* rndmPtrIn,
30 BeamParticle* beamAPtrIn, BeamParticle* beamBPtrIn,
31 BeamParticle* beamPomAPtrIn, BeamParticle* beamPomBPtrIn,
32 Couplings* couplingsPtrIn, PartonSystems* partonSystemsPtrIn,
33 SigmaTotal* sigmaTotPtr, TimeShower* timesDecPtrIn, TimeShower* timesPtrIn,
34 SpaceShower* spacePtrIn, UserHooks* userHooksPtrIn) {
36 // Store input pointers and modes for future use.
38 particleDataPtr = particleDataPtrIn;
40 beamAPtr = beamAPtrIn;
41 beamBPtr = beamBPtrIn;
42 beamHadAPtr = beamAPtr;
43 beamHadBPtr = beamBPtr;
44 beamPomAPtr = beamPomAPtrIn;
45 beamPomBPtr = beamPomBPtrIn;
46 couplingsPtr = couplingsPtrIn;
47 partonSystemsPtr = partonSystemsPtrIn;
48 timesDecPtr = timesDecPtrIn;
49 timesPtr = timesPtrIn;
50 spacePtr = spacePtrIn;
51 userHooksPtr = userHooksPtrIn;
53 // Min bias and single diffraction processes need special treatment.
54 doMinBias = settings.flag("SoftQCD:all")
55 || settings.flag("SoftQCD:minBias");
56 doDiffraction = settings.flag("SoftQCD:all")
57 || settings.flag("SoftQCD:singleDiffractive")
58 || settings.flag("SoftQCD:doubleDiffractive");
60 // Separate low-mass (unresolved) and high-mass (perturbative) diffraction.
61 mMinDiff = settings.parm("Diffraction:mMinPert");
62 mWidthDiff = settings.parm("Diffraction:mWidthPert");
63 if (mMinDiff + mWidthDiff > infoPtr->eCM()) doDiffraction = false;
65 // Need MI initialization for soft QCD processes, even if only first MI.
66 // But no need to initialize MI if never going to use it.
67 doMI = settings.flag("PartonLevel:MI");
72 if (doMinBias || doDiffraction) doMIinit = true;
73 if (!settings.flag("PartonLevel:all")) doMIinit = false;
75 // Flags for showers: ISR and FSR.
76 doISR = settings.flag("PartonLevel:ISR");
77 bool FSR = settings.flag("PartonLevel:FSR");
78 bool FSRinProcess = settings.flag("PartonLevel:FSRinProcess");
79 bool interleaveFSR = settings.flag("TimeShower:interleave");
80 doFSRduringProcess = FSR && FSRinProcess && interleaveFSR;
81 doFSRafterProcess = FSR && FSRinProcess && !interleaveFSR;
82 doFSRinResonances = FSR && settings.flag("PartonLevel:FSRinResonances");
85 doRemnants = settings.flag("PartonLevel:Remnants");
86 doSecondHard = settings.flag("SecondHard:generate");
88 // Flag if lepton beams, and if non-resolved ones. May change main flags.
89 hasLeptonBeams = ( beamAPtr->isLepton() || beamBPtr->isLepton() );
90 hasPointLeptons = ( hasLeptonBeams
91 && (beamAPtr->isUnresolved() || beamBPtr->isUnresolved() ) );
98 if (hasPointLeptons) {
103 // Possibility to allow user veto during evolution.
104 canVetoPT = (userHooksPtr > 0) ? userHooksPtr->canVetoPT() : false;
105 pTvetoPT = (canVetoPT) ? userHooksPtr->scaleVetoPT() : -1.;
106 canVetoStep = (userHooksPtr > 0) ? userHooksPtr->canVetoStep() : false;
107 nVetoStep = (canVetoStep) ? userHooksPtr->numberVetoStep() : -1;
108 canVetoMIStep = (userHooksPtr > 0) ? userHooksPtr->canVetoMIStep() : false;
109 nVetoMIStep = (canVetoStep) ? userHooksPtr->numberVetoMIStep() : -1;
111 // Possibility to set maximal shower scale in resonance decays.
112 canSetScale = (userHooksPtr > 0) ? userHooksPtr->canSetResonanceScale()
115 // Set info and initialize the respective program elements.
116 timesPtr->init( beamAPtr, beamBPtr);
117 if (doISR) spacePtr->init( beamAPtr, beamBPtr);
118 doMIMB = multiMB.init( doMIinit, 0, infoPtr, settings, particleDataPtr,
119 rndmPtr, beamAPtr, beamBPtr, couplingsPtr, partonSystemsPtr, sigmaTotPtr);
120 if (doDiffraction) doMISDA = multiSDA.init( doMIinit, 1, infoPtr,
121 settings, particleDataPtr, rndmPtr, beamPomBPtr, beamAPtr, couplingsPtr,
122 partonSystemsPtr, sigmaTotPtr);
123 if (doDiffraction) doMISDB = multiSDB.init( doMIinit, 2, infoPtr,
124 settings, particleDataPtr, rndmPtr, beamPomAPtr, beamBPtr, couplingsPtr,
125 partonSystemsPtr, sigmaTotPtr);
126 remnants.init( infoPtr, settings, rndmPtr, beamAPtr, beamBPtr,
129 // Succeeded, or not.
131 if (doMIinit && !doMIMB) return false;
132 if (doMIinit && doDiffraction && (!doMISDA || !doMISDB)) return false;
133 if (!doMIMB || !doMISDA || !doMISDB) doMI = false;
137 //--------------------------------------------------------------------------
139 // Main routine to do the parton-level evolution.
141 bool PartonLevel::next( Event& process, Event& event) {
143 // Current event classification.
144 isResolved = infoPtr->isResolved();
145 isResolvedA = isResolved;
146 isResolvedB = isResolved;
147 isDiffA = infoPtr->isDiffractiveA();
148 isDiffB = infoPtr->isDiffractiveB();
149 isDiff = isDiffA || isDiffB;
150 isDoubleDiff = isDiffA && isDiffB;
151 isSingleDiff = isDiff && !isDoubleDiff;
152 isMinBias = infoPtr->isMinBias();
154 // nHardLoop counts how many hard-scattering subsystems are to be processed.
155 // Almost always 1, but elastic and low-mass diffraction gives 0, while
156 // double diffraction can give up to 2. Not to be confused with SecondHard.
158 if (!isResolved) nHardLoop = (isDiff) ? decideResolvedDiff( process) : 0;
160 // Handle unresolved subsystems. Done if no resolved ones.
163 if (!isResolvedA || !isResolvedB) {
164 bool physical = setupUnresolvedSys( process, event);
165 if (!physical || nHardLoop == 0) return physical;
166 sizeProcess = process.size();
167 sizeEvent = event.size();
170 // Big outer loop to handle up to two systems (in double diffraction),
171 // but normally one. (Not indented in following, but end clearly marked.)
172 for (int iHardLoop = 1; iHardLoop <= nHardLoop; ++iHardLoop) {
173 infoPtr->setCounter(20, iHardLoop);
174 infoPtr->setCounter(21);
176 // Process and event records can be out of step for diffraction.
177 if (iHardLoop == 2) {
178 sizeProcess = process.size();
179 sizeEvent = event.size();
180 partonSystemsPtr->clear();
183 // If you need to restore then do not throw existing diffractive system.
186 event.saveJunctionSize();
189 // Allow special treatment of diffractive systems.
190 if (isDiff) setupResolvedDiff(iHardLoop, process);
192 // Prepare to do multiple interactions; at new mass for diffraction.
193 if (doMIinit) multiPtr->reset();
195 // Special case if minimum bias: do hardest interaction.
196 if (isMinBias || isDiff) {
198 multiPtr->setupFirstSys( process);
201 // Allow up to ten tries; failure possible for beam remnants.
202 // Main cause: inconsistent colour flow at the end of the day.
203 bool physical = true;
205 for (int iTry = 0; iTry < NTRY; ++ iTry) {
206 infoPtr->addCounter(21);
207 for (int i = 22; i < 32; ++i) infoPtr->setCounter(i);
209 // Reset flag, counters and max scales.
211 nMI = (doSecondHard) ? 2 : 1;
221 // Identify hard interaction system for showers.
222 setupHardSys( iHardLoop, process, event);
224 // Optionally check for a veto after the hardest interaction.
226 doVeto = userHooksPtr->doVetoMIStep( 1, event);
227 // Abort event if vetoed.
229 if (isDiff) leaveResolvedDiff( iHardLoop, event);
234 // Check matching of process scale to maximum ISR/FSR/MI scales.
235 double Q2Fac = infoPtr->Q2Fac();
236 double Q2Ren = infoPtr->Q2Ren();
237 bool limitPTmaxISR = (doISR)
238 ? spacePtr->limitPTmax( event, Q2Fac, Q2Ren) : false;
239 bool limitPTmaxFSR = (doFSRduringProcess)
240 ? timesPtr->limitPTmax( event, Q2Fac, Q2Ren) : false;
241 bool limitPTmaxMI = (doMI) ? multiPtr->limitPTmax( event) : false;
243 // Set hard scale, maximum for showers and multiple interactions,
244 double pTscale = process.scale();
245 if (doSecondHard) pTscale = max( pTscale, process.scaleSecond() );
246 double pTmaxMI = (limitPTmaxMI) ? pTscale : infoPtr->eCM();
247 double pTmaxISR = (limitPTmaxISR) ? spacePtr->enhancePTmax() * pTscale
249 double pTmaxFSR = (limitPTmaxFSR) ? timesPtr->enhancePTmax() * pTscale
251 double pTmax = max( pTmaxMI, max( pTmaxISR, pTmaxFSR) );
253 pTsaveISR = pTmaxISR;
254 pTsaveFSR = pTmaxFSR;
256 // Prepare the classes to begin the generation.
257 if (doMI) multiPtr->prepare( pTmaxMI);
258 if (doISR) spacePtr->prepare( 0, event, limitPTmaxISR);
259 if (doFSRduringProcess) timesPtr->prepare( 0, event, limitPTmaxFSR);
260 if (doSecondHard && doISR) spacePtr->prepare( 1, event, limitPTmaxISR);
261 if (doSecondHard && doFSRduringProcess)
262 timesPtr->prepare( 1, event, limitPTmaxFSR);
264 // Set up initial veto scale.
266 double pTveto = pTvetoPT;
269 // Begin evolution down in pT from hard pT scale.
271 infoPtr->addCounter(22);
273 nRad = nISR + nFSRinProc;
275 // Find next pT value for FSR, MI and ISR.
276 // Order calls to minimize time expenditure.
278 double pTtimes = (doFSRduringProcess)
279 ? timesPtr->pTnext( event, pTmaxFSR, pTgen) : -1.;
280 pTgen = max( pTgen, pTtimes);
281 double pTmulti = (doMI)
282 ? multiPtr->pTnext( pTmaxMI, pTgen, event) : -1.;
283 pTgen = max( pTgen, pTmulti);
284 double pTspace = (doISR)
285 ? spacePtr->pTnext( event, pTmaxISR, pTgen, nRad) : -1.;
286 double pTnow = max( pTtimes, max( pTmulti, pTspace));
287 infoPtr->setPTnow( pTnow);
289 // Allow a user veto. Only do it once, so remember to change pTveto.
290 if (pTveto > 0. && pTveto > pTnow) {
292 doVeto = userHooksPtr->doVetoPT( typeLatest, event);
293 // Abort event if vetoed.
295 if (isDiff) leaveResolvedDiff( iHardLoop, event);
300 // Do a multiple interaction (if allowed).
301 if (pTmulti > 0. && pTmulti > pTspace && pTmulti > pTtimes) {
302 infoPtr->addCounter(23);
303 multiPtr->scatter( event);
306 if (canVetoMIStep && nMI <= nVetoMIStep) typeVetoStep = 1;
308 // Update ISR and FSR dipoles.
309 if (doISR) spacePtr->prepare( nMI - 1, event);
310 if (doFSRduringProcess) timesPtr->prepare( nMI - 1, event);
312 // Set maximal scales for next pT to pick.
314 pTmaxISR = min( pTmulti, pTmaxISR);
315 pTmaxFSR = min( pTmulti, pTmaxFSR);
319 // Do an initial-state emission (if allowed).
320 else if (pTspace > 0. && pTspace > pTtimes) {
321 infoPtr->addCounter(24);
322 if (spacePtr->branch( event)) {
324 iSysNow = spacePtr->system();
326 if (iSysNow == 0) ++nISRhard;
327 if (canVetoStep && iSysNow == 0 && nISRhard <= nVetoStep)
330 // Update FSR dipoles.
331 if (doFSRduringProcess) timesPtr->update( iSysNow, event);
333 // Rescatter: it is possible for kinematics to fail, in which
334 // case we need to restart the parton level processing.
335 } else if (spacePtr->doRestart()) {
340 // Set maximal scales for next pT to pick.
341 pTmaxMI = min( pTspace, pTmaxMI);
343 pTmaxFSR = min( pTspace, pTmaxFSR);
347 // Do a final-state emission (if allowed).
348 else if (pTtimes > 0.) {
349 infoPtr->addCounter(25);
350 if (timesPtr->branch( event, true)) {
352 iSysNow = timesPtr->system();
354 if (iSysNow == 0) ++nFSRhard;
355 if (canVetoStep && iSysNow == 0 && nFSRhard <= nVetoStep)
358 // Update ISR dipoles.
359 if (doISR) spacePtr->update( iSysNow, event);
362 // Set maximal scales for next pT to pick.
363 pTmaxMI = min( pTtimes, pTmaxMI);
364 pTmaxISR = min( pTtimes, pTmaxISR);
369 // If no pT scales above zero then nothing to be done.
372 // Optionally check for a veto after the first few interactions,
373 // or after the first few emissions, ISR or FSR, in the hardest system.
374 if (typeVetoStep == 1) {
375 doVeto = userHooksPtr->doVetoMIStep( nMI, event);
376 } else if (typeVetoStep > 1) {
377 doVeto = userHooksPtr->doVetoStep( typeVetoStep, nISRhard,
381 // Abort event if vetoed.
383 if (isDiff) leaveResolvedDiff( iHardLoop, event);
387 // Keep on evolving until nothing is left to be done.
388 if (typeLatest > 0 && typeLatest < 4)
389 infoPtr->addCounter(25 + typeLatest);
390 infoPtr->setPartEvolved( nMI, nISR);
391 } while (pTmax > 0.);
393 // Do all final-state emissions if not already considered above.
394 if (doFSRafterProcess) {
396 // Find largest scale for final partons.
398 for (int i = 0; i < event.size(); ++i)
399 if (event[i].isFinal() && event[i].scale() > pTmax)
400 pTmax = event[i].scale();
403 // Prepare all subsystems for evolution.
404 for (int iSys = 0; iSys < partonSystemsPtr->sizeSys(); ++iSys)
405 timesPtr->prepare( iSys, event);
407 // Set up initial veto scale.
411 // Begin evolution down in pT from hard pT scale.
413 infoPtr->addCounter(29);
415 double pTtimes = timesPtr->pTnext( event, pTmax, 0.);
416 infoPtr->setPTnow( pTtimes);
418 // Allow a user veto. Only do it once, so remember to change pTveto.
419 if (pTveto > 0. && pTveto > pTtimes) {
421 doVeto = userHooksPtr->doVetoPT( 4, event);
422 // Abort event if vetoed.
424 if (isDiff) leaveResolvedDiff( iHardLoop, event);
429 // Do a final-state emission (if allowed).
431 infoPtr->addCounter(30);
432 if (timesPtr->branch( event, true)) {
433 iSysNow = timesPtr->system();
435 if (iSysNow == 0) ++nFSRhard;
436 if (canVetoStep && iSysNow == 0 && nFSRhard <= nVetoStep)
442 // If no pT scales above zero then nothing to be done.
445 // Optionally check for a veto after the first few emissions.
446 if (typeVetoStep > 0) {
447 doVeto = userHooksPtr->doVetoStep( typeVetoStep, nISRhard,
449 // Abort event if vetoed.
451 if (isDiff) leaveResolvedDiff( iHardLoop, event);
456 // Keep on evolving until nothing is left to be done.
457 infoPtr->addCounter(31);
458 } while (pTmax > 0.);
461 // Add beam remnants, including primordial kT kick and colour tracing.
462 if (physical && doRemnants && !remnants.add( event)) physical = false;
464 // If no problems then done.
467 // Else restore and loop, but do not throw existing diffractive system.
468 if (!isDiff) event.clear();
471 event.restoreJunctionSize();
475 partonSystemsPtr->clear();
477 // End loop over ten tries. Restore from diffraction. Hopefully it worked.
479 if (isDiff) leaveResolvedDiff( iHardLoop, event);
480 if (!physical) return false;
482 // End big outer loop to handle two systems in double diffraction.
485 // Perform showers in resonance decay chains.
486 doVeto = !resonanceShowers( process, event);
487 // Abort event if vetoed.
488 if (doVeto) return false;
490 // Store event properties.
491 infoPtr->setImpact( multiPtr->bMI(), multiPtr->enhanceMI());
492 infoPtr->setEvolution( pTsaveMI, pTsaveISR, pTsaveFSR,
493 nMI, nISR, nFSRinProc, nFSRinRes);
499 //--------------------------------------------------------------------------
501 // Decide which diffractive subsystems are resolved (= perturbative).
503 int PartonLevel::decideResolvedDiff( Event& process) {
505 // Loop over two systems.
507 for (int iDiffSys = 1; iDiffSys <= 2; ++iDiffSys) {
508 int iDiffMot = iDiffSys + 2;
510 // Only high-mass diffractive systems should be resolved.
511 double mDiff = process[iDiffMot].m();
512 bool isHighMass = ( mDiff > mMinDiff
513 && rndmPtr->flat() < 1. - exp( -(mDiff - mMinDiff) / mWidthDiff ) );
515 // Set outcome and done.
516 if (isHighMass) ++nHighMass;
517 if (iDiffSys == 1) isResolvedA = isHighMass;
518 if (iDiffSys == 2) isResolvedB = isHighMass;
524 //--------------------------------------------------------------------------
526 // Set up an unresolved process, i.e. elastic or diffractive.
528 bool PartonLevel::setupUnresolvedSys( Event& process, Event& event) {
530 // No hard scale in event.
533 // Copy particles from process to event.
534 for (int i = 0; i < process.size(); ++ i) event.append( process[i]);
536 // Loop to find diffractively excited beams.
537 for (int i = 0; i < 2; ++i)
538 if ( (i == 0 && isDiffA && !isResolvedA)
539 || (i == 1 && isDiffB && !isResolvedB) ) {
541 BeamParticle* beamPtr = (i == 0) ? beamAPtr : beamBPtr;
543 // Diffractive mass. Reconstruct boost and rotation to event cm frame.
544 double mDiff = process[iBeam].m();
545 double m2Diff = mDiff*mDiff;
546 double beta = process[iBeam].pAbs() / process[iBeam].e();
547 double theta = process[iBeam].theta();
548 double phi = process[iBeam].phi();
550 // Pick quark or gluon kicked out and flavour subdivision.
551 bool gluonIsKicked = beamPtr->pickGluon(mDiff);
552 int id1 = beamPtr->pickValence();
553 int id2 = beamPtr->pickRemnant();
555 // Find flavour masses. Scale them down if too big.
556 double m1 = particleDataPtr->constituentMass(id1);
557 double m2 = particleDataPtr->constituentMass(id2);
558 if (m1 + m2 > 0.5 * mDiff) {
559 double reduce = 0.5 * mDiff / (m1 + m2);
564 // If quark is kicked out, then trivial kinematics in rest frame.
565 if (!gluonIsKicked) {
566 double pAbs = sqrt( pow2(m2Diff - m1*m1 - m2*m2)
567 - pow2(2. * m1 * m2) ) / (2. * mDiff);
568 double e1 = (m2Diff + m1*m1 - m2*m2) / (2. * mDiff);
569 double e2 = (m2Diff + m2*m2 - m1*m1) / (2. * mDiff);
570 Vec4 p1(0.,0., -pAbs, e1);
571 Vec4 p2(0.,0., pAbs, e2);
573 // Boost and rotate to event cm frame.
574 p1.bst(0., 0., beta); p1.rot(theta, phi);
575 p2.bst(0., 0., beta); p2.rot(theta, phi);
578 int col1, acol1, col2, acol2;
579 if (particleDataPtr->colType(id1) == 1) {
580 col1 = event.nextColTag(); acol1 = 0;
581 col2 = 0; acol2 = col1;
583 col1 = 0; acol1 = event.nextColTag();
584 col2 = acol1; acol2 = 0;
586 // Update process colours to stay in step.
587 process.nextColTag();
589 // Store partons of diffractive system and mark system decayed.
590 int iDauBeg = event.append( id1, 23, iBeam, 0, 0, 0, col1, acol1,
592 int iDauEnd = event.append( id2, 63, iBeam, 0, 0, 0, col2, acol2,
594 event[iBeam].statusNeg();
595 event[iBeam].daughters(iDauBeg, iDauEnd);
598 // If gluon is kicked out: share momentum between two remnants.
600 double m2Sys, zSys, pxSys, pySys, mTS1, mTS2;
601 zSys = beamPtr->zShare(mDiff, m1, m2);
603 // Provide relative pT kick in remnant. Construct (transverse) masses.
604 pxSys = beamPtr->pxShare();
605 pySys = beamPtr->pyShare();
606 mTS1 = m1*m1 + pxSys*pxSys + pySys*pySys;
607 mTS2 = m2*m2 + pxSys*pxSys + pySys*pySys;
608 m2Sys = mTS1 / zSys + mTS2 / (1. - zSys);
610 // Momentum of kicked-out massless gluon in diffractive rest frame.
611 double pAbs = (m2Diff - m2Sys) / (2. * mDiff);
612 Vec4 pG(0., 0., -pAbs, pAbs);
613 Vec4 pRem(0., 0., pAbs, mDiff - pAbs);
615 // Momenta of the two beam remnant flavours. (Lightcone p+ = m_diff!)
616 double e1 = 0.5 * (zSys * mDiff + mTS1 / (zSys * mDiff));
617 double pL1 = 0.5 * (zSys * mDiff - mTS1 / (zSys * mDiff));
618 Vec4 p1(pxSys, pySys, pL1, e1);
621 // Boost and rotate to event cm frame.
622 pG.bst(0., 0., beta); pG.rot(theta, phi);
623 p1.bst(0., 0., beta); p1.rot(theta, phi);
624 p2.bst(0., 0., beta); p2.rot(theta, phi);
627 int colG, acolG, col1, acol1, col2, acol2;
628 if (particleDataPtr->colType(id1) == 1) {
629 col1 = event.nextColTag(); acol1 = 0;
630 colG = event.nextColTag(); acolG = col1;
631 col2 = 0; acol2 = colG;
633 col1 = 0; acol1 = event.nextColTag();
634 colG = acol1; acolG = event.nextColTag();
635 col2 = acolG; acol2 = 0;
637 // Update process colours to stay in step.
638 process.nextColTag();
639 process.nextColTag();
641 // Store partons of diffractive system and mark system decayed.
642 int iDauBeg = event.append( 21, 23, iBeam, 0, 0, 0, colG, acolG,
644 event.append( id1, 63, iBeam, 0, 0, 0, col1, acol1, p1, m1);
645 int iDauEnd = event.append( id2, 63, iBeam, 0, 0, 0, col2, acol2,
647 event[iBeam].statusNeg();
648 event[iBeam].daughters(iDauBeg, iDauEnd);
651 // End loop over beams. Done.
657 //--------------------------------------------------------------------------
659 // Set up the hard process(es), excluding subsequent resonance decays.
661 void PartonLevel::setupHardSys( int iHardLoop, Event& process,
664 // Incoming partons to hard process are stored in slots 3 and 4.
669 // Identify any diffractive system, mother, last entry. Offset.
670 int iDiffSys = (iHardLoop == 2 || !isResolvedA) ? 2 : 1;
671 int iDiffMot = iDiffSys + 2;
672 int iDiffDau = process.size() - 1;
673 int nOffset = sizeEvent - sizeProcess;
675 // Resolved diffraction means more entries.
681 // Diffractively excited particle described as Pomeron-hadron beams.
682 event[inS].statusNeg();
683 event[inS].daughters( inP - 2 + nOffset, inM - 2 + nOffset);
686 // If two hard interactions then find where second begins.
687 int iBeginSecond = process.size();
690 while (process[iBeginSecond].status() != -21) ++iBeginSecond;
693 // If incoming partons are massive then recalculate to put them massless.
694 if (process[inP].m() != 0. || process[inM].m() != 0.) {
695 double pPos = process[inP].pPos() + process[inM].pPos();
696 double pNeg = process[inP].pNeg() + process[inM].pNeg();
697 process[inP].pz( 0.5 * pPos);
698 process[inP].e( 0.5 * pPos);
700 process[inM].pz(-0.5 * pNeg);
701 process[inM].e( 0.5 * pNeg);
705 // Add incoming hard-scattering partons to list in beam remnants.
706 double x1 = process[inP].pPos() / process[inS].m();
707 beamAPtr->append( inP + nOffset, process[inP].id(), x1);
708 double x2 = process[inM].pNeg() / process[inS].m();
709 beamBPtr->append( inM + nOffset, process[inM].id(), x2);
711 // Scale. Find whether incoming partons are valence or sea. Store.
712 double scale = process.scale();
713 beamAPtr->xfISR( 0, process[inP].id(), x1, scale*scale);
714 int vsc1 = beamAPtr->pickValSeaComp();
715 beamBPtr->xfISR( 0, process[inM].id(), x2, scale*scale);
716 int vsc2 = beamBPtr->pickValSeaComp();
717 bool isVal1 = (vsc1 == -3);
718 bool isVal2 = (vsc2 == -3);
719 infoPtr->setValence( isVal1, isVal2);
721 // Initialize info needed for subsequent sequential decays + showers.
722 nHardDone = sizeProcess;
723 iPosBefShow.resize( process.size() );
725 // Add the beam and hard subprocess partons to the event record.
726 for (int i = sizeProcess; i < iBeginSecond; ++ i) {
727 if (process[i].mother1() > inM) break;
728 int j = event.append(process[i]);
731 // Offset history if process and event not in step.
733 int iOrd = i - iBeginSecond + 7;
734 if (iOrd == 1 || iOrd == 2)
735 event[j].offsetHistory( 0, 0, 0, nOffset);
736 else if (iOrd == 3 || iOrd == 4)
737 event[j].offsetHistory( 0, nOffset, 0, nOffset);
738 else if (iOrd == 5 || iOrd == 6)
739 event[j].offsetHistory( 0, nOffset, 0, 0);
742 // Currently outgoing ones should not count as decayed.
743 if (event[j].status() == -22) {
744 event[j].statusPos();
745 event[j].daughters(0, 0);
748 // Complete task of copying hard subsystem into event record.
752 // Store participating partons as first set in list of all systems.
753 partonSystemsPtr->addSys();
754 partonSystemsPtr->setInA(0, inP + nOffset);
755 partonSystemsPtr->setInB(0, inM + nOffset);
756 for (int i = inM + 1; i < nHardDone; ++i)
757 partonSystemsPtr->addOut(0, i + nOffset);
758 partonSystemsPtr->setSHat( 0,
759 (event[inP + nOffset].p() + event[inM + nOffset].p()).m2Calc() );
761 // Identify second hard process where applicable.
762 // Since internally generated incoming partons are guaranteed massless.
764 int inP2 = iBeginSecond;
765 int inM2 = iBeginSecond + 1;
767 // Add incoming hard-scattering partons to list in beam remnants.
768 // Not valid if not in rest frame??
769 x1 = process[inP2].pPos() / process[0].e();
770 beamAPtr->append( inP2, process[inP2].id(), x1);
771 x2 = process[inM2].pNeg() / process[0].e();
772 beamBPtr->append( inM2, process[inM2].id(), x2);
774 // Find whether incoming partons are valence or sea.
775 scale = process.scaleSecond();
776 beamAPtr->xfISR( 1, process[inP2].id(), x1, scale*scale);
777 beamAPtr->pickValSeaComp();
778 beamBPtr->xfISR( 1, process[inM2].id(), x2, scale*scale);
779 beamBPtr->pickValSeaComp();
781 // Add the beam and hard subprocess partons to the event record.
782 for (int i = inP2; i < process.size(); ++ i) {
783 int mother = process[i].mother1();
784 if ( (mother > 2 && mother < inP2) || mother > inM2 ) break;
785 event.append(process[i]);
788 // Currently outgoing ones should not count as decayed.
789 if (event[i].status() == -22) {
790 event[i].statusPos();
791 event[i].daughters(0, 0);
794 // Complete task of copying hard subsystem into event record.
798 // Store participating partons as second set in list of all systems.
799 partonSystemsPtr->addSys();
800 partonSystemsPtr->setInA(1, inP2);
801 partonSystemsPtr->setInB(1, inM2);
802 for (int i = inM2 + 1; i < nHardDone; ++i)
803 partonSystemsPtr->addOut(1, i);
804 partonSystemsPtr->setSHat( 1,
805 (event[inP2].p() + event[inM2].p()).m2Calc() );
807 // End code for second hard process.
810 // Update event colour tag to maximum in whole process.
812 for (int i = 0; i < process.size(); ++ i) {
813 if (process[i].col() > maxColTag) maxColTag = process[i].col();
814 if (process[i].acol() > maxColTag) maxColTag = process[i].acol();
816 event.initColTag(maxColTag);
818 // Copy junctions from process to event.
819 for (int i = 0; i < process.sizeJunction(); ++i)
820 event.appendJunction( process.getJunction(i));
825 //--------------------------------------------------------------------------
827 // Resolved diffraction: replace full event with diffractive subsystem.
829 void PartonLevel::setupResolvedDiff(int iHardLoop, Event& process) {
831 // Identify diffractive system, mother, last entry.
832 int iDiffSys = (iHardLoop == 2 || !isResolvedA) ? 2 : 1;
833 int iDiffMot = iDiffSys + 2;
834 int iDiffDau = process.size() - 1;
836 // Diffractive system mass.
837 double mDiff = process[iDiffMot].m();
838 double m2Diff = mDiff * mDiff;
840 // Diffractively excited particle described as Pomeron-hadron beams.
841 process[iDiffMot].statusNeg();
842 process[iDiffMot].daughters( iDiffDau + 1, iDiffDau + 2);
844 // Set up Pomeron-proton system as if it were the complete collision.
845 int idHad = process[iDiffSys].id();
846 double mHad = process[iDiffSys].m();
847 double m2Had = mHad * mHad;
848 double m2Pom = (process[2].p() - process[4].p()).m2Calc();
849 double mPom = (m2Pom >= 0.) ? sqrt(m2Pom) : -sqrt(-m2Pom);
850 double eHad = 0.5 * (m2Diff + m2Had - m2Pom) / mDiff;
851 double ePom = 0.5 * (m2Diff + m2Pom - m2Had) / mDiff;
852 double pzHP = 0.5 * sqrtpos( pow2(m2Diff - m2Had - m2Pom)
853 - 4. * m2Had * m2Pom ) / mDiff;
854 process.append( 990, 13, iDiffMot, 0, 0, 0, 0, 0,
855 0., 0., pzHP, ePom, mPom);
856 process.append( idHad, 13, iDiffMot, 0, 0, 0, 0, 0,
857 0., 0., -pzHP, eHad, mHad);
859 // Reassign multiple interactions pointer to right object.
860 multiPtr = (iDiffSys == 1) ? &multiSDA : &multiSDB;
862 // Reassign one beam pointer to refer to incoming Pomeron.
864 beamAPtr = beamPomBPtr;
865 beamBPtr = beamHadAPtr;
867 beamAPtr = beamPomAPtr;
868 beamBPtr = beamHadBPtr;
871 // Beams not found in normal slots 1 and 2.
872 int beamOffset = (sizeEvent > 0) ? sizeEvent - 1 : 4;
874 // Reassign beam pointers in other classes.
875 timesPtr->reassignBeamPtrs( beamAPtr, beamBPtr, beamOffset);
876 spacePtr->reassignBeamPtrs( beamAPtr, beamBPtr);
877 remnants.reassignBeamPtrs( beamAPtr, beamBPtr);
879 // Pretend that the diffractive system is the whole collision.
880 eCMsave = infoPtr->eCM();
881 infoPtr->setECM( mDiff);
882 beamAPtr->newPzE( pzHP, ePom);
883 beamBPtr->newPzE( -pzHP, eHad);
887 //--------------------------------------------------------------------------
889 // Resolved diffraction: restore to original behaviour.
891 void PartonLevel::leaveResolvedDiff( int iHardLoop, Event& event) {
893 // Identify diffractive system.
894 int iDiffSys = (iHardLoop == 2 || !isResolvedA) ? 2 : 1;
896 // Reconstruct boost and rotation to event cm frame.
897 Vec4 pPom = event[3 - iDiffSys].p() - event[5 - iDiffSys].p();
898 Vec4 pHad = event[iDiffSys].p();
900 MtoCM.fromCMframe( pPom, pHad);
902 // Perform rotation and boost on diffractive system.
903 int iFirst = (iHardLoop == 1) ? 5 + sizeEvent - sizeProcess : sizeEvent;
904 for (int i = iFirst; i < event.size(); ++i)
905 event[i].rotbst( MtoCM);
907 // Restore multiple interactions pointer to default object.
910 // Restore beam pointers to incoming hadrons.
911 beamAPtr = beamHadAPtr;
912 beamBPtr = beamHadBPtr;
914 // Reassign beam pointers in other classes.
915 timesPtr->reassignBeamPtrs( beamAPtr, beamBPtr, 0);
916 spacePtr->reassignBeamPtrs( beamAPtr, beamBPtr);
917 remnants.reassignBeamPtrs( beamAPtr, beamBPtr);
919 // Restore cm energy.
920 infoPtr->setECM( eCMsave);
921 beamAPtr->newPzE( event[1].pz(), event[1].e());
922 beamBPtr->newPzE( event[2].pz(), event[2].e());
926 //--------------------------------------------------------------------------
928 // Handle showers in successive resonance decays.
930 bool PartonLevel::resonanceShowers( Event& process, Event& event) {
932 // Isolate next system to be processed, if anything remains.
935 while (nHardDone < process.size()) {
937 int iBegin = nHardDone;
939 // Mother in hard process and in complete event (after shower).
940 int iHardMother = process[iBegin].mother1();
941 Particle& hardMother = process[iHardMother];
942 int iBefMother = iPosBefShow[iHardMother];
943 int iAftMother = event.iBotCopyId(iBefMother);
944 Particle& aftMother = event[iAftMother];
946 // From now on mother counts as decayed.
947 aftMother.statusNeg();
949 // Mother can have been moved by showering (in any of previous steps),
950 // so prepare to update colour and momentum information for system.
951 int colBef = hardMother.col();
952 int acolBef = hardMother.acol();
953 int colAft = aftMother.col();
954 int acolAft = aftMother.acol();
956 M.bst( hardMother.p(), aftMother.p());
958 // Extract next partons from hard event into normal event record.
959 for (int i = iBegin; i < process.size(); ++ i) {
960 if (process[i].mother1() != iHardMother) break;
961 int iNow = event.append( process[i] );
962 iPosBefShow[i] = iNow;
963 Particle& now = event.back();
965 // Currently outgoing ones should not count as decayed.
966 if (now.status() == -22) {
971 // Update daughter and mother information.
972 if (i == iBegin) event[iAftMother].daughter1( iNow);
973 else event[iAftMother].daughter2( iNow);
974 now.mother1(iAftMother);
976 // Update colour and momentum information.
977 if (now.col() == colBef) now.col( colAft);
978 if (now.acol() == acolBef) now.acol( acolAft);
981 // Complete task of copying next subsystem into event record.
984 int iEnd = nHardDone - 1;
986 // Do parton showers inside subsystem: maximum scale by mother mass.
987 if (doFSRinResonances) {
988 double pTmax = 0.5 * hardMother.m();
989 if (canSetScale) pTmax = userHooksPtr->scaleResonance( iAftMother, event);
992 // Add new system, automatically with two empty beam slots.
993 int iSys = partonSystemsPtr->addSys();
994 partonSystemsPtr->setSHat(iSys, pow2(hardMother.m()) );
996 // Loop over allowed range to find all final-state particles.
997 for (int i = iPosBefShow[iBegin]; i <= iPosBefShow[iEnd]; ++i)
998 if (event[i].isFinal()) partonSystemsPtr->addOut( iSys, i);
1000 // Let prepare routine do the setup.
1001 timesDecPtr->prepare( iSys, event);
1003 // Set up initial veto scale.
1005 double pTveto = pTvetoPT;
1007 // Begin evolution down in pT from hard pT scale.
1010 double pTtimes = timesDecPtr->pTnext( event, pTmax, 0.);
1012 // Allow a user veto. Only do it once, so remember to change pTveto.
1013 if (pTveto > 0. && pTveto > pTtimes) {
1015 doVeto = userHooksPtr->doVetoPT( 5, event);
1016 // Abort event if vetoed.
1017 if (doVeto) return false;
1020 // Do a final-state emission (if allowed).
1022 if (timesDecPtr->branch( event)) {
1025 if (canVetoStep && nFSRhard <= nVetoStep) typeVetoStep = 5;
1030 // If no pT scales above zero then nothing to be done.
1033 // Optionally check for a veto after the first few emissions.
1034 if (typeVetoStep > 0) {
1035 doVeto = userHooksPtr->doVetoStep( typeVetoStep, 0, nFSRhard,
1037 // Abort event if vetoed.
1038 if (doVeto) return false;
1041 // Keep on evolving until nothing is left to be done.
1042 } while (pTmax > 0.);
1046 // No more systems to be processed. Set total number of emissions.
1048 nFSRinRes = nFSRres;
1053 //==========================================================================
1055 } // end namespace Pythia8