1 // TimeShower.cc is a part of the PYTHIA event generator.
2 // Copyright (C) 2012 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 TimeShower class.
8 #include "TimeShower.h"
12 //==========================================================================
14 // The TimeShower 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 // For small x approximate 1 - sqrt(1 - x) by x/2.
22 const double TimeShower::SIMPLIFYROOT = 1e-8;
24 // Do not allow x too close to 0 or 1 in matrix element expressions.
25 // Warning: cuts into phase space for E_CM > 2 * pTmin * sqrt(1/XMARGIN),
26 // i.e. will become problem roughly for E_CM > 10^6 GeV.
27 const double TimeShower::XMARGIN = 1e-12;
28 const double TimeShower::XMARGINCOMB = 1e-4;
30 // Lower limit on PDF value in order to avoid division by zero.
31 const double TimeShower::TINYPDF = 1e-10;
33 // Big starting value in search for smallest invariant-mass pair.
34 const double TimeShower::LARGEM2 = 1e20;
36 // In g -> q qbar or gamma -> f fbar require m2_pair > this * m2_q/f.
37 const double TimeShower::THRESHM2 = 4.004;
39 // Never pick pT so low that alphaS is evaluated too close to Lambda_3.
40 const double TimeShower::LAMBDA3MARGIN = 1.1;
42 // Rescatter: rescattering + ISR + FSR + primordial kT can lead to
43 // systems not locally conserving momentum.
44 // Fix up momentum in intermediate systems with rescattering
45 const bool TimeShower::FIXRESCATTER = true;
46 // Veto negative energies when using FIXRESCATTER option.
47 const bool TimeShower::VETONEGENERGY = false;
48 // Do not allow too large time- or spacelike virtualities in fixing-up.
49 const double TimeShower::MAXVIRTUALITYFRACTION = 0.5;
50 // Do not allow too large negative spacelike energy in system rest frame.
51 const double TimeShower::MAXNEGENERGYFRACTION = 0.7;
53 //--------------------------------------------------------------------------
55 // Initialize alphaStrong, alphaEM and related pTmin parameters.
57 void TimeShower::init( BeamParticle* beamAPtrIn,
58 BeamParticle* beamBPtrIn) {
60 // Store input pointers for future use.
61 beamAPtr = beamAPtrIn;
62 beamBPtr = beamBPtrIn;
65 doQCDshower = settingsPtr->flag("TimeShower:QCDshower");
66 doQEDshowerByQ = settingsPtr->flag("TimeShower:QEDshowerByQ");
67 doQEDshowerByL = settingsPtr->flag("TimeShower:QEDshowerByL");
68 doQEDshowerByGamma = settingsPtr->flag("TimeShower:QEDshowerByGamma");
69 doMEcorrections = settingsPtr->flag("TimeShower:MEcorrections");
70 doMEafterFirst = settingsPtr->flag("TimeShower:MEafterFirst");
71 doPhiPolAsym = settingsPtr->flag("TimeShower:phiPolAsym");
72 doInterleave = settingsPtr->flag("TimeShower:interleave");
73 allowBeamRecoil = settingsPtr->flag("TimeShower:allowBeamRecoil");
74 dampenBeamRecoil = settingsPtr->flag("TimeShower:dampenBeamRecoil");
75 recoilToColoured = settingsPtr->flag("TimeShower:recoilToColoured");
77 // Matching in pT of hard interaction or MPI to shower evolution.
78 pTmaxMatch = settingsPtr->mode("TimeShower:pTmaxMatch");
79 pTdampMatch = settingsPtr->mode("TimeShower:pTdampMatch");
80 pTmaxFudge = settingsPtr->parm("TimeShower:pTmaxFudge");
81 pTmaxFudgeMPI = settingsPtr->parm("TimeShower:pTmaxFudgeMPI");
82 pTdampFudge = settingsPtr->parm("TimeShower:pTdampFudge");
84 // Charm and bottom mass thresholds.
85 mc = particleDataPtr->m0(4);
86 mb = particleDataPtr->m0(5);
90 // Parameters of scale choices.
91 renormMultFac = settingsPtr->parm("TimeShower:renormMultFac");
92 factorMultFac = settingsPtr->parm("TimeShower:factorMultFac");
94 // Parameters of alphaStrong generation.
95 alphaSvalue = settingsPtr->parm("TimeShower:alphaSvalue");
96 alphaSorder = settingsPtr->mode("TimeShower:alphaSorder");
97 alphaS2pi = 0.5 * alphaSvalue / M_PI;
99 // Initialize alphaStrong generation.
100 alphaS.init( alphaSvalue, alphaSorder);
102 // Lambda for 5, 4 and 3 flavours.
103 Lambda3flav = alphaS.Lambda3();
104 Lambda4flav = alphaS.Lambda4();
105 Lambda5flav = alphaS.Lambda5();
106 Lambda5flav2 = pow2(Lambda5flav);
107 Lambda4flav2 = pow2(Lambda4flav);
108 Lambda3flav2 = pow2(Lambda3flav);
110 // Parameters of QCD evolution. Warn if pTmin must be raised.
111 nGluonToQuark = settingsPtr->mode("TimeShower:nGluonToQuark");
112 pTcolCutMin = settingsPtr->parm("TimeShower:pTmin");
113 if (pTcolCutMin > LAMBDA3MARGIN * Lambda3flav / sqrt(renormMultFac))
114 pTcolCut = pTcolCutMin;
116 pTcolCut = LAMBDA3MARGIN * Lambda3flav / sqrt(renormMultFac);
117 ostringstream newPTcolCut;
118 newPTcolCut << fixed << setprecision(3) << pTcolCut;
119 infoPtr->errorMsg("Warning in TimeShower::init: pTmin too low",
120 ", raised to " + newPTcolCut.str() );
121 infoPtr->setTooLowPTmin(true);
123 pT2colCut = pow2(pTcolCut);
125 // Parameters of alphaEM generation .
126 alphaEMorder = settingsPtr->mode("TimeShower:alphaEMorder");
128 // Initialize alphaEM generation.
129 alphaEM.init( alphaEMorder, settingsPtr);
131 // Parameters of QED evolution.
132 nGammaToQuark = settingsPtr->mode("TimeShower:nGammaToQuark");
133 nGammaToLepton = settingsPtr->mode("TimeShower:nGammaToLepton");
134 pTchgQCut = settingsPtr->parm("TimeShower:pTminChgQ");
135 pT2chgQCut = pow2(pTchgQCut);
136 pTchgLCut = settingsPtr->parm("TimeShower:pTminChgL");
137 pT2chgLCut = pow2(pTchgLCut);
138 mMaxGamma = settingsPtr->parm("TimeShower:mMaxGamma");
139 m2MaxGamma = pow2(mMaxGamma);
141 // Consisteny check for gamma -> f fbar variables.
142 if (nGammaToQuark <= 0 && nGammaToLepton <= 0) doQEDshowerByGamma = false;
144 // Possibility of a global recoil stategy, e.g. for MC@NLO.
145 globalRecoil = settingsPtr->flag("TimeShower:globalRecoil");
146 nMaxGlobalRecoil = settingsPtr->mode("TimeShower:nMaxGlobalRecoil");
148 // Fraction and colour factor of gluon emission off onium octat state.
149 octetOniumFraction = settingsPtr->parm("TimeShower:octetOniumFraction");
150 octetOniumColFac = settingsPtr->parm("TimeShower:octetOniumColFac");
152 // Z0 properties needed for gamma/Z0 mixing.
153 mZ = particleDataPtr->m0(23);
154 gammaZ = particleDataPtr->mWidth(23);
155 thetaWRat = 1. / (16. * coupSMPtr->sin2thetaW()
156 * coupSMPtr->cos2thetaW());
158 // May have to fix up recoils related to rescattering.
159 allowRescatter = settingsPtr->flag("PartonLevel:MPI")
160 && settingsPtr->flag("MultipartonInteractions:allowRescatter");
162 // Hidden Valley scenario with further shower activity.
163 doHVshower = settingsPtr->flag("HiddenValley:FSR");
164 nCHV = settingsPtr->mode("HiddenValley:Ngauge");
165 alphaHVfix = settingsPtr->parm("HiddenValley:alphaFSR");
166 pThvCut = settingsPtr->parm("HiddenValley:pTminFSR");
167 pT2hvCut = pThvCut * pThvCut;
168 CFHV = (nCHV == 1) ? 1. : (nCHV * nCHV - 1.)/(2. * nCHV);
169 idHV = (nCHV == 1) ? 4900022 : 4900021;
170 mHV = particleDataPtr->m0(idHV);
171 brokenHVsym = (nCHV == 1 && mHV > 0.);
173 // Possibility to allow user veto of emission step.
174 canVetoEmission = (userHooksPtr != 0)
175 ? userHooksPtr->canVetoFSREmission() : false;
179 //--------------------------------------------------------------------------
181 // Find whether to limit maximum scale of emissions.
182 // Also allow for dampening at factorization or renormalization scale.
184 bool TimeShower::limitPTmax( Event& event, double Q2Fac, double Q2Ren) {
186 // Find whether to limit pT. Begin by user-set cases.
187 bool dopTlimit = false;
188 if (pTmaxMatch == 1) dopTlimit = true;
189 else if (pTmaxMatch == 2) dopTlimit = false;
191 // Look if any quark (u, d, s, c, b), gluon or photon in final state.
193 for (int i = 5; i < event.size(); ++i)
194 if (event[i].status() != -21) {
195 int idAbs = event[i].idAbs();
196 if (idAbs <= 5 || idAbs == 21 || idAbs == 22) dopTlimit = true;
200 // Dampening at factorization or renormalization scale.
203 if ( !dopTlimit && (pTdampMatch == 1 || pTdampMatch == 2) ) {
205 pT2damp = pow2(pTdampFudge) * ((pTdampMatch == 1) ? Q2Fac : Q2Ren);
213 //--------------------------------------------------------------------------
215 // Top-level routine to do a full time-like shower in resonance decay.
217 int TimeShower::shower( int iBeg, int iEnd, Event& event, double pTmax,
220 // Add new system, automatically with two empty beam slots.
221 int iSys = partonSystemsPtr->addSys();
223 // Loop over allowed range to find all final-state particles.
225 for (int i = iBeg; i <= iEnd; ++i) if (event[i].isFinal()) {
226 partonSystemsPtr->addOut( iSys, i);
227 pSum += event[i].p();
229 partonSystemsPtr->setSHat( iSys, pSum.m2Calc() );
231 // Let prepare routine do the setup.
232 prepare( iSys, event, true);
234 // Begin evolution down in pT from hard pT scale.
238 double pTtimes = pTnext( event, pTmax, 0.);
240 // Do a final-state emission (if allowed).
242 if (branch( event)) {
244 pTLastBranch = pTtimes;
249 // Keep on evolving until nothing is left to be done.
251 } while (pTmax > 0. && (nBranchMax <= 0 || nBranch < nBranchMax));
253 // Return number of emissions that were performed.
258 //--------------------------------------------------------------------------
260 // Prepare system for evolution; identify ME.
262 void TimeShower::prepare( int iSys, Event& event, bool limitPTmaxIn) {
264 // Reset dipole-ends list for first interaction and for resonance decays.
265 int iInA = partonSystemsPtr->getInA(iSys);
266 int iInB = partonSystemsPtr->getInB(iSys);
267 if (iSys == 0 || iInA == 0) dipEnd.resize(0);
268 int dipEndSizeBeg = dipEnd.size();
270 // No dipoles for 2 -> 1 processes.
271 if (partonSystemsPtr->sizeOut(iSys) < 2) return;
273 // Loop through final state of system to find possible dipole ends.
274 for (int i = 0; i < partonSystemsPtr->sizeOut(iSys); ++i) {
275 int iRad = partonSystemsPtr->getOut( iSys, i);
276 if (event[iRad].isFinal() && event[iRad].scale() > 0.) {
278 // Identify colour octet onium state. Check whether QCD shower allowed.
279 int idRad = event[iRad].id();
280 int idRadAbs = abs(idRad);
282 = ( idRad == 9900441 || idRad == 9900443 || idRad == 9910441
283 || idRad == 9900551 || idRad == 9900553 || idRad == 9910551 );
284 bool doQCD = doQCDshower;
285 if (doQCD && isOctetOnium)
286 doQCD = (rndmPtr->flat() < octetOniumFraction);
288 // Find dipole end formed by colour index.
289 int colTag = event[iRad].col();
290 if (doQCD && colTag > 0) setupQCDdip( iSys, i, colTag, 1, event,
291 isOctetOnium, limitPTmaxIn);
293 // Find dipole end formed by anticolour index.
294 int acolTag = event[iRad].acol();
295 if (doQCD && acolTag > 0) setupQCDdip( iSys, i, acolTag, -1, event,
296 isOctetOnium, limitPTmaxIn);
298 // Find "charge-dipole" and "photon-dipole" ends.
299 int chgType = event[iRad].chargeType();
300 bool doChgDip = (chgType != 0)
301 && ( ( doQEDshowerByQ && event[iRad].isQuark() )
302 || ( doQEDshowerByL && event[iRad].isLepton() ) );
303 int gamType = (idRad == 22) ? 1 : 0;
304 bool doGamDip = (gamType == 1) && doQEDshowerByGamma;
305 if (doChgDip || doGamDip) setupQEDdip( iSys, i, chgType, gamType,
306 event, limitPTmaxIn);
308 // Find Hidden Valley dipole ends.
309 bool isHVrad = (idRadAbs > 4900000 && idRadAbs < 4900007)
310 || (idRadAbs > 4900010 && idRadAbs < 4900017)
311 || idRadAbs == 4900101;
312 if (doHVshower && isHVrad) setupHVdip( iSys, i, event, limitPTmaxIn);
314 // End loop over system final state. Have now found the dipole ends.
318 // Loop through dipole ends to find matrix element corrections.
319 for (int iDip = dipEndSizeBeg; iDip < int(dipEnd.size()); ++iDip)
320 findMEtype( event, dipEnd[iDip]);
322 // Update dipole list after a multiparton interactions rescattering.
323 if (iSys > 0 && ( (iInA > 0 && event[iInA].status() == -34)
324 || (iInB > 0 && event[iInB].status() == -34) ) )
325 rescatterUpdate( iSys, event);
329 //--------------------------------------------------------------------------
331 // Update dipole list after a multiparton interactions rescattering.
332 void TimeShower::rescatterUpdate( int iSys, Event& event) {
334 // Loop over two incoming partons in system; find their rescattering mother.
335 // (iOut is outgoing from old system = incoming iIn of rescattering system.)
336 for (int iResc = 0; iResc < 2; ++iResc) {
337 int iIn = (iResc == 0) ? partonSystemsPtr->getInA(iSys)
338 : partonSystemsPtr->getInB(iSys);
339 if (iIn == 0 || event[iIn].status() != -34) continue;
340 int iOut = event[iIn].mother1();
342 // Loop over all dipoles.
343 int dipEndSize = dipEnd.size();
344 for (int iDip = 0; iDip < dipEndSize; ++iDip) {
345 TimeDipoleEnd& dipNow = dipEnd[iDip];
347 // Kill dipoles where rescattered parton is radiator.
348 if (dipNow.iRadiator == iOut) {
354 // No matrix element for dipoles between scatterings.
355 if (dipNow.iMEpartner == iOut) {
357 dipNow.iMEpartner = -1;
360 // Update dipoles where outgoing rescattered parton is recoiler.
361 if (dipNow.iRecoiler == iOut) {
362 int iRad = dipNow.iRadiator;
364 // Colour dipole: recoil in final state, initial state or new.
365 if (dipNow.colType > 0) {
366 int colTag = event[iRad].col();
368 for (int i = 0; i < partonSystemsPtr->sizeOut(iSys); ++i) {
369 int iRecNow = partonSystemsPtr->getOut( iSys, i);
370 if (event[iRecNow].acol() == colTag) {
371 dipNow.iRecoiler = iRecNow;
372 dipNow.systemRec = iSys;
379 int iIn2 = (iResc == 0) ? partonSystemsPtr->getInB(iSys)
380 : partonSystemsPtr->getInA(iSys);
381 if (event[iIn2].col() == colTag) {
382 dipNow.iRecoiler = iIn2;
383 dipNow.systemRec = iSys;
385 int isrType = event[iIn2].mother1();
386 // This line in case mother is a rescattered parton.
387 while (isrType > 2 + beamOffset)
388 isrType = event[isrType].mother1();
389 if (isrType > 2) isrType -= beamOffset;
390 dipNow.isrType = isrType;
394 // If above options failed, then create new dipole.
396 int iRadNow = partonSystemsPtr->getIndexOfOut(dipNow.system, iRad);
398 setupQCDdip(dipNow.system, iRadNow, event[iRad].col(), 1,
399 event, dipNow.isOctetOnium, true);
401 infoPtr->errorMsg("Warning in TimeShower::rescatterUpdate: "
402 "failed to locate radiator in system");
408 infoPtr->errorMsg("Warning in TimeShower::rescatterUpdate: "
409 "failed to locate new recoiling colour partner");
412 // Anticolour dipole: recoil in final state, initial state or new.
413 } else if (dipNow.colType < 0) {
414 int acolTag = event[iRad].acol();
416 for (int i = 0; i < partonSystemsPtr->sizeOut(iSys); ++i) {
417 int iRecNow = partonSystemsPtr->getOut( iSys, i);
418 if (event[iRecNow].col() == acolTag) {
419 dipNow.iRecoiler = iRecNow;
420 dipNow.systemRec = iSys;
427 int iIn2 = (iResc == 0) ? partonSystemsPtr->getInB(iSys)
428 : partonSystemsPtr->getInA(iSys);
429 if (event[iIn2].acol() == acolTag) {
430 dipNow.iRecoiler = iIn2;
431 dipNow.systemRec = iSys;
433 int isrType = event[iIn2].mother1();
434 // This line in case mother is a rescattered parton.
435 while (isrType > 2 + beamOffset)
436 isrType = event[isrType].mother1();
437 if (isrType > 2) isrType -= beamOffset;
438 dipNow.isrType = isrType;
442 // If above options failed, then create new dipole.
444 int iRadNow = partonSystemsPtr->getIndexOfOut(dipNow.system, iRad);
446 setupQCDdip(dipNow.system, iRadNow, event[iRad].acol(), -1,
447 event, dipNow.isOctetOnium, true);
449 infoPtr->errorMsg("Warning in TimeShower::rescatterUpdate: "
450 "failed to locate radiator in system");
456 infoPtr->errorMsg("Warning in TimeShower::rescatterUpdate: "
457 "failed to locate new recoiling colour partner");
460 // Charge or photon dipoles: same flavour in final or initial state.
461 } else if (dipNow.chgType != 0 || dipNow.gamType != 0) {
462 int idTag = event[dipNow.iRecoiler].id();
464 for (int i = 0; i < partonSystemsPtr->sizeOut(iSys); ++i) {
465 int iRecNow = partonSystemsPtr->getOut( iSys, i);
466 if (event[iRecNow].id() == idTag) {
467 dipNow.iRecoiler = iRecNow;
468 dipNow.systemRec = iSys;
475 int iIn2 = (iResc == 0) ? partonSystemsPtr->getInB(iSys)
476 : partonSystemsPtr->getInA(iSys);
477 if (event[iIn2].id() == -idTag) {
478 dipNow.iRecoiler = iIn2;
479 dipNow.systemRec = iSys;
481 int isrType = event[iIn2].mother1();
482 // This line in case mother is a rescattered parton.
483 while (isrType > 2 + beamOffset)
484 isrType = event[isrType].mother1();
485 if (isrType > 2) isrType -= beamOffset;
486 dipNow.isrType = isrType;
490 // If above options failed, then create new dipole
492 int iRadNow = partonSystemsPtr->getIndexOfOut(dipNow.system, iRad);
494 setupQEDdip(dipNow.system, iRadNow, dipNow.chgType,
495 dipNow.gamType, event, true);
497 infoPtr->errorMsg("Warning in TimeShower::rescatterUpdate: "
498 "failed to locate radiator in system");
504 infoPtr->errorMsg("Warning in TimeShower::rescatterUpdate: "
505 "failed to locate new recoiling charge partner");
510 // End of loop over dipoles and two incoming sides.
516 //--------------------------------------------------------------------------
518 // Update dipole list after each ISR emission (so not used for resonances).
520 void TimeShower::update( int iSys, Event& event) {
522 // Start list of rescatterers that gave further changed systems in ISR.
523 vector<int> iRescatterer;
525 // Find new and old positions of incoming partons in the system.
526 vector<int> iNew, iOld;
527 iNew.push_back( partonSystemsPtr->getInA(iSys) );
528 iOld.push_back( event[iNew[0]].daughter2() );
529 iNew.push_back( partonSystemsPtr->getInB(iSys) );
530 iOld.push_back( event[iNew[1]].daughter2() );
532 // Ditto for outgoing partons, except the newly created one.
533 int sizeOut = partonSystemsPtr->sizeOut(iSys) - 1;
534 for (int i = 0; i < sizeOut; ++i) {
535 int iNow = partonSystemsPtr->getOut(iSys, i);
536 iNew.push_back( iNow );
537 iOld.push_back( event[iNow].mother1() );
538 // Add non-final to list of rescatterers.
539 if (!event[iNow].isFinal()) iRescatterer.push_back( iNow );
541 int iNewNew = partonSystemsPtr->getOut(iSys, sizeOut);
543 // Swap beams to let 0 be side on which branching occured.
544 if (event[iNew[0]].status() != -41) {
545 swap( iNew[0], iNew[1]);
546 swap( iOld[0], iOld[1]);
549 // Loop over all dipole ends belonging to the system
550 // or to the recoil system, if different.
551 for (int iDip = 0; iDip < int(dipEnd.size()); ++iDip)
552 if (dipEnd[iDip].system == iSys || dipEnd[iDip].systemRec == iSys) {
553 TimeDipoleEnd& dipNow = dipEnd[iDip];
555 // Replace radiator (always in final state so simple).
556 for (int i = 2; i < 2 + sizeOut; ++i)
557 if (dipNow.iRadiator == iOld[i]) {
558 dipNow.iRadiator = iNew[i];
562 // Replace ME partner (always in final state, if exists, so simple).
563 for (int i = 2; i < 2 + sizeOut; ++i)
564 if (dipNow.iMEpartner == iOld[i]) {
565 dipNow.iMEpartner = iNew[i];
569 // Recoiler: by default pick old one, only moved. Note excluded beam.
571 if (dipNow.systemRec == iSys) {
572 for (int i = 1; i < 2 + sizeOut; ++i)
573 if (dipNow.iRecoiler == iOld[i]) {
578 // QCD recoiler: check if colour hooks up with new final parton.
579 if ( dipNow.colType > 0
580 && event[dipNow.iRadiator].col() == event[iNewNew].acol() ) {
584 if ( dipNow.colType < 0
585 && event[dipNow.iRadiator].acol() == event[iNewNew].col() ) {
590 // QCD recoiler: check if colour hooks up with new beam parton.
591 if ( iRec == 0 && dipNow.colType > 0
592 && event[dipNow.iRadiator].col() == event[iNew[0]].col() )
594 if ( iRec == 0 && dipNow.colType < 0
595 && event[dipNow.iRadiator].acol() == event[iNew[0]].acol() )
598 // QED/photon recoiler: either to new particle or remains to beam.
599 if ( iRec == 0 && (dipNow.chgType != 0 || dipNow.gamType != 0) ) {
600 if ( event[iNew[0]].chargeType() == 0 ) {
608 // Recoiler in another system: keep it as is.
609 } else iRec = dipNow.iRecoiler;
611 // Done. Kill dipole if failed to find new recoiler.
612 dipNow.iRecoiler = iRec;
613 if ( iRec == 0 && (dipNow.colType != 0 || dipNow.chgType != 0
614 || dipNow.gamType != 0) ) {
618 infoPtr->errorMsg("Error in TimeShower::update: "
619 "failed to locate new recoiling partner");
623 // Find new dipole end formed by colour index.
624 int colTag = event[iNewNew].col();
625 if (doQCDshower && colTag > 0)
626 setupQCDdip( iSys, sizeOut, colTag, 1, event, false, true);
628 // Find new dipole end formed by anticolour index.
629 int acolTag = event[iNewNew].acol();
630 if (doQCDshower && acolTag > 0)
631 setupQCDdip( iSys, sizeOut, acolTag, -1, event, false, true);
633 // Find new "charge-dipole" and "photon-dipole" ends.
634 int chgType = event[iNewNew].chargeType();
635 bool doChgDip = (chgType != 0)
636 && ( ( doQEDshowerByQ && event[iNewNew].isQuark() )
637 || ( doQEDshowerByL && event[iNewNew].isLepton() ) );
638 int gamType = (event[iNewNew].id() == 22) ? 1 : 0;
639 bool doGamDip = (gamType == 1) && doQEDshowerByGamma;
640 if (doChgDip || doGamDip)
641 setupQEDdip( iSys, sizeOut, chgType, gamType, event, true);
643 // Start iterate over list of rescatterers - may be empty.
645 while (++iRescNow < int(iRescatterer.size())) {
647 // Identify systems that rescatterers belong to.
648 int iOutNew = iRescatterer[iRescNow];
649 int iInNew = event[iOutNew].daughter1();
650 int iSysResc = partonSystemsPtr->getSystemOf(iInNew, true);
652 // Find new and old positions of incoming partons in the system.
655 iNew.push_back( partonSystemsPtr->getInA(iSysResc) );
656 iOld.push_back( event[iNew[0]].daughter1() );
657 iNew.push_back( partonSystemsPtr->getInB(iSysResc) );
658 iOld.push_back( event[iNew[1]].daughter1() );
660 // Ditto for outgoing partons.
661 sizeOut = partonSystemsPtr->sizeOut(iSysResc);
662 for (int i = 0; i < sizeOut; ++i) {
663 int iNow = partonSystemsPtr->getOut(iSysResc, i);
664 iNew.push_back( iNow );
665 iOld.push_back( event[iNow].mother1() );
666 // Add non-final to list of rescatterers.
667 if (!event[iNow].isFinal()) iRescatterer.push_back( iNow );
670 // Loop over all dipole ends belonging to the system
671 // or to the recoil system, if different.
672 for (int iDip = 0; iDip < int(dipEnd.size()); ++iDip)
673 if (dipEnd[iDip].system == iSysResc
674 || dipEnd[iDip].systemRec == iSysResc) {
675 TimeDipoleEnd& dipNow = dipEnd[iDip];
677 // Replace radiator (always in final state so simple).
678 for (int i = 2; i < 2 + sizeOut; ++i)
679 if (dipNow.iRadiator == iOld[i]) {
680 dipNow.iRadiator = iNew[i];
684 // Replace ME partner (always in final state, if exists, so simple).
685 for (int i = 2; i < 2 + sizeOut; ++i)
686 if (dipNow.iMEpartner == iOld[i]) {
687 dipNow.iMEpartner = iNew[i];
692 for (int i = 0; i < 2 + sizeOut; ++i)
693 if (dipNow.iRecoiler == iOld[i]) {
694 dipNow.iRecoiler = iNew[i];
699 // End iterate over list of rescatterers.
704 //--------------------------------------------------------------------------
706 // Setup a dipole end for a QCD colour charge.
708 void TimeShower::setupQCDdip( int iSys, int i, int colTag, int colSign,
709 Event& event, bool isOctetOnium, bool limitPTmaxIn) {
711 // Initial values. Find if allowed to hook up beams.
712 int iRad = partonSystemsPtr->getOut(iSys, i);
714 int sizeAllA = partonSystemsPtr->sizeAll(iSys);
715 int sizeOut = partonSystemsPtr->sizeOut(iSys);
716 int sizeAll = ( allowBeamRecoil ) ? sizeAllA : sizeOut;
717 int sizeIn = sizeAll - sizeOut;
718 int sizeInA = sizeAllA - sizeIn - sizeOut;
719 int iOffset = i + sizeAllA - sizeOut;
720 bool otherSystemRec = false;
721 bool allowInitial = (partonSystemsPtr->hasInAB(iSys)) ? true : false;
722 // PS dec 2010: possibility to allow for several recoilers and each with
723 // flexible normalization
724 bool isFlexible = false;
725 double flexFactor = 1.0;
726 vector<int> iRecVec(0);
728 // Colour: other end by same index in beam or opposite in final state.
729 // Exclude rescattered incoming and not final outgoing.
731 for (int j = 0; j < sizeAll; ++j) if (j + sizeInA != iOffset) {
732 int iRecNow = partonSystemsPtr->getAll(iSys, j + sizeInA);
733 if ( ( j < sizeIn && event[iRecNow].col() == colTag
734 && !event[iRecNow].isRescatteredIncoming() )
735 || ( j >= sizeIn && event[iRecNow].acol() == colTag
736 && event[iRecNow].isFinal() ) ) {
742 // Anticolour: other end by same index in beam or opposite in final state.
743 // Exclude rescattered incoming and not final outgoing.
745 for (int j = 0; j < sizeAll; ++j) if (j + sizeInA != iOffset) {
746 int iRecNow = partonSystemsPtr->getAll(iSys, j + sizeInA);
747 if ( ( j < sizeIn && event[iRecNow].acol() == colTag
748 && !event[iRecNow].isRescatteredIncoming() )
749 || ( j >= sizeIn && event[iRecNow].col() == colTag
750 && event[iRecNow].isFinal() ) ) {
756 // Resonance decays (= no instate):
757 // other end to nearest recoiler in same system final state,
758 // by (p_i + p_j)^2 - (m_i + m_j)^2 = 2 (p_i p_j - m_i m_j).
759 // (junction colours more involved, so keep track if junction colour)
760 bool hasJunction = false;
761 if (iRec == 0 && !allowInitial) {
762 for (int iJun = 0; iJun < event.sizeJunction(); ++ iJun) {
763 // For types 1&2, all legs in final state
764 // For types 3&4, two legs in final state
765 // For types 5&6, one leg in final state
766 int iBeg = (event.kindJunction(iJun)-1)/2;
767 for (int iLeg = iBeg; iLeg < 3; ++iLeg)
768 if (event.endColJunction( iJun, iLeg) == colTag) hasJunction = true;
770 double ppMin = LARGEM2;
771 for (int j = 0; j < sizeOut; ++j) if (j != i) {
772 int iRecNow = partonSystemsPtr->getOut(iSys, j);
773 if (!event[iRecNow].isFinal()) continue;
774 double ppNow = event[iRecNow].p() * event[iRad].p()
775 - event[iRecNow].m() * event[iRad].m();
783 // If no success then look for matching (anti)colour anywhere in final state.
784 if ( iRec == 0 || (!doInterleave && !event[iRec].isFinal()) ) {
786 for (int j = 0; j < event.size(); ++j) if (event[j].isFinal())
787 if ( (colSign > 0 && event[j].acol() == colTag)
788 || (colSign < 0 && event[j].col() == colTag) ) {
790 otherSystemRec = true;
794 // If no success then look for match to non-rescattered in initial state.
795 if (iRec == 0 && allowInitial) {
796 for (int iSysR = 0; iSysR < partonSystemsPtr->sizeSys(); ++iSysR)
798 int j = partonSystemsPtr->getInA(iSysR);
799 if (j > 0 && event[j].isRescatteredIncoming()) j = 0;
800 if (j > 0 && ( (colSign > 0 && event[j].col() == colTag)
801 || (colSign < 0 && event[j].acol() == colTag) ) ) {
803 otherSystemRec = true;
806 j = partonSystemsPtr->getInB(iSysR);
807 if (j > 0 && event[j].isRescatteredIncoming()) j = 0;
808 if (j > 0 && ( (colSign > 0 && event[j].col() == colTag)
809 || (colSign < 0 && event[j].acol() == colTag) ) ) {
811 otherSystemRec = true;
818 // Junctions (PS&ND dec 2010)
819 // For types 1&2: all legs in final state
820 // half-strength dipoles between all legs
821 // For types 3&4, two legs in final state
822 // full-strength dipole between final-state legs
823 // For types 5&6, one leg in final state
824 // no final-state dipole end
827 for (int iJun = 0; iJun < event.sizeJunction(); ++ iJun) {
828 int kindJun = event.kindJunction(iJun);
829 int iBeg = (kindJun-1)/2;
830 for (int iLeg = iBeg; iLeg < 3; ++iLeg) {
831 if (event.endColJunction( iJun, iLeg) == colTag) {
832 // For types 5&6, no other leg to recoil against. Switch off if
833 // no other particles at all, since radiation then handled by ISR.
834 // Example: qq -> ~t* : no radiation off ~t*
835 // Allow radiation + recoil if unconnected partners available
836 // Example: qq -> ~t* -> tbar ~chi0 : allow radiation off tbar,
837 // with ~chi0 as recoiler
839 if (sizeOut == 1) return;
842 // For junction types 3 & 4, span one full-strength dipole
843 // (only look inside same decay system)
844 else if (kindJun >= 3) {
845 int iLegRec = 3-iLeg;
846 int colTagRec = event.endColJunction( iJun, iLegRec);
847 for (int j = 0; j < sizeOut; ++j) if (j != i) {
848 int iRecNow = partonSystemsPtr->getOut(iSys, j);
849 if (!event[iRecNow].isFinal()) continue;
850 if ( (colSign > 0 && event[iRecNow].col() == colTagRec)
851 || (colSign < 0 && event[iRecNow].acol() == colTagRec) ) {
852 // Only accept if staying inside same system
858 // For junction types 1 & 2, span two half-strength dipoles
859 // (only look inside same decay system)
861 // Loop over two half-strength dipole connections
862 for (int jLeg = 1; jLeg <= 2; jLeg++) {
863 int iLegRec = (iLeg + jLeg) % 3;
864 int colTagRec = event.endColJunction( iJun, iLegRec);
865 for (int j = 0; j < sizeOut; ++j) if (j != i) {
866 int iRecNow = partonSystemsPtr->getOut(iSys, j);
867 if (!event[iRecNow].isFinal()) continue;
868 if ( (colSign > 0 && event[iRecNow].col() == colTagRec)
869 || (colSign < 0 && event[iRecNow].acol() == colTagRec) ) {
870 // Store recoilers in temporary array
871 iRecVec.push_back(iRecNow);
872 // Set iRec != 0 for checks below
878 } // End if-then-else of junction kinds
880 } // End if leg has right color tag
881 } // End of loop over junction legs
882 } // End loop over junctions
884 } // End main junction if
886 // If fail, then other end to nearest recoiler in same system final state,
887 // by (p_i + p_j)^2 - (m_i + m_j)^2 = 2 (p_i p_j - m_i m_j).
889 double ppMin = LARGEM2;
890 for (int j = 0; j < sizeOut; ++j) if (j != i) {
891 int iRecNow = partonSystemsPtr->getOut(iSys, j);
892 if (!event[iRecNow].isFinal()) continue;
893 double ppNow = event[iRecNow].p() * event[iRad].p()
894 - event[iRecNow].m() * event[iRad].m();
902 // If fail, then other end to nearest recoiler in any system final state,
903 // by (p_i + p_j)^2 - (m_i + m_j)^2 = 2 (p_i p_j - m_i m_j).
905 double ppMin = LARGEM2;
906 for (int iRecNow = 0; iRecNow < event.size(); ++iRecNow)
907 if (iRecNow != iRad && event[iRecNow].isFinal()) {
908 double ppNow = event[iRecNow].p() * event[iRad].p()
909 - event[iRecNow].m() * event[iRad].m();
912 otherSystemRec = true;
918 // PS dec 2010: make sure iRec is stored in iRecVec
919 if (iRecVec.size() == 0 && iRec != 0) iRecVec.push_back(iRec);
921 // Remove any zero recoilers from normalization
922 int nRec = iRecVec.size();
923 for (unsigned int mRec = 0; mRec < iRecVec.size(); ++mRec)
924 if (iRecVec[mRec] <= 0) nRec--;
927 flexFactor = 1.0/nRec;
930 // Check for failure to locate any recoiler
932 infoPtr->errorMsg("Error in TimeShower::setupQCDdip: "
933 "failed to locate any recoiling partner");
937 // Store dipole colour end(s).
938 for (unsigned int mRec = 0; mRec < iRecVec.size(); ++mRec) {
939 iRec = iRecVec[mRec];
940 if (iRec <= 0) continue;
941 // Max scale either by parton scale or by half dipole mass.
942 double pTmax = event[iRad].scale();
944 if (iSys == 0) pTmax *= pTmaxFudge;
945 if (iSys > 0 && sizeIn > 0) pTmax *= pTmaxFudgeMPI;
946 } else pTmax = 0.5 * m( event[iRad], event[iRec]);
947 int colType = (event[iRad].id() == 21) ? 2 * colSign : colSign;
948 int isrType = (event[iRec].isFinal()) ? 0 : event[iRec].mother1();
949 // This line in case mother is a rescattered parton.
950 while (isrType > 2 + beamOffset) isrType = event[isrType].mother1();
951 if (isrType > 2) isrType -= beamOffset;
952 dipEnd.push_back( TimeDipoleEnd( iRad, iRec, pTmax,
953 colType, 0, 0, isrType, iSys, -1, -1, isOctetOnium) );
955 // If hooked up with other system then find which.
956 if (otherSystemRec) {
957 int systemRec = partonSystemsPtr->getSystemOf(iRec, true);
958 if (systemRec >= 0) dipEnd.back().systemRec = systemRec;
959 dipEnd.back().MEtype = 0;
963 // If non-unity (flexible) normalization, set normalization factor
965 dipEnd.back().isFlexible = true;
966 dipEnd.back().flexFactor = flexFactor;
972 //--------------------------------------------------------------------------
974 // Setup a dipole end for a QED colour charge or a photon.
975 // No failsafe choice of recoiler, so gradually widen search.
977 void TimeShower::setupQEDdip( int iSys, int i, int chgType, int gamType,
978 Event& event, bool limitPTmaxIn) {
980 // Initial values. Find if allowed to hook up beams.
981 int iRad = partonSystemsPtr->getOut(iSys, i);
982 int idRad = event[iRad].id();
984 int sizeAllA = partonSystemsPtr->sizeAll(iSys);
985 int sizeOut = partonSystemsPtr->sizeOut(iSys);
986 int sizeAll = ( allowBeamRecoil ) ? sizeAllA : sizeOut;
987 int sizeIn = sizeAll - sizeOut;
988 int sizeInA = sizeAllA - sizeIn - sizeOut;
989 int iOffset = i + sizeAllA - sizeOut;
990 double ppMin = LARGEM2;
991 bool hasRescattered = false;
992 bool otherSystemRec = false;
994 // Find nearest same- (opposide-) flavour recoiler in initial (final)
995 // state of same system, excluding rescattered (in or out) partons.
996 // Also find if system is involved in rescattering.
997 // Note: (p_i + p_j)2 - (m_i + m_j)2 = 2 (p_i p_j - m_i m_j).
998 for (int j = 0; j < sizeAll; ++j) if (j + sizeInA != iOffset) {
999 int iRecNow = partonSystemsPtr->getAll(iSys, j + sizeInA);
1000 if ( (j < sizeIn && !event[iRecNow].isRescatteredIncoming())
1001 || (j >= sizeIn && event[iRecNow].isFinal()) ) {
1002 if ( (j < sizeIn && event[iRecNow].id() == idRad)
1003 || (j >= sizeIn && event[iRecNow].id() == -idRad) ) {
1004 double ppNow = event[iRecNow].p() * event[iRad].p()
1005 - event[iRecNow].m() * event[iRad].m();
1006 if (ppNow < ppMin) {
1011 } else hasRescattered = true;
1014 // If rescattering then find nearest opposite-flavour recoiler
1015 // anywhere in final state.
1016 if (iRec == 0 && hasRescattered) {
1017 for (int iRecNow = 0; iRecNow < event.size(); ++iRecNow)
1018 if (event[iRecNow].id() == -idRad && event[iRecNow].isFinal()) {
1019 double ppNow = event[iRecNow].p() * event[iRad].p()
1020 - event[iRecNow].m() * event[iRad].m();
1021 if (ppNow < ppMin) {
1024 otherSystemRec = true;
1029 // Find nearest recoiler in same system, charge-squared-weighted,
1030 // including initial state, but excluding rescatterer.
1032 for (int j = 0; j < sizeAll; ++j) if (j + sizeInA != iOffset) {
1033 int iRecNow = partonSystemsPtr->getAll(iSys, j + sizeInA);
1034 int chgTypeRecNow = event[iRecNow].chargeType();
1035 if (chgTypeRecNow == 0) continue;
1036 if ( (j < sizeIn && !event[iRecNow].isRescatteredIncoming())
1037 || (j >= sizeIn && event[iRecNow].isFinal()) ) {
1038 double ppNow = (event[iRecNow].p() * event[iRad].p()
1039 - event[iRecNow].m() * event[iRad].m())
1040 / pow2(chgTypeRecNow);
1041 if (ppNow < ppMin) {
1048 // If rescattering then find nearest recoiler in the final state,
1049 // charge-squared-weighted.
1050 if (iRec == 0 && hasRescattered) {
1051 for (int iRecNow = 0; iRecNow < event.size(); ++iRecNow)
1052 if (iRecNow != iRad && event[iRecNow].isFinal()) {
1053 int chgTypeRecNow = event[iRecNow].chargeType();
1054 if (chgTypeRecNow != 0 && event[iRecNow].isFinal()) {
1055 double ppNow = (event[iRecNow].p() * event[iRad].p()
1056 - event[iRecNow].m() * event[iRad].m())
1057 / pow2(chgTypeRecNow);
1058 if (ppNow < ppMin) {
1061 otherSystemRec = true;
1067 // Find any nearest recoiler in final state of same system.
1069 for (int j = 0; j < sizeOut; ++j) if (j != i) {
1070 int iRecNow = partonSystemsPtr->getOut(iSys, j);
1071 double ppNow = event[iRecNow].p() * event[iRad].p()
1072 - event[iRecNow].m() * event[iRad].m();
1073 if (ppNow < ppMin) {
1079 // Find any nearest recoiler in final state.
1081 for (int iRecNow = 0; iRecNow < event.size(); ++iRecNow)
1082 if (iRecNow != iRad && event[iRecNow].isFinal()) {
1083 double ppNow = event[iRecNow].p() * event[iRad].p()
1084 - event[iRecNow].m() * event[iRad].m();
1085 if (ppNow < ppMin) {
1088 otherSystemRec = true;
1092 // Fill charge-dipole or photon-dipole end.
1094 // Max scale either by parton scale or by half dipole mass.
1095 double pTmax = event[iRad].scale();
1097 if (iSys == 0) pTmax *= pTmaxFudge;
1098 if (iSys > 0 && sizeIn > 0) pTmax *= pTmaxFudgeMPI;
1099 } else pTmax = 0.5 * m( event[iRad], event[iRec]);
1100 int isrType = (event[iRec].isFinal()) ? 0 : event[iRec].mother1();
1101 // This line in case mother is a rescattered parton.
1102 while (isrType > 2 + beamOffset) isrType = event[isrType].mother1();
1103 if (isrType > 2) isrType -= beamOffset;
1104 dipEnd.push_back( TimeDipoleEnd(iRad, iRec, pTmax,
1105 0, chgType, gamType, isrType, iSys, -1) );
1107 // If hooked up with other system then find which.
1108 if (otherSystemRec) {
1109 int systemRec = partonSystemsPtr->getSystemOf(iRec);
1110 if (systemRec >= 0) dipEnd.back().systemRec = systemRec;
1111 dipEnd.back().MEtype = 0;
1114 // Failure to find other end of dipole.
1116 infoPtr->errorMsg("Error in TimeShower::setupQEDdip: "
1117 "failed to locate any recoiling partner");
1122 //--------------------------------------------------------------------------
1124 // Setup a dipole end for a Hidden Valley colour charge.
1126 void TimeShower::setupHVdip( int iSys, int i, Event& event,
1127 bool limitPTmaxIn) {
1130 int iRad = partonSystemsPtr->getOut(iSys, i);
1132 int idRad = event[iRad].id();
1133 int sizeOut = partonSystemsPtr->sizeOut(iSys);
1135 // Hidden Valley colour positive for positive id, and vice versa.
1136 // Find opposte HV colour in final state of same system.
1137 for (int j = 0; j < sizeOut; ++j) if (j != i) {
1138 int iRecNow = partonSystemsPtr->getOut(iSys, j);
1139 int idRec = event[iRecNow].id();
1140 if ( (abs(idRec) > 4900000 && abs(idRec) < 4900017)
1141 && idRad * idRec < 0) {
1147 // Else find heaviest other final-state in same system.
1148 // (Intended for decays; should mainly be two-body so unique.)
1149 double mMax = -sqrt(LARGEM2);
1151 for (int j = 0; j < sizeOut; ++j) if (j != i) {
1152 int iRecNow = partonSystemsPtr->getOut(iSys, j);
1153 if (event[iRecNow].m() > mMax) {
1155 mMax = event[iRecNow].m();
1159 // Set up dipole end, or report failure.
1161 // Max scale either by parton scale or by half dipole mass.
1162 double pTmax = event[iRad].scale();
1164 if (iSys == 0) pTmax *= pTmaxFudge;
1165 } else pTmax = 0.5 * m( event[iRad], event[iRec]);
1166 int colvType = (event[iRad].id() > 0) ? 1 : -1;
1167 dipEnd.push_back( TimeDipoleEnd( iRad, iRec, pTmax, 0, 0, 0, 0,
1168 iSys, -1, -1, false, true, colvType) );
1169 } else infoPtr->errorMsg("Error in TimeShower::setupHVdip: "
1170 "failed to locate any recoiling partner");
1174 //--------------------------------------------------------------------------
1176 // Select next pT in downwards evolution of the existing dipoles.
1178 double TimeShower::pTnext( Event& event, double pTbegAll, double pTendAll) {
1180 // Begin loop over all possible radiating dipole ends.
1183 double pT2sel = pTendAll * pTendAll;
1184 for (int iDip = 0; iDip < int(dipEnd.size()); ++iDip) {
1185 TimeDipoleEnd& dip = dipEnd[iDip];
1187 // Check if global recoil should be used.
1188 useLocalRecoilNow = !(globalRecoil && dip.system == 0
1189 && partonSystemsPtr->sizeOut(0) <= nMaxGlobalRecoil);
1191 // Dipole properties; normal local recoil.
1192 dip.mRad = event[dip.iRadiator].m();
1193 if (useLocalRecoilNow) {
1194 dip.mRec = event[dip.iRecoiler].m();
1195 dip.mDip = m( event[dip.iRadiator], event[dip.iRecoiler] );
1197 // Dipole properties, alternative global recoil. Squares.
1200 for (int i = 0; i < partonSystemsPtr->sizeOut( dip.system); ++i) {
1201 int ii = partonSystemsPtr->getOut( dip.system, i);
1202 if (ii != dip.iRadiator) pSumGlobal += event[ii].p();
1204 dip.mRec = pSumGlobal.mCalc();
1205 dip.mDip = m( event[dip.iRadiator].p(), pSumGlobal);
1207 dip.m2Rad = pow2(dip.mRad);
1208 dip.m2Rec = pow2(dip.mRec);
1209 dip.m2Dip = pow2(dip.mDip);
1211 // Find maximum evolution scale for dipole.
1212 dip.m2DipCorr = pow2(dip.mDip - dip.mRec) - dip.m2Rad;
1213 double pTbegDip = min( pTbegAll, dip.pTmax );
1214 double pT2begDip = min( pow2(pTbegDip), 0.25 * dip.m2DipCorr);
1216 // Do QCD, QED or HV evolution if it makes sense.
1218 if (pT2begDip > pT2sel) {
1219 if (dip.colType != 0)
1220 pT2nextQCD(pT2begDip, pT2sel, dip, event);
1221 else if (dip.chgType != 0 || dip.gamType != 0)
1222 pT2nextQED(pT2begDip, pT2sel, dip, event);
1223 else if (dip.colvType != 0)
1224 pT2nextHV(pT2begDip, pT2sel, dip, event);
1226 // Update if found larger pT than current maximum.
1227 if (dip.pT2 > pT2sel) {
1235 // Return nonvanishing value if found pT bigger than already found.
1236 return (dipSel == 0) ? 0. : sqrt(pT2sel);
1240 //--------------------------------------------------------------------------
1242 // Evolve a QCD dipole end.
1244 void TimeShower::pT2nextQCD(double pT2begDip, double pT2sel,
1245 TimeDipoleEnd& dip, Event& event) {
1247 // Lower cut for evolution. Return if no evolution range.
1248 double pT2endDip = max( pT2sel, pT2colCut );
1249 if (pT2begDip < pT2endDip) return;
1251 // Upper estimate for matrix element weighting and colour factor.
1252 // Special cases for triplet recoiling against gluino and octet onia.
1253 // Note that g -> g g and g -> q qbar are split on two sides.
1254 int colTypeAbs = abs(dip.colType);
1255 double wtPSglue = 2.;
1256 double colFac = (colTypeAbs == 1) ? 4./3. : 3./2.;
1257 if (dip.MEgluinoRec) colFac = 3.;
1258 if (dip.isOctetOnium) colFac *= 0.5 * octetOniumColFac;
1259 // PS dec 2010. Include possibility for flexible normalization,
1260 // e.g., for dipoles stretched to junctions or to switch off radiation.
1261 if (dip.isFlexible) colFac *= dip.flexFactor;
1262 double wtPSqqbar = (colTypeAbs == 2) ? 0.25 * nGluonToQuark : 0.;
1264 // Variables used inside evolution loop. (Mainly dummy start values.)
1265 dip.pT2 = pT2begDip;
1267 double zMinAbs = 0.5;
1268 double pT2min = pT2endDip;
1270 double Lambda2 = Lambda3flav2;
1271 double emitCoefGlue = 0.;
1272 double emitCoefQqbar = 0.;
1273 double emitCoefTot = 0.;
1275 bool mustFindRange = true;
1277 // Begin evolution loop towards smaller pT values.
1280 // Initialize evolution coefficients at the beginning and
1281 // reinitialize when crossing c and b flavour thresholds.
1282 if (mustFindRange) {
1284 // Determine overestimated z range; switch at c and b masses.
1285 if (dip.pT2 > m2b) {
1287 pT2min = max( m2b, pT2endDip);
1289 Lambda2 = Lambda5flav2;
1290 } else if (dip.pT2 > m2c) {
1292 pT2min = max( m2c, pT2endDip);
1294 Lambda2 = Lambda4flav2;
1299 Lambda2 = Lambda3flav2;
1301 // A change of renormalization scale expressed by a change of Lambda.
1302 Lambda2 /= renormMultFac;
1303 zMinAbs = 0.5 - sqrtpos( 0.25 - pT2min / dip.m2DipCorr );
1304 if (zMinAbs < SIMPLIFYROOT) zMinAbs = pT2min / dip.m2DipCorr;
1306 // Find emission coefficients for X -> X g and g -> q qbar.
1307 emitCoefGlue = wtPSglue * colFac * log(1. / zMinAbs - 1.);
1308 emitCoefTot = emitCoefGlue;
1309 if (colTypeAbs == 2 && event[dip.iRadiator].id() == 21) {
1310 emitCoefQqbar = wtPSqqbar * (1. - 2. * zMinAbs);
1311 emitCoefTot += emitCoefQqbar;
1314 // Initialization done for current range.
1315 mustFindRange = false;
1318 // Pick pT2 (in overestimated z range) for fixed alpha_strong.
1319 if (alphaSorder == 0) {
1320 dip.pT2 = dip.pT2 * pow( rndmPtr->flat(),
1321 1. / (alphaS2pi * emitCoefTot) );
1323 // Ditto for first-order alpha_strong.
1324 } else if (alphaSorder == 1) {
1325 dip.pT2 = Lambda2 * pow( dip.pT2 / Lambda2,
1326 pow( rndmPtr->flat(), b0 / emitCoefTot) );
1328 // For second order reject by second term in alpha_strong expression.
1330 do dip.pT2 = Lambda2 * pow( dip.pT2 / Lambda2,
1331 pow( rndmPtr->flat(), b0 / emitCoefTot) );
1332 while (alphaS.alphaS2OrdCorr(renormMultFac * dip.pT2) < rndmPtr->flat()
1333 && dip.pT2 > pT2min);
1337 // If crossed c or b thresholds: continue evolution from threshold.
1338 if (nFlavour == 5 && dip.pT2 < m2b) {
1339 mustFindRange = true;
1341 } else if ( nFlavour == 4 && dip.pT2 < m2c) {
1342 mustFindRange = true;
1345 // Abort evolution if below cutoff scale, or below another branching.
1347 if ( dip.pT2 < pT2endDip) { dip.pT2 = 0.; return; }
1349 // Pick kind of branching: X -> X g or g -> q qbar.
1352 if (colTypeAbs == 2 && emitCoefQqbar > rndmPtr->flat()
1353 * emitCoefTot) dip.flavour = 0;
1355 // Pick z: either dz/(1-z) or flat dz.
1356 if (dip.flavour == 21) {
1357 dip.z = 1. - zMinAbs * pow( 1. / zMinAbs - 1., rndmPtr->flat() );
1359 dip.z = zMinAbs + (1. - 2. * zMinAbs) * rndmPtr->flat();
1362 // Do not accept branching if outside allowed z range.
1363 double zMin = 0.5 - sqrtpos( 0.25 - dip.pT2 / dip.m2DipCorr );
1364 if (zMin < SIMPLIFYROOT) zMin = dip.pT2 / dip.m2DipCorr;
1365 dip.m2 = dip.m2Rad + dip.pT2 / (dip.z * (1. - dip.z));
1366 if (dip.z > zMin && dip.z < 1. - zMin
1367 && dip.m2 * dip.m2Dip < dip.z * (1. - dip.z)
1368 * pow2(dip.m2Dip + dip.m2 - dip.m2Rec) ) {
1370 // Flavour choice for g -> q qbar.
1371 if (dip.flavour == 0) {
1372 dip.flavour = min(5, 1 + int(nGluonToQuark * rndmPtr->flat()));
1373 dip.mFlavour = particleDataPtr->m0(dip.flavour);
1376 // No z weight, except threshold, if to do ME corrections later on.
1377 if (dip.MEtype > 0) {
1379 if (dip.flavour < 10 && dip.m2 < THRESHM2 * pow2(dip.mFlavour))
1382 // z weight for X -> X g.
1383 } else if (dip.flavour == 21
1384 && (colTypeAbs == 1 || colTypeAbs == 3) ) {
1385 wt = (1. + pow2(dip.z)) / wtPSglue;
1386 } else if (dip.flavour == 21) {
1387 wt = (1. + pow3(dip.z)) / wtPSglue;
1389 // z weight for g -> q qbar.
1391 double beta = sqrtpos( 1. - 4. * pow2(dip.mFlavour) / dip.m2 );
1392 wt = beta * ( pow2(dip.z) + pow2(1. - dip.z) );
1395 // Suppression factors for dipole to beam remnant.
1396 if (dip.isrType != 0 && useLocalRecoilNow) {
1397 BeamParticle& beam = (dip.isrType == 1) ? *beamAPtr : *beamBPtr;
1398 int iSysRec = dip.systemRec;
1399 double xOld = beam[iSysRec].x();
1400 double xNew = xOld * (1. + (dip.m2 - dip.m2Rad) /
1401 (dip.m2Dip - dip.m2Rad));
1402 double xMaxAbs = beam.xMax(iSysRec);
1404 infoPtr->errorMsg("Warning in TimeShower::pT2nextQCD: "
1405 "xMaxAbs negative");
1409 // Firstly reduce by PDF ratio.
1410 if (xNew > xMaxAbs) wt = 0.;
1412 int idRec = event[dip.iRecoiler].id();
1413 double pdfOld = max ( TINYPDF,
1414 beam.xfISR( iSysRec, idRec, xOld, factorMultFac * dip.pT2) );
1416 beam.xfISR( iSysRec, idRec, xNew, factorMultFac * dip.pT2);
1417 wt *= min( 1., pdfNew / pdfOld);
1420 // Secondly optionally reduce by 4 pT2_hard / (4 pT2_hard + m2).
1421 if (dampenBeamRecoil) {
1422 double pTpT = sqrt(event[dip.iRadiator].pT2() * dip.pT2);
1423 wt *= pTpT / (pTpT + dip.m2);
1429 // Iterate until acceptable pT (or have fallen below pTmin).
1430 } while (wt < rndmPtr->flat());
1434 //--------------------------------------------------------------------------
1436 // Evolve a QED dipole end, either charged or photon.
1438 void TimeShower::pT2nextQED(double pT2begDip, double pT2sel,
1439 TimeDipoleEnd& dip, Event& event) {
1441 // Lower cut for evolution. Return if no evolution range.
1442 double pT2chgCut = (dip.chgType != 0 && abs(dip.chgType) != 3)
1443 ? pT2chgQCut : pT2chgLCut;
1444 double pT2endDip = max( pT2sel, pT2chgCut );
1445 if (pT2begDip < pT2endDip) return;
1447 // Emission of photon or photon branching.
1448 bool hasCharge = (dip.chgType != 0);
1451 double wtPSgam = 0.;
1452 double chg2Sum = 0.;
1453 double chg2SumL = 0.;
1454 double chg2SumQ = 0.;
1455 double zMinAbs = 0.;
1456 double emitCoefTot = 0.;
1458 // alpha_em at maximum scale provides upper estimate.
1459 double alphaEMmax = alphaEM.alphaEM(renormMultFac * pT2begDip);
1460 double alphaEM2pi = alphaEMmax / (2. * M_PI);
1462 // Emission: upper estimate for matrix element weighting; charge factor.
1465 double chg2 = pow2(dip.chgType / 3.);
1467 // Determine overestimated z range. Find evolution coefficient.
1468 zMinAbs = 0.5 - sqrtpos( 0.25 - pT2endDip / dip.m2DipCorr );
1469 if (zMinAbs < SIMPLIFYROOT) zMinAbs = pT2endDip / dip.m2DipCorr;
1470 emitCoefTot = alphaEM2pi * chg2 * wtPSgam * log(1. / zMinAbs - 1.);
1472 // Branching: sum of squared charge factors for lepton and quark daughters.
1474 chg2SumL = max(0, min(3, nGammaToLepton));
1475 if (nGammaToQuark > 4) chg2SumQ = 11. / 9.;
1476 else if (nGammaToQuark > 3) chg2SumQ = 10. / 9.;
1477 else if (nGammaToQuark > 2) chg2SumQ = 6. / 9.;
1478 else if (nGammaToQuark > 1) chg2SumQ = 5. / 9.;
1479 else if (nGammaToQuark > 0) chg2SumQ = 1. / 9.;
1481 // Total sum of squared charge factors. Find evolution coefficient.
1482 chg2Sum = chg2SumL + 3. * chg2SumQ;
1483 emitCoefTot = alphaEM2pi * chg2Sum;
1486 // Variables used inside evolution loop.
1487 dip.pT2 = pT2begDip;
1490 // Begin evolution loop towards smaller pT values.
1493 // Pick pT2 (in overestimated z range).
1494 dip.pT2 = dip.pT2 * pow(rndmPtr->flat(), 1. / emitCoefTot);
1497 // Abort evolution if below cutoff scale, or below another branching.
1498 if ( dip.pT2 < pT2endDip) { dip.pT2 = 0.; return; }
1500 // Pick z according to dz/(1-z) or flat.
1501 if (hasCharge) dip.z = 1. - zMinAbs
1502 * pow( 1. / zMinAbs - 1., rndmPtr->flat() );
1503 else dip.z = rndmPtr->flat();
1505 // Do not accept branching if outside allowed z range.
1506 double zMin = 0.5 - sqrtpos( 0.25 - dip.pT2 / dip.m2DipCorr );
1507 if (zMin < SIMPLIFYROOT) zMin = dip.pT2 / dip.m2DipCorr;
1508 dip.m2 = dip.m2Rad + dip.pT2 / (dip.z * (1. - dip.z));
1509 if (dip.z > zMin && dip.z < 1. - zMin
1510 && dip.m2 * dip.m2Dip < dip.z * (1. - dip.z)
1511 * pow2(dip.m2Dip + dip.m2 - dip.m2Rec)
1512 // For gamma -> f fbar also impose maximum mass.
1513 && (hasCharge || dip.m2 < m2MaxGamma) ) {
1515 // Photon emission: unique flavour choice.
1520 // Photon branching: either lepton or quark flavour choice.
1522 if (rndmPtr->flat() * chg2Sum < chg2SumL)
1523 dip.flavour = 9 + 2 * min(3, 1 + int(chg2SumL * rndmPtr->flat()));
1525 double rndmQ = 9. * chg2SumQ * rndmPtr->flat();
1526 if (rndmQ < 1.) dip.flavour = 1;
1527 else if (rndmQ < 5.) dip.flavour = 2;
1528 else if (rndmQ < 6.) dip.flavour = 3;
1529 else if (rndmQ < 10.) dip.flavour = 4;
1530 else dip.flavour = 5;
1532 dip.mFlavour = particleDataPtr->m0(dip.flavour);
1535 // No z weight, except threshold, if to do ME corrections later on.
1536 if (dip.MEtype > 0) {
1538 if (dip.flavour < 20 && dip.m2 < THRESHM2 * pow2(dip.mFlavour))
1541 // z weight for X -> X gamma.
1542 } else if (hasCharge) {
1543 wt = (1. + pow2(dip.z)) / wtPSgam;
1545 // z weight for gamma -> f fbar.
1547 double beta = sqrtpos( 1. - 4. * pow2(dip.mFlavour) / dip.m2 );
1548 wt = beta * ( pow2(dip.z) + pow2(1. - dip.z) );
1551 // Correct to current value of alpha_EM.
1552 double alphaEMnow = alphaEM.alphaEM(renormMultFac * dip.pT2);
1553 wt *= (alphaEMnow / alphaEMmax);
1555 // Suppression factors for dipole to beam remnant.
1556 if (dip.isrType != 0 && useLocalRecoilNow) {
1557 BeamParticle& beam = (dip.isrType == 1) ? *beamAPtr : *beamBPtr;
1558 int iSys = dip.system;
1559 double xOld = beam[iSys].x();
1560 double xNew = xOld * (1. + (dip.m2 - dip.m2Rad) /
1561 (dip.m2Dip - dip.m2Rad));
1562 double xMaxAbs = beam.xMax(iSys);
1564 infoPtr->errorMsg("Warning in TimeShower::pT2nextQED: "
1565 "xMaxAbs negative");
1569 // Firstly reduce by PDF ratio.
1570 if (xNew > xMaxAbs) wt = 0.;
1572 int idRec = event[dip.iRecoiler].id();
1573 double pdfOld = max ( TINYPDF,
1574 beam.xfISR( iSys, idRec, xOld, factorMultFac * dip.pT2) );
1576 beam.xfISR( iSys, idRec, xNew, factorMultFac * dip.pT2);
1577 wt *= min( 1., pdfNew / pdfOld);
1580 // Secondly optionally reduce by 4 pT2_hard / (4 pT2_hard + m2).
1581 if (dampenBeamRecoil) {
1582 double pT24 = 4. * event[dip.iRadiator].pT2();
1583 wt *= pT24 / (pT24 + dip.m2);
1588 // Iterate until acceptable pT (or have fallen below pTmin).
1589 } while (wt < rndmPtr->flat());
1593 //--------------------------------------------------------------------------
1595 // Evolve a Hidden Valley dipole end.
1597 void TimeShower::pT2nextHV(double pT2begDip, double pT2sel,
1598 TimeDipoleEnd& dip, Event& ) {
1600 // Lower cut for evolution. Return if no evolution range.
1601 double pT2endDip = max( pT2sel, pT2hvCut );
1602 if (pT2begDip < pT2endDip) return;
1604 // C_F * alpha_HV/2 pi.
1605 int colvTypeAbs = abs(dip.colvType);
1606 double colvFac = (colvTypeAbs == 1) ? CFHV : 0.5 * nCHV;
1607 double alphaHV2pi = colvFac * (alphaHVfix / (2. * M_PI));
1609 // Determine overestimated z range. Find evolution coefficient.
1610 double zMinAbs = 0.5 - sqrtpos( 0.25 - pT2endDip / dip.m2DipCorr );
1611 if (zMinAbs < SIMPLIFYROOT) zMinAbs = pT2endDip / dip.m2DipCorr;
1612 double emitCoefTot = alphaHV2pi * 2. * log(1. / zMinAbs - 1.);
1614 // Variables used inside evolution loop.
1615 dip.pT2 = pT2begDip;
1618 // Begin evolution loop towards smaller pT values.
1621 // Pick pT2 (in overestimated z range).
1622 dip.pT2 = dip.pT2 * pow(rndmPtr->flat(), 1. / emitCoefTot);
1625 // Abort evolution if below cutoff scale, or below another branching.
1626 if ( dip.pT2 < pT2endDip) { dip.pT2 = 0.; return; }
1628 // Pick z according to dz/(1-z).
1629 dip.z = 1. - zMinAbs * pow( 1. / zMinAbs - 1., rndmPtr->flat() );
1631 // Do not accept branching if outside allowed z range.
1632 double zMin = 0.5 - sqrtpos( 0.25 - dip.pT2 / dip.m2DipCorr );
1633 if (zMin < SIMPLIFYROOT) zMin = dip.pT2 / dip.m2DipCorr;
1634 dip.m2 = dip.m2Rad + dip.pT2 / (dip.z * (1. - dip.z));
1635 if (dip.z > zMin && dip.z < 1. - zMin
1636 && dip.m2 * dip.m2Dip < dip.z * (1. - dip.z)
1637 * pow2(dip.m2Dip + dip.m2 - dip.m2Rec) ) {
1639 // HV gamma or gluon emission: unique flavour choice.
1643 // No z weight, except threshold, if to do ME corrections later on.
1644 if (dip.MEtype > 0) wt = 1.;
1646 // z weight for X -> X g_HV.
1647 else if (colvTypeAbs == 1) wt = (1. + pow2(dip.z)) / 2.;
1648 else wt = (1. + pow3(dip.z)) / 2.;
1651 // Iterate until acceptable pT (or have fallen below pTmin).
1652 } while (wt < rndmPtr->flat());
1656 //--------------------------------------------------------------------------
1658 // ME corrections and kinematics that may give failure.
1659 // Notation: radBef, recBef = radiator, recoiler before emission,
1660 // rad, rec, emt = radiator, recoiler, emitted efter emission.
1661 // (rad, emt distinguished by colour flow for g -> q qbar.)
1663 bool TimeShower::branch( Event& event, bool isInterleaved) {
1665 // Check if global recoil should be used.
1666 useLocalRecoilNow = !(globalRecoil && dipSel->system == 0
1667 && partonSystemsPtr->sizeOut(0) <= nMaxGlobalRecoil);
1669 // Find initial radiator and recoiler particles in dipole branching.
1670 int iRadBef = dipSel->iRadiator;
1671 int iRecBef = dipSel->iRecoiler;
1672 Particle& radBef = event[iRadBef];
1673 Particle& recBef = event[iRecBef];
1675 // Find their momenta, with special sum for global recoil.
1676 Vec4 pRadBef = event[iRadBef].p();
1678 vector<int> iGRecBef, iGRec;
1679 if (useLocalRecoilNow) pRecBef = event[iRecBef].p();
1681 for (int i = 0; i < partonSystemsPtr->sizeOut( dipSel->system); ++i) {
1682 int iG = partonSystemsPtr->getOut( dipSel->system, i);
1683 if (iG != dipSel->iRadiator) {
1684 iGRecBef.push_back(iG);
1685 pRecBef += event[iG].p();
1690 // Default flavours and colour tags for new particles in dipole branching.
1691 int idRad = radBef.id();
1692 int idEmt = dipSel->flavour;
1693 int colRad = radBef.col();
1694 int acolRad = radBef.acol();
1697 iSysSel = dipSel->system;
1698 int iSysSelRec = dipSel->systemRec;
1700 // Default OK for photon, photon_HV or gluon_HV emission.
1701 if (dipSel->flavour == 22 || dipSel->flavour == idHV) {
1702 // New colour tag required for gluon emission.
1703 } else if (dipSel->flavour == 21 && dipSel->colType > 0) {
1705 colRad = event.nextColTag();
1707 } else if (dipSel->flavour == 21) {
1709 acolRad = event.nextColTag();
1711 // New flavours for g -> q qbar; split colours.
1712 } else if (dipSel->colType > 0) {
1713 idEmt = dipSel->flavour ;
1717 } else if (dipSel->colType < 0) {
1718 idEmt = -dipSel->flavour ;
1722 // New flavours for gamma -> f fbar, and maybe also colours.
1723 } else if (dipSel->gamType == 1 && rndmPtr->flat() > 0.5) {
1724 idEmt = -dipSel->flavour ;
1726 if (idRad < 10) colRad = event.nextColTag();
1728 } else if (dipSel->gamType == 1) {
1729 idEmt = dipSel->flavour ;
1731 if (idEmt < 10) colEmt = event.nextColTag();
1735 // Construct kinematics in dipole rest frame:
1736 // begin simple (like g -> g g).
1737 double pTorig = sqrt( dipSel->pT2);
1738 double eRadPlusEmt = 0.5 * (dipSel->m2Dip + dipSel->m2 - dipSel->m2Rec)
1740 double e2RadPlusEmt = pow2(eRadPlusEmt);
1741 double pzRadPlusEmt = 0.5 * sqrtpos( pow2(dipSel->m2Dip - dipSel->m2
1742 - dipSel->m2Rec) - 4. * dipSel->m2 * dipSel->m2Rec ) / dipSel->mDip;
1743 double pT2corr = dipSel->m2 * (e2RadPlusEmt * dipSel->z * (1. - dipSel->z)
1744 - 0.25 * dipSel->m2) / pow2(pzRadPlusEmt);
1745 double pTcorr = sqrtpos( pT2corr );
1746 double pzRad = (e2RadPlusEmt * dipSel->z - 0.5 * dipSel->m2)
1748 double pzEmt = (e2RadPlusEmt * (1. - dipSel->z) - 0.5 * dipSel->m2)
1750 double mRad = dipSel->mRad;
1753 // Kinematics reduction for q -> q gamma_v when m_q > 0 and m_gamma_v > 0.
1754 if ( abs(dipSel->colvType) == 1 && dipSel->mFlavour > 0.) {
1755 mEmt = dipSel->mFlavour;
1756 if (pow2(mRad + mEmt) > dipSel->m2) return false;
1757 double m2Emt = pow2(mEmt);
1758 double lambda = sqrtpos( pow2(dipSel->m2 - dipSel->m2Rad - m2Emt)
1759 - 4. * dipSel->m2Rad * m2Emt );
1760 kRad = 0.5 * (dipSel->m2 - lambda + m2Emt - dipSel->m2Rad)
1762 kEmt = 0.5 * (dipSel->m2 - lambda + dipSel->m2Rad - m2Emt)
1764 pTorig *= 1. - kRad - kEmt;
1765 pTcorr *= 1. - kRad - kEmt;
1766 double pzMove = kRad * pzRad - kEmt * pzEmt;
1770 // Kinematics reduction for q -> q g/gamma/g_HV when m_q > 0.
1771 } else if (abs(dipSel->colType) == 1 || dipSel->chgType != 0
1772 || abs(dipSel->colvType) == 1) {
1773 pTorig *= 1. - dipSel->m2Rad / dipSel->m2;
1774 pTcorr *= 1. - dipSel->m2Rad / dipSel->m2;
1775 pzRad += pzEmt * dipSel->m2Rad / dipSel->m2;
1776 pzEmt *= 1. - dipSel->m2Rad / dipSel->m2;
1778 // Kinematics reduction for g -> q qbar or gamma -> f fbar when m_f > 0;
1779 } else if (abs(dipSel->flavour) < 20) {
1780 mEmt = dipSel->mFlavour;
1782 double beta = sqrtpos( 1. - 4. * pow2(mEmt) / dipSel->m2 );
1785 pzRad = 0.5 * ( (1. + beta) * pzRad + (1. - beta) * pzEmt );
1786 pzEmt = pzRadPlusEmt - pzRad;
1789 // Reject g emission where mass effects have reduced pT below cutoff.
1790 if (idEmt == 21 && pTorig < pTcolCut) return false;
1792 // Find rest frame and angles of original dipole.
1794 M.fromCMframe(pRadBef, pRecBef);
1796 // Evaluate coefficient of azimuthal asymmetry from gluon polarization.
1797 findAsymPol( event, dipSel);
1799 // Begin construction of new dipole kinematics: pick azimuthal angle.
1800 Vec4 pRad, pEmt, pRec;
1803 double phi = 2. * M_PI * rndmPtr->flat();
1805 // Define kinematics of branching in dipole rest frame.
1806 pRad = Vec4( pTcorr * cos(phi), pTcorr * sin(phi), pzRad,
1807 sqrt( pow2(pTcorr) + pow2(pzRad) + pow2(mRad) ) );
1808 pEmt = Vec4( -pRad.px(), -pRad.py(), pzEmt,
1809 sqrt( pow2(pTcorr) + pow2(pzEmt) + pow2(mEmt) ) );
1810 pRec = Vec4( 0., 0., -pzRadPlusEmt, sqrt( pow2(pzRadPlusEmt)
1811 + dipSel->m2Rec ) );
1813 // Rotate and boost dipole products to the event frame.
1818 // Azimuthal phi weighting: loop to new phi value if required.
1819 if (dipSel->asymPol != 0.) {
1820 Vec4 pAunt = event[dipSel->iAunt].p();
1821 double cosPhi = cosphi( pRad, pAunt, pRadBef );
1822 wtPhi = ( 1. + dipSel->asymPol * (2. * pow2(cosPhi) - 1.) )
1823 / ( 1. + abs(dipSel->asymPol) );
1825 } while (wtPhi < rndmPtr->flat()) ;
1827 // Kinematics when recoiler is initial-state parton.
1828 int isrTypeNow = dipSel->isrType;
1829 int isrTypeSave = isrTypeNow;
1830 if (!useLocalRecoilNow) isrTypeNow = 0;
1831 if (isrTypeNow != 0) pRec = 2. * recBef.p() - pRec;
1833 // PS dec 2010: check if radiator has flexible normalization
1834 bool isFlexible = dipSel->isFlexible;
1836 // Define new particles from dipole branching.
1837 double pTsel = sqrt(dipSel->pT2);
1838 Particle rad = Particle(idRad, 51, iRadBef, 0, 0, 0,
1839 colRad, acolRad, pRad, mRad, pTsel);
1840 Particle emt = Particle(idEmt, 51, iRadBef, 0, 0, 0,
1841 colEmt, acolEmt, pEmt, mEmt, pTsel);
1843 // Recoiler either in final or in initial state
1844 Particle rec = (isrTypeNow == 0)
1845 ? Particle(recBef.id(), 52, iRecBef, iRecBef, 0, 0,
1846 recBef.col(), recBef.acol(), pRec, dipSel->mRec, pTsel)
1847 : Particle(recBef.id(), -53, 0, 0, iRecBef, iRecBef,
1848 recBef.col(), recBef.acol(), pRec, 0., 0.);
1850 // ME corrections can lead to branching being rejected.
1851 if (dipSel->MEtype > 0) {
1852 Particle& partner = (dipSel->iMEpartner == iRecBef)
1853 ? rec : event[dipSel->iMEpartner];
1854 if ( findMEcorr( dipSel, rad, partner, emt) < rndmPtr->flat() )
1858 // Rescatter: if the recoiling partner is not in the same system
1859 // as the radiator, fix up intermediate systems (can lead
1860 // to emissions being vetoed)
1861 if (allowRescatter && FIXRESCATTER && isInterleaved
1862 && iSysSel != iSysSelRec) {
1863 Vec4 pNew = rad.p() + emt.p();
1864 if (!rescatterPropagateRecoil(event, pNew)) return false;
1867 // Save properties to be restored in case of user-hook veto of emission.
1868 int eventSizeOld = event.size();
1869 int iRadStatusV = event[iRadBef].status();
1870 int iRadDau1V = event[iRadBef].daughter1();
1871 int iRadDau2V = event[iRadBef].daughter2();
1872 int iRecStatusV = event[iRecBef].status();
1873 int iRecMot1V = event[iRecBef].mother1();
1874 int iRecMot2V = event[iRecBef].mother2();
1875 int iRecDau1V = event[iRecBef].daughter1();
1876 int iRecDau2V = event[iRecBef].daughter2();
1877 int beamOff1 = 1 + beamOffset;
1878 int beamOff2 = 2 + beamOffset;
1879 int ev1Dau1V = event[beamOff1].daughter1();
1880 int ev2Dau1V = event[beamOff2].daughter1();
1882 // Shower may occur at a displaced vertex.
1883 if (radBef.hasVertex()) {
1884 rad.vProd( radBef.vProd() );
1885 emt.vProd( radBef.vProd() );
1887 if (recBef.hasVertex()) rec.vProd( recBef.vProd() );
1889 // Put new particles into the event record.
1890 // Mark original dipole partons as branched and set daughters/mothers.
1891 int iRad = event.append(rad);
1892 int iEmt = event.append(emt);
1893 event[iRadBef].statusNeg();
1894 event[iRadBef].daughters( iRad, iEmt);
1896 if (useLocalRecoilNow) {
1897 iRec = event.append(rec);
1898 if (isrTypeNow == 0) {
1899 event[iRecBef].statusNeg();
1900 event[iRecBef].daughters( iRec, iRec);
1902 event[iRecBef].mothers( iRec, iRec);
1903 event[iRec].mothers( iRecMot1V, iRecMot2V);
1904 if (iRecMot1V == beamOff1) event[beamOff1].daughter1( iRec);
1905 if (iRecMot1V == beamOff2) event[beamOff2].daughter1( iRec);
1908 // Global recoil: need to find relevant rotation+boost for recoilers:
1909 // boost+rotate to rest frame, boost along z axis, rotate+boost back.
1911 RotBstMatrix MG = M;
1913 double pzRecBef = -0.5 * sqrtpos( pow2(dipSel->m2Dip - dipSel->m2Rad
1914 - dipSel->m2Rec) - 4. * dipSel->m2Rad * dipSel->m2Rec ) / dipSel->mDip;
1915 double eRecBef = sqrt( pow2(pzRecBef) + dipSel->m2Rec);
1916 double pzRecAft = -pzRadPlusEmt;
1917 double eRecAft = sqrt( pow2(pzRecAft) + dipSel->m2Rec);
1918 MG.bst( Vec4(0., 0., pzRecBef, eRecBef), Vec4(0., 0., pzRecAft, eRecAft) );
1921 // Global recoil: copy particles, and rotate+boost momenta (not vertices).
1922 for (int iG = 0; iG < int(iGRecBef.size()); ++iG) {
1923 iRec = event.copy( iGRecBef[iG], 52);
1924 iGRec.push_back( iRec);
1925 Vec4 pGRec = event[iRec].p();
1927 event[iRec].p( pGRec);
1931 // Allow veto of branching. If so restore event record to before emission.
1932 bool inResonance = (partonSystemsPtr->getInA(iSysSel) == 0) ? true : false;
1933 if ( canVetoEmission && userHooksPtr->doVetoFSREmission( eventSizeOld,
1934 event, iSysSel, inResonance) ) {
1935 event.popBack( event.size() - eventSizeOld);
1936 event[iRadBef].status( iRadStatusV);
1937 event[iRadBef].daughters( iRadDau1V, iRadDau2V);
1938 if (useLocalRecoilNow && isrTypeNow == 0) {
1939 event[iRecBef].status( iRecStatusV);
1940 event[iRecBef].daughters( iRecDau1V, iRecDau2V);
1941 } else if (useLocalRecoilNow) {
1942 event[iRecBef].mothers( iRecMot1V, iRecMot2V);
1943 if (iRecMot1V == beamOff1) event[beamOff1].daughter1( ev1Dau1V);
1944 if (iRecMot1V == beamOff2) event[beamOff2].daughter1( ev2Dau1V);
1946 for (int iG = 0; iG < int(iGRecBef.size()); ++iG) {
1947 event[iGRecBef[iG]].statusPos();
1948 event[iGRecBef[iG]].daughters( 0, 0);
1954 // For global recoil restore the one nominal recoiler, for bookkeeping.
1955 if (!useLocalRecoilNow) {
1957 for (int iG = 0; iG < int(iGRecBef.size()); ++iG)
1958 if (iGRecBef[iG] == iRecBef) iRec = iGRec[iG];
1961 // For initial-state recoiler also update beam and sHat info.
1962 if (isrTypeNow != 0) {
1963 BeamParticle& beamRec = (isrTypeNow == 1) ? *beamAPtr : *beamBPtr;
1964 double xOld = beamRec[iSysSelRec].x();
1965 double xRec = 2. * pRec.e() / (beamAPtr->e() + beamBPtr->e());
1966 beamRec[iSysSelRec].iPos( iRec);
1967 beamRec[iSysSelRec].x( xRec);
1968 partonSystemsPtr->setSHat( iSysSelRec,
1969 partonSystemsPtr->getSHat(iSysSelRec) * xRec / xOld);
1972 // Photon emission: update to new dipole ends; add new photon "dipole".
1973 if (dipSel->flavour == 22) {
1974 dipSel->iRadiator = iRad;
1975 dipSel->iRecoiler = iRec;
1976 // When recoiler was uncharged particle, in resonance decays,
1977 // assign recoil to emitted photons.
1978 if (recoilToColoured && inResonance && event[iRec].chargeType() == 0)
1979 dipSel->iRecoiler = iEmt;
1980 dipSel->pTmax = pTsel;
1981 if (doQEDshowerByGamma) dipEnd.push_back( TimeDipoleEnd(iEmt, iRad,
1982 pTsel, 0, 0, 1, 0, iSysSel, 0));
1984 // Gluon emission: update both dipole ends and add two new ones.
1985 } else if (dipSel->flavour == 21) {
1986 dipSel->iRadiator = iRad;
1987 dipSel->iRecoiler = iEmt;
1988 dipSel->systemRec = iSysSel;
1989 dipSel->isrType = 0;
1990 dipSel->pTmax = pTsel;
1991 // Optionally also kill ME corrections after first emission.
1992 if (!doMEafterFirst) dipSel->MEtype = 0;
1993 // PS dec 2010: check normalization of radiating dipole
1994 // Dipole corresponding to the newly created color tag has normal strength
1995 double flexFactor = (isFlexible) ? dipSel->flexFactor : 1.0;
1996 dipSel->isFlexible = false;
1997 for (int i = 0; i < int(dipEnd.size()); ++i) {
1998 if (dipEnd[i].iRadiator == iRecBef && dipEnd[i].iRecoiler == iRadBef
1999 && dipEnd[i].colType != 0) {
2000 dipEnd[i].iRadiator = iRec;
2001 dipEnd[i].iRecoiler = iEmt;
2002 // Optionally also kill ME corrections after first emission.
2003 if (!doMEafterFirst) dipEnd[i].MEtype = 0;
2004 // Strive to match colour to anticolour inside closed system.
2005 if ( !isFlexible && dipEnd[i].colType * dipSel->colType > 0)
2006 dipEnd[i].iRecoiler = iRad;
2007 dipEnd[i].pTmax = pTsel;
2008 // PS dec 2010: if the (iRadBef,iRecBef) dipole was flexible, the
2009 // same should be true for this (opposite) end. If so, this end keeps
2010 // the modified normalization, so we shouldn't need to do anything.
2013 int colType = (dipSel->colType > 0) ? 2 : -2 ;
2014 // When recoiler was uncoloured particle, in resonance decays,
2015 // assign recoil to coloured particle.
2017 if (recoilToColoured && inResonance && event[iRec].col() == 0
2018 && event[iRec].acol() == 0) iRecMod = iRad;
2019 dipEnd.push_back( TimeDipoleEnd(iEmt, iRecMod, pTsel,
2020 colType, 0, 0, isrTypeSave, iSysSel, 0));
2021 dipEnd.back().systemRec = iSysSelRec;
2022 // PS dec 2010: the (iEmt,iRec) dipole "inherits" flexible normalization
2024 dipEnd.back().isFlexible = true;
2025 dipEnd.back().flexFactor = flexFactor;
2027 dipEnd.push_back( TimeDipoleEnd(iEmt, iRad, pTsel,
2028 -colType, 0, 0, 0, iSysSel, 0));
2030 // Gluon branching to q qbar: update current dipole and other of gluon.
2031 } else if (dipSel->colType != 0) {
2032 for (int i = 0; i < int(dipEnd.size()); ++i) {
2033 // Strive to match colour to anticolour inside closed system.
2034 if ( !isFlexible && dipEnd[i].iRecoiler == iRadBef
2035 && dipEnd[i].colType * dipSel->colType < 0 )
2036 dipEnd[i].iRecoiler = iEmt;
2037 if (dipEnd[i].iRadiator == iRadBef && abs(dipEnd[i].colType) == 2) {
2038 dipEnd[i].colType /= 2;
2039 if (dipEnd[i].system != dipEnd[i].systemRec) continue;
2041 // Note: gluino -> quark + squark gives a deeper radiation dip than
2042 // the more obvious alternative photon decay, so is more realistic.
2043 dipEnd[i].MEtype = 66;
2044 if (&dipEnd[i] == dipSel) dipEnd[i].iMEpartner = iRad;
2045 else dipEnd[i].iMEpartner = iEmt;
2048 dipSel->iRadiator = iEmt;
2049 dipSel->iRecoiler = iRec;
2050 dipSel->pTmax = pTsel;
2052 // Gluon branching to q qbar: also add two charge dipole ends.
2053 // Note: gluino -> quark + squark gives a deeper radiation dip than
2054 // the more obvious alternative photon decay, so is more realistic.
2055 if (doQEDshowerByQ) {
2056 int chgType = event[iRad].chargeType();
2057 dipEnd.push_back( TimeDipoleEnd(iRad, iEmt, pTsel,
2058 0, chgType, 0, 0, iSysSel, 66, iEmt));
2059 dipEnd.push_back( TimeDipoleEnd(iEmt, iRad, pTsel,
2060 0, -chgType, 0, 0, iSysSel, 66, iRad));
2063 // Photon branching to f fbar: inactivate photon "dipole";
2064 // optionally add new charge and colour dipole ends.
2065 } else if (dipSel->gamType != 0) {
2066 dipSel->gamType = 0;
2067 int chgType = event[iRad].chargeType();
2068 int colType = event[iRad].colType();
2069 // MEtype = 102 for charge in vector decay.
2070 if ( chgType != 0 && ( ( doQEDshowerByQ && colType != 0 )
2071 || ( doQEDshowerByL && colType == 0 ) ) ) {
2072 dipEnd.push_back( TimeDipoleEnd(iRad, iEmt, pTsel,
2073 0, chgType, 0, 0, iSysSel, 102, iEmt));
2074 dipEnd.push_back( TimeDipoleEnd(iEmt, iRad, pTsel,
2075 0, -chgType, 0, 0, iSysSel, 102, iRad));
2077 // MEtype = 11 for colour in vector decay.
2078 if (colType != 0 && doQCDshower) {
2079 dipEnd.push_back( TimeDipoleEnd(iRad, iEmt, pTsel,
2080 colType, 0, 0, 0, iSysSel, 11, iEmt));
2081 dipEnd.push_back( TimeDipoleEnd(iEmt, iRad, pTsel,
2082 -colType, 0, 0, 0, iSysSel, 11, iRad));
2085 // Photon_HV emission: update to new dipole ends.
2086 } else if (dipSel->flavour == 4900022) {
2087 dipSel->iRadiator = iRad;
2088 dipSel->iRecoiler = iRec;
2089 dipSel->pTmax = pTsel;
2091 // Gluon_HV emission: update to new dipole ends.
2092 } else if (dipSel->flavour == 4900021) {
2093 dipSel->iRadiator = iRad;
2094 dipSel->iRecoiler = iEmt;
2095 dipSel->pTmax = pTsel;
2096 for (int i = 0; i < int(dipEnd.size()); ++i)
2097 if (dipEnd[i].iRadiator == iRecBef && dipEnd[i].iRecoiler == iRadBef
2098 && dipEnd[i].isHiddenValley) {
2099 dipEnd[i].iRadiator = iRec;
2100 dipEnd[i].iRecoiler = iEmt;
2101 dipEnd[i].pTmax = pTsel;
2103 int colvType = (dipSel->colvType > 0) ? 2 : -2 ;
2104 dipEnd.push_back( TimeDipoleEnd(iEmt, iRec, pTsel,
2105 0, 0, 0, isrTypeSave, iSysSel, 0, -1, false, true, colvType) );
2106 dipEnd.back().systemRec = iSysSelRec;
2107 dipEnd.push_back( TimeDipoleEnd(iEmt, iRad, pTsel,
2108 0, 0, 0, 0, iSysSel, 0, -1, false, true, -colvType) );
2111 // Copy or set lifetime for new final state.
2112 if (event[iRad].id() == event[iRadBef].id()) {
2113 event[iRad].tau( event[iRadBef].tau() );
2115 event[iRad].tau( event[iRad].tau0() * rndmPtr->exp() );
2116 event[iEmt].tau( event[iEmt].tau0() * rndmPtr->exp() );
2118 event[iRec].tau( event[iRecBef].tau() );
2120 // Now update other dipoles that also involved the radiator or recoiler.
2121 for (int i = 0; i < int(dipEnd.size()); ++i) {
2122 // PS dec 2010: if radiator was flexible and now is normal, there may
2123 // be other flexible dipoles that need updating.
2124 if (isFlexible && !dipSel->isFlexible && dipEnd[i].isFlexible) {
2125 if (dipEnd[i].iRecoiler == iRadBef) dipEnd[i].iRecoiler = iEmt;
2126 if (dipEnd[i].iRadiator == iRadBef) {
2127 dipEnd[i].iRadiator = iEmt;
2128 if (dipEnd[i].colType == 1 && dipSel->flavour == 21)
2129 dipEnd[i].colType = 2;
2130 if (dipEnd[i].colType ==-1 && dipSel->flavour == 21)
2131 dipEnd[i].colType =-2;
2134 if (dipEnd[i].iRadiator == iRadBef) dipEnd[i].iRadiator = iRad;
2135 if (dipEnd[i].iRecoiler == iRadBef) dipEnd[i].iRecoiler = iRad;
2136 if (dipEnd[i].iMEpartner == iRadBef) dipEnd[i].iMEpartner = iRad;
2137 if (useLocalRecoilNow) {
2138 if (dipEnd[i].iRadiator == iRecBef) dipEnd[i].iRadiator = iRec;
2139 if (dipEnd[i].iRecoiler == iRecBef) dipEnd[i].iRecoiler = iRec;
2140 if (dipEnd[i].iMEpartner == iRecBef) dipEnd[i].iMEpartner = iRec;
2142 for (int iG = 0; iG < int(iGRecBef.size()); ++iG) {
2143 if (dipEnd[i].iRadiator == iGRecBef[iG])
2144 dipEnd[i].iRadiator = iGRec[iG];
2145 if (dipEnd[i].iRecoiler == iGRecBef[iG])
2146 dipEnd[i].iRecoiler = iGRec[iG];
2147 if (dipEnd[i].iMEpartner == iGRecBef[iG])
2148 dipEnd[i].iMEpartner = iGRec[iG];
2154 // Update any junctions downstream of this branching (if necessary)
2155 // (This happens, e.g., via LHEF, when adding showers to intermediate
2156 // coloured resonances whose decays involved junctions)
2157 for (int iJun = 0; iJun < event.sizeJunction(); iJun++) {
2158 // Number of incoming colour lines for this junction.
2159 int nIncoming = (event.kindJunction(iJun)-1)/2;
2160 // Check radiator colour or anticolour, depending on junction kind
2161 // (if junction, incoming = anticolours, and vice versa)
2163 colChk = ( event.kindJunction(iJun) % 2 == 0 )
2164 ? event[iRadBef].col() : event[iRadBef].acol();
2165 // Loop over incoming junction ends
2166 for (int iCol = 0; iCol < nIncoming; iCol++) {
2167 int colJun = event.colJunction( iJun, iCol);
2168 // If match, update junction end with new upstream (anti)colour
2169 if (colJun == colChk) {
2171 if ( event.kindJunction(iJun) % 2 == 0 ) colNew = colRad;
2172 else colNew = acolRad;
2173 event.colJunction( iJun, iCol, colNew );
2178 // Finally update the list of all partons in all systems.
2179 partonSystemsPtr->replace(iSysSel, iRadBef, iRad);
2180 partonSystemsPtr->addOut(iSysSel, iEmt);
2181 if (useLocalRecoilNow)
2182 partonSystemsPtr->replace(iSysSelRec, iRecBef, iRec);
2184 for (int iG = 0; iG < int(iGRecBef.size()); ++iG)
2185 partonSystemsPtr->replace(iSysSel, iGRecBef[iG], iGRec[iG]);
2193 //--------------------------------------------------------------------------
2195 // Rescatter: If a dipole stretches between two different systems, those
2196 // systems will no longer locally conserve momentum. These
2197 // imbalances become problematic when ISR or primordial kT
2198 // is switched on as these steps involve Lorentz boosts.
2200 // 'rescatterPropagateRecoil' tries to fix momentum in all
2201 // systems by propogating recoil momentum through all
2202 // intermediate systems. As the momentum transfer is already
2203 // defined, this can lead to internal lines gaining a
2206 // Useful definitions for a pair of integers and a vector of pairs
2207 typedef pair < int, int > pairInt;
2208 typedef vector < pairInt > vectorPairInt;
2210 //--------------------------------------------------------------------------
2212 // findParentSystems
2213 // Utility routine to find all parent systems of a given system
2214 // Returns a vector of pairs of integers with:
2215 // a) The system index, including the starting system (negative
2216 // if (b) points to a parent system, positive if (b) points
2217 // to a daughter system
2218 // b) The event record index that is the path out of the system
2219 // (if forwards == false, this is an incoming parton to the
2220 // system, and is +ve if side A or -ve if side B,
2221 // if forwards == true, this is an outgoing parton from the
2223 // Returns as empty vector on failure
2224 // Note: this assumes single rescattering only and therefore only
2225 // one possible parent system
2227 inline vectorPairInt findParentSystems(const int sys,
2228 Event& event, PartonSystems* partonSystemsPtr, bool forwards) {
2230 vectorPairInt parentSystems;
2231 parentSystems.reserve(10);
2235 // Get two incoming partons
2236 int iInA = partonSystemsPtr->getInA(iSysCur);
2237 int iInB = partonSystemsPtr->getInB(iSysCur);
2239 // Check if either of these links to another system
2241 if (event[iInA].isRescatteredIncoming()) iIn = iInA;
2242 if (event[iInB].isRescatteredIncoming()) iIn = -iInB;
2244 // Save the current system to the vector
2245 parentSystems.push_back( pairInt(-iSysCur, iIn) );
2246 if (iIn == 0) break;
2248 int iInAbs = abs(iIn);
2249 int iMother = event[iInAbs].mother1();
2250 iSysCur = partonSystemsPtr->getSystemOf(iMother);
2251 if (iSysCur == -1) {
2252 parentSystems.clear();
2257 // If forwards is set, change all event record indices to go to daughter
2258 // systems rather than parent systems
2260 vectorPairInt::reverse_iterator rit;
2261 for (rit = parentSystems.rbegin(); rit < (parentSystems.rend() - 1);
2263 pairInt &cur = *rit;
2264 pairInt &next = *(rit + 1);
2265 cur.first = -cur.first;
2266 cur.second = (next.second < 0) ? -event[abs(next.second)].mother1() :
2267 event[abs(next.second)].mother1();
2271 return parentSystems;
2274 //--------------------------------------------------------------------------
2276 // rescatterPropagateRecoil
2277 // Fix up momentum in all intermediate systems when radiator and recoiler
2278 // systems are different. The strategy is to look at all parent systems
2279 // from the radiator system and the recoiler system and find where they
2282 bool TimeShower::rescatterPropagateRecoil( Event& event, Vec4& pNew) {
2284 // Some useful variables for later
2285 int iRadBef = dipSel->iRadiator;
2286 iSysSel = dipSel->system;
2287 int iSysSelRec = dipSel->systemRec;
2288 Vec4 pImbal = pNew - event[iRadBef].p();
2290 // Store changes locally at first in case we veto the branching
2291 // eventMod stores index into the event record and new 4-vector
2292 vector < pair < int, Vec4 > > eventMod;
2293 eventMod.reserve(10);
2294 // systemMod stores system index (iSys) and system-parton index (iMem)
2295 // iMem >= 0 - index into outgoing partons (iOut)
2296 // iMem == -1 - incoming A
2297 // iMem == -2 - incoming B
2298 vectorPairInt systemMod;
2299 systemMod.reserve(10);
2301 // Find all parent systems from radiating and recoiling systems
2302 vectorPairInt radParent = findParentSystems(iSysSel, event,
2303 partonSystemsPtr, false);
2304 vectorPairInt recParent = findParentSystems(iSysSelRec, event,
2305 partonSystemsPtr, true);
2306 if (radParent.size() == 0 || recParent.size() == 0) {
2307 // This should never happen
2308 infoPtr->errorMsg("Error in TimeShower::rescatterPropagateRecoil: "
2309 "couldn't find parent system; branching vetoed");
2312 // Find the system that connects radiating and recoiling system
2313 bool foundPath = false;
2314 unsigned int iRadP = 0;
2315 unsigned int iRecP = 0;
2316 for (iRadP = 0; iRadP < radParent.size(); iRadP++) {
2317 for (iRecP = 0; iRecP < recParent.size(); iRecP++)
2318 if (abs(radParent[iRadP].first) == abs(recParent[iRecP].first)) {
2322 if (foundPath) break;
2325 // Can fail e.g. for QED dipoles where there is no connection
2326 // between radiator and recoiler systems
2327 infoPtr->errorMsg("Warning in TimeShower::rescatterPropagateRecoil: "
2328 "couldn't find recoil path; branching vetoed");
2332 // Join together to form complete path from radiating system
2333 // to recoiling system
2335 if (radParent.size() > 1)
2336 path.assign(radParent.begin(), radParent.begin() + iRadP);
2337 if (recParent.size() > 1)
2338 path.insert(path.end(), recParent.rend() - iRecP - 1,
2339 recParent.rend() - 1);
2341 // Follow the path fixing up momenta as we go
2342 for (unsigned int i = 0; i < path.size(); i++) {
2343 // Line out of the current system
2344 bool isIncoming = (path[i].first < 0) ? true : false;
2345 int iSysCur = abs(path[i].first);
2346 bool isIncomingA = (path[i].second > 0) ? true : false;
2347 int iLink = abs(path[i].second);
2350 if (isIncoming) iMemCur = (isIncomingA) ? -1 : -2;
2353 for (int j = 0; j < partonSystemsPtr->sizeOut(iSysCur); j++)
2354 if (partonSystemsPtr->getOut(iSysCur, j) == iLink) {
2358 if (iMemCur == -1) {
2359 // This should never happen
2360 infoPtr->errorMsg("Error in TimeShower::rescatterPropagateRecoil: "
2361 "couldn't find parton system; branching vetoed");
2366 Vec4 pMod = (isIncoming) ? event[iLink].p() + pImbal :
2367 event[iLink].p() - pImbal;
2368 eventMod.push_back(pair <int, Vec4> (iLink, pMod));
2369 systemMod.push_back(pairInt(iSysCur, iMemCur));
2371 // Calculate sHat of iSysCur
2372 int iInCurA = partonSystemsPtr->getInA(iSysCur);
2373 int iInCurB = partonSystemsPtr->getInB(iSysCur);
2374 Vec4 pTotCur = event[iInCurA].p() + event[iInCurB].p();
2376 // If iMemCur is -1 or -2, then we must have changed the sHat of iSysCur
2377 if (iMemCur < 0) pTotCur += (isIncoming) ? pImbal : -pImbal;
2378 double sHatCur = pTotCur.m2Calc();
2380 // The fixed-up incoming and outgoing partons should not have
2381 // too large a virtuality in relation to the system mass-square.
2382 if (abs(pMod.m2Calc()) > MAXVIRTUALITYFRACTION * sHatCur) {
2383 infoPtr->errorMsg("Warning in TimeShower::rescatterPropagateRecoil: "
2384 "virtuality much larger than sHat; branching vetoed");
2388 // Outgoing ones should also not have too large negative energy
2389 // in the rest frame of the system.
2390 if (!isIncoming && pMod * pTotCur < -MAXNEGENERGYFRACTION * sHatCur) {
2391 infoPtr->errorMsg("Warning in TimeShower::rescatterPropagateRecoil: "
2392 "rest frame energy too negative; branching vetoed");
2396 // Veto negative sHat.
2397 if (sHatCur < 0.0) {
2398 infoPtr->errorMsg("Warning in TimeShower::rescatterPropagateRecoil: "
2399 "sHat became negative; branching vetoed");
2403 // Line into the new current system
2404 iLink = (isIncoming) ? event[iLink].mother1() :
2405 event[iLink].daughter1();
2406 iSysCur = partonSystemsPtr->getSystemOf(iLink, true);
2408 if (!isIncoming) iMemCur = (isIncomingA) ? -1 : -2;
2411 for (int j = 0; j < partonSystemsPtr->sizeOut(iSysCur); j++)
2412 if (partonSystemsPtr->getOut(iSysCur, j) == iLink) {
2416 if (iMemCur == -1) {
2417 // This should never happen
2418 infoPtr->errorMsg("Error in TimeShower::rescatterPropagateRecoil: "
2419 "couldn't find parton system; branching vetoed");
2424 pMod = (isIncoming) ? event[iLink].p() + pImbal :
2425 event[iLink].p() - pImbal;
2426 eventMod.push_back(pair <int, Vec4> (iLink, pMod));
2427 systemMod.push_back(pairInt(iSysCur, iMemCur));
2429 // Calculate sHat of iSysCur
2430 iInCurA = partonSystemsPtr->getInA(iSysCur);
2431 iInCurB = partonSystemsPtr->getInB(iSysCur);
2432 pTotCur = event[iInCurA].p() + event[iInCurB].p();
2434 // If iMemCur is -1 or -2, then we must have changed the sHat of iSysCur
2435 if (iMemCur < 0) pTotCur += (isIncoming) ? pImbal : -pImbal;
2436 sHatCur = pTotCur.m2Calc();
2438 // The fixed-up incoming and outgoing partons should not have
2439 // too large a virtuality in relation to the system mass-square.
2440 if (abs(pMod.m2Calc()) > MAXVIRTUALITYFRACTION * sHatCur) {
2441 infoPtr->errorMsg("Warning in TimeShower::rescatterPropagateRecoil: "
2442 "virtuality much larger than sHat; branching vetoed");
2446 // Outgoing ones should also not have too large negative energy
2447 // in the rest frame of the system.
2448 if (!isIncoming && pMod * pTotCur < -MAXNEGENERGYFRACTION * sHatCur) {
2449 infoPtr->errorMsg("Warning in TimeShower::rescatterPropagateRecoil: "
2450 "rest frame energy too negative; branching vetoed");
2454 // Veto negative sHat
2455 if (sHatCur < 0.0) {
2456 infoPtr->errorMsg("Warning in TimeShower::rescatterPropagateRecoil: "
2457 "sHat became negative; branching vetoed");
2461 // Do negative energy veto
2462 if (VETONEGENERGY && pMod.e() < 0.0) {
2463 infoPtr->errorMsg("Warning in TimeShower::rescatterPropagateRecoil: "
2464 "energy became negative; branching vetoed");
2468 } // for (unsigned int i = 0; i < path.size(); i++)
2470 // If no vetos by this point, apply the changes to the event record
2471 // An incoming particle with changed momentum is given status code -54,
2472 // an outgoing particle with changed momentum is given status code -55
2473 for (unsigned int i = 0; i < eventMod.size(); i++) {
2474 int idx = eventMod[i].first;
2475 Vec4 &pMod = eventMod[i].second;
2476 int iSys = systemMod[i].first;
2477 int iMem = systemMod[i].second;
2479 // If incoming to a process then set the copy to be the mother
2480 if (event[idx].isRescatteredIncoming()) {
2481 int mother1 = event[idx].mother1();
2482 idx = event.copy(idx, -54);
2483 event[mother1].daughters(idx, idx);
2485 // Update beam information if necessary
2486 double eCM = sqrt(m2( beamAPtr->p(), beamBPtr->p()));
2488 partonSystemsPtr->setInA(iSys, idx);
2489 (*beamAPtr)[iSys].x((pMod.e() + pMod.pz()) / eCM);
2490 (*beamAPtr)[iSys].m(pMod.mCalc());
2491 (*beamAPtr)[iSys].p(pMod);
2492 (*beamAPtr)[iSys].iPos(idx);
2493 } else if (iMem == -2) {
2494 partonSystemsPtr->setInB(iSys, idx);
2495 (*beamBPtr)[iSys].x((pMod.e() - pMod.pz()) / eCM);
2496 (*beamBPtr)[iSys].m(pMod.mCalc());
2497 (*beamBPtr)[iSys].p(pMod);
2498 (*beamBPtr)[iSys].iPos(idx);
2500 // This should never happen
2501 infoPtr->errorMsg("Error in TimeShower::rescatterPropagateRecoil: "
2502 "internal bookeeping error");
2505 // Otherwise set the new event record entry to be the daughter
2507 int daughter1 = event[idx].daughter1();
2508 idx = event.copy(idx, 55);
2509 event[idx].statusNeg();
2510 event[daughter1].mothers(idx, idx);
2512 partonSystemsPtr->setOut(iSys, iMem, idx);
2515 event[idx].p( eventMod[i].second );
2516 event[idx].m( event[idx].mCalc() );
2523 //--------------------------------------------------------------------------
2525 // Find class of QCD ME correction.
2526 // MEtype classification follow codes in Norrbin article,
2527 // additionally -1 = try to find type, 0 = no ME corrections.
2528 // Warning: not yet tried out to do a correct assignment in
2529 // arbitrary multiparton configurations! ??
2531 void TimeShower::findMEtype( Event& event, TimeDipoleEnd& dip) {
2533 // Initial value. Mark if no ME corrections to be applied.
2535 if (!doMEcorrections) setME = false;
2536 int iMother = event[dip.iRadiator].mother1();
2537 int iMother2 = event[dip.iRadiator].mother2();
2539 // Allow ME corrections for Hidden Valley pair in 2 -> 2.
2540 if (dip.isHiddenValley && event[dip.iRecoiler].id()
2541 == -event[dip.iRadiator].id());
2543 // Else no ME corrections in 2 -> n processes.
2545 if (iMother2 != iMother && iMother2 != 0) setME = false;
2546 if (event[dip.iRecoiler].mother1() != iMother) setME = false;
2547 if (event[dip.iRecoiler].mother2() != iMother2) setME = false;
2550 // No ME corrections for recoiler in initial state.
2551 if (event[dip.iRecoiler].status() < 0) setME = false;
2553 // No ME corrections for recoiler not in same system
2554 if (dip.system != dip.systemRec) setME = false;
2556 // Done if no ME to be set.
2562 // If no ME partner set, assume it is the recoiler.
2563 if (dip.iMEpartner < 0) dip.iMEpartner = dip.iRecoiler;
2565 // Now begin processing of colour dipole, including Hidden Valley.
2566 if (dip.colType != 0 || dip.colvType != 0) {
2567 bool isHiddenColour = (dip.colvType != 0);
2569 // Find daughter types (may or may not be used later on).
2570 int idDau1 = event[dip.iRadiator].id();
2571 int idDau2 = event[dip.iMEpartner].id();
2572 int dau1Type = findMEparticle(idDau1, isHiddenColour);
2573 int dau2Type = findMEparticle(idDau2, isHiddenColour);
2574 int minDauType = min(dau1Type, dau2Type);
2575 int maxDauType = max(dau1Type, dau2Type);
2577 // Reorder dipole ends in kinematics. Split ME expression in two sides.
2578 dip.MEorder = (dau2Type >= dau1Type);
2579 dip.MEsplit = (maxDauType <= 6);
2580 dip.MEgluinoRec = false;
2582 // If type already set (or set not to have) then done.
2583 if (minDauType == 0 && dip.MEtype < 0) dip.MEtype = 0;
2584 if (dip.MEtype >= 0) return;
2587 // For H -> gg -> ggg we found that DGLAP kernels do better than eikonal.
2588 if (dau1Type == 4 && dau2Type == 4) return;
2590 // Find mother type.
2592 if ( event[dip.iRecoiler].mother1() == iMother && iMother >= 0)
2593 idMother = event[iMother].id();
2594 int motherType = (idMother != 0)
2595 ? findMEparticle(idMother, isHiddenColour) : 0;
2597 // When a mother if not known then use colour and spin content to guess.
2598 if (motherType == 0) {
2599 int col1 = event[dip.iRadiator].col();
2600 int acol1 = event[dip.iRadiator].acol();
2601 int col2 = event[dip.iMEpartner].col();
2602 int acol2 = event[dip.iMEpartner].acol();
2603 // spinT = 0/1 = integer or half-integer.
2604 int spinT = ( event[dip.iRadiator].spinType()
2605 + event[dip.iMEpartner].spinType() )%2;
2606 // Colour singlet mother.
2607 if ( col1 == acol2 && acol1 == col2 )
2608 motherType = (spinT == 0) ? 7 : 9;
2609 // Colour octet mother.
2610 else if ( (col1 == acol2 && acol1 != 0 && col2 != 0)
2611 || (acol1 == col2 && col1 != 0 && acol2 != 0) )
2612 motherType = (spinT == 0) ? 4 : 5;
2613 // Colour triplet mother.
2614 else if ( (col1 == acol2 && acol1 != col2)
2615 || (acol1 == col2 && col1 != acol2) )
2616 motherType = (spinT == 0) ? 2 : 1;
2617 // If no colours are matched then cannot have common mother, so done.
2621 // Now start from default, which is eikonal ME corrections,
2622 // and try to find matching ME cases below.
2627 // Hidden Valley with massive gamma_v covered by two special cases.
2628 if (isHiddenColour && brokenHVsym) {
2629 MEkind = (dau2Type == 0 || dau2Type > 6) ? 30 : 31;
2630 dip.MEtype = 5 * MEkind + 1;
2634 // Triplet recoiling against gluino needs enhanced radiation
2635 // to match to matrix elements.
2636 dip.MEgluinoRec = (dau1Type >= 1 && dau1Type <= 3 && dau2Type == 5);
2638 // Vector/axial vector -> q + qbar.
2639 if (minDauType == 1 && maxDauType == 1 &&
2640 (motherType == 4 || motherType == 7) ) {
2642 if (idMother == 21 || idMother == 22) MEcombi = 1;
2643 else if (idMother == 23 || idDau1 + idDau2 == 0) {
2645 dip.MEmix = gammaZmix( event, iMother, dip.iRadiator, dip.iRecoiler );
2647 else if (idMother == 24) MEcombi = 4;
2649 // For chi -> chi q qbar, use V/A -> q qbar as first approximation.
2650 else if (minDauType == 1 && maxDauType == 1 && motherType == 9)
2654 else if (minDauType == 1 && maxDauType == 7 && motherType == 1)
2656 if (idDau1 == 22 || idDau2 == 22) MEcombi = 1;
2658 // Scalar/pseudoscalar -> q + qbar; q -> q + S.
2659 else if (minDauType == 1 && maxDauType == 1 && motherType == 8) {
2661 if (idMother == 25 || idMother == 35 || idMother == 37) MEcombi = 1;
2662 else if (idMother == 36) MEcombi = 2;
2664 else if (minDauType == 1 && maxDauType == 8 && motherType == 1)
2667 // V -> ~q + ~qbar; ~q -> ~q + V; S -> ~q + ~qbar; ~q -> ~q + S.
2668 else if (minDauType == 2 && maxDauType == 2 && (motherType == 4
2669 || motherType == 7) ) MEkind = 6;
2670 else if (minDauType == 2 && (maxDauType == 4 || maxDauType == 7)
2671 && motherType == 2) MEkind = 7;
2672 else if (minDauType == 2 && maxDauType == 2 && motherType == 8)
2674 else if (minDauType == 2 && maxDauType == 8 && motherType == 2)
2677 // chi -> q + ~qbar; ~q -> q + chi; q -> ~q + chi.
2678 else if (minDauType == 1 && maxDauType == 2 && motherType == 9)
2680 else if (minDauType == 1 && maxDauType == 9 && motherType == 2)
2682 else if (minDauType == 2 && maxDauType == 9 && motherType == 1)
2685 // ~g -> q + ~qbar; ~q -> q + ~g; q -> ~q + ~g.
2686 else if (minDauType == 1 && maxDauType == 2 && motherType == 5)
2688 else if (minDauType == 1 && maxDauType == 5 && motherType == 2)
2690 else if (minDauType == 2 && maxDauType == 5 && motherType == 1)
2693 // In cases where coloured spin 1 particle involved use spin 0.
2694 // V_coloured -> q + l.
2695 else if (minDauType == 1 && maxDauType == 9 && motherType == 3)
2697 // q -> V_coloured + l;
2698 else if (minDauType == 3 && maxDauType == 9 && motherType == 1)
2701 // g (+V, S) -> ~g + ~g (eikonal approximation).
2702 else if (minDauType == 5 && maxDauType == 5) MEkind = 16;
2704 // Save ME type and gamma_5 admixture.
2705 dip.MEtype = 5 * MEkind + MEcombi;
2707 // Now begin processing of charge dipole - still primitive.
2708 } else if (dip.chgType != 0) {
2710 // Set defaults for QED case; then possibly done.
2713 if (dip.MEtype >= 0) return;
2715 // So far only ME corrections for q qbar or l lbar.
2716 int idDau1 = event[dip.iRadiator].id();
2717 int idDau2 = event[dip.iMEpartner].id();
2718 if (abs(idDau1) < 9 && abs(idDau2) < 9 && idDau1 * idDau2 < 0) ;
2719 else if (abs(idDau1) > 10 && abs(idDau1) < 19 && abs(idDau2) > 10
2720 && abs(idDau2) < 19 && idDau1 * idDau2 < 0) ;
2721 else { dip.MEtype = 0; return; }
2723 // Distinguish charge sum != 0 or = 0; in latter assume vector source.
2725 if (idDau1 + idDau2 == 0) dip.MEtype = 102;
2731 //--------------------------------------------------------------------------
2733 // Find type of particle for ME type: 0 = unknown, 1 = quark, 2 = squark,
2734 // 3 = spare triplet, 4 = gluon, 5 = gluino, 6 = spare octet,
2735 // 7 = vector boson, 8 = colourless scalar, 9 = colourless spin 1/2.
2737 int TimeShower::findMEparticle( int id, bool isHiddenColour) {
2739 // find colour and spin of particle.
2741 int colType = abs(particleDataPtr->colType(id));
2742 int spinType = particleDataPtr->spinType(id);
2744 // For hidden valley particle treat HV colour as normal one.
2745 // Note: no need to assign gv/gammav since not in ME.
2746 if (isHiddenColour) {
2748 int idAbs = abs(id);
2749 if ( (idAbs > 4900000 && idAbs < 4900007)
2750 || (idAbs > 4900010 && idAbs < 4900017)
2751 || idAbs == 4900101) colType = 1;
2754 // Find particle type from colour and spin.
2755 if (colType == 1 && spinType == 2) type = 1;
2756 else if (colType == 1 && spinType == 1) type = 2;
2757 else if (colType == 1) type = 3;
2758 else if (colType == 2 && spinType == 3) type = 4;
2759 else if (colType == 2 && spinType == 2) type = 5;
2760 else if (colType == 2) type = 6;
2761 else if (colType == 0 && spinType == 3) type = 7;
2762 else if (colType == 0 && spinType == 1) type = 8;
2763 else if (colType == 0 && spinType == 2) type = 9;
2770 //--------------------------------------------------------------------------
2772 // Find mixture of V and A in gamma/Z: energy- and flavour-dependent.
2774 double TimeShower::gammaZmix( Event& event, int iRes, int iDau1, int iDau2) {
2776 // Try to identify initial flavours; use e+e- as default.
2779 int iIn1 = (iRes >= 0) ? event[iRes].mother1() : -1;
2780 int iIn2 = (iRes >= 0) ? event[iRes].mother2() : -1;
2781 if (iIn1 >=0) idIn1 = event[iIn1].id();
2782 if (iIn2 >=0) idIn2 = event[iIn1].id();
2784 // In processes f + g/gamma -> f + Z only need find one fermion.
2785 if (idIn1 == 21 || idIn1 == 22) idIn1 = -idIn2;
2786 if (idIn2 == 21 || idIn2 == 22) idIn2 = -idIn1;
2788 // Initial flavours and couplings; return if don't make sense.
2789 if (idIn1 + idIn2 != 0 ) return 0.5;
2790 int idInAbs = abs(idIn1);
2791 if (idInAbs == 0 || idInAbs > 18 ) return 0.5;
2792 double ei = coupSMPtr->ef(idInAbs);
2793 double vi = coupSMPtr->vf(idInAbs);
2794 double ai = coupSMPtr->af(idInAbs);
2796 // Final flavours and couplings; return if don't make sense.
2797 if (event[iDau1].id() + event[iDau2].id() != 0) return 0.5;
2798 int idOutAbs = abs(event[iDau1].id());
2799 if (idOutAbs == 0 || idOutAbs >18 ) return 0.5;
2800 double ef = coupSMPtr->ef(idOutAbs);
2801 double vf = coupSMPtr->vf(idOutAbs);
2802 double af = coupSMPtr->af(idOutAbs);
2804 // Calculate prefactors for interference and resonance part.
2805 Vec4 psum = event[iDau1].p() + event[iDau2].p();
2806 double sH = psum.m2Calc();
2807 double intNorm = 2. * thetaWRat * sH * (sH - mZ*mZ)
2808 / ( pow2(sH - mZ*mZ) + pow2(sH * gammaZ / mZ) );
2809 double resNorm = pow2(thetaWRat * sH)
2810 / ( pow2(sH - mZ*mZ) + pow2(sH * gammaZ / mZ) );
2812 // Calculate vector and axial expressions and find mix.
2813 double vect = ei*ei * ef*ef + ei*vi * intNorm * ef*vf
2814 + (vi*vi + ai*ai) * resNorm * vf*vf;
2815 double axiv = (vi*vi + ai*ai) * resNorm * af*af;
2816 return vect / (vect + axiv);
2819 //--------------------------------------------------------------------------
2821 // Set up to calculate QCD ME correction with calcMEcorr.
2822 // Normally for primary particles, but also from g/gamma -> f fbar.
2824 double TimeShower::findMEcorr(TimeDipoleEnd* dip, Particle& rad,
2825 Particle& partner, Particle& emt) {
2827 // Initial values and matrix element kind.
2830 int MEkind = dip->MEtype / 5;
2831 int MEcombi = dip->MEtype % 5;
2833 // Construct ME variables.
2834 Vec4 sum = rad.p() + partner.p() + emt.p();
2835 double eCMME = sum.mCalc();
2836 double x1 = 2. * (sum * rad.p()) / pow2(eCMME);
2837 double x2 = 2. * (sum * partner.p()) / pow2(eCMME);
2838 double r1 = rad.m() / eCMME;
2839 double r2 = partner.m() / eCMME;
2842 // Evaluate kinematics for Hidden Valley with massive gamma_v.
2843 double gammavCorr = 1.;
2844 if (dip->colvType != 0 && brokenHVsym) {
2845 r3 = emt.m() / eCMME;
2846 double x3Tmp = 2. - x1 - x2;
2847 gammavCorr = x3Tmp / (x3Tmp - kRad * (x1 + x3Tmp));
2848 // For Q_v Qbar_v pair correct kinematics to common average mass.
2850 double m2Pair = (rad.p() + partner.p()).m2Calc();
2851 double m2Avg = 0.5 * (rad.m2() + partner.m2())
2852 - 0.25 * pow2(rad.m2() - partner.m2()) / m2Pair;
2853 r1 = sqrt(m2Avg) / eCMME;
2855 double xShift = 0.5 * (x1 + x2) * (partner.m2() - rad.m2()) / m2Pair;
2861 // Derived ME variables, suitably protected.
2862 double x1minus = max(XMARGIN, 1. + r1*r1 - r2*r2 - x1);
2863 double x2minus = max(XMARGIN, 1. + r2*r2 - r1*r1 - x2) ;
2864 double x3 = max(XMARGIN, 2. - x1 - x2);
2866 // Begin processing of QCD dipoles.
2867 if (dip->colType !=0 || dip->colvType != 0) {
2869 // Evaluate normal ME, for proper order of particles.
2871 wtME = calcMEcorr(MEkind, MEcombi, dip->MEmix, x1, x2, r1, r2, r3);
2872 else wtME = calcMEcorr(MEkind, MEcombi, dip->MEmix, x2, x1, r2, r1, r3);
2874 // Split up total ME when two radiating particles.
2875 if (dip->MEsplit) wtME = wtME * x1minus / x3;
2877 // Evaluate shower rate to be compared with.
2878 wtPS = 2. / ( x3 * x2minus );
2879 if (dip->MEgluinoRec) wtPS *= 9./4.;
2880 if (dip->colvType != 0 && brokenHVsym) wtPS *= gammavCorr;
2882 // For generic charge combination currently only massless expression.
2883 // (Masses included only to respect phase space boundaries.)
2884 } else if (dip->chgType !=0 && dip->MEtype == 101) {
2885 double chg1 = particleDataPtr->charge(rad.id());
2886 double chg2 = particleDataPtr->charge(partner.id());
2887 wtME = (x1*x1 + x2*x2) * pow2( chg1 * x1minus / x3
2888 - chg2 * x2minus / x3 );
2889 wtPS = 2. * ( chg1*chg1 * x1minus / x3 + chg2*chg2 * x2minus / x3 );
2891 // For flavour neutral system assume vector source and include masses.
2892 } else if (dip->chgType !=0 && dip->MEtype == 102) {
2893 wtME = calcMEcorr(2, 1, dip->MEmix, x1, x2, r1, r2) * x1minus / x3;
2894 wtPS = 2. / ( x3 * x2minus );
2896 if (wtME > wtPS) infoPtr->errorMsg("Warning in TimeShower::findMEcorr: "
2897 "ME weight above PS one");
2899 // Return ratio of actual ME to assumed PS rate of emission.
2903 //--------------------------------------------------------------------------
2905 // Matrix elements for gluon (or photon) emission from
2906 // a two-body state; to be used by the parton shower routine.
2907 // Here x_i = 2 E_i/E_cm, r_i = m_i/E_cm and
2908 // 1/sigma_0 d(sigma)/d(x_1)d(x_2) = (alpha-strong/2 pi) * C_F * (this),
2909 // i.e. normalization is such that one recovers the familiar
2910 // (x_1^2 + x_2^2)/((1-x_1)*(1-x_2)) for the massless case.
2911 // Coupling structure:
2912 // kind = 1 : eikonal soft-gluon expression (spin-independent)
2913 // = 2 : V -> q qbar (V = vector/axial vector colour singlet)
2915 // = 4 : S -> q qbar (S = scalar/pseudoscalar colour singlet)
2917 // = 6 : V -> ~q ~qbar (~q = squark)
2919 // = 8 : S -> ~q ~qbar
2921 // = 10 : chi -> q ~qbar (chi = neutralino/chargino)
2922 // = 11 : ~q -> q chi
2923 // = 12 : q -> ~q chi
2924 // = 13 : ~g -> q ~qbar
2925 // = 14 : ~q -> q ~g
2926 // = 15 : q -> ~q ~g
2927 // = 16 : (9/4)*(eikonal) for gg -> ~g ~g
2928 // = 30 : Dv -> d qv (Dv= hidden valley fermion, qv= valley scalar)
2929 // = 31 : S -> Dv Dvbar (S=scalar color singlet)
2930 // Note that the order of the decay products is important.
2931 // combi = 1 : pure non-gamma5, i.e. vector/scalar/...
2932 // = 2 : pure gamma5, i.e. axial vector/pseudoscalar/....
2933 // = 3 : mixture mix*(combi=1) + (1-mix)*(combi=2)
2934 // = 4 : mixture (combi=1) +- (combi=2)
2936 double TimeShower::calcMEcorr( int kind, int combiIn, double mixIn,
2937 double x1, double x2, double r1, double r2, double r3) {
2939 // Frequent variable combinations.
2940 double x3 = 2. - x1 - x2;
2941 double x1s = x1 * x1;
2942 double x2s = x2 * x2;
2943 double x3s = x3 * x3;
2944 double x1c = x1 * x1s;
2945 double x2c = x2 * x2s;
2946 double x3c = x3 * x3s;
2947 double r1s = r1 * r1;
2948 double r2s = r2 * r2;
2949 double r1c = r1 * r1s;
2950 double r2c = r2 * r2s;
2951 double r1q = r1s * r1s;
2952 double r2q = r2s * r2s;
2953 double prop1 = 1. + r1s - r2s - x1;
2954 double prop2 = 1. + r2s - r1s - x2;
2955 double prop1s = prop1 * prop1;
2956 double prop2s = prop2 * prop2;
2957 double prop12 = prop1 * prop2;
2958 double prop13 = prop1 * x3;
2959 double prop23 = prop2 * x3;
2961 // Special case: Hidden-Valley massive photon.
2962 double r3s = r3 * r3;
2963 double prop3 = r3s - x3;
2964 double prop3s = prop3 * prop3;
2965 if (kind == 30) prop13 = prop1 * prop3;
2967 // Check input values. Return zero outside allowed phase space.
2968 if (x1 - 2.*r1 < XMARGIN || prop1 < XMARGIN) return 0.;
2969 if (x2 - 2.*r2 < XMARGIN || prop2 < XMARGIN) return 0.;
2970 // Limits not worked out for r3 > 0.
2971 if (kind != 30 && kind != 31) {
2972 if (x1 + x2 - 1. - pow2(r1+r2) < XMARGIN) return 0.;
2973 // Note: equivalent rewritten form 4. * ( (1. - x1) * (1. - x2)
2974 // * (1. - r1s - r2s - x3) + r1s * (1. - x2s - x3) + r2s
2975 // * (1. - x1s - x3) - pow2(r1s - r2s) ) gives about same result.
2976 if ( (x1s - 4.*r1s) * (x2s - 4.*r2s)
2977 - pow2( 2. * (1. - x1 - x2 + r1s + r2s) + x1*x2 )
2978 < XMARGIN * (XMARGINCOMB + r1 + r2) ) return 0.;
2981 // Initial values; phase space.
2982 int combi = max(1, min(4, combiIn) );
2983 double mix = max(0., min(1., mixIn) );
2984 bool isSet1 = false;
2985 bool isSet2 = false;
2986 bool isSet4 = false;
2987 double ps = sqrtpos( pow2(1. - r1*r1 - r2*r2) - pow2(2. * r1 * r2) );
2988 double rLO = 0., rFO = 0., rLO1 = 0., rFO1 = 0., rLO2 = 0.,
2989 rFO2 = 0., rLO4 = 0., rFO4 = 0.;
2992 // Select which kind of ME to use.
2995 // case 1 is equal to default, i.e. eikonal expression.
2997 // V -> q qbar (V = gamma*/Z0/W+-/...).
2999 if (combi == 1 || combi == 3) {
3000 rLO1 = ps*(2.-r1s-r1q+6.*r1*r2-r2s+2.*r1s*r2s-r2q)/2.;
3001 rFO1 = -(3.+6.*r1s+r1q-6.*r1*r2+6.*r1c*r2-2.*r2s-6.*r1s*r2s
3002 +6.*r1*r2c+r2q-3.*x1+6.*r1*r2*x1+2.*r2s*x1+x1s-2.*r1s*x1s
3003 +3.*r1s*x3+6.*r1*r2*x3-r2s*x3-2.*x1*x3-5.*r1s*x1*x3
3004 +r2s*x1*x3+x1s*x3-3.*x3s-3.*r1s*x3s+r2s*x3s
3007 -2.*(-3.+r1s-6.*r1*r2+6.*r1c*r2+3.*r2s-4.*r1s*r2s
3008 +6.*r1*r2c+2.*x1+3.*r1s*x1+r2s*x1-x1s-r1s*x1s
3009 -r2s*x1s+4.*x3+2.*r1s*x3+3.*r1*r2*x3-r2s*x3-3.*x1*x3
3010 -2.*r1s*x1*x3+x1s*x3-x3s-r1s*x3s+r1*r2*x3s+x1*x3s)
3012 -(-1.+2.*r1s+r1q+6.*r1*r2+6.*r1c*r2-2.*r2s-6.*r1s*r2s
3013 +6.*r1*r2c+r2q-x1-2.*r1s*x1-6.*r1*r2*x1+8.*r2s*x1+x1s
3014 -2.*r2s*x1s-r1s*x3+r2s*x3-r1s*x1*x3+r2s*x1*x3+x1s*x3+x2)
3019 if (combi == 2 || combi == 3) {
3020 rLO2 = ps*(2.-r1s-r1q-6.*r1*r2-r2s+2.*r1s*r2s-r2q)/2.;
3021 rFO2 = -(3.+6.*r1s+r1q+6.*r1*r2-6.*r1c*r2-2.*r2s-6.*r1s*r2s
3022 -6.*r1*r2c+r2q-3.*x1-6.*r1*r2*x1+2.*r2s*x1+x1s-2.*r1s*x1s
3023 +3.*r1s*x3-6.*r1*r2*x3-r2s*x3-2.*x1*x3-5.*r1s*x1*x3
3024 +r2s*x1*x3+x1s*x3-3.*x3s-3.*r1s*x3s+r2s*x3s+2.*x1*x3s+x3c-x2)
3026 -2.*(-3+r1s+6.*r1*r2-6.*r1c*r2+3.*r2s-4.*r1s*r2s-6.*r1*r2c
3027 +2.*x1+3.*r1s*x1+r2s*x1-x1s-r1s*x1s-r2s*x1s+4.*x3+2.*r1s*x3
3028 -3.*r1*r2*x3-r2s*x3-3.*x1*x3-2.*r1s*x1*x3+x1s*x3-x3s-r1s*x3s
3031 -(-1.+2.*r1s+r1q-6.*r1*r2-6.*r1c*r2-2.*r2s-6.*r1s*r2s
3032 -6.*r1*r2c+r2q-x1-2.*r1s*x1+6.*r1*r2*x1+8.*r2s*x1+x1s
3033 -2.*r2s*x1s-r1s*x3+r2s*x3-r1s*x1*x3+r2s*x1*x3+x1s*x3+x2)
3039 rLO4 = ps*(2.-r1s-r1q-r2s+2.*r1s*r2s-r2q)/2.;
3040 rFO4 = (1.-r1q+6.*r1s*r2s-r2q+x1+3.*r1s*x1-9.*r2s*x1-3.*x1s
3041 -r1s*x1s+3.*r2s*x1s+x1c-x2-r1s*x2+r2s*x2-r1s*x1*x2+r2s*x1*x2
3044 -2.*(1.+r1s+r2s-4.*r1s*r2s+r1s*x1+2.*r2s*x1-x1s-r2s*x1s
3045 +2.*r1s*x2+r2s*x2-3.*x1*x2+x1s*x2-x2s-r1s*x2s+x1*x2s)
3047 +(1.-r1q+6.*r1s*r2s-r2q-x1+r1s*x1-r2s*x1+x2-9.*r1s*x2
3048 +3.*r2s*x2+r1s*x1*x2-r2s*x1*x2-3.*x2s+3.*r1s*x2s-r2s*x2s
3058 if (combi == 1 || combi == 3) {
3059 rLO1 = ps*(1.-2.*r1s+r1q+r2s-6.*r1*r2s+r1s*r2s-2.*r2q);
3060 rFO1 = -2.*(-1.+r1-2.*r1s+2.*r1c-r1q+pow5(r1)-r2s+r1*r2s
3061 -5.*r1s*r2s+r1c*r2s-2.*r1*r2q+2.*x1-2.*r1*x1+2.*r1s*x1
3062 -2.*r1c*x1+2.*r2s*x1+5.*r1*r2s*x1+r1s*r2s*x1+2.*r2q*x1
3063 -x1s+r1*x1s-r2s*x1s+3.*x2+4.*r1s*x2+r1q*x2+2.*r2s*x2
3064 +2.*r1s*r2s*x2-4.*x1*x2-2.*r1s*x1*x2-r2s*x1*x2+x1s*x2
3065 -2.*x2s-2.*r1s*x2s+x1*x2s)
3067 +(2.*r2s+6.*r1*r2s-6.*r1s*r2s+6.*r1c*r2s+2.*r2q+6.*r1*r2q
3068 -r2s*x1+r1s*r2s*x1-r2q*x1+x2-r1q*x2-3.*r2s*x2-6.*r1*r2s*x2
3069 +9.*r1s*r2s*x2-2.*r2q*x2-x1*x2+r1s*x1*x2-x2s-3.*r1s*x2s
3072 +(-4.-8.*r1s-4.*r1q+4.*r2s-4.*r1s*r2s+8.*r2q+9.*x1+10.*r1s*x1
3073 +r1q*x1-3.*r2s*x1+6.*r1*r2s*x1+r1s*r2s*x1-2.*r2q*x1-6.*x1s-
3074 2.*r1s*x1s+x1c+7.*x2+8.*r1s*x2+r1q*x2-7.*r2s*x2+6.*r1*r2s*x2
3075 +r1s*r2s*x2-2.*r2q*x2-9.*x1*x2-3.*r1s*x1*x2+2.*r2s*x1*x2
3076 +2.*x1s*x2-3.*x2s-r1s*x2s+2.*r2s*x2s+x1*x2s)
3080 if (combi == 2 || combi == 3) {
3081 rLO2 = ps*(1.-2.*r1s+r1q+r2s+6.*r1*r2s+r1s*r2s-2.*r2q);
3082 rFO2 = 2*(1.+r1+2.*r1s+2.*r1c+r1q+pow5(r1)+r2s+r1*r2s
3083 +5.*r1s*r2s+r1c*r2s-2.*r1*r2q-2.*x1-2.*r1*x1-2.*r1s*x1
3084 -2.*r1c*x1-2.*r2s*x1+5.*r1*r2s*x1-r1s*r2s*x1-2.*r2q*x1+x1s
3085 +r1*x1s+r2s*x1s-3.*x2-4.*r1s*x2-r1q*x2-2.*r2s*x2
3086 -2.*r1s*r2s*x2+4.*x1*x2+2.*r1s*x1*x2+r2s*x1*x2-x1s*x2
3087 +2.*x2s+2.*r1s*x2s-x1*x2s)
3089 +(2.*r2s-6.*r1*r2s-6.*r1s*r2s-6.*r1c*r2s+2.*r2q-6.*r1*r2q
3090 -r2s*x1+r1s*r2s*x1-r2q*x1+x2-r1q*x2-3.*r2s*x2+6.*r1*r2s*x2
3091 +9.*r1s*r2s*x2-2.*r2q*x2-x1*x2+r1s*x1*x2-x2s-3.*r1s*x2s
3094 +(-4.-8.*r1s-4.*r1q+4.*r2s-4.*r1s*r2s+8.*r2q+9.*x1+10.*r1s*x1
3095 +r1q*x1-3.*r2s*x1-6.*r1*r2s*x1+r1s*r2s*x1-2.*r2q*x1-6.*x1s
3096 -2.*r1s*x1s+x1c+7.*x2+8.*r1s*x2+r1q*x2-7.*r2s*x2-6.*r1*r2s*x2
3097 +r1s*r2s*x2-2.*r2q*x2-9.*x1*x2-3.*r1s*x1*x2+2.*r2s*x1*x2
3098 +2.*x1s*x2-3.*x2s-r1s*x2s+2.*r2s*x2s+x1*x2s)
3103 rLO4 = ps*(1.-2.*r1s+r1q+r2s+r1s*r2s-2.*r2q);
3104 rFO4 = 2*(1.+2.*r1s+r1q+r2s+5.*r1s*r2s-2.*x1-2.*r1s*x1
3105 -2.*r2s*x1-r1s*r2s*x1-2.*r2q*x1+x1s+r2s*x1s-3.*x2-4.*r1s*x2
3106 -r1q*x2-2.*r2s*x2-2.*r1s*r2s*x2+4.*x1*x2+2.*r1s*x1*x2+r2s*x1*x2
3107 -x1s*x2+2.*x2s+2.*r1s*x2s-x1*x2s)
3109 +(2.*r2s-6.*r1s*r2s+2.*r2q-r2s*x1+r1s*r2s*x1-r2q*x1+x2-r1q*x2
3110 -3.*r2s*x2+9.*r1s*r2s*x2-2.*r2q*x2-x1*x2+r1s*x1*x2-x2s-3.*r1s*x2s
3113 +(-4.-8.*r1s-4.*r1q+4.*r2s-4.*r1s*r2s+8.*r2q+9.*x1+10.*r1s*x1
3114 +r1q*x1-3.*r2s*x1+r1s*r2s*x1-2.*r2q*x1-6.*x1s-2.*r1s*x1s+x1c
3115 +7.*x2+8.*r1s*x2+r1q*x2-7.*r2s*x2+r1s*r2s*x2-2.*r2q*x2-9.*x1*x2
3116 -3.*r1s*x1*x2+2.*r2s*x1*x2+2.*x1s*x2-3.*x2s-r1s*x2s+2.*r2s*x2s
3123 // S -> q qbar (S = h0/H0/A0/H+-/...).
3125 if (combi == 1 || combi == 3) {
3126 rLO1 = ps*(1.-r1s-r2s-2.*r1*r2);
3127 rFO1 = -(-1.+r1q-2.*r1*r2-2.*r1c*r2-6.*r1s*r2s-2.*r1*r2c+r2q+x1
3128 -r1s*x1+2.*r1*r2*x1+3.*r2s*x1+x2+r1s*x2-r2s*x2-x1*x2)
3130 -2.*(r1s+r1q-2.*r1c*r2+r2s-6.*r1s*r2s-2.*r1*r2c+r2q-r1s*x1
3131 +r1*r2*x1+2.*r2s*x1+2.*r1s*x2+r1*r2*x2-r2s*x2-x1*x2)
3133 -(-1.+r1q-2.*r1*r2-2.*r1c*r2-6.*r1s*r2s-2.*r1*r2c+r2q+x1-r1s*x1
3134 +r2s*x1+x2+3.*r1s*x2+2.*r1*r2*x2-r2s*x2-x1*x2)
3138 if (combi == 2 || combi == 3) {
3139 rLO2 = ps*(1.-r1s-r2s+2.*r1*r2);
3140 rFO2 = -(-1.+r1q+2.*r1*r2+2.*r1c*r2-6.*r1s*r2s+2.*r1*r2c+r2q+x1
3141 -r1s*x1-2.*r1*r2*x1+3.*r2s*x1+x2+r1s*x2-r2s*x2-x1*x2)
3143 -(-1.+r1q+2.*r1*r2+2.*r1c*r2-6.*r1s*r2s+2.*r1*r2c+r2q+x1
3144 -r1s*x1+r2s*x1+x2+3.*r1s*x2-2.*r1*r2*x2-r2s*x2-x1*x2)
3146 +2.*(-r1s-r1q-2.*r1c*r2-r2s+6.*r1s*r2s-2.*r1*r2c-r2q+r1s*x1
3147 +r1*r2*x1-2.*r2s*x1-2.*r1s*x2+r1*r2*x2+r2s*x2+x1*x2)
3152 rLO4 = ps*(1.-r1s-r2s);
3153 rFO4 = -(-1.+r1q-6.*r1s*r2s+r2q+x1-r1s*x1+3.*r2s*x1+x2
3154 +r1s*x2-r2s*x2-x1*x2)
3156 -2.*(r1s+r1q+r2s-6.*r1s*r2s+r2q-r1s*x1
3157 +2.*r2s*x1+2.*r1s*x2-r2s*x2-x1*x2)
3159 -(-1.+r1q-6.*r1s*r2s+r2q+x1-r1s*x1+r2s*x1
3160 +x2+3.*r1s*x2-r2s*x2-x1*x2)
3168 if (combi == 1 || combi == 3) {
3169 rLO1 = ps*(1.+r1s-r2s+2.*r1);
3170 rFO1 = (4.-4.*r1s+4.*r2s-3.*x1-2.*r1*x1+r1s*x1-r2s*x1-5.*x2
3171 -2.*r1*x2+r1s*x2-r2s*x2+x1*x2+x2s)
3173 -2.*(3.-r1-5.*r1s-r1c+3.*r2s+r1*r2s-2.*x1-r1*x1
3174 +r1s*x1-4.*x2+2.*r1s*x2-r2s*x2+x1*x2+x2s)
3176 +(2.-2.*r1-6.*r1s-2.*r1c+2.*r2s-2.*r1*r2s-x1+r1s*x1
3177 -r2s*x1-3.*x2+2.*r1*x2+3.*r1s*x2-r2s*x2+x1*x2+x2s)
3181 if (combi == 2 || combi == 3) {
3182 rLO2 = ps*(1.+r1s-r2s-2.*r1);
3183 rFO2 = (4.-4.*r1s+4.*r2s-3.*x1+2.*r1*x1+r1s*x1-r2s*x1-5.*x2
3184 +2.*r1*x2+r1s*x2-r2s*x2+x1*x2+x2s)
3186 -2.*(3.+r1-5.*r1s+r1c+3.*r2s-r1*r2s-2.*x1+r1*x1
3187 +r1s*x1-4.*x2+2.*r1s*x2-r2s*x2+x1*x2+x2s)
3189 +(2.+2.*r1-6.*r1s+2.*r1c+2.*r2s+2.*r1*r2s-x1+r1s*x1
3190 -r2s*x1-3.*x2-2.*r1*x2+3.*r1s*x2-r2s*x2+x1*x2+x2s)
3195 rLO4 = ps*(1.+r1s-r2s);
3196 rFO4 = (4.-4.*r1s+4.*r2s-3.*x1+r1s*x1-r2s*x1-5.*x2+r1s*x2
3199 -2.*(3.-5.*r1s+3.*r2s-2.*x1+r1s*x1-4.*x2+2.*r1s*x2
3202 +(2.-6.*r1s+2.*r2s-x1+r1s*x1-r2s*x1-3.*x2+3.*r1s*x2
3209 // V -> ~q ~qbar (~q = squark).
3211 rLO1 = ps*(1.-2.*r1s+r1q-2.*r2s-2.*r1s*r2s+r2q);
3212 rFO1 = 2.*3.+(1.+r1s+r2s-x1)*(4.*r1s-x1s)
3214 +2.*(-1.-3.*r1s-r2s+x1+x1s*0.5+x2-x1*x2*0.5)
3216 +(1.+r1s+r2s-x2)*(4.*r2s-x2s)
3218 +2.*(-1.-r1s-3.*r2s+x1+x2-x1*x2*0.5+x2s*0.5)
3220 -(-4.*r1s-4.*r1q-4.*r2s-8.*r1s*r2s-4.*r2q+2.*x1+6.*r1s*x1
3221 +6.*r2s*x1-2.*x1s+2.*x2+6.*r1s*x2+6.*r2s*x2-4.*x1*x2
3222 -2.*r1s*x1*x2-2.*r2s*x1*x2+x1s*x2-2.*x2s+x1*x2s)
3229 rLO1 = ps*(1.-2.*r1s+r1q-2.*r2s-2.*r1s*r2s+r2q);
3230 rFO1 = 16.*r2s-8.*(4.*r2s+2.*r2s*x1+x2+r1s*x2+r2s*x2-x1*x2
3233 +8.*(1.+r1s+r2s-x2)*(4.*r2s-x2s)
3235 +8.*(x1+x2)*(-1.-2.*r1s-r1q-2.*r2s+2.*r1s*r2s-r2q+2.*x1
3236 +2.*r1s*x1+2.*r2s*x1-x1s+2.*x2+2.*r1s*x2+2.*r2s*x2-2.*x1*x2-x2s)
3238 +8.*(-1.-r1s+r2s-x1)*(2.*r2s*x1+x2+r1s*x2+r2s*x2-x1*x2-x2s)
3240 -8.*(1.+2.*r1s+r1q+2.*r2s-2.*r1s*r2s+r2q-2.*x1-2.*r1s*x1
3241 -4.*r2s*x1+x1s-3.*x2-3.*r1s*x2-3.*r2s*x2+3.*x1*x2+2.*x2s)
3250 rFO1 = (-1.-2.*r1s-r1q-2.*r2s+2.*r1s*r2s-r2q+2.*x1+2.*r1s*x1
3251 +2.*r2s*x1-x1s-r2s*x1s+2.*x2+2.*r1s*x2+2.*r2s*x2-3.*x1*x2
3252 -r1s*x1*x2-r2s*x1*x2+x1s*x2-x2s-r1s*x2s+x1*x2s)
3261 rFO1 = (-1.-r1s-r2s+x2)
3270 // chi -> q ~qbar (chi = neutralino/chargino).
3272 if (combi == 1 || combi == 3) {
3273 rLO1 = ps*(1.+r1s-r2s+2.*r1);
3274 rFO1 = (2.*r1+x1)*(-1.-r1s-r2s+x1)
3276 +2.*(-1.-r1s-2.*r1c-r2s-2.*r1*r2s+3.*x1*0.5+r1*x1
3277 -r1s*x1*0.5-r2s*x1*0.5+x2+r1*x2+r1s*x2-x1*x2*0.5)
3279 +(2.-2.*r1-6.*r1s-2.*r1c+2.*r2s-2.*r1*r2s-x1+r1s*x1
3280 -r2s*x1-3.*x2+2.*r1*x2+3.*r1s*x2-r2s*x2+x1*x2+x2s)
3284 if (combi == 2 || combi == 3) {
3285 rLO2 = ps*(1.-2.*r1+r1s-r2s);
3286 rFO2 = (2.*r1-x1)*(1.+r1s+r2s-x1)
3288 +2.*(-1.-r1s+2.*r1c-r2s+2.*r1*r2s+3.*x1*0.5-r1*x1
3289 -r1s*x1*0.5-r2s*x1*0.5+x2-r1*x2+r1s*x2-x1*x2*0.5)
3291 +(2.+2.*r1-6.*r1s+2.*r1c+2.*r2s+2.*r1*r2s-x1+r1s*x1
3292 -r2s*x1-3.*x2-2.*r1*x2+3.*r1s*x2-r2s*x2+x1*x2+x2s)/
3297 rLO4 = ps*(1.+r1s-r2s);
3298 rFO4 = x1*(-1.-r1s-r2s+x1)
3300 +2.*(-1.-r1s-r2s+3.*x1*0.5-r1s*x1*0.5-r2s*x1*0.5
3301 +x2+r1s*x2-x1*x2*0.5)
3303 +(2.-6.*r1s+2.*r2s-x1+r1s*x1-r2s*x1-3.*x2+3.*r1s*x2
3312 if (combi == 1 || combi == 3) {
3313 rLO1 = ps*(1.-pow2(r1+r2));
3314 rFO1 = (1.+r1s+2.*r1*r2+r2s-x1-x2)*(x1+x2)
3316 -(-1.+r1q-2.*r1*r2-2.*r1c*r2-6.*r1s*r2s-2.*r1*r2c+r2q+x1
3317 -r1s*x1+r2s*x1+x2+3.*r1s*x2+2.*r1*r2*x2-r2s*x2-x1*x2)
3319 +(-1.-2.*r1s-r1q-2.*r1*r2-2.*r1c*r2+2.*r1*r2c+r2q+x1+r1s*x1
3320 -2.*r1*r2*x1-3.*r2s*x1+2.*r1s*x2-2.*r2s*x2+x1*x2+x2s)
3324 if (combi == 2 || combi == 3) {
3325 rLO2 = ps*(1.-pow2(r1-r2));
3326 rFO2 = (1.+r1s-2.*r1*r2+r2s-x1-x2)*(x1+x2)
3328 -(-1.+r1q+2.*r1*r2+2.*r1c*r2-6.*r1s*r2s+2.*r1*r2c+r2q+x1
3329 -r1s*x1+r2s*x1+x2+3.*r1s*x2-2.*r1*r2*x2-r2s*x2-x1*x2)
3331 +(-1.-2.*r1s-r1q+2.*r1*r2+2.*r1c*r2-2.*r1*r2c+r2q+x1+r1s*x1
3332 +2.*r1*r2*x1-3.*r2s*x1+2.*r1s*x2-2.*r2s*x2+x1*x2+x2s)
3337 rLO4 = ps*(1.-r1s-r2s);
3338 rFO4 = (1.+r1s+r2s-x1-x2)*(x1+x2)
3340 -(-1.+r1q-6.*r1s*r2s+r2q+x1-r1s*x1+r2s*x1+x2
3341 +3.*r1s*x2-r2s*x2-x1*x2)
3343 +(-1.-2.*r1s-r1q+r2q+x1+r1s*x1-3.*r2s*x1
3344 +2.*r1s*x2-2.*r2s*x2+x1*x2+x2s)
3352 if (combi == 1 || combi == 3) {
3353 rLO1 = ps*(1.-r1s+r2s+2.*r2);
3354 rFO1 = (2.*r2+x2)*(-1.-r1s-r2s+x2)
3356 +(4.+4.*r1s-4.*r2s-5.*x1-r1s*x1-2.*r2*x1+r2s*x1+x1s
3357 -3.*x2-r1s*x2-2.*r2*x2+r2s*x2+x1*x2)
3359 +2.*(-1.-r1s+r2+r1s*r2-r2s-r2c+x1+r2*x1+r2s*x1+2.*x2
3360 +r1s*x2-x1*x2*0.5-x2s*0.5)
3364 if (combi == 2 || combi == 3) {
3365 rLO2 = ps*(1.-r1s+r2s-2.*r2);
3366 rFO2 = (2.*r2-x2)*(1.+r1s+r2s-x2)
3368 +(4.+4.*r1s-4.*r2s-5.*x1-r1s*x1+2.*r2*x1+r2s*x1+x1s
3369 -3.*x2-r1s*x2+2.*r2*x2+r2s*x2+x1*x2)
3371 +2.*(-1.-r1s-r2-r1s*r2-r2s+r2c+x1-r2*x1+r2s*x1+2.*x2
3372 +r1s*x2-x1*x2*0.5-x2s*0.5)
3377 rLO4 = ps*(1.-r1s+r2s);
3378 rFO4 = x2*(-1.-r1s-r2s+x2)
3380 +(4.+4.*r1s-4.*r2s-5.*x1-r1s*x1+r2s*x1+x1s
3381 -3.*x2-r1s*x2+r2s*x2+x1*x2)
3383 +2.*(-1.-r1s-r2s+x1+r2s*x1+2.*x2
3384 +r1s*x2-x1*x2*0.5-x2s*0.5)
3392 if (combi == 1 || combi == 3) {
3393 rLO1 = ps*(1.+r1s-r2s+2.*r1);
3394 rFO1 = 4.*(2.*r1+x1)*(-1.-r1s-r2s+x1)
3396 -(-1.-r1s-2.*r1c-r2s-2.*r1*r2s+3.*x1*0.5+r1*x1-r1s*x1*0.5
3397 -r2s*x1*0.5+x2+r1*x2+r1s*x2-x1*x2*0.5)
3399 +3.*(-1.+r1-r1s-r1c-r2s+r1*r2s+2.*x1+r2s*x1-x1s*0.5+x2+r1*x2
3402 +3.*(4.-4.*r1s+4.*r2s-3.*x1-2.*r1*x1+r1s*x1-r2s*x1-5.*x2
3403 -2.*r1*x2+r1s*x2-r2s*x2+x1*x2+x2s)
3405 -3.*(3.-r1-5.*r1s-r1c+3.*r2s+r1*r2s-2.*x1-r1*x1+r1s*x1
3406 -4.*x2+2.*r1s*x2-r2s*x2+x1*x2+x2s)
3408 +4.*(2.-2.*r1-6.*r1s-2.*r1c+2.*r2s-2.*r1*r2s-x1+r1s*x1-r2s*x1
3409 -3.*x2+2.*r1*x2+3.*r1s*x2-r2s*x2+x1*x2+x2s)
3414 if (combi == 2 || combi == 3) {
3415 rLO2 = ps*(1.+r1s-r2s-2.*r1);
3416 rFO2 = 4.*(2.*r1-x1)*(1.+r1s+r2s-x1)
3418 +3.*(-1.-r1-r1s+r1c-r2s-r1*r2s+2.*x1+r2s*x1-x1s*0.5
3419 +x2-r1*x2+r1s*x2-x1*x2*0.5)
3421 +(2.+2.*r1s-4.*r1c+2.*r2s-4.*r1*r2s-3.*x1+2.*r1*x1
3422 +r1s*x1+r2s*x1-2.*x2+2.*r1*x2-2.*r1s*x2+x1*x2)
3424 +3.*(4.-4.*r1s+4.*r2s-3.*x1+2.*r1*x1+r1s*x1-r2s*x1-5.*x2
3425 +2.*r1*x2+r1s*x2-r2s*x2+x1*x2+x2s)
3427 -3.*(3.+r1-5.*r1s+r1c+3.*r2s-r1*r2s-2.*x1+r1*x1+r1s*x1-4.*x2
3428 +2.*r1s*x2-r2s*x2+x1*x2+x2s)
3430 +4.*(2.+2.*r1-6.*r1s+2.*r1c+2.*r2s+2.*r1*r2s-x1+r1s*x1-r2s*x1
3431 -3.*x2-2.*r1*x2+3.*r1s*x2-r2s*x2+x1*x2+x2s)
3437 rLO4 = ps*(1.+r1s-r2s);
3438 rFO4 = 8.*x1*(-1.-r1s-r2s+x1)
3440 +6.*(-1-r1s-r2s+2.*x1+r2s*x1-x1s*0.5+x2+r1s*x2-x1*x2*0.5)
3442 +(2.+2.*r1s+2.*r2s-3.*x1+r1s*x1+r2s*x1-2.*x2-2.*r1s*x2+x1*x2)
3444 +6.*(4.-4.*r1s+4.*r2s-3.*x1+r1s*x1-r2s*x1-5.*x2+r1s*x2-r2s*x2
3447 -6.*(3.-5.*r1s+3.*r2s-2.*x1+r1s*x1-4.*x2+2.*r1s*x2-r2s*x2+x1*x2+x2s)
3449 +8.*(2.-6.*r1s+2.*r2s-x1+r1s*x1-r2s*x1-3.*x2+3.*r1s*x2-r2s*x2
3459 if (combi == 1 || combi == 3) {
3460 rLO1 = ps*(1.-r1s-r2s-2.*r1*r2);
3461 rFO1 = 64.*(1.+r1s+2.*r1*r2+r2s-x1-x2)*(x1+x2)
3463 -16.*(-1.+r1q-2.*r1*r2-2.*r1c*r2-6.*r1s*r2s-2.*r1*r2c+r2q
3464 +x1-r1s*x1+2.*r1*r2*x1+3.*r2s*x1+x2+r1s*x2-r2s*x2-x1*x2)
3466 -16.*(r1s+r1q-2.*r1c*r2+r2s-6.*r1s*r2s-2.*r1*r2c+r2q-r1s*x1
3467 +r1*r2*x1+2.*r2s*x1+2.*r1s*x2+r1*r2*x2-r2s*x2-x1*x2)
3469 -64.*(-1.+r1q-2.*r1*r2-2.*r1c*r2-6.*r1s*r2s-2.*r1*r2c+r2q+x1
3470 -r1s*x1+r2s*x1+x2+3.*r1s*x2+2.*r1*r2*x2-r2s*x2-x1*x2)
3472 +8.*(-1.+r1q-2.*r1*r2+2.*r1c*r2-2.*r2s-2.*r1*r2c-r2q-2.*r1s*x1
3473 +2.*r2s*x1+x1s+x2-3.*r1s*x2-2.*r1*r2*x2+r2s*x2+x1*x2)
3475 -8.*(-1.-2.*r1s-r1q-2.*r1*r2-2.*r1c*r2+2.*r1*r2c+r2q+x1+r1s*x1
3476 -2.*r1*r2*x1-3.*r2s*x1+2.*r1s*x2-2.*r2s*x2+x1*x2+x2s)
3481 if (combi == 2 || combi == 3) {
3482 rLO2 = ps*(1.-r1s-r2s+2.*r1*r2);
3483 rFO2 = 64.*(1.+r1s-2.*r1*r2+r2s-x1-x2)*(x1+x2)
3485 -16.*(-1.+r1q+2.*r1*r2+2.*r1c*r2-6.*r1s*r2s+2.*r1*r2c+r2q+x1
3486 -r1s*x1-2.*r1*r2*x1+3.*r2s*x1+x2+r1s*x2-r2s*x2-x1*x2)
3488 -64.*(-1.+r1q+2.*r1*r2+2.*r1c*r2-6.*r1s*r2s+2.*r1*r2c+r2q+x1
3489 -r1s*x1+r2s*x1+x2+3.*r1s*x2-2.*r1*r2*x2-r2s*x2-x1*x2)
3491 +16.*(-r1s-r1q-2.*r1c*r2-r2s+6.*r1s*r2s-2.*r1*r2c-r2q+r1s*x1
3492 +r1*r2*x1-2.*r2s*x1-2.*r1s*x2+r1*r2*x2+r2s*x2+x1*x2)
3494 +8.*(-1.+r1q+2.*r1*r2-2.*r1c*r2-2.*r2s+2.*r1*r2c-r2q-2.*r1s*x1
3495 +2.*r2s*x1+x1s+x2-3.*r1s*x2+2.*r1*r2*x2+r2s*x2+x1*x2)
3497 -8.*(-1.-2.*r1s-r1q+2.*r1*r2+2.*r1c*r2-2.*r1*r2c+r2q+x1+r1s*x1+
3498 2.*r1*r2*x1-3.*r2s*x1+2.*r1s*x2-2.*r2s*x2+x1*x2+x2s)
3504 rLO4 = ps*(1.-r1s-r2s);
3505 rFO4 = 128.*(1.+r1s+r2s-x1-x2)*(x1+x2)
3507 -32*(-1.+r1q-6.*r1s*r2s+r2q+x1-r1s*x1+3.*r2s*x1+x2
3508 +r1s*x2-r2s*x2-x1*x2)
3510 -32.*(r1s+r1q+r2s-6.*r1s*r2s+r2q-r1s*x1+2.*r2s*x1+2.*r1s*x2
3513 -128.*(-1.+r1q-6.*r1s*r2s+r2q+x1-r1s*x1+r2s*x1+x2+3.*r1s*x2
3516 +16.*(-1.+r1q-2.*r2s-r2q-2.*r1s*x1+2.*r2s*x1+x1s
3517 +x2-3.*r1s*x2+r2s*x2+x1*x2)
3519 -16.*(-1.-2.*r1s-r1q+r2q+x1+r1s*x1-3.*r2s*x1
3520 +2.*r1s*x2-2.*r2s*x2+x1*x2+x2s)
3522 rFO4 = 9.*rFO4/128.;
3529 if (combi == 1 || combi == 3) {
3530 rLO1 = ps*(1.-r1s+r2s+2.*r2);
3531 rFO1 = 32*(2.*r2+x2)*(-1.-r1s-r2s+x2)
3533 +8.*(-1.-r1s-2.*r1s*r2-r2s-2.*r2c+x1+r2*x1+r2s*x1
3534 +3.*x2*0.5-r1s*x2*0.5+r2*x2-r2s*x2*0.5-x1*x2*0.5)
3536 +8.*(2.+2.*r1s-2.*r2-2.*r1s*r2-6.*r2s-2.*r2c-3.*x1-r1s*x1
3537 +2.*r2*x1+3.*r2s*x1+x1s-x2-r1s*x2+r2s*x2+x1*x2)
3539 +32.*(4.+4.*r1s-4.*r2s-5.*x1-r1s*x1-2.*r2*x1+r2s*x1+x1s
3540 -3.*x2-r1s*x2-2.*r2*x2+r2s*x2+x1*x2)
3542 -8.*(3.+3.*r1s-r2+r1s*r2-5.*r2s-r2c-4.*x1-r1s*x1
3543 +2.*r2s*x1+x1s-2.*x2-r2*x2+r2s*x2+x1*x2)
3545 -8.*(-1.-r1s+r2+r1s*r2-r2s-r2c+x1+r2*x1+r2s*x1+2.*x2+r1s*x2
3551 if (combi == 2 || combi == 3) {
3552 rLO2 = ps*(1.-r1s+r2s-2.*r2);
3553 rFO2 = 32*(2.*r2-x2)*(1.+r1s+r2s-x2)
3555 +8.*(-1.-r1s+2.*r1s*r2-r2s+2.*r2c+x1-r2*x1+r2s*x1
3556 +3.*x2*0.5-r1s*x2*0.5-r2*x2-r2s*x2*0.5-x1*x2*0.5)
3558 +8.*(2.+2.*r1s+2.*r2+2.*r1s*r2-6.*r2s+2.*r2c-3.*x1-r1s*x1
3559 -2.*r2*x1+3.*r2s*x1+x1s-x2-r1s*x2+r2s*x2+x1*x2)
3561 -8.*(3.+3.*r1s+r2-r1s*r2-5.*r2s+r2c-4.*x1-r1s*x1+2.*r2s*x1+x1s
3562 -2.*x2+r2*x2+r2s*x2+x1*x2)
3564 +32*(4.+4.*r1s-4.*r2s-5.*x1-r1s*x1+2.*r2*x1+r2s*x1
3565 +x1s-3.*x2-r1s*x2+2.*r2*x2+r2s*x2+x1*x2)
3567 -8.*(-1.-r1s-r2-r1s*r2-r2s+r2c+x1-r2*x1+r2s*x1+2.*x2+r1s*x2
3574 rLO4 = ps*(1.-r1s+r2s);
3575 rFO4 = 64.*x2*(-1.-r1s-r2s+x2)
3577 +16.*(-1.-r1s-r2s+x1+r2s*x1+3.*x2*0.5-r1s*x2*0.5
3578 -r2s*x2*0.5-x1*x2*0.5)
3580 -16.*(3.+3.*r1s-5.*r2s-4.*x1-r1s*x1+2.*r2s*x1+x1s-2.*x2+r2s*x2
3583 +64.*(4.+4.*r1s-4.*r2s-5.*x1-r1s*x1+r2s*x1+x1s-3.*x2
3584 -r1s*x2+r2s*x2+x1*x2)
3586 +16.*(2.+2.*r1s-6.*r2s-3.*x1-r1s*x1+3.*r2s*x1+x1s
3587 -x2-r1s*x2+r2s*x2+x1*x2)
3589 -16.*(-1.-r1s-r2s+x1+r2s*x1+2.*x2+r1s*x2-x1*x2*0.5-x2s*0.5)
3596 // g -> ~g ~g. Use (9/4)*eikonal. May be changed in the future.
3599 if (combi == 2) offset = x3s;
3600 else if (combi == 3) offset = mix * x3s;
3601 else if (combi == 4) offset = 0.5 * x3s;
3602 rFO = ps * 4.5 * ( (x1+x2-1.+offset-r1s-r2s)/prop12
3603 - r1s/prop2s - r2s/prop1s );
3608 rLO = ps*(1.-r1s+r2s+2.*r2);
3609 rFO = ( 0.5*r3s + 2.*r1q + 0.5*r2s*r3s + r2*r3s - 2.*r1s
3610 - 0.5*r1s*r3s - 2.*r1s*r2s - 4.*r1s*r2 ) / prop2s
3611 + ( -2. + 2.*r2q + 2.*r1q + 2.*r2s*r3s - 4.*r2 + 2.*r2*r3s
3612 + 4.*r2*r2s - 4.*r1s*r2s - 4.*r1s*r2 ) /prop23
3613 + ( -2. - 0.5*r3s - 2.*r2s - 4.*r2 + 2.*r1s ) / prop2
3614 + ( -2. - r3s - 2.*r2s - r2s*r3s - 4.*r2 - 2.*r2*r3s
3615 + 2.*r1s + r1s*r3s ) / prop3s
3616 + ( -1. - r3s - r2s - 4.*r2 + r1s - x2 ) / prop3
3622 rLO = ps*(1.-4.*r1s);
3623 rFO = (r3s + 2.*r1s) * (-1. + 4.*r1s) * (1./prop1s + 1./prop2s)
3624 + (-1. + 8.*r1s - x2) / prop1
3625 + (-1. + 8.*r1s - x1) / prop2
3626 + 2. * (1. - 6.*r1s + 8.*r1q + 4.*r3s*r1s) / prop12
3630 // Eikonal expression for kind == 1; also acts as default.
3633 if (combi == 2) offset = x3s;
3634 else if (combi == 3) offset = mix * x3s;
3635 else if (combi == 4) offset = 0.5 * x3s;
3636 rFO = ps * 2. * ( (x1+x2-1.+offset-r1s-r2s)/prop12
3637 - r1s/prop2s - r2s/prop1s );
3643 // Find relevant leading and first order expressions.
3644 if (combi == 1 && isSet1) {
3647 else if (combi == 2 && isSet2) {
3650 else if (combi == 3 && isSet1 && isSet2) {
3651 rLO = mix * rLO1 + (1.-mix) * rLO2;
3652 rFO = mix * rFO1 + (1.-mix) * rFO2; }
3656 else if (combi == 4 && isSet1 && isSet2) {
3657 rLO = 0.5 * (rLO1 + rLO2);
3658 rFO = 0.5 * (rFO1 + rFO2); }
3663 // Return ratio of first to leading order cross section.
3667 //--------------------------------------------------------------------------
3669 // Find coefficient of azimuthal asymmetry from gluon polarization.
3671 void TimeShower::findAsymPol( Event& event, TimeDipoleEnd* dip) {
3673 // Default is no asymmetry. Only gluons are studied.
3676 int iRad = dip->iRadiator;
3677 if (!doPhiPolAsym || event[iRad].id() != 21) return;
3679 // Trace grandmother via possibly intermediate recoil copies.
3680 int iMother = event.iTopCopy(iRad);
3681 int iGrandM = event[iMother].mother1();
3683 // If grandmother in initial state of hard scattering,
3684 // then only keep gg and qq initial states.
3685 int statusGrandM = event[iGrandM].status();
3686 bool isHardProc = (statusGrandM == -21 || statusGrandM == -31);
3688 if (event[iGrandM + 1].status() != statusGrandM) return;
3689 if (event[iGrandM].isGluon() && event[iGrandM + 1].isGluon());
3690 else if (event[iGrandM].isQuark() && event[iGrandM + 1].isQuark());
3694 // Set aunt by history or, for hard scattering, by colour flow.
3695 if (isHardProc) dip->iAunt = dip->iRecoiler;
3696 else dip->iAunt = (event[iGrandM].daughter1() == iMother)
3697 ? event[iGrandM].daughter2() : event[iGrandM].daughter1();
3699 // Coefficient from gluon production (approximate z by energy).
3700 // For hard process arbitrarily put z = 1/2.
3701 double zProd = (isHardProc) ? 0.5 : event[iRad].e()
3702 / (event[iRad].e() + event[dip->iAunt].e());
3703 if (event[iGrandM].isGluon()) dip->asymPol = pow2( (1. - zProd)
3704 / (1. - zProd * (1. - zProd) ) );
3705 else dip->asymPol = 2. * (1. - zProd) / (1. + pow2(1. - zProd) );
3707 // Coefficients from gluon decay.
3708 if (dip->flavour == 21) dip->asymPol *= pow2( (1. - dip->z)
3709 / (1. - dip->z * (1. - dip->z) ) );
3710 else dip->asymPol *= -2. * dip->z *( 1. - dip->z )
3711 / (1. - 2. * dip->z * (1. - dip->z) );
3715 //--------------------------------------------------------------------------
3717 // Print the list of dipoles.
3719 void TimeShower::list(ostream& os) const {
3722 os << "\n -------- PYTHIA TimeShower Dipole Listing ----------------"
3723 << "--------------------------------------------- \n \n i rad"
3724 << " rec pTmax col chg gam oni hv isr sys sysR typ"
3725 << "e MErec mix ord spl ~gR \n" << fixed << setprecision(3);
3727 // Loop over dipole list and print it.
3728 for (int i = 0; i < int(dipEnd.size()); ++i)
3729 os << setw(5) << i << setw(7) << dipEnd[i].iRadiator
3730 << setw(7) << dipEnd[i].iRecoiler << setw(12) << dipEnd[i].pTmax
3731 << setw(5) << dipEnd[i].colType << setw(5) << dipEnd[i].chgType
3732 << setw(5) << dipEnd[i].gamType << setw(5) << dipEnd[i].isOctetOnium
3733 << setw(5) << dipEnd[i].isHiddenValley << setw(5) << dipEnd[i].isrType
3734 << setw(5) << dipEnd[i].system << setw(5) << dipEnd[i].systemRec
3735 << setw(5) << dipEnd[i].MEtype << setw(7) << dipEnd[i].iMEpartner
3736 << setw(8) << dipEnd[i].MEmix << setw(5) << dipEnd[i].MEorder
3737 << setw(5) << dipEnd[i].MEsplit << setw(5) << dipEnd[i].MEgluinoRec
3741 os << "\n -------- End PYTHIA TimeShower Dipole Listing ------------"
3742 << "---------------------------------------------" << endl;
3746 //==========================================================================
3748 } // end namespace Pythia8