StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
TimeShower.cc
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.
5 
6 // Function definitions (not found in the header) for the TimeShower class.
7 
8 #include "TimeShower.h"
9 
10 namespace Pythia8 {
11 
12 //==========================================================================
13 
14 // The TimeShower class.
15 
16 //--------------------------------------------------------------------------
17 
18 // Constants: could be changed here if desired, but normally should not.
19 // These are of technical nature, as described for each.
20 
21 // For small x approximate 1 - sqrt(1 - x) by x/2.
22 const double TimeShower::SIMPLIFYROOT = 1e-8;
23 
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;
29 
30 // Lower limit on PDF value in order to avoid division by zero.
31 const double TimeShower::TINYPDF = 1e-10;
32 
33 // Big starting value in search for smallest invariant-mass pair.
34 const double TimeShower::LARGEM2 = 1e20;
35 
36 // In g -> q qbar or gamma -> f fbar require m2_pair > this * m2_q/f.
37 const double TimeShower::THRESHM2 = 4.004;
38 
39 // Never pick pT so low that alphaS is evaluated too close to Lambda_3.
40 const double TimeShower::LAMBDA3MARGIN = 1.1;
41 
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;
52 
53 //--------------------------------------------------------------------------
54 
55 // Initialize alphaStrong, alphaEM and related pTmin parameters.
56 
57 void TimeShower::init( BeamParticle* beamAPtrIn,
58  BeamParticle* beamBPtrIn) {
59 
60  // Store input pointers for future use.
61  beamAPtr = beamAPtrIn;
62  beamBPtr = beamBPtrIn;
63 
64  // Main flags.
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");
76 
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");
83 
84  // Charm and bottom mass thresholds.
85  mc = particleDataPtr->m0(4);
86  mb = particleDataPtr->m0(5);
87  m2c = mc * mc;
88  m2b = mb * mb;
89 
90  // Parameters of alphaStrong generation .
91  alphaSvalue = settingsPtr->parm("TimeShower:alphaSvalue");
92  alphaSorder = settingsPtr->mode("TimeShower:alphaSorder");
93  alphaS2pi = 0.5 * alphaSvalue / M_PI;
94 
95  // Initialize alphaStrong generation.
96  alphaS.init( alphaSvalue, alphaSorder);
97 
98  // Lambda for 5, 4 and 3 flavours.
99  Lambda3flav = alphaS.Lambda3();
100  Lambda4flav = alphaS.Lambda4();
101  Lambda5flav = alphaS.Lambda5();
102  Lambda5flav2 = pow2(Lambda5flav);
103  Lambda4flav2 = pow2(Lambda4flav);
104  Lambda3flav2 = pow2(Lambda3flav);
105 
106  // Parameters of QCD evolution. Warn if pTmin must be raised.
107  nGluonToQuark = settingsPtr->mode("TimeShower:nGluonToQuark");
108  pTcolCutMin = settingsPtr->parm("TimeShower:pTmin");
109  if (pTcolCutMin > LAMBDA3MARGIN * Lambda3flav)
110  pTcolCut = pTcolCutMin;
111  else {
112  pTcolCut = LAMBDA3MARGIN * Lambda3flav;
113  ostringstream newPTcolCut;
114  newPTcolCut << fixed << setprecision(3) << pTcolCut;
115  infoPtr->errorMsg("Warning in TimeShower::init: pTmin too low",
116  ", raised to " + newPTcolCut.str() );
117  infoPtr->setTooLowPTmin(true);
118  }
119  pT2colCut = pow2(pTcolCut);
120 
121  // Parameters of alphaEM generation .
122  alphaEMorder = settingsPtr->mode("TimeShower:alphaEMorder");
123 
124  // Initialize alphaEM generation.
125  alphaEM.init( alphaEMorder, settingsPtr);
126 
127  // Parameters of QED evolution.
128  nGammaToQuark = settingsPtr->mode("TimeShower:nGammaToQuark");
129  nGammaToLepton = settingsPtr->mode("TimeShower:nGammaToLepton");
130  pTchgQCut = settingsPtr->parm("TimeShower:pTminChgQ");
131  pT2chgQCut = pow2(pTchgQCut);
132  pTchgLCut = settingsPtr->parm("TimeShower:pTminChgL");
133  pT2chgLCut = pow2(pTchgLCut);
134  mMaxGamma = settingsPtr->parm("TimeShower:mMaxGamma");
135  m2MaxGamma = pow2(mMaxGamma);
136 
137  // Consisteny check for gamma -> f fbar variables.
138  if (nGammaToQuark <= 0 && nGammaToLepton <= 0) doQEDshowerByGamma = false;
139 
140  // Possibility of a global recoil stategy, e.g. for MC@NLO.
141  globalRecoil = settingsPtr->flag("TimeShower:globalRecoil");
142  nMaxGlobalRecoil = settingsPtr->mode("TimeShower:nMaxGlobalRecoil");
143 
144  // Fraction and colour factor of gluon emission off onium octat state.
145  octetOniumFraction = settingsPtr->parm("TimeShower:octetOniumFraction");
146  octetOniumColFac = settingsPtr->parm("TimeShower:octetOniumColFac");
147 
148  // Z0 properties needed for gamma/Z0 mixing.
149  mZ = particleDataPtr->m0(23);
150  gammaZ = particleDataPtr->mWidth(23);
151  thetaWRat = 1. / (16. * coupSMPtr->sin2thetaW()
152  * coupSMPtr->cos2thetaW());
153 
154  // May have to fix up recoils related to rescattering.
155  allowRescatter = settingsPtr->flag("PartonLevel:MPI")
156  && settingsPtr->flag("MultipartonInteractions:allowRescatter");
157 
158  // Hidden Valley scenario with further shower activity.
159  doHVshower = settingsPtr->flag("HiddenValley:FSR");
160  nCHV = settingsPtr->mode("HiddenValley:Ngauge");
161  alphaHVfix = settingsPtr->parm("HiddenValley:alphaFSR");
162  pThvCut = settingsPtr->parm("HiddenValley:pTminFSR");
163  pT2hvCut = pThvCut * pThvCut;
164  CFHV = (nCHV == 1) ? 1. : (nCHV * nCHV - 1.)/(2. * nCHV);
165  idHV = (nCHV == 1) ? 4900022 : 4900021;
166  mHV = particleDataPtr->m0(idHV);
167  brokenHVsym = (nCHV == 1 && mHV > 0.);
168 
169  // Possibility to allow user veto of emission step.
170  canVetoEmission = (userHooksPtr > 0) ? userHooksPtr->canVetoFSREmission()
171  : false;
172 
173 }
174 
175 //--------------------------------------------------------------------------
176 
177 // Find whether to limit maximum scale of emissions.
178 // Also allow for dampening at factorization or renormalization scale.
179 
180 bool TimeShower::limitPTmax( Event& event, double Q2Fac, double Q2Ren) {
181 
182  // Find whether to limit pT. Begin by user-set cases.
183  bool dopTlimit = false;
184  if (pTmaxMatch == 1) dopTlimit = true;
185  else if (pTmaxMatch == 2) dopTlimit = false;
186 
187  // Look if any quark (u, d, s, c, b), gluon or photon in final state.
188  else {
189  for (int i = 5; i < event.size(); ++i)
190  if (event[i].status() != -21) {
191  int idAbs = event[i].idAbs();
192  if (idAbs <= 5 || idAbs == 21 || idAbs == 22) dopTlimit = true;
193  }
194  }
195 
196  // Dampening at factorization or renormalization scale.
197  dopTdamp = false;
198  pT2damp = 0.;
199  if ( !dopTlimit && (pTdampMatch == 1 || pTdampMatch == 2) ) {
200  dopTdamp = true;
201  pT2damp = pow2(pTdampFudge) * ((pTdampMatch == 1) ? Q2Fac : Q2Ren);
202  }
203 
204  // Done.
205  return dopTlimit;
206 
207 }
208 
209 //--------------------------------------------------------------------------
210 
211 // Top-level routine to do a full time-like shower in resonance decay.
212 
213 int TimeShower::shower( int iBeg, int iEnd, Event& event, double pTmax,
214  int nBranchMax) {
215 
216  // Add new system, automatically with two empty beam slots.
217  int iSys = partonSystemsPtr->addSys();
218 
219  // Loop over allowed range to find all final-state particles.
220  Vec4 pSum;
221  for (int i = iBeg; i <= iEnd; ++i) if (event[i].isFinal()) {
222  partonSystemsPtr->addOut( iSys, i);
223  pSum += event[i].p();
224  }
225  partonSystemsPtr->setSHat( iSys, pSum.m2Calc() );
226 
227  // Let prepare routine do the setup.
228  prepare( iSys, event, true);
229 
230  // Begin evolution down in pT from hard pT scale.
231  int nBranch = 0;
232  pTLastBranch = 0.;
233  do {
234  double pTtimes = pTnext( event, pTmax, 0.);
235 
236  // Do a final-state emission (if allowed).
237  if (pTtimes > 0.) {
238  if (branch( event)) {
239  ++nBranch;
240  pTLastBranch = pTtimes;
241  }
242  pTmax = pTtimes;
243  }
244 
245  // Keep on evolving until nothing is left to be done.
246  else pTmax = 0.;
247  } while (pTmax > 0. && (nBranchMax <= 0 || nBranch < nBranchMax));
248 
249  // Return number of emissions that were performed.
250  return nBranch;
251 
252 }
253 
254 //--------------------------------------------------------------------------
255 
256 // Prepare system for evolution; identify ME.
257 
258 void TimeShower::prepare( int iSys, Event& event, bool limitPTmaxIn) {
259 
260  // Reset dipole-ends list for first interaction and for resonance decays.
261  int iInA = partonSystemsPtr->getInA(iSys);
262  int iInB = partonSystemsPtr->getInB(iSys);
263  if (iSys == 0 || iInA == 0) dipEnd.resize(0);
264  int dipEndSizeBeg = dipEnd.size();
265 
266  // Loop through final state of system to find possible dipole ends.
267  for (int i = 0; i < partonSystemsPtr->sizeOut(iSys); ++i) {
268  int iRad = partonSystemsPtr->getOut( iSys, i);
269  if (event[iRad].isFinal() && event[iRad].scale() > 0.) {
270 
271  // Identify colour octet onium state. Check whether QCD shower allowed.
272  int idRad = event[iRad].id();
273  int idRadAbs = abs(idRad);
274  bool isOctetOnium
275  = ( idRad == 9900441 || idRad == 9900443 || idRad == 9910441
276  || idRad == 9900551 || idRad == 9900553 || idRad == 9910551 );
277  bool doQCD = doQCDshower;
278  if (doQCD && isOctetOnium)
279  doQCD = (rndmPtr->flat() < octetOniumFraction);
280 
281  // Find dipole end formed by colour index.
282  int colTag = event[iRad].col();
283  if (doQCD && colTag > 0) setupQCDdip( iSys, i, colTag, 1, event,
284  isOctetOnium, limitPTmaxIn);
285 
286  // Find dipole end formed by anticolour index.
287  int acolTag = event[iRad].acol();
288  if (doQCD && acolTag > 0) setupQCDdip( iSys, i, acolTag, -1, event,
289  isOctetOnium, limitPTmaxIn);
290 
291  // Find "charge-dipole" and "photon-dipole" ends.
292  int chgType = event[iRad].chargeType();
293  bool doChgDip = (chgType != 0)
294  && ( ( doQEDshowerByQ && event[iRad].isQuark() )
295  || ( doQEDshowerByL && event[iRad].isLepton() ) );
296  int gamType = (idRad == 22) ? 1 : 0;
297  bool doGamDip = (gamType == 1) && doQEDshowerByGamma;
298  if (doChgDip || doGamDip) setupQEDdip( iSys, i, chgType, gamType,
299  event, limitPTmaxIn);
300 
301  // Find Hidden Valley dipole ends.
302  bool isHVrad = (idRadAbs > 4900000 && idRadAbs < 4900007)
303  || (idRadAbs > 4900010 && idRadAbs < 4900017)
304  || idRadAbs == 4900101;
305  if (doHVshower && isHVrad) setupHVdip( iSys, i, event, limitPTmaxIn);
306 
307  // End loop over system final state. Have now found the dipole ends.
308  }
309  }
310 
311  // Loop through dipole ends to find matrix element corrections.
312  for (int iDip = dipEndSizeBeg; iDip < int(dipEnd.size()); ++iDip)
313  findMEtype( event, dipEnd[iDip]);
314 
315  // Update dipole list after a multiparton interactions rescattering.
316  if (iSys > 0 && ( (iInA > 0 && event[iInA].status() == -34)
317  || (iInB > 0 && event[iInB].status() == -34) ) )
318  rescatterUpdate( iSys, event);
319 
320 }
321 
322 //--------------------------------------------------------------------------
323 
324 // Update dipole list after a multiparton interactions rescattering.
325 void TimeShower::rescatterUpdate( int iSys, Event& event) {
326 
327  // Loop over two incoming partons in system; find their rescattering mother.
328  // (iOut is outgoing from old system = incoming iIn of rescattering system.)
329  for (int iResc = 0; iResc < 2; ++iResc) {
330  int iIn = (iResc == 0) ? partonSystemsPtr->getInA(iSys)
331  : partonSystemsPtr->getInB(iSys);
332  if (iIn == 0 || event[iIn].status() != -34) continue;
333  int iOut = event[iIn].mother1();
334 
335  // Loop over all dipoles.
336  int dipEndSize = dipEnd.size();
337  for (int iDip = 0; iDip < dipEndSize; ++iDip) {
338  TimeDipoleEnd& dipNow = dipEnd[iDip];
339 
340  // Kill dipoles where rescattered parton is radiator.
341  if (dipNow.iRadiator == iOut) {
342  dipNow.colType = 0;
343  dipNow.chgType = 0;
344  dipNow.gamType = 0;
345  continue;
346  }
347  // No matrix element for dipoles between scatterings.
348  if (dipNow.iMEpartner == iOut) {
349  dipNow.MEtype = 0;
350  dipNow.iMEpartner = -1;
351  }
352 
353  // Update dipoles where outgoing rescattered parton is recoiler.
354  if (dipNow.iRecoiler == iOut) {
355  int iRad = dipNow.iRadiator;
356 
357  // Colour dipole: recoil in final state, initial state or new.
358  if (dipNow.colType > 0) {
359  int colTag = event[iRad].col();
360  bool done = false;
361  for (int i = 0; i < partonSystemsPtr->sizeOut(iSys); ++i) {
362  int iRecNow = partonSystemsPtr->getOut( iSys, i);
363  if (event[iRecNow].acol() == colTag) {
364  dipNow.iRecoiler = iRecNow;
365  dipNow.systemRec = iSys;
366  dipNow.MEtype = 0;
367  done = true;
368  break;
369  }
370  }
371  if (!done) {
372  int iIn2 = (iResc == 0) ? partonSystemsPtr->getInB(iSys)
373  : partonSystemsPtr->getInA(iSys);
374  if (event[iIn2].col() == colTag) {
375  dipNow.iRecoiler = iIn2;
376  dipNow.systemRec = iSys;
377  dipNow.MEtype = 0;
378  int isrType = event[iIn2].mother1();
379  // This line in case mother is a rescattered parton.
380  while (isrType > 2 + beamOffset)
381  isrType = event[isrType].mother1();
382  if (isrType > 2) isrType -= beamOffset;
383  dipNow.isrType = isrType;
384  done = true;
385  }
386  }
387  // If above options failed, then create new dipole.
388  if (!done) {
389  int iRadNow = partonSystemsPtr->getIndexOfOut(dipNow.system, iRad);
390  if (iRadNow != -1)
391  setupQCDdip(dipNow.system, iRadNow, event[iRad].col(), 1,
392  event, dipNow.isOctetOnium, true);
393  else
394  infoPtr->errorMsg("Warning in TimeShower::rescatterUpdate: "
395  "failed to locate radiator in system");
396 
397  dipNow.colType = 0;
398  dipNow.chgType = 0;
399  dipNow.gamType = 0;
400 
401  infoPtr->errorMsg("Warning in TimeShower::rescatterUpdate: "
402  "failed to locate new recoiling colour partner");
403  }
404 
405  // Anticolour dipole: recoil in final state, initial state or new.
406  } else if (dipNow.colType < 0) {
407  int acolTag = event[iRad].acol();
408  bool done = false;
409  for (int i = 0; i < partonSystemsPtr->sizeOut(iSys); ++i) {
410  int iRecNow = partonSystemsPtr->getOut( iSys, i);
411  if (event[iRecNow].col() == acolTag) {
412  dipNow.iRecoiler = iRecNow;
413  dipNow.systemRec = iSys;
414  dipNow.MEtype = 0;
415  done = true;
416  break;
417  }
418  }
419  if (!done) {
420  int iIn2 = (iResc == 0) ? partonSystemsPtr->getInB(iSys)
421  : partonSystemsPtr->getInA(iSys);
422  if (event[iIn2].acol() == acolTag) {
423  dipNow.iRecoiler = iIn2;
424  dipNow.systemRec = iSys;
425  dipNow.MEtype = 0;
426  int isrType = event[iIn2].mother1();
427  // This line in case mother is a rescattered parton.
428  while (isrType > 2 + beamOffset)
429  isrType = event[isrType].mother1();
430  if (isrType > 2) isrType -= beamOffset;
431  dipNow.isrType = isrType;
432  done = true;
433  }
434  }
435  // If above options failed, then create new dipole.
436  if (!done) {
437  int iRadNow = partonSystemsPtr->getIndexOfOut(dipNow.system, iRad);
438  if (iRadNow != -1)
439  setupQCDdip(dipNow.system, iRadNow, event[iRad].acol(), -1,
440  event, dipNow.isOctetOnium, true);
441  else
442  infoPtr->errorMsg("Warning in TimeShower::rescatterUpdate: "
443  "failed to locate radiator in system");
444 
445  dipNow.colType = 0;
446  dipNow.chgType = 0;
447  dipNow.gamType = 0;
448 
449  infoPtr->errorMsg("Warning in TimeShower::rescatterUpdate: "
450  "failed to locate new recoiling colour partner");
451  }
452 
453  // Charge or photon dipoles: same flavour in final or initial state.
454  } else if (dipNow.chgType != 0 || dipNow.gamType != 0) {
455  int idTag = event[dipNow.iRecoiler].id();
456  bool done = false;
457  for (int i = 0; i < partonSystemsPtr->sizeOut(iSys); ++i) {
458  int iRecNow = partonSystemsPtr->getOut( iSys, i);
459  if (event[iRecNow].id() == idTag) {
460  dipNow.iRecoiler = iRecNow;
461  dipNow.systemRec = iSys;
462  dipNow.MEtype = 0;
463  done = true;
464  break;
465  }
466  }
467  if (!done) {
468  int iIn2 = (iResc == 0) ? partonSystemsPtr->getInB(iSys)
469  : partonSystemsPtr->getInA(iSys);
470  if (event[iIn2].id() == -idTag) {
471  dipNow.iRecoiler = iIn2;
472  dipNow.systemRec = iSys;
473  dipNow.MEtype = 0;
474  int isrType = event[iIn2].mother1();
475  // This line in case mother is a rescattered parton.
476  while (isrType > 2 + beamOffset)
477  isrType = event[isrType].mother1();
478  if (isrType > 2) isrType -= beamOffset;
479  dipNow.isrType = isrType;
480  done = true;
481  }
482  }
483  // If above options failed, then create new dipole
484  if (!done) {
485  int iRadNow = partonSystemsPtr->getIndexOfOut(dipNow.system, iRad);
486  if (iRadNow != -1)
487  setupQEDdip(dipNow.system, iRadNow, dipNow.chgType,
488  dipNow.gamType, event, true);
489  else
490  infoPtr->errorMsg("Warning in TimeShower::rescatterUpdate: "
491  "failed to locate radiator in system");
492 
493  dipNow.colType = 0;
494  dipNow.chgType = 0;
495  dipNow.gamType = 0;
496 
497  infoPtr->errorMsg("Warning in TimeShower::rescatterUpdate: "
498  "failed to locate new recoiling charge partner");
499  }
500  }
501  }
502 
503  // End of loop over dipoles and two incoming sides.
504  }
505  }
506 
507 }
508 
509 //--------------------------------------------------------------------------
510 
511 // Update dipole list after each ISR emission (so not used for resonances).
512 
513 void TimeShower::update( int iSys, Event& event) {
514 
515  // Start list of rescatterers that gave further changed systems in ISR.
516  vector<int> iRescatterer;
517 
518  // Find new and old positions of incoming partons in the system.
519  vector<int> iNew, iOld;
520  iNew.push_back( partonSystemsPtr->getInA(iSys) );
521  iOld.push_back( event[iNew[0]].daughter2() );
522  iNew.push_back( partonSystemsPtr->getInB(iSys) );
523  iOld.push_back( event[iNew[1]].daughter2() );
524 
525  // Ditto for outgoing partons, except the newly created one.
526  int sizeOut = partonSystemsPtr->sizeOut(iSys) - 1;
527  for (int i = 0; i < sizeOut; ++i) {
528  int iNow = partonSystemsPtr->getOut(iSys, i);
529  iNew.push_back( iNow );
530  iOld.push_back( event[iNow].mother1() );
531  // Add non-final to list of rescatterers.
532  if (!event[iNow].isFinal()) iRescatterer.push_back( iNow );
533  }
534  int iNewNew = partonSystemsPtr->getOut(iSys, sizeOut);
535 
536  // Swap beams to let 0 be side on which branching occured.
537  if (event[iNew[0]].status() != -41) {
538  swap( iNew[0], iNew[1]);
539  swap( iOld[0], iOld[1]);
540  }
541 
542  // Loop over all dipole ends belonging to the system
543  // or to the recoil system, if different.
544  for (int iDip = 0; iDip < int(dipEnd.size()); ++iDip)
545  if (dipEnd[iDip].system == iSys || dipEnd[iDip].systemRec == iSys) {
546  TimeDipoleEnd& dipNow = dipEnd[iDip];
547 
548  // Replace radiator (always in final state so simple).
549  for (int i = 2; i < 2 + sizeOut; ++i)
550  if (dipNow.iRadiator == iOld[i]) {
551  dipNow.iRadiator = iNew[i];
552  break;
553  }
554 
555  // Replace ME partner (always in final state, if exists, so simple).
556  for (int i = 2; i < 2 + sizeOut; ++i)
557  if (dipNow.iMEpartner == iOld[i]) {
558  dipNow.iMEpartner = iNew[i];
559  break;
560  }
561 
562  // Recoiler: by default pick old one, only moved. Note excluded beam.
563  int iRec = 0;
564  if (dipNow.systemRec == iSys) {
565  for (int i = 1; i < 2 + sizeOut; ++i)
566  if (dipNow.iRecoiler == iOld[i]) {
567  iRec = iNew[i];
568  break;
569  }
570 
571  // QCD recoiler: check if colour hooks up with new final parton.
572  if ( dipNow.colType > 0
573  && event[dipNow.iRadiator].col() == event[iNewNew].acol() ) {
574  iRec = iNewNew;
575  dipNow.isrType = 0;
576  }
577  if ( dipNow.colType < 0
578  && event[dipNow.iRadiator].acol() == event[iNewNew].col() ) {
579  iRec = iNewNew;
580  dipNow.isrType = 0;
581  }
582 
583  // QCD recoiler: check if colour hooks up with new beam parton.
584  if ( iRec == 0 && dipNow.colType > 0
585  && event[dipNow.iRadiator].col() == event[iNew[0]].col() )
586  iRec = iNew[0];
587  if ( iRec == 0 && dipNow.colType < 0
588  && event[dipNow.iRadiator].acol() == event[iNew[0]].acol() )
589  iRec = iNew[0];
590 
591  // QED/photon recoiler: either to new particle or remains to beam.
592  if ( iRec == 0 && (dipNow.chgType != 0 || dipNow.gamType != 0) ) {
593  if ( event[iNew[0]].chargeType() == 0 ) {
594  iRec = iNewNew;
595  dipNow.isrType = 0;
596  } else {
597  iRec = iNew[0];
598  }
599  }
600 
601  // Recoiler in another system: keep it as is.
602  } else iRec = dipNow.iRecoiler;
603 
604  // Done. Kill dipole if failed to find new recoiler.
605  dipNow.iRecoiler = iRec;
606  if ( iRec == 0 && (dipNow.colType != 0 || dipNow.chgType != 0
607  || dipNow.gamType != 0) ) {
608  dipNow.colType = 0;
609  dipNow.chgType = 0;
610  dipNow.gamType = 0;
611  infoPtr->errorMsg("Error in TimeShower::update: "
612  "failed to locate new recoiling partner");
613  }
614  }
615 
616  // Find new dipole end formed by colour index.
617  int colTag = event[iNewNew].col();
618  if (doQCDshower && colTag > 0)
619  setupQCDdip( iSys, sizeOut, colTag, 1, event, false, true);
620 
621  // Find new dipole end formed by anticolour index.
622  int acolTag = event[iNewNew].acol();
623  if (doQCDshower && acolTag > 0)
624  setupQCDdip( iSys, sizeOut, acolTag, -1, event, false, true);
625 
626  // Find new "charge-dipole" and "photon-dipole" ends.
627  int chgType = event[iNewNew].chargeType();
628  bool doChgDip = (chgType != 0)
629  && ( ( doQEDshowerByQ && event[iNewNew].isQuark() )
630  || ( doQEDshowerByL && event[iNewNew].isLepton() ) );
631  int gamType = (event[iNewNew].id() == 22) ? 1 : 0;
632  bool doGamDip = (gamType == 1) && doQEDshowerByGamma;
633  if (doChgDip || doGamDip)
634  setupQEDdip( iSys, sizeOut, chgType, gamType, event, true);
635 
636  // Start iterate over list of rescatterers - may be empty.
637  int iRescNow = -1;
638  while (++iRescNow < int(iRescatterer.size())) {
639 
640  // Identify systems that rescatterers belong to.
641  int iOutNew = iRescatterer[iRescNow];
642  int iInNew = event[iOutNew].daughter1();
643  int iSysResc = partonSystemsPtr->getSystemOf(iInNew, true);
644 
645  // Find new and old positions of incoming partons in the system.
646  iNew.resize(0);
647  iOld.resize(0);
648  iNew.push_back( partonSystemsPtr->getInA(iSysResc) );
649  iOld.push_back( event[iNew[0]].daughter1() );
650  iNew.push_back( partonSystemsPtr->getInB(iSysResc) );
651  iOld.push_back( event[iNew[1]].daughter1() );
652 
653  // Ditto for outgoing partons.
654  sizeOut = partonSystemsPtr->sizeOut(iSysResc);
655  for (int i = 0; i < sizeOut; ++i) {
656  int iNow = partonSystemsPtr->getOut(iSysResc, i);
657  iNew.push_back( iNow );
658  iOld.push_back( event[iNow].mother1() );
659  // Add non-final to list of rescatterers.
660  if (!event[iNow].isFinal()) iRescatterer.push_back( iNow );
661  }
662 
663  // Loop over all dipole ends belonging to the system
664  // or to the recoil system, if different.
665  for (int iDip = 0; iDip < int(dipEnd.size()); ++iDip)
666  if (dipEnd[iDip].system == iSysResc
667  || dipEnd[iDip].systemRec == iSysResc) {
668  TimeDipoleEnd& dipNow = dipEnd[iDip];
669 
670  // Replace radiator (always in final state so simple).
671  for (int i = 2; i < 2 + sizeOut; ++i)
672  if (dipNow.iRadiator == iOld[i]) {
673  dipNow.iRadiator = iNew[i];
674  break;
675  }
676 
677  // Replace ME partner (always in final state, if exists, so simple).
678  for (int i = 2; i < 2 + sizeOut; ++i)
679  if (dipNow.iMEpartner == iOld[i]) {
680  dipNow.iMEpartner = iNew[i];
681  break;
682  }
683 
684  // Replace recoiler.
685  for (int i = 0; i < 2 + sizeOut; ++i)
686  if (dipNow.iRecoiler == iOld[i]) {
687  dipNow.iRecoiler = iNew[i];
688  break;
689  }
690  }
691 
692  // End iterate over list of rescatterers.
693  }
694 
695 }
696 
697 //--------------------------------------------------------------------------
698 
699 // Setup a dipole end for a QCD colour charge.
700 
701 void TimeShower::setupQCDdip( int iSys, int i, int colTag, int colSign,
702  Event& event, bool isOctetOnium, bool limitPTmaxIn) {
703 
704  // Initial values. Find if allowed to hook up beams.
705  int iRad = partonSystemsPtr->getOut(iSys, i);
706  int iRec = 0;
707  int sizeAllA = partonSystemsPtr->sizeAll(iSys);
708  int sizeOut = partonSystemsPtr->sizeOut(iSys);
709  int sizeAll = ( allowBeamRecoil ) ? sizeAllA : sizeOut;
710  int sizeIn = sizeAll - sizeOut;
711  int sizeInA = sizeAllA - sizeIn - sizeOut;
712  int iOffset = i + sizeAllA - sizeOut;
713  bool otherSystemRec = false;
714  bool allowInitial = (partonSystemsPtr->hasInAB(iSys)) ? true : false;
715  // PS dec 2010: possibility to allow for several recoilers and each with
716  // flexible normalization
717  bool isFlexible = false;
718  double flexFactor = 1.0;
719  vector<int> iRecVec(0);
720 
721  // Colour: other end by same index in beam or opposite in final state.
722  // Exclude rescattered incoming and not final outgoing.
723  if (colSign > 0)
724  for (int j = 0; j < sizeAll; ++j) if (j + sizeInA != iOffset) {
725  int iRecNow = partonSystemsPtr->getAll(iSys, j + sizeInA);
726  if ( ( j < sizeIn && event[iRecNow].col() == colTag
727  && !event[iRecNow].isRescatteredIncoming() )
728  || ( j >= sizeIn && event[iRecNow].acol() == colTag
729  && event[iRecNow].isFinal() ) ) {
730  iRec = iRecNow;
731  break;
732  }
733  }
734 
735  // Anticolour: other end by same index in beam or opposite in final state.
736  // Exclude rescattered incoming and not final outgoing.
737  if (colSign < 0)
738  for (int j = 0; j < sizeAll; ++j) if (j + sizeInA != iOffset) {
739  int iRecNow = partonSystemsPtr->getAll(iSys, j + sizeInA);
740  if ( ( j < sizeIn && event[iRecNow].acol() == colTag
741  && !event[iRecNow].isRescatteredIncoming() )
742  || ( j >= sizeIn && event[iRecNow].col() == colTag
743  && event[iRecNow].isFinal() ) ) {
744  iRec = iRecNow;
745  break;
746  }
747  }
748 
749  // Resonance decays (= no instate):
750  // other end to nearest recoiler in same system final state,
751  // by (p_i + p_j)^2 - (m_i + m_j)^2 = 2 (p_i p_j - m_i m_j).
752  // (junction colours more involved, so keep track if junction colour)
753  bool hasJunction = false;
754  if (iRec == 0 && !allowInitial) {
755  for (int iJun = 0; iJun < event.sizeJunction(); ++ iJun) {
756  // For types 1&2, all legs in final state
757  // For types 3&4, two legs in final state
758  // For types 5&6, one leg in final state
759  int iBeg = (event.kindJunction(iJun)-1)/2;
760  for (int iLeg = iBeg; iLeg < 3; ++iLeg)
761  if (event.endColJunction( iJun, iLeg) == colTag) hasJunction = true;
762  }
763  double ppMin = LARGEM2;
764  for (int j = 0; j < sizeOut; ++j) if (j != i) {
765  int iRecNow = partonSystemsPtr->getOut(iSys, j);
766  if (!event[iRecNow].isFinal()) continue;
767  double ppNow = event[iRecNow].p() * event[iRad].p()
768  - event[iRecNow].m() * event[iRad].m();
769  if (ppNow < ppMin) {
770  iRec = iRecNow;
771  ppMin = ppNow;
772  }
773  }
774  }
775 
776  // If no success then look for matching (anti)colour anywhere in final state.
777  if ( iRec == 0 || (!doInterleave && !event[iRec].isFinal()) ) {
778  iRec = 0;
779  for (int j = 0; j < event.size(); ++j) if (event[j].isFinal())
780  if ( (colSign > 0 && event[j].acol() == colTag)
781  || (colSign < 0 && event[j].col() == colTag) ) {
782  iRec = j;
783  otherSystemRec = true;
784  break;
785  }
786 
787  // If no success then look for match to non-rescattered in initial state.
788  if (iRec == 0 && allowInitial) {
789  for (int iSysR = 0; iSysR < partonSystemsPtr->sizeSys(); ++iSysR)
790  if (iSysR != iSys) {
791  int j = partonSystemsPtr->getInA(iSysR);
792  if (j > 0 && event[j].isRescatteredIncoming()) j = 0;
793  if (j > 0 && ( (colSign > 0 && event[j].col() == colTag)
794  || (colSign < 0 && event[j].acol() == colTag) ) ) {
795  iRec = j;
796  otherSystemRec = true;
797  break;
798  }
799  j = partonSystemsPtr->getInB(iSysR);
800  if (j > 0 && event[j].isRescatteredIncoming()) j = 0;
801  if (j > 0 && ( (colSign > 0 && event[j].col() == colTag)
802  || (colSign < 0 && event[j].acol() == colTag) ) ) {
803  iRec = j;
804  otherSystemRec = true;
805  break;
806  }
807  }
808  }
809  }
810 
811  // Junctions (PS&ND dec 2010)
812  // For types 1&2: all legs in final state
813  // half-strength dipoles between all legs
814  // For types 3&4, two legs in final state
815  // full-strength dipole between final-state legs
816  // For types 5&6, one leg in final state
817  // no final-state dipole end
818 
819  if (hasJunction) {
820  for (int iJun = 0; iJun < event.sizeJunction(); ++ iJun) {
821  int kindJun = event.kindJunction(iJun);
822  int iBeg = (kindJun-1)/2;
823  for (int iLeg = iBeg; iLeg < 3; ++iLeg) {
824  if (event.endColJunction( iJun, iLeg) == colTag) {
825  // For types 5&6, no other leg to recoil against. Switch off if
826  // no other particles at all, since radiation then handled by ISR.
827  // Example: qq -> ~t* : no radiation off ~t*
828  // Allow radiation + recoil if unconnected partners available
829  // Example: qq -> ~t* -> tbar ~chi0 : allow radiation off tbar,
830  // with ~chi0 as recoiler
831  if (kindJun >= 5) {
832  if (sizeOut == 1) return;
833  else break;
834  }
835  // For junction types 3 & 4, span one full-strength dipole
836  // (only look inside same decay system)
837  else if (kindJun >= 3) {
838  int iLegRec = 3-iLeg;
839  int colTagRec = event.endColJunction( iJun, iLegRec);
840  for (int j = 0; j < sizeOut; ++j) if (j != i) {
841  int iRecNow = partonSystemsPtr->getOut(iSys, j);
842  if (!event[iRecNow].isFinal()) continue;
843  if ( (colSign > 0 && event[iRecNow].col() == colTagRec)
844  || (colSign < 0 && event[iRecNow].acol() == colTagRec) ) {
845  // Only accept if staying inside same system
846  iRec = iRecNow;
847  break;
848  }
849  }
850  }
851  // For junction types 1 & 2, span two half-strength dipoles
852  // (only look inside same decay system)
853  else {
854  // Loop over two half-strength dipole connections
855  for (int jLeg = 1; jLeg <= 2; jLeg++) {
856  int iLegRec = (iLeg + jLeg) % 3;
857  int colTagRec = event.endColJunction( iJun, iLegRec);
858  for (int j = 0; j < sizeOut; ++j) if (j != i) {
859  int iRecNow = partonSystemsPtr->getOut(iSys, j);
860  if (!event[iRecNow].isFinal()) continue;
861  if ( (colSign > 0 && event[iRecNow].col() == colTagRec)
862  || (colSign < 0 && event[iRecNow].acol() == colTagRec) ) {
863  // Store recoilers in temporary array
864  iRecVec.push_back(iRecNow);
865  // Set iRec != 0 for checks below
866  iRec = iRecNow;
867  }
868  }
869  }
870 
871  } // End if-then-else of junction kinds
872 
873  } // End if leg has right color tag
874  } // End of loop over junction legs
875  } // End loop over junctions
876 
877  } // End main junction if
878 
879  // If fail, then other end to nearest recoiler in same system final state,
880  // by (p_i + p_j)^2 - (m_i + m_j)^2 = 2 (p_i p_j - m_i m_j).
881  if (iRec == 0) {
882  double ppMin = LARGEM2;
883  for (int j = 0; j < sizeOut; ++j) if (j != i) {
884  int iRecNow = partonSystemsPtr->getOut(iSys, j);
885  if (!event[iRecNow].isFinal()) continue;
886  double ppNow = event[iRecNow].p() * event[iRad].p()
887  - event[iRecNow].m() * event[iRad].m();
888  if (ppNow < ppMin) {
889  iRec = iRecNow;
890  ppMin = ppNow;
891  }
892  }
893  }
894 
895  // If fail, then other end to nearest recoiler in any system final state,
896  // by (p_i + p_j)^2 - (m_i + m_j)^2 = 2 (p_i p_j - m_i m_j).
897  if (iRec == 0) {
898  double ppMin = LARGEM2;
899  for (int iRecNow = 0; iRecNow < event.size(); ++iRecNow)
900  if (iRecNow != iRad && event[iRecNow].isFinal()) {
901  double ppNow = event[iRecNow].p() * event[iRad].p()
902  - event[iRecNow].m() * event[iRad].m();
903  if (ppNow < ppMin) {
904  iRec = iRecNow;
905  otherSystemRec = true;
906  ppMin = ppNow;
907  }
908  }
909  }
910 
911  // PS dec 2010: make sure iRec is stored in iRecVec
912  if (iRecVec.size() == 0 && iRec != 0) iRecVec.push_back(iRec);
913 
914  // Remove any zero recoilers from normalization
915  int nRec = iRecVec.size();
916  for (unsigned int mRec = 0; mRec < iRecVec.size(); ++mRec)
917  if (iRecVec[mRec] <= 0) nRec--;
918  if (nRec >= 2) {
919  isFlexible = true;
920  flexFactor = 1.0/nRec;
921  }
922 
923  // Check for failure to locate any recoiler
924  if ( nRec <= 0 ) {
925  infoPtr->errorMsg("Error in TimeShower::setupQCDdip: "
926  "failed to locate any recoiling partner");
927  return;
928  }
929 
930  // Store dipole colour end(s).
931  for (unsigned int mRec = 0; mRec < iRecVec.size(); ++mRec) {
932  iRec = iRecVec[mRec];
933  if (iRec <= 0) continue;
934  // Max scale either by parton scale or by half dipole mass.
935  double pTmax = event[iRad].scale();
936  if (limitPTmaxIn) {
937  if (iSys == 0) pTmax *= pTmaxFudge;
938  if (iSys > 0 && sizeIn > 0) pTmax *= pTmaxFudgeMPI;
939  } else pTmax = 0.5 * m( event[iRad], event[iRec]);
940  int colType = (event[iRad].id() == 21) ? 2 * colSign : colSign;
941  int isrType = (event[iRec].isFinal()) ? 0 : event[iRec].mother1();
942  // This line in case mother is a rescattered parton.
943  while (isrType > 2 + beamOffset) isrType = event[isrType].mother1();
944  if (isrType > 2) isrType -= beamOffset;
945  dipEnd.push_back( TimeDipoleEnd( iRad, iRec, pTmax,
946  colType, 0, 0, isrType, iSys, -1, -1, isOctetOnium) );
947 
948  // If hooked up with other system then find which.
949  if (otherSystemRec) {
950  int systemRec = partonSystemsPtr->getSystemOf(iRec, true);
951  if (systemRec >= 0) dipEnd.back().systemRec = systemRec;
952  dipEnd.back().MEtype = 0;
953  }
954 
955  // PS dec 2010
956  // If non-unity (flexible) normalization, set normalization factor
957  if (isFlexible) {
958  dipEnd.back().isFlexible = true;
959  dipEnd.back().flexFactor = flexFactor;
960  }
961  }
962 
963 }
964 
965 //--------------------------------------------------------------------------
966 
967 // Setup a dipole end for a QED colour charge or a photon.
968 // No failsafe choice of recoiler, so gradually widen search.
969 
970 void TimeShower::setupQEDdip( int iSys, int i, int chgType, int gamType,
971  Event& event, bool limitPTmaxIn) {
972 
973  // Initial values. Find if allowed to hook up beams.
974  int iRad = partonSystemsPtr->getOut(iSys, i);
975  int idRad = event[iRad].id();
976  int iRec = 0;
977  int sizeAllA = partonSystemsPtr->sizeAll(iSys);
978  int sizeOut = partonSystemsPtr->sizeOut(iSys);
979  int sizeAll = ( allowBeamRecoil ) ? sizeAllA : sizeOut;
980  int sizeIn = sizeAll - sizeOut;
981  int sizeInA = sizeAllA - sizeIn - sizeOut;
982  int iOffset = i + sizeAllA - sizeOut;
983  double ppMin = LARGEM2;
984  bool hasRescattered = false;
985  bool otherSystemRec = false;
986 
987  // Find nearest same- (opposide-) flavour recoiler in initial (final)
988  // state of same system, excluding rescattered (in or out) partons.
989  // Also find if system is involved in rescattering.
990  // Note: (p_i + p_j)2 - (m_i + m_j)2 = 2 (p_i p_j - m_i m_j).
991  for (int j = 0; j < sizeAll; ++j) if (j + sizeInA != iOffset) {
992  int iRecNow = partonSystemsPtr->getAll(iSys, j + sizeInA);
993  if ( (j < sizeIn && !event[iRecNow].isRescatteredIncoming())
994  || (j >= sizeIn && event[iRecNow].isFinal()) ) {
995  if ( (j < sizeIn && event[iRecNow].id() == idRad)
996  || (j >= sizeIn && event[iRecNow].id() == -idRad) ) {
997  double ppNow = event[iRecNow].p() * event[iRad].p()
998  - event[iRecNow].m() * event[iRad].m();
999  if (ppNow < ppMin) {
1000  iRec = iRecNow;
1001  ppMin = ppNow;
1002  }
1003  }
1004  } else hasRescattered = true;
1005  }
1006 
1007  // If rescattering then find nearest opposite-flavour recoiler
1008  // anywhere in final state.
1009  if (iRec == 0 && hasRescattered) {
1010  for (int iRecNow = 0; iRecNow < event.size(); ++iRecNow)
1011  if (event[iRecNow].id() == -idRad && event[iRecNow].isFinal()) {
1012  double ppNow = event[iRecNow].p() * event[iRad].p()
1013  - event[iRecNow].m() * event[iRad].m();
1014  if (ppNow < ppMin) {
1015  iRec = iRecNow;
1016  ppMin = ppNow;
1017  otherSystemRec = true;
1018  }
1019  }
1020  }
1021 
1022  // Find nearest recoiler in same system, charge-squared-weighted,
1023  // including initial state, but excluding rescatterer.
1024  if (iRec == 0)
1025  for (int j = 0; j < sizeAll; ++j) if (j + sizeInA != iOffset) {
1026  int iRecNow = partonSystemsPtr->getAll(iSys, j + sizeInA);
1027  int chgTypeRecNow = event[iRecNow].chargeType();
1028  if (chgTypeRecNow == 0) continue;
1029  if ( (j < sizeIn && !event[iRecNow].isRescatteredIncoming())
1030  || (j >= sizeIn && event[iRecNow].isFinal()) ) {
1031  double ppNow = (event[iRecNow].p() * event[iRad].p()
1032  - event[iRecNow].m() * event[iRad].m())
1033  / pow2(chgTypeRecNow);
1034  if (ppNow < ppMin) {
1035  iRec = iRecNow;
1036  ppMin = ppNow;
1037  }
1038  }
1039  }
1040 
1041  // If rescattering then find nearest recoiler in the final state,
1042  // charge-squared-weighted.
1043  if (iRec == 0 && hasRescattered) {
1044  for (int iRecNow = 0; iRecNow < event.size(); ++iRecNow)
1045  if (iRecNow != iRad && event[iRecNow].isFinal()) {
1046  int chgTypeRecNow = event[iRecNow].chargeType();
1047  if (chgTypeRecNow != 0 && event[iRecNow].isFinal()) {
1048  double ppNow = (event[iRecNow].p() * event[iRad].p()
1049  - event[iRecNow].m() * event[iRad].m())
1050  / pow2(chgTypeRecNow);
1051  if (ppNow < ppMin) {
1052  iRec = iRecNow;
1053  ppMin = ppNow;
1054  otherSystemRec = true;
1055  }
1056  }
1057  }
1058  }
1059 
1060  // Find any nearest recoiler in final state of same system.
1061  if (iRec == 0)
1062  for (int j = 0; j < sizeOut; ++j) if (j != i) {
1063  int iRecNow = partonSystemsPtr->getOut(iSys, j);
1064  double ppNow = event[iRecNow].p() * event[iRad].p()
1065  - event[iRecNow].m() * event[iRad].m();
1066  if (ppNow < ppMin) {
1067  iRec = iRecNow;
1068  ppMin = ppNow;
1069  }
1070  }
1071 
1072  // Find any nearest recoiler in final state.
1073  if (iRec == 0)
1074  for (int iRecNow = 0; iRecNow < event.size(); ++iRecNow)
1075  if (iRecNow != iRad && event[iRecNow].isFinal()) {
1076  double ppNow = event[iRecNow].p() * event[iRad].p()
1077  - event[iRecNow].m() * event[iRad].m();
1078  if (ppNow < ppMin) {
1079  iRec = iRecNow;
1080  ppMin = ppNow;
1081  otherSystemRec = true;
1082  }
1083  }
1084 
1085  // Fill charge-dipole or photon-dipole end.
1086  if (iRec > 0) {
1087  // Max scale either by parton scale or by half dipole mass.
1088  double pTmax = event[iRad].scale();
1089  if (limitPTmaxIn) {
1090  if (iSys == 0) pTmax *= pTmaxFudge;
1091  if (iSys > 0 && sizeIn > 0) pTmax *= pTmaxFudgeMPI;
1092  } else pTmax = 0.5 * m( event[iRad], event[iRec]);
1093  int isrType = (event[iRec].isFinal()) ? 0 : event[iRec].mother1();
1094  // This line in case mother is a rescattered parton.
1095  while (isrType > 2 + beamOffset) isrType = event[isrType].mother1();
1096  if (isrType > 2) isrType -= beamOffset;
1097  dipEnd.push_back( TimeDipoleEnd(iRad, iRec, pTmax,
1098  0, chgType, gamType, isrType, iSys, -1) );
1099 
1100  // If hooked up with other system then find which.
1101  if (otherSystemRec) {
1102  int systemRec = partonSystemsPtr->getSystemOf(iRec);
1103  if (systemRec >= 0) dipEnd.back().systemRec = systemRec;
1104  dipEnd.back().MEtype = 0;
1105  }
1106 
1107  // Failure to find other end of dipole.
1108  } else {
1109  infoPtr->errorMsg("Error in TimeShower::setupQEDdip: "
1110  "failed to locate any recoiling partner");
1111  }
1112 
1113 }
1114 
1115 //--------------------------------------------------------------------------
1116 
1117 // Setup a dipole end for a Hidden Valley colour charge.
1118 
1119 void TimeShower::setupHVdip( int iSys, int i, Event& event,
1120  bool limitPTmaxIn) {
1121 
1122  // Initial values.
1123  int iRad = partonSystemsPtr->getOut(iSys, i);
1124  int iRec = 0;
1125  int idRad = event[iRad].id();
1126  int sizeOut = partonSystemsPtr->sizeOut(iSys);
1127 
1128  // Hidden Valley colour positive for positive id, and vice versa.
1129  // Find opposte HV colour in final state of same system.
1130  for (int j = 0; j < sizeOut; ++j) if (j != i) {
1131  int iRecNow = partonSystemsPtr->getOut(iSys, j);
1132  int idRec = event[iRecNow].id();
1133  if ( (abs(idRec) > 4900000 && abs(idRec) < 4900017)
1134  && idRad * idRec < 0) {
1135  iRec = iRecNow;
1136  break;
1137  }
1138  }
1139 
1140  // Else find heaviest other final-state in same system.
1141  // (Intended for decays; should mainly be two-body so unique.)
1142  double mMax = -sqrt(LARGEM2);
1143  if (iRec == 0)
1144  for (int j = 0; j < sizeOut; ++j) if (j != i) {
1145  int iRecNow = partonSystemsPtr->getOut(iSys, j);
1146  if (event[iRecNow].m() > mMax) {
1147  iRec = iRecNow;
1148  mMax = event[iRecNow].m();
1149  }
1150  }
1151 
1152  // Set up dipole end, or report failure.
1153  if (iRec > 0) {
1154  // Max scale either by parton scale or by half dipole mass.
1155  double pTmax = event[iRad].scale();
1156  if (limitPTmaxIn) {
1157  if (iSys == 0) pTmax *= pTmaxFudge;
1158  } else pTmax = 0.5 * m( event[iRad], event[iRec]);
1159  int colvType = (event[iRad].id() > 0) ? 1 : -1;
1160  dipEnd.push_back( TimeDipoleEnd( iRad, iRec, pTmax, 0, 0, 0, 0,
1161  iSys, -1, -1, false, true, colvType) );
1162  } else infoPtr->errorMsg("Error in TimeShower::setupHVdip: "
1163  "failed to locate any recoiling partner");
1164 
1165 }
1166 
1167 //--------------------------------------------------------------------------
1168 
1169 // Select next pT in downwards evolution of the existing dipoles.
1170 
1171 double TimeShower::pTnext( Event& event, double pTbegAll, double pTendAll) {
1172 
1173  // Begin loop over all possible radiating dipole ends.
1174  dipSel = 0;
1175  iDipSel = -1;
1176  double pT2sel = pTendAll * pTendAll;
1177  for (int iDip = 0; iDip < int(dipEnd.size()); ++iDip) {
1178  TimeDipoleEnd& dip = dipEnd[iDip];
1179 
1180  // Check if global recoil should be used.
1181  useLocalRecoilNow = !(globalRecoil && dip.system == 0
1182  && partonSystemsPtr->sizeOut(0) <= nMaxGlobalRecoil);
1183 
1184  // Dipole properties; normal local recoil.
1185  dip.mRad = event[dip.iRadiator].m();
1186  if (useLocalRecoilNow) {
1187  dip.mRec = event[dip.iRecoiler].m();
1188  dip.mDip = m( event[dip.iRadiator], event[dip.iRecoiler] );
1189 
1190  // Dipole properties, alternative global recoil. Squares.
1191  } else {
1192  Vec4 pSumGlobal;
1193  for (int i = 0; i < partonSystemsPtr->sizeOut( dip.system); ++i) {
1194  int ii = partonSystemsPtr->getOut( dip.system, i);
1195  if (ii != dip.iRadiator) pSumGlobal += event[ii].p();
1196  }
1197  dip.mRec = pSumGlobal.mCalc();
1198  dip.mDip = m( event[dip.iRadiator].p(), pSumGlobal);
1199  }
1200  dip.m2Rad = pow2(dip.mRad);
1201  dip.m2Rec = pow2(dip.mRec);
1202  dip.m2Dip = pow2(dip.mDip);
1203 
1204  // Find maximum evolution scale for dipole.
1205  dip.m2DipCorr = pow2(dip.mDip - dip.mRec) - dip.m2Rad;
1206  double pTbegDip = min( pTbegAll, dip.pTmax );
1207  double pT2begDip = min( pow2(pTbegDip), 0.25 * dip.m2DipCorr);
1208 
1209  // Do QCD, QED or HV evolution if it makes sense.
1210  dip.pT2 = 0.;
1211  if (pT2begDip > pT2sel) {
1212  if (dip.colType != 0)
1213  pT2nextQCD(pT2begDip, pT2sel, dip, event);
1214  else if (dip.chgType != 0 || dip.gamType != 0)
1215  pT2nextQED(pT2begDip, pT2sel, dip, event);
1216  else if (dip.colvType != 0)
1217  pT2nextHV(pT2begDip, pT2sel, dip, event);
1218 
1219  // Update if found larger pT than current maximum.
1220  if (dip.pT2 > pT2sel) {
1221  pT2sel = dip.pT2;
1222  dipSel = &dip;
1223  iDipSel = iDip;
1224  }
1225  }
1226  }
1227 
1228  // Return nonvanishing value if found pT bigger than already found.
1229  return (dipSel == 0) ? 0. : sqrt(pT2sel);
1230 
1231 }
1232 
1233 //--------------------------------------------------------------------------
1234 
1235 // Evolve a QCD dipole end.
1236 
1237 void TimeShower::pT2nextQCD(double pT2begDip, double pT2sel,
1238  TimeDipoleEnd& dip, Event& event) {
1239 
1240  // Lower cut for evolution. Return if no evolution range.
1241  double pT2endDip = max( pT2sel, pT2colCut );
1242  if (pT2begDip < pT2endDip) return;
1243 
1244  // Upper estimate for matrix element weighting and colour factor.
1245  // Special cases for triplet recoiling against gluino and octet onia.
1246  // Note that g -> g g and g -> q qbar are split on two sides.
1247  int colTypeAbs = abs(dip.colType);
1248  double wtPSglue = 2.;
1249  double colFac = (colTypeAbs == 1) ? 4./3. : 3./2.;
1250  if (dip.MEgluinoRec) colFac = 3.;
1251  if (dip.isOctetOnium) colFac *= 0.5 * octetOniumColFac;
1252  // PS dec 2010. Include possibility for flexible normalization,
1253  // e.g., for dipoles stretched to junctions or to switch off radiation.
1254  if (dip.isFlexible) colFac *= dip.flexFactor;
1255  double wtPSqqbar = (colTypeAbs == 2) ? 0.25 * nGluonToQuark : 0.;
1256 
1257  // Variables used inside evolution loop. (Mainly dummy start values.)
1258  dip.pT2 = pT2begDip;
1259  int nFlavour = 3;
1260  double zMinAbs = 0.5;
1261  double pT2min = pT2endDip;
1262  double b0 = 4.5;
1263  double Lambda2 = Lambda3flav2;
1264  double emitCoefGlue = 0.;
1265  double emitCoefQqbar = 0.;
1266  double emitCoefTot = 0.;
1267  double wt = 0.;
1268  bool mustFindRange = true;
1269 
1270  // Begin evolution loop towards smaller pT values.
1271  do {
1272 
1273  // Initialize evolution coefficients at the beginning and
1274  // reinitialize when crossing c and b flavour thresholds.
1275  if (mustFindRange) {
1276 
1277  // Determine overestimated z range; switch at c and b masses.
1278  if (dip.pT2 > m2b) {
1279  nFlavour = 5;
1280  pT2min = max( m2b, pT2endDip);
1281  b0 = 23./6.;
1282  Lambda2 = Lambda5flav2;
1283  } else if (dip.pT2 > m2c) {
1284  nFlavour = 4;
1285  pT2min = max( m2c, pT2endDip);
1286  b0 = 25./6.;
1287  Lambda2 = Lambda4flav2;
1288  } else {
1289  nFlavour = 3;
1290  pT2min = pT2endDip;
1291  b0 = 27./6.;
1292  Lambda2 = Lambda3flav2;
1293  }
1294  zMinAbs = 0.5 - sqrtpos( 0.25 - pT2min / dip.m2DipCorr );
1295  if (zMinAbs < SIMPLIFYROOT) zMinAbs = pT2min / dip.m2DipCorr;
1296 
1297  // Find emission coefficients for X -> X g and g -> q qbar.
1298  emitCoefGlue = wtPSglue * colFac * log(1. / zMinAbs - 1.);
1299  emitCoefTot = emitCoefGlue;
1300  if (colTypeAbs == 2 && event[dip.iRadiator].id() == 21) {
1301  emitCoefQqbar = wtPSqqbar * (1. - 2. * zMinAbs);
1302  emitCoefTot += emitCoefQqbar;
1303  }
1304 
1305  // Initialization done for current range.
1306  mustFindRange = false;
1307  }
1308 
1309  // Pick pT2 (in overestimated z range) for fixed alpha_strong.
1310  if (alphaSorder == 0) {
1311  dip.pT2 = dip.pT2 * pow( rndmPtr->flat(),
1312  1. / (alphaS2pi * emitCoefTot) );
1313 
1314  // Ditto for first-order alpha_strong.
1315  } else if (alphaSorder == 1) {
1316  dip.pT2 = Lambda2 * pow( dip.pT2 / Lambda2,
1317  pow( rndmPtr->flat(), b0 / emitCoefTot) );
1318 
1319  // For second order reject by second term in alpha_strong expression.
1320  } else {
1321  do dip.pT2 = Lambda2 * pow( dip.pT2 / Lambda2,
1322  pow( rndmPtr->flat(), b0 / emitCoefTot) );
1323  while (alphaS.alphaS2OrdCorr(dip.pT2) < rndmPtr->flat()
1324  && dip.pT2 > pT2min);
1325  }
1326  wt = 0.;
1327 
1328  // If crossed c or b thresholds: continue evolution from threshold.
1329  if (nFlavour == 5 && dip.pT2 < m2b) {
1330  mustFindRange = true;
1331  dip.pT2 = m2b;
1332  } else if ( nFlavour == 4 && dip.pT2 < m2c) {
1333  mustFindRange = true;
1334  dip.pT2 = m2c;
1335 
1336  // Abort evolution if below cutoff scale, or below another branching.
1337  } else {
1338  if ( dip.pT2 < pT2endDip) { dip.pT2 = 0.; return; }
1339 
1340  // Pick kind of branching: X -> X g or g -> q qbar.
1341  dip.flavour = 21;
1342  dip.mFlavour = 0.;
1343  if (colTypeAbs == 2 && emitCoefQqbar > rndmPtr->flat()
1344  * emitCoefTot) dip.flavour = 0;
1345 
1346  // Pick z: either dz/(1-z) or flat dz.
1347  if (dip.flavour == 21) {
1348  dip.z = 1. - zMinAbs * pow( 1. / zMinAbs - 1., rndmPtr->flat() );
1349  } else {
1350  dip.z = zMinAbs + (1. - 2. * zMinAbs) * rndmPtr->flat();
1351  }
1352 
1353  // Do not accept branching if outside allowed z range.
1354  double zMin = 0.5 - sqrtpos( 0.25 - dip.pT2 / dip.m2DipCorr );
1355  if (zMin < SIMPLIFYROOT) zMin = dip.pT2 / dip.m2DipCorr;
1356  dip.m2 = dip.m2Rad + dip.pT2 / (dip.z * (1. - dip.z));
1357  if (dip.z > zMin && dip.z < 1. - zMin
1358  && dip.m2 * dip.m2Dip < dip.z * (1. - dip.z)
1359  * pow2(dip.m2Dip + dip.m2 - dip.m2Rec) ) {
1360 
1361  // Flavour choice for g -> q qbar.
1362  if (dip.flavour == 0) {
1363  dip.flavour = min(5, 1 + int(nGluonToQuark * rndmPtr->flat()));
1364  dip.mFlavour = particleDataPtr->m0(dip.flavour);
1365  }
1366 
1367  // No z weight, except threshold, if to do ME corrections later on.
1368  if (dip.MEtype > 0) {
1369  wt = 1.;
1370  if (dip.flavour < 10 && dip.m2 < THRESHM2 * pow2(dip.mFlavour))
1371  wt = 0.;
1372 
1373  // z weight for X -> X g.
1374  } else if (dip.flavour == 21
1375  && (colTypeAbs == 1 || colTypeAbs == 3) ) {
1376  wt = (1. + pow2(dip.z)) / wtPSglue;
1377  } else if (dip.flavour == 21) {
1378  wt = (1. + pow3(dip.z)) / wtPSglue;
1379 
1380  // z weight for g -> q qbar.
1381  } else {
1382  double beta = sqrtpos( 1. - 4. * pow2(dip.mFlavour) / dip.m2 );
1383  wt = beta * ( pow2(dip.z) + pow2(1. - dip.z) );
1384  }
1385 
1386  // Suppression factors for dipole to beam remnant.
1387  if (dip.isrType != 0 && useLocalRecoilNow) {
1388  BeamParticle& beam = (dip.isrType == 1) ? *beamAPtr : *beamBPtr;
1389  int iSysRec = dip.systemRec;
1390  double xOld = beam[iSysRec].x();
1391  double xNew = xOld * (1. + (dip.m2 - dip.m2Rad) /
1392  (dip.m2Dip - dip.m2Rad));
1393  double xMaxAbs = beam.xMax(iSysRec);
1394  if (xMaxAbs < 0.) {
1395  infoPtr->errorMsg("Warning in TimeShower::pT2nextQCD: "
1396  "xMaxAbs negative");
1397  return;
1398  }
1399 
1400  // Firstly reduce by PDF ratio.
1401  if (xNew > xMaxAbs) wt = 0.;
1402  else {
1403  int idRec = event[dip.iRecoiler].id();
1404  double pdfOld = max ( TINYPDF,
1405  beam.xfISR( iSysRec, idRec, xOld, dip.pT2) );
1406  double pdfNew = beam.xfISR( iSysRec, idRec, xNew, dip.pT2);
1407  wt *= min( 1., pdfNew / pdfOld);
1408  }
1409 
1410  // Secondly optionally reduce by 4 pT2_hard / (4 pT2_hard + m2).
1411  if (dampenBeamRecoil) {
1412  double pTpT = sqrt(event[dip.iRadiator].pT2() * dip.pT2);
1413  wt *= pTpT / (pTpT + dip.m2);
1414  }
1415  }
1416  }
1417  }
1418 
1419  // Iterate until acceptable pT (or have fallen below pTmin).
1420  } while (wt < rndmPtr->flat());
1421 
1422 }
1423 
1424 //--------------------------------------------------------------------------
1425 
1426 // Evolve a QED dipole end, either charged or photon.
1427 
1428 void TimeShower::pT2nextQED(double pT2begDip, double pT2sel,
1429  TimeDipoleEnd& dip, Event& event) {
1430 
1431  // Lower cut for evolution. Return if no evolution range.
1432  double pT2chgCut = (dip.chgType != 0 && abs(dip.chgType) != 3)
1433  ? pT2chgQCut : pT2chgLCut;
1434  double pT2endDip = max( pT2sel, pT2chgCut );
1435  if (pT2begDip < pT2endDip) return;
1436 
1437  // Emission of photon or photon branching.
1438  bool hasCharge = (dip.chgType != 0);
1439 
1440  // Default values.
1441  double wtPSgam = 0.;
1442  double chg2Sum = 0.;
1443  double chg2SumL = 0.;
1444  double chg2SumQ = 0.;
1445  double zMinAbs = 0.;
1446  double emitCoefTot = 0.;
1447 
1448  // alpha_em at maximum scale provides upper estimate.
1449  double alphaEMmax = alphaEM.alphaEM(pT2begDip);
1450  double alphaEM2pi = alphaEMmax / (2. * M_PI);
1451 
1452  // Emission: upper estimate for matrix element weighting; charge factor.
1453  if (hasCharge) {
1454  wtPSgam = 2.;
1455  double chg2 = pow2(dip.chgType / 3.);
1456 
1457  // Determine overestimated z range. Find evolution coefficient.
1458  zMinAbs = 0.5 - sqrtpos( 0.25 - pT2endDip / dip.m2DipCorr );
1459  if (zMinAbs < SIMPLIFYROOT) zMinAbs = pT2endDip / dip.m2DipCorr;
1460  emitCoefTot = alphaEM2pi * chg2 * wtPSgam * log(1. / zMinAbs - 1.);
1461 
1462  // Branching: sum of squared charge factors for lepton and quark daughters.
1463  } else {
1464  chg2SumL = max(0, min(3, nGammaToLepton));
1465  if (nGammaToQuark > 4) chg2SumQ = 11. / 9.;
1466  else if (nGammaToQuark > 3) chg2SumQ = 10. / 9.;
1467  else if (nGammaToQuark > 2) chg2SumQ = 6. / 9.;
1468  else if (nGammaToQuark > 1) chg2SumQ = 5. / 9.;
1469  else if (nGammaToQuark > 0) chg2SumQ = 1. / 9.;
1470 
1471  // Total sum of squared charge factors. Find evolution coefficient.
1472  chg2Sum = chg2SumL + 3. * chg2SumQ;
1473  emitCoefTot = alphaEM2pi * chg2Sum;
1474  }
1475 
1476  // Variables used inside evolution loop.
1477  dip.pT2 = pT2begDip;
1478  double wt;
1479 
1480  // Begin evolution loop towards smaller pT values.
1481  do {
1482 
1483  // Pick pT2 (in overestimated z range).
1484  dip.pT2 = dip.pT2 * pow(rndmPtr->flat(), 1. / emitCoefTot);
1485  wt = 0.;
1486 
1487  // Abort evolution if below cutoff scale, or below another branching.
1488  if ( dip.pT2 < pT2endDip) { dip.pT2 = 0.; return; }
1489 
1490  // Pick z according to dz/(1-z) or flat.
1491  if (hasCharge) dip.z = 1. - zMinAbs
1492  * pow( 1. / zMinAbs - 1., rndmPtr->flat() );
1493  else dip.z = rndmPtr->flat();
1494 
1495  // Do not accept branching if outside allowed z range.
1496  double zMin = 0.5 - sqrtpos( 0.25 - dip.pT2 / dip.m2DipCorr );
1497  if (zMin < SIMPLIFYROOT) zMin = dip.pT2 / dip.m2DipCorr;
1498  dip.m2 = dip.m2Rad + dip.pT2 / (dip.z * (1. - dip.z));
1499  if (dip.z > zMin && dip.z < 1. - zMin
1500  && dip.m2 * dip.m2Dip < dip.z * (1. - dip.z)
1501  * pow2(dip.m2Dip + dip.m2 - dip.m2Rec)
1502  // For gamma -> f fbar also impose maximum mass.
1503  && (hasCharge || dip.m2 < m2MaxGamma) ) {
1504 
1505  // Photon emission: unique flavour choice.
1506  if (hasCharge) {
1507  dip.flavour = 22;
1508  dip.mFlavour = 0.;
1509 
1510  // Photon branching: either lepton or quark flavour choice.
1511  } else {
1512  if (rndmPtr->flat() * chg2Sum < chg2SumL)
1513  dip.flavour = 9 + 2 * min(3, 1 + int(chg2SumL * rndmPtr->flat()));
1514  else {
1515  double rndmQ = 9. * chg2SumQ * rndmPtr->flat();
1516  if (rndmQ < 1.) dip.flavour = 1;
1517  else if (rndmQ < 5.) dip.flavour = 2;
1518  else if (rndmQ < 6.) dip.flavour = 3;
1519  else if (rndmQ < 10.) dip.flavour = 4;
1520  else dip.flavour = 5;
1521  }
1522  dip.mFlavour = particleDataPtr->m0(dip.flavour);
1523  }
1524 
1525 
1526  // No z weight, except threshold, if to do ME corrections later on.
1527  if (dip.MEtype > 0) {
1528  wt = 1.;
1529  if (dip.flavour < 20 && dip.m2 < THRESHM2 * pow2(dip.mFlavour))
1530  wt = 0.;
1531 
1532  // z weight for X -> X gamma.
1533  } else if (hasCharge) {
1534  wt = (1. + pow2(dip.z)) / wtPSgam;
1535 
1536  // z weight for gamma -> f fbar.
1537  } else {
1538  double beta = sqrtpos( 1. - 4. * pow2(dip.mFlavour) / dip.m2 );
1539  wt = beta * ( pow2(dip.z) + pow2(1. - dip.z) );
1540  }
1541 
1542  // Correct to current value of alpha_EM.
1543  double alphaEMnow = alphaEM.alphaEM(dip.pT2);
1544  wt *= (alphaEMnow / alphaEMmax);
1545 
1546  // Suppression factors for dipole to beam remnant.
1547  if (dip.isrType != 0 && useLocalRecoilNow) {
1548  BeamParticle& beam = (dip.isrType == 1) ? *beamAPtr : *beamBPtr;
1549  int iSys = dip.system;
1550  double xOld = beam[iSys].x();
1551  double xNew = xOld * (1. + (dip.m2 - dip.m2Rad) /
1552  (dip.m2Dip - dip.m2Rad));
1553  double xMaxAbs = beam.xMax(iSys);
1554  if (xMaxAbs < 0.) {
1555  infoPtr->errorMsg("Warning in TimeShower::pT2nextQED: "
1556  "xMaxAbs negative");
1557  return;
1558  }
1559 
1560  // Firstly reduce by PDF ratio.
1561  if (xNew > xMaxAbs) wt = 0.;
1562  else {
1563  int idRec = event[dip.iRecoiler].id();
1564  double pdfOld = max ( TINYPDF,
1565  beam.xfISR( iSys, idRec, xOld, dip.pT2) );
1566  double pdfNew = beam.xfISR( iSys, idRec, xNew, dip.pT2);
1567  wt *= min( 1., pdfNew / pdfOld);
1568  }
1569 
1570  // Secondly optionally reduce by 4 pT2_hard / (4 pT2_hard + m2).
1571  if (dampenBeamRecoil) {
1572  double pT24 = 4. * event[dip.iRadiator].pT2();
1573  wt *= pT24 / (pT24 + dip.m2);
1574  }
1575  }
1576  }
1577 
1578  // Iterate until acceptable pT (or have fallen below pTmin).
1579  } while (wt < rndmPtr->flat());
1580 
1581 }
1582 
1583 //--------------------------------------------------------------------------
1584 
1585 // Evolve a Hidden Valley dipole end.
1586 
1587 void TimeShower::pT2nextHV(double pT2begDip, double pT2sel,
1588  TimeDipoleEnd& dip, Event& ) {
1589 
1590  // Lower cut for evolution. Return if no evolution range.
1591  double pT2endDip = max( pT2sel, pT2hvCut );
1592  if (pT2begDip < pT2endDip) return;
1593 
1594  // C_F * alpha_HV/2 pi.
1595  int colvTypeAbs = abs(dip.colvType);
1596  double colvFac = (colvTypeAbs == 1) ? CFHV : 0.5 * nCHV;
1597  double alphaHV2pi = colvFac * (alphaHVfix / (2. * M_PI));
1598 
1599  // Determine overestimated z range. Find evolution coefficient.
1600  double zMinAbs = 0.5 - sqrtpos( 0.25 - pT2endDip / dip.m2DipCorr );
1601  if (zMinAbs < SIMPLIFYROOT) zMinAbs = pT2endDip / dip.m2DipCorr;
1602  double emitCoefTot = alphaHV2pi * 2. * log(1. / zMinAbs - 1.);
1603 
1604  // Variables used inside evolution loop.
1605  dip.pT2 = pT2begDip;
1606  double wt;
1607 
1608  // Begin evolution loop towards smaller pT values.
1609  do {
1610 
1611  // Pick pT2 (in overestimated z range).
1612  dip.pT2 = dip.pT2 * pow(rndmPtr->flat(), 1. / emitCoefTot);
1613  wt = 0.;
1614 
1615  // Abort evolution if below cutoff scale, or below another branching.
1616  if ( dip.pT2 < pT2endDip) { dip.pT2 = 0.; return; }
1617 
1618  // Pick z according to dz/(1-z).
1619  dip.z = 1. - zMinAbs * pow( 1. / zMinAbs - 1., rndmPtr->flat() );
1620 
1621  // Do not accept branching if outside allowed z range.
1622  double zMin = 0.5 - sqrtpos( 0.25 - dip.pT2 / dip.m2DipCorr );
1623  if (zMin < SIMPLIFYROOT) zMin = dip.pT2 / dip.m2DipCorr;
1624  dip.m2 = dip.m2Rad + dip.pT2 / (dip.z * (1. - dip.z));
1625  if (dip.z > zMin && dip.z < 1. - zMin
1626  && dip.m2 * dip.m2Dip < dip.z * (1. - dip.z)
1627  * pow2(dip.m2Dip + dip.m2 - dip.m2Rec) ) {
1628 
1629  // HV gamma or gluon emission: unique flavour choice.
1630  dip.flavour = idHV;
1631  dip.mFlavour = mHV;
1632 
1633  // No z weight, except threshold, if to do ME corrections later on.
1634  if (dip.MEtype > 0) wt = 1.;
1635 
1636  // z weight for X -> X g_HV.
1637  else if (colvTypeAbs == 1) wt = (1. + pow2(dip.z)) / 2.;
1638  else wt = (1. + pow3(dip.z)) / 2.;
1639  }
1640 
1641  // Iterate until acceptable pT (or have fallen below pTmin).
1642  } while (wt < rndmPtr->flat());
1643 
1644 }
1645 
1646 //--------------------------------------------------------------------------
1647 
1648 // ME corrections and kinematics that may give failure.
1649 // Notation: radBef, recBef = radiator, recoiler before emission,
1650 // rad, rec, emt = radiator, recoiler, emitted efter emission.
1651 // (rad, emt distinguished by colour flow for g -> q qbar.)
1652 
1653 bool TimeShower::branch( Event& event, bool isInterleaved) {
1654 
1655  // Check if global recoil should be used.
1656  useLocalRecoilNow = !(globalRecoil && dipSel->system == 0
1657  && partonSystemsPtr->sizeOut(0) <= nMaxGlobalRecoil);
1658 
1659  // Find initial radiator and recoiler particles in dipole branching.
1660  int iRadBef = dipSel->iRadiator;
1661  int iRecBef = dipSel->iRecoiler;
1662  Particle& radBef = event[iRadBef];
1663  Particle& recBef = event[iRecBef];
1664 
1665  // Find their momenta, with special sum for global recoil.
1666  Vec4 pRadBef = event[iRadBef].p();
1667  Vec4 pRecBef;
1668  vector<int> iGRecBef, iGRec;
1669  if (useLocalRecoilNow) pRecBef = event[iRecBef].p();
1670  else {
1671  for (int i = 0; i < partonSystemsPtr->sizeOut( dipSel->system); ++i) {
1672  int iG = partonSystemsPtr->getOut( dipSel->system, i);
1673  if (iG != dipSel->iRadiator) {
1674  iGRecBef.push_back(iG);
1675  pRecBef += event[iG].p();
1676  }
1677  }
1678  }
1679 
1680  // Default flavours and colour tags for new particles in dipole branching.
1681  int idRad = radBef.id();
1682  int idEmt = dipSel->flavour;
1683  int colRad = radBef.col();
1684  int acolRad = radBef.acol();
1685  int colEmt = 0;
1686  int acolEmt = 0;
1687  iSysSel = dipSel->system;
1688  int iSysSelRec = dipSel->systemRec;
1689 
1690  // Default OK for photon, photon_HV or gluon_HV emission.
1691  if (dipSel->flavour == 22 || dipSel->flavour == idHV) {
1692  // New colour tag required for gluon emission.
1693  } else if (dipSel->flavour == 21 && dipSel->colType > 0) {
1694  colEmt = colRad;
1695  colRad = event.nextColTag();
1696  acolEmt = colRad;
1697  } else if (dipSel->flavour == 21) {
1698  acolEmt = acolRad;
1699  acolRad = event.nextColTag();
1700  colEmt = acolRad;
1701  // New flavours for g -> q qbar; split colours.
1702  } else if (dipSel->colType > 0) {
1703  idEmt = dipSel->flavour ;
1704  idRad = -idEmt;
1705  colEmt = colRad;
1706  colRad = 0;
1707  } else if (dipSel->colType < 0) {
1708  idEmt = -dipSel->flavour ;
1709  idRad = -idEmt;
1710  acolEmt = acolRad;
1711  acolRad = 0;
1712  // New flavours for gamma -> f fbar, and maybe also colours.
1713  } else if (dipSel->gamType == 1 && rndmPtr->flat() > 0.5) {
1714  idEmt = -dipSel->flavour ;
1715  idRad = -idEmt;
1716  if (idRad < 10) colRad = event.nextColTag();
1717  acolEmt = colRad;
1718  } else if (dipSel->gamType == 1) {
1719  idEmt = dipSel->flavour ;
1720  idRad = -idEmt;
1721  if (idEmt < 10) colEmt = event.nextColTag();
1722  acolRad = colEmt;
1723  }
1724 
1725  // Construct kinematics in dipole rest frame:
1726  // begin simple (like g -> g g).
1727  double pTorig = sqrt( dipSel->pT2);
1728  double eRadPlusEmt = 0.5 * (dipSel->m2Dip + dipSel->m2 - dipSel->m2Rec)
1729  / dipSel->mDip;
1730  double e2RadPlusEmt = pow2(eRadPlusEmt);
1731  double pzRadPlusEmt = 0.5 * sqrtpos( pow2(dipSel->m2Dip - dipSel->m2
1732  - dipSel->m2Rec) - 4. * dipSel->m2 * dipSel->m2Rec ) / dipSel->mDip;
1733  double pT2corr = dipSel->m2 * (e2RadPlusEmt * dipSel->z * (1. - dipSel->z)
1734  - 0.25 * dipSel->m2) / pow2(pzRadPlusEmt);
1735  double pTcorr = sqrtpos( pT2corr );
1736  double pzRad = (e2RadPlusEmt * dipSel->z - 0.5 * dipSel->m2)
1737  / pzRadPlusEmt;
1738  double pzEmt = (e2RadPlusEmt * (1. - dipSel->z) - 0.5 * dipSel->m2)
1739  / pzRadPlusEmt;
1740  double mRad = dipSel->mRad;
1741  double mEmt = 0.;
1742 
1743  // Kinematics reduction for q -> q gamma_v when m_q > 0 and m_gamma_v > 0.
1744  if ( abs(dipSel->colvType) == 1 && dipSel->mFlavour > 0.) {
1745  mEmt = dipSel->mFlavour;
1746  if (pow2(mRad + mEmt) > dipSel->m2) return false;
1747  double m2Emt = pow2(mEmt);
1748  double lambda = sqrtpos( pow2(dipSel->m2 - dipSel->m2Rad - m2Emt)
1749  - 4. * dipSel->m2Rad * m2Emt );
1750  kRad = 0.5 * (dipSel->m2 - lambda + m2Emt - dipSel->m2Rad)
1751  / dipSel->m2;
1752  kEmt = 0.5 * (dipSel->m2 - lambda + dipSel->m2Rad - m2Emt)
1753  / dipSel->m2;
1754  pTorig *= 1. - kRad - kEmt;
1755  pTcorr *= 1. - kRad - kEmt;
1756  double pzMove = kRad * pzRad - kEmt * pzEmt;
1757  pzRad -= pzMove;
1758  pzEmt += pzMove;
1759 
1760  // Kinematics reduction for q -> q g/gamma/g_HV when m_q > 0.
1761  } else if (abs(dipSel->colType) == 1 || dipSel->chgType != 0
1762  || abs(dipSel->colvType) == 1) {
1763  pTorig *= 1. - dipSel->m2Rad / dipSel->m2;
1764  pTcorr *= 1. - dipSel->m2Rad / dipSel->m2;
1765  pzRad += pzEmt * dipSel->m2Rad / dipSel->m2;
1766  pzEmt *= 1. - dipSel->m2Rad / dipSel->m2;
1767 
1768  // Kinematics reduction for g -> q qbar or gamma -> f fbar when m_f > 0;
1769  } else if (abs(dipSel->flavour) < 20) {
1770  mEmt = dipSel->mFlavour;
1771  mRad = mEmt;
1772  double beta = sqrtpos( 1. - 4. * pow2(mEmt) / dipSel->m2 );
1773  pTorig *= beta;
1774  pTcorr *= beta;
1775  pzRad = 0.5 * ( (1. + beta) * pzRad + (1. - beta) * pzEmt );
1776  pzEmt = pzRadPlusEmt - pzRad;
1777  }
1778 
1779  // Reject g emission where mass effects have reduced pT below cutoff.
1780  if (idEmt == 21 && pTorig < pTcolCut) return false;
1781 
1782  // Find rest frame and angles of original dipole.
1783  RotBstMatrix M;
1784  M.fromCMframe(pRadBef, pRecBef);
1785 
1786  // Evaluate coefficient of azimuthal asymmetry from gluon polarization.
1787  findAsymPol( event, dipSel);
1788 
1789  // Begin construction of new dipole kinematics: pick azimuthal angle.
1790  Vec4 pRad, pEmt, pRec;
1791  double wtPhi = 1.;
1792  do {
1793  double phi = 2. * M_PI * rndmPtr->flat();
1794 
1795  // Define kinematics of branching in dipole rest frame.
1796  pRad = Vec4( pTcorr * cos(phi), pTcorr * sin(phi), pzRad,
1797  sqrt( pow2(pTcorr) + pow2(pzRad) + pow2(mRad) ) );
1798  pEmt = Vec4( -pRad.px(), -pRad.py(), pzEmt,
1799  sqrt( pow2(pTcorr) + pow2(pzEmt) + pow2(mEmt) ) );
1800  pRec = Vec4( 0., 0., -pzRadPlusEmt, sqrt( pow2(pzRadPlusEmt)
1801  + dipSel->m2Rec ) );
1802 
1803  // Rotate and boost dipole products to the event frame.
1804  pRad.rotbst(M);
1805  pEmt.rotbst(M);
1806  pRec.rotbst(M);
1807 
1808  // Azimuthal phi weighting: loop to new phi value if required.
1809  if (dipSel->asymPol != 0.) {
1810  Vec4 pAunt = event[dipSel->iAunt].p();
1811  double cosPhi = cosphi( pRad, pAunt, pRadBef );
1812  wtPhi = ( 1. + dipSel->asymPol * (2. * pow2(cosPhi) - 1.) )
1813  / ( 1. + abs(dipSel->asymPol) );
1814  }
1815  } while (wtPhi < rndmPtr->flat()) ;
1816 
1817  // Kinematics when recoiler is initial-state parton.
1818  int isrTypeNow = dipSel->isrType;
1819  int isrTypeSave = isrTypeNow;
1820  if (!useLocalRecoilNow) isrTypeNow = 0;
1821  if (isrTypeNow != 0) pRec = 2. * recBef.p() - pRec;
1822 
1823  // PS dec 2010: check if radiator has flexible normalization
1824  bool isFlexible = dipSel->isFlexible;
1825 
1826  // Define new particles from dipole branching.
1827  double pTsel = sqrt(dipSel->pT2);
1828  Particle rad = Particle(idRad, 51, iRadBef, 0, 0, 0,
1829  colRad, acolRad, pRad, mRad, pTsel);
1830  Particle emt = Particle(idEmt, 51, iRadBef, 0, 0, 0,
1831  colEmt, acolEmt, pEmt, mEmt, pTsel);
1832 
1833  // Recoiler either in final or in initial state
1834  Particle rec = (isrTypeNow == 0)
1835  ? Particle(recBef.id(), 52, iRecBef, iRecBef, 0, 0,
1836  recBef.col(), recBef.acol(), pRec, dipSel->mRec, pTsel)
1837  : Particle(recBef.id(), -53, 0, 0, iRecBef, iRecBef,
1838  recBef.col(), recBef.acol(), pRec, 0., 0.);
1839 
1840  // ME corrections can lead to branching being rejected.
1841  if (dipSel->MEtype > 0) {
1842  Particle& partner = (dipSel->iMEpartner == iRecBef)
1843  ? rec : event[dipSel->iMEpartner];
1844  if ( findMEcorr( dipSel, rad, partner, emt) < rndmPtr->flat() )
1845  return false;
1846  }
1847 
1848  // Rescatter: if the recoiling partner is not in the same system
1849  // as the radiator, fix up intermediate systems (can lead
1850  // to emissions being vetoed)
1851  if (allowRescatter && FIXRESCATTER && isInterleaved
1852  && iSysSel != iSysSelRec) {
1853  Vec4 pNew = rad.p() + emt.p();
1854  if (!rescatterPropagateRecoil(event, pNew)) return false;
1855  }
1856 
1857  // Save properties to be restored in case of user-hook veto of emission.
1858  int eventSizeOld = event.size();
1859  int iRadStatusV = event[iRadBef].status();
1860  int iRadDau1V = event[iRadBef].daughter1();
1861  int iRadDau2V = event[iRadBef].daughter2();
1862  int iRecStatusV = event[iRecBef].status();
1863  int iRecMot1V = event[iRecBef].mother1();
1864  int iRecMot2V = event[iRecBef].mother2();
1865  int iRecDau1V = event[iRecBef].daughter1();
1866  int iRecDau2V = event[iRecBef].daughter2();
1867  int beamOff1 = 1 + beamOffset;
1868  int beamOff2 = 2 + beamOffset;
1869  int ev1Dau1V = event[beamOff1].daughter1();
1870  int ev2Dau1V = event[beamOff2].daughter1();
1871 
1872  // Shower may occur at a displaced vertex.
1873  if (radBef.hasVertex()) {
1874  rad.vProd( radBef.vProd() );
1875  emt.vProd( radBef.vProd() );
1876  }
1877  if (recBef.hasVertex()) rec.vProd( recBef.vProd() );
1878 
1879  // Put new particles into the event record.
1880  // Mark original dipole partons as branched and set daughters/mothers.
1881  int iRad = event.append(rad);
1882  int iEmt = event.append(emt);
1883  event[iRadBef].statusNeg();
1884  event[iRadBef].daughters( iRad, iEmt);
1885  int iRec = 0;
1886  if (useLocalRecoilNow) {
1887  iRec = event.append(rec);
1888  if (isrTypeNow == 0) {
1889  event[iRecBef].statusNeg();
1890  event[iRecBef].daughters( iRec, iRec);
1891  } else {
1892  event[iRecBef].mothers( iRec, iRec);
1893  event[iRec].mothers( iRecMot1V, iRecMot2V);
1894  if (iRecMot1V == beamOff1) event[beamOff1].daughter1( iRec);
1895  if (iRecMot1V == beamOff2) event[beamOff2].daughter1( iRec);
1896  }
1897 
1898  // Global recoil: need to find relevant rotation+boost for recoilers:
1899  // boost+rotate to rest frame, boost along z axis, rotate+boost back.
1900  } else {
1901  RotBstMatrix MG = M;
1902  MG.invert();
1903  double pzRecBef = -0.5 * sqrtpos( pow2(dipSel->m2Dip - dipSel->m2Rad
1904  - dipSel->m2Rec) - 4. * dipSel->m2Rad * dipSel->m2Rec ) / dipSel->mDip;
1905  double eRecBef = sqrt( pow2(pzRecBef) + dipSel->m2Rec);
1906  double pzRecAft = -pzRadPlusEmt;
1907  double eRecAft = sqrt( pow2(pzRecAft) + dipSel->m2Rec);
1908  MG.bst( Vec4(0., 0., pzRecBef, eRecBef), Vec4(0., 0., pzRecAft, eRecAft) );
1909  MG.rotbst( M);
1910 
1911  // Global recoil: copy particles, and rotate+boost momenta (not vertices).
1912  for (int iG = 0; iG < int(iGRecBef.size()); ++iG) {
1913  iRec = event.copy( iGRecBef[iG], 52);
1914  iGRec.push_back( iRec);
1915  Vec4 pGRec = event[iRec].p();
1916  pGRec.rotbst( MG);
1917  event[iRec].p( pGRec);
1918  }
1919  }
1920 
1921  // Allow veto of branching. If so restore event record to before emission.
1922  bool inResonance = (partonSystemsPtr->getInA(iSysSel) == 0) ? true : false;
1923  if ( canVetoEmission && userHooksPtr->doVetoFSREmission( eventSizeOld,
1924  event, iSysSel, inResonance) ) {
1925  event.popBack( event.size() - eventSizeOld);
1926  event[iRadBef].status( iRadStatusV);
1927  event[iRadBef].daughters( iRadDau1V, iRadDau2V);
1928  if (useLocalRecoilNow && isrTypeNow == 0) {
1929  event[iRecBef].status( iRecStatusV);
1930  event[iRecBef].daughters( iRecDau1V, iRecDau2V);
1931  } else if (useLocalRecoilNow) {
1932  event[iRecBef].mothers( iRecMot1V, iRecMot2V);
1933  if (iRecMot1V == beamOff1) event[beamOff1].daughter1( ev1Dau1V);
1934  if (iRecMot1V == beamOff2) event[beamOff2].daughter1( ev2Dau1V);
1935  } else {
1936  for (int iG = 0; iG < int(iGRecBef.size()); ++iG) {
1937  event[iGRecBef[iG]].statusPos();
1938  event[iGRecBef[iG]].daughters( 0, 0);
1939  }
1940  }
1941  return false;
1942  }
1943 
1944  // For global recoil restore the one nominal recoiler, for bookkeeping.
1945  if (!useLocalRecoilNow) {
1946  iRec = iRecBef;
1947  for (int iG = 0; iG < int(iGRecBef.size()); ++iG)
1948  if (iGRecBef[iG] == iRecBef) iRec = iGRec[iG];
1949  }
1950 
1951  // For initial-state recoiler also update beam and sHat info.
1952  if (isrTypeNow != 0) {
1953  BeamParticle& beamRec = (isrTypeNow == 1) ? *beamAPtr : *beamBPtr;
1954  double xOld = beamRec[iSysSelRec].x();
1955  double xRec = 2. * pRec.e() / (beamAPtr->e() + beamBPtr->e());
1956  beamRec[iSysSelRec].iPos( iRec);
1957  beamRec[iSysSelRec].x( xRec);
1958  partonSystemsPtr->setSHat( iSysSelRec,
1959  partonSystemsPtr->getSHat(iSysSelRec) * xRec / xOld);
1960  }
1961 
1962  // Photon emission: update to new dipole ends; add new photon "dipole".
1963  if (dipSel->flavour == 22) {
1964  dipSel->iRadiator = iRad;
1965  dipSel->iRecoiler = iRec;
1966  // When recoiler was uncharged particle, in resonance decays,
1967  // assign recoil to emitted photons.
1968  if (recoilToColoured && inResonance && event[iRec].chargeType() == 0)
1969  dipSel->iRecoiler = iEmt;
1970  dipSel->pTmax = pTsel;
1971  if (doQEDshowerByGamma) dipEnd.push_back( TimeDipoleEnd(iEmt, iRad,
1972  pTsel, 0, 0, 1, 0, iSysSel, 0));
1973 
1974  // Gluon emission: update both dipole ends and add two new ones.
1975  } else if (dipSel->flavour == 21) {
1976  dipSel->iRadiator = iRad;
1977  dipSel->iRecoiler = iEmt;
1978  dipSel->systemRec = iSysSel;
1979  dipSel->isrType = 0;
1980  dipSel->pTmax = pTsel;
1981  // Optionally also kill ME corrections after first emission.
1982  if (!doMEafterFirst) dipSel->MEtype = 0;
1983  // PS dec 2010: check normalization of radiating dipole
1984  // Dipole corresponding to the newly created color tag has normal strength
1985  double flexFactor = (isFlexible) ? dipSel->flexFactor : 1.0;
1986  dipSel->isFlexible = false;
1987  for (int i = 0; i < int(dipEnd.size()); ++i) {
1988  if (dipEnd[i].iRadiator == iRecBef && dipEnd[i].iRecoiler == iRadBef
1989  && dipEnd[i].colType != 0) {
1990  dipEnd[i].iRadiator = iRec;
1991  dipEnd[i].iRecoiler = iEmt;
1992  // Optionally also kill ME corrections after first emission.
1993  if (!doMEafterFirst) dipEnd[i].MEtype = 0;
1994  // Strive to match colour to anticolour inside closed system.
1995  if ( !isFlexible && dipEnd[i].colType * dipSel->colType > 0)
1996  dipEnd[i].iRecoiler = iRad;
1997  dipEnd[i].pTmax = pTsel;
1998  // PS dec 2010: if the (iRadBef,iRecBef) dipole was flexible, the
1999  // same should be true for this (opposite) end. If so, this end keeps
2000  // the modified normalization, so we shouldn't need to do anything.
2001  }
2002  }
2003  int colType = (dipSel->colType > 0) ? 2 : -2 ;
2004  // When recoiler was uncoloured particle, in resonance decays,
2005  // assign recoil to coloured particle.
2006  int iRecMod = iRec;
2007  if (recoilToColoured && inResonance && event[iRec].col() == 0
2008  && event[iRec].acol() == 0) iRecMod = iRad;
2009  dipEnd.push_back( TimeDipoleEnd(iEmt, iRecMod, pTsel,
2010  colType, 0, 0, isrTypeSave, iSysSel, 0));
2011  dipEnd.back().systemRec = iSysSelRec;
2012  // PS dec 2010: the (iEmt,iRec) dipole "inherits" flexible normalization
2013  if (isFlexible) {
2014  dipEnd.back().isFlexible = true;
2015  dipEnd.back().flexFactor = flexFactor;
2016  }
2017  dipEnd.push_back( TimeDipoleEnd(iEmt, iRad, pTsel,
2018  -colType, 0, 0, 0, iSysSel, 0));
2019 
2020  // Gluon branching to q qbar: update current dipole and other of gluon.
2021  } else if (dipSel->colType != 0) {
2022  for (int i = 0; i < int(dipEnd.size()); ++i) {
2023  // Strive to match colour to anticolour inside closed system.
2024  if ( !isFlexible && dipEnd[i].iRecoiler == iRadBef
2025  && dipEnd[i].colType * dipSel->colType < 0 )
2026  dipEnd[i].iRecoiler = iEmt;
2027  if (dipEnd[i].iRadiator == iRadBef && abs(dipEnd[i].colType) == 2) {
2028  dipEnd[i].colType /= 2;
2029  if (dipEnd[i].system != dipEnd[i].systemRec) continue;
2030 
2031  // Note: gluino -> quark + squark gives a deeper radiation dip than
2032  // the more obvious alternative photon decay, so is more realistic.
2033  dipEnd[i].MEtype = 66;
2034  if (&dipEnd[i] == dipSel) dipEnd[i].iMEpartner = iRad;
2035  else dipEnd[i].iMEpartner = iEmt;
2036  }
2037  }
2038  dipSel->iRadiator = iEmt;
2039  dipSel->iRecoiler = iRec;
2040  dipSel->pTmax = pTsel;
2041 
2042  // Gluon branching to q qbar: also add two charge dipole ends.
2043  // Note: gluino -> quark + squark gives a deeper radiation dip than
2044  // the more obvious alternative photon decay, so is more realistic.
2045  if (doQEDshowerByQ) {
2046  int chgType = event[iRad].chargeType();
2047  dipEnd.push_back( TimeDipoleEnd(iRad, iEmt, pTsel,
2048  0, chgType, 0, 0, iSysSel, 66, iEmt));
2049  dipEnd.push_back( TimeDipoleEnd(iEmt, iRad, pTsel,
2050  0, -chgType, 0, 0, iSysSel, 66, iRad));
2051  }
2052 
2053  // Photon branching to f fbar: inactivate photon "dipole";
2054  // optionally add new charge and colour dipole ends.
2055  } else if (dipSel->gamType != 0) {
2056  dipSel->gamType = 0;
2057  int chgType = event[iRad].chargeType();
2058  int colType = event[iRad].colType();
2059  // MEtype = 102 for charge in vector decay.
2060  if ( chgType != 0 && ( ( doQEDshowerByQ && colType != 0 )
2061  || ( doQEDshowerByL && colType == 0 ) ) ) {
2062  dipEnd.push_back( TimeDipoleEnd(iRad, iEmt, pTsel,
2063  0, chgType, 0, 0, iSysSel, 102, iEmt));
2064  dipEnd.push_back( TimeDipoleEnd(iEmt, iRad, pTsel,
2065  0, -chgType, 0, 0, iSysSel, 102, iRad));
2066  }
2067  // MEtype = 11 for colour in vector decay.
2068  if (colType != 0 && doQCDshower) {
2069  dipEnd.push_back( TimeDipoleEnd(iRad, iEmt, pTsel,
2070  colType, 0, 0, 0, iSysSel, 11, iEmt));
2071  dipEnd.push_back( TimeDipoleEnd(iEmt, iRad, pTsel,
2072  -colType, 0, 0, 0, iSysSel, 11, iRad));
2073  }
2074 
2075  // Photon_HV emission: update to new dipole ends.
2076  } else if (dipSel->flavour == 4900022) {
2077  dipSel->iRadiator = iRad;
2078  dipSel->iRecoiler = iRec;
2079  dipSel->pTmax = pTsel;
2080 
2081  // Gluon_HV emission: update to new dipole ends.
2082  } else if (dipSel->flavour == 4900021) {
2083  dipSel->iRadiator = iRad;
2084  dipSel->iRecoiler = iEmt;
2085  dipSel->pTmax = pTsel;
2086  for (int i = 0; i < int(dipEnd.size()); ++i)
2087  if (dipEnd[i].iRadiator == iRecBef && dipEnd[i].iRecoiler == iRadBef
2088  && dipEnd[i].isHiddenValley) {
2089  dipEnd[i].iRadiator = iRec;
2090  dipEnd[i].iRecoiler = iEmt;
2091  dipEnd[i].pTmax = pTsel;
2092  }
2093  int colvType = (dipSel->colvType > 0) ? 2 : -2 ;
2094  dipEnd.push_back( TimeDipoleEnd(iEmt, iRec, pTsel,
2095  0, 0, 0, isrTypeSave, iSysSel, 0, -1, false, true, colvType) );
2096  dipEnd.back().systemRec = iSysSelRec;
2097  dipEnd.push_back( TimeDipoleEnd(iEmt, iRad, pTsel,
2098  0, 0, 0, 0, iSysSel, 0, -1, false, true, -colvType) );
2099  }
2100 
2101  // Copy or set lifetime for new final state.
2102  if (event[iRad].id() == event[iRadBef].id()) {
2103  event[iRad].tau( event[iRadBef].tau() );
2104  } else {
2105  event[iRad].tau( event[iRad].tau0() * rndmPtr->exp() );
2106  event[iEmt].tau( event[iEmt].tau0() * rndmPtr->exp() );
2107  }
2108  event[iRec].tau( event[iRecBef].tau() );
2109 
2110  // Now update other dipoles that also involved the radiator or recoiler.
2111  for (int i = 0; i < int(dipEnd.size()); ++i) {
2112  // PS dec 2010: if radiator was flexible and now is normal, there may
2113  // be other flexible dipoles that need updating.
2114  if (isFlexible && !dipSel->isFlexible && dipEnd[i].isFlexible) {
2115  if (dipEnd[i].iRecoiler == iRadBef) dipEnd[i].iRecoiler = iEmt;
2116  if (dipEnd[i].iRadiator == iRadBef) {
2117  dipEnd[i].iRadiator = iEmt;
2118  if (dipEnd[i].colType == 1 && dipSel->flavour == 21)
2119  dipEnd[i].colType = 2;
2120  if (dipEnd[i].colType ==-1 && dipSel->flavour == 21)
2121  dipEnd[i].colType =-2;
2122  }
2123  }
2124  if (dipEnd[i].iRadiator == iRadBef) dipEnd[i].iRadiator = iRad;
2125  if (dipEnd[i].iRecoiler == iRadBef) dipEnd[i].iRecoiler = iRad;
2126  if (dipEnd[i].iMEpartner == iRadBef) dipEnd[i].iMEpartner = iRad;
2127  if (useLocalRecoilNow) {
2128  if (dipEnd[i].iRadiator == iRecBef) dipEnd[i].iRadiator = iRec;
2129  if (dipEnd[i].iRecoiler == iRecBef) dipEnd[i].iRecoiler = iRec;
2130  if (dipEnd[i].iMEpartner == iRecBef) dipEnd[i].iMEpartner = iRec;
2131  } else {
2132  for (int iG = 0; iG < int(iGRecBef.size()); ++iG) {
2133  if (dipEnd[i].iRadiator == iGRecBef[iG])
2134  dipEnd[i].iRadiator = iGRec[iG];
2135  if (dipEnd[i].iRecoiler == iGRecBef[iG])
2136  dipEnd[i].iRecoiler = iGRec[iG];
2137  if (dipEnd[i].iMEpartner == iGRecBef[iG])
2138  dipEnd[i].iMEpartner = iGRec[iG];
2139  }
2140  }
2141  }
2142 
2143  // PS Apr 2011
2144  // Update any junctions downstream of this branching (if necessary)
2145  // (This happens, e.g., via LHEF, when adding showers to intermediate
2146  // coloured resonances whose decays involved junctions)
2147  for (int iJun = 0; iJun < event.sizeJunction(); iJun++) {
2148  // Number of incoming colour lines for this junction.
2149  int nIncoming = (event.kindJunction(iJun)-1)/2;
2150  // Check radiator colour or anticolour, depending on junction kind
2151  // (if junction, incoming = anticolours, and vice versa)
2152  int colChk = 0;
2153  colChk = ( event.kindJunction(iJun) % 2 == 0 )
2154  ? event[iRadBef].col() : event[iRadBef].acol();
2155  // Loop over incoming junction ends
2156  for (int iCol = 0; iCol < nIncoming; iCol++) {
2157  int colJun = event.colJunction( iJun, iCol);
2158  // If match, update junction end with new upstream (anti)colour
2159  if (colJun == colChk) {
2160  int colNew = 0;
2161  if ( event.kindJunction(iJun) % 2 == 0 ) colNew = colRad;
2162  else colNew = acolRad;
2163  event.colJunction( iJun, iCol, colNew );
2164  }
2165  }
2166  }
2167 
2168  // Finally update the list of all partons in all systems.
2169  partonSystemsPtr->replace(iSysSel, iRadBef, iRad);
2170  partonSystemsPtr->addOut(iSysSel, iEmt);
2171  if (useLocalRecoilNow)
2172  partonSystemsPtr->replace(iSysSelRec, iRecBef, iRec);
2173  else {
2174  for (int iG = 0; iG < int(iGRecBef.size()); ++iG)
2175  partonSystemsPtr->replace(iSysSel, iGRecBef[iG], iGRec[iG]);
2176  }
2177 
2178  // Done.
2179  return true;
2180 
2181 }
2182 
2183 //--------------------------------------------------------------------------
2184 
2185 // Rescatter: If a dipole stretches between two different systems, those
2186 // systems will no longer locally conserve momentum. These
2187 // imbalances become problematic when ISR or primordial kT
2188 // is switched on as these steps involve Lorentz boosts.
2189 //
2190 // 'rescatterPropagateRecoil' tries to fix momentum in all
2191 // systems by propogating recoil momentum through all
2192 // intermediate systems. As the momentum transfer is already
2193 // defined, this can lead to internal lines gaining a
2194 // virtuality.
2195 
2196 // Useful definitions for a pair of integers and a vector of pairs
2197 typedef pair < int, int > pairInt;
2198 typedef vector < pairInt > vectorPairInt;
2199 
2200 //--------------------------------------------------------------------------
2201 
2202 // findParentSystems
2203 // Utility routine to find all parent systems of a given system
2204 // Returns a vector of pairs of integers with:
2205 // a) The system index, including the starting system (negative
2206 // if (b) points to a parent system, positive if (b) points
2207 // to a daughter system
2208 // b) The event record index that is the path out of the system
2209 // (if forwards == false, this is an incoming parton to the
2210 // system, and is +ve if side A or -ve if side B,
2211 // if forwards == true, this is an outgoing parton from the
2212 // system).
2213 // Returns as empty vector on failure
2214 // Note: this assumes single rescattering only and therefore only
2215 // one possible parent system
2216 
2217 inline vectorPairInt findParentSystems(const int sys,
2218  Event& event, PartonSystems* partonSystemsPtr, bool forwards) {
2219 
2220  vectorPairInt parentSystems;
2221  parentSystems.reserve(10);
2222 
2223  int iSysCur = sys;
2224  while (true) {
2225  // Get two incoming partons
2226  int iInA = partonSystemsPtr->getInA(iSysCur);
2227  int iInB = partonSystemsPtr->getInB(iSysCur);
2228 
2229  // Check if either of these links to another system
2230  int iIn = 0;
2231  if (event[iInA].isRescatteredIncoming()) iIn = iInA;
2232  if (event[iInB].isRescatteredIncoming()) iIn = -iInB;
2233 
2234  // Save the current system to the vector
2235  parentSystems.push_back( pairInt(-iSysCur, iIn) );
2236  if (iIn == 0) break;
2237 
2238  int iInAbs = abs(iIn);
2239  int iMother = event[iInAbs].mother1();
2240  iSysCur = partonSystemsPtr->getSystemOf(iMother);
2241  if (iSysCur == -1) {
2242  parentSystems.clear();
2243  break;
2244  }
2245  } // while (true)
2246 
2247  // If forwards is set, change all event record indices to go to daughter
2248  // systems rather than parent systems
2249  if (forwards) {
2250  vectorPairInt::reverse_iterator rit;
2251  for (rit = parentSystems.rbegin(); rit < (parentSystems.rend() - 1);
2252  ++rit) {
2253  pairInt &cur = *rit;
2254  pairInt &next = *(rit + 1);
2255  cur.first = -cur.first;
2256  cur.second = (next.second < 0) ? -event[abs(next.second)].mother1() :
2257  event[abs(next.second)].mother1();
2258  }
2259  }
2260 
2261  return parentSystems;
2262 }
2263 
2264 //--------------------------------------------------------------------------
2265 
2266 // rescatterPropagateRecoil
2267 // Fix up momentum in all intermediate systems when radiator and recoiler
2268 // systems are different. The strategy is to look at all parent systems
2269 // from the radiator system and the recoiler system and find where they
2270 // intersect.
2271 
2272 bool TimeShower::rescatterPropagateRecoil( Event& event, Vec4& pNew) {
2273 
2274  // Some useful variables for later
2275  int iRadBef = dipSel->iRadiator;
2276  iSysSel = dipSel->system;
2277  int iSysSelRec = dipSel->systemRec;
2278  Vec4 pImbal = pNew - event[iRadBef].p();
2279 
2280  // Store changes locally at first in case we veto the branching
2281  // eventMod stores index into the event record and new 4-vector
2282  vector < pair < int, Vec4 > > eventMod;
2283  eventMod.reserve(10);
2284  // systemMod stores system index (iSys) and system-parton index (iMem)
2285  // iMem >= 0 - index into outgoing partons (iOut)
2286  // iMem == -1 - incoming A
2287  // iMem == -2 - incoming B
2288  vectorPairInt systemMod;
2289  systemMod.reserve(10);
2290 
2291  // Find all parent systems from radiating and recoiling systems
2292  vectorPairInt radParent = findParentSystems(iSysSel, event,
2293  partonSystemsPtr, false);
2294  vectorPairInt recParent = findParentSystems(iSysSelRec, event,
2295  partonSystemsPtr, true);
2296  if (radParent.size() == 0 || recParent.size() == 0) {
2297  // This should never happen
2298  infoPtr->errorMsg("Error in TimeShower::rescatterPropagateRecoil: "
2299  "couldn't find parent system; branching vetoed");
2300  return false;
2301  }
2302  // Find the system that connects radiating and recoiling system
2303  bool foundPath = false;
2304  unsigned int iRadP = 0;
2305  unsigned int iRecP = 0;
2306  for (iRadP = 0; iRadP < radParent.size(); iRadP++) {
2307  for (iRecP = 0; iRecP < recParent.size(); iRecP++)
2308  if (abs(radParent[iRadP].first) == abs(recParent[iRecP].first)) {
2309  foundPath = true;
2310  break;
2311  }
2312  if (foundPath) break;
2313  }
2314  if (!foundPath) {
2315  // Can fail e.g. for QED dipoles where there is no connection
2316  // between radiator and recoiler systems
2317  infoPtr->errorMsg("Warning in TimeShower::rescatterPropagateRecoil: "
2318  "couldn't find recoil path; branching vetoed");
2319  return false;
2320  }
2321 
2322  // Join together to form complete path from radiating system
2323  // to recoiling system
2324  vectorPairInt path;
2325  if (radParent.size() > 1)
2326  path.assign(radParent.begin(), radParent.begin() + iRadP);
2327  if (recParent.size() > 1)
2328  path.insert(path.end(), recParent.rend() - iRecP - 1,
2329  recParent.rend() - 1);
2330 
2331  // Follow the path fixing up momenta as we go
2332  for (unsigned int i = 0; i < path.size(); i++) {
2333  // Line out of the current system
2334  bool isIncoming = (path[i].first < 0) ? true : false;
2335  int iSysCur = abs(path[i].first);
2336  bool isIncomingA = (path[i].second > 0) ? true : false;
2337  int iLink = abs(path[i].second);
2338 
2339  int iMemCur;
2340  if (isIncoming) iMemCur = (isIncomingA) ? -1 : -2;
2341  else {
2342  iMemCur = -1;
2343  for (int j = 0; j < partonSystemsPtr->sizeOut(iSysCur); j++)
2344  if (partonSystemsPtr->getOut(iSysCur, j) == iLink) {
2345  iMemCur = j;
2346  break;
2347  }
2348  if (iMemCur == -1) {
2349  // This should never happen
2350  infoPtr->errorMsg("Error in TimeShower::rescatterPropagateRecoil: "
2351  "couldn't find parton system; branching vetoed");
2352  return false;
2353  }
2354  }
2355 
2356  Vec4 pMod = (isIncoming) ? event[iLink].p() + pImbal :
2357  event[iLink].p() - pImbal;
2358  eventMod.push_back(pair <int, Vec4> (iLink, pMod));
2359  systemMod.push_back(pairInt(iSysCur, iMemCur));
2360 
2361  // Calculate sHat of iSysCur
2362  int iInCurA = partonSystemsPtr->getInA(iSysCur);
2363  int iInCurB = partonSystemsPtr->getInB(iSysCur);
2364  Vec4 pTotCur = event[iInCurA].p() + event[iInCurB].p();
2365 
2366  // If iMemCur is -1 or -2, then we must have changed the sHat of iSysCur
2367  if (iMemCur < 0) pTotCur += (isIncoming) ? pImbal : -pImbal;
2368  double sHatCur = pTotCur.m2Calc();
2369 
2370  // The fixed-up incoming and outgoing partons should not have
2371  // too large a virtuality in relation to the system mass-square.
2372  if (abs(pMod.m2Calc()) > MAXVIRTUALITYFRACTION * sHatCur) {
2373  infoPtr->errorMsg("Warning in TimeShower::rescatterPropagateRecoil: "
2374  "virtuality much larger than sHat; branching vetoed");
2375  return false;
2376  }
2377 
2378  // Outgoing ones should also not have too large negative energy
2379  // in the rest frame of the system.
2380  if (!isIncoming && pMod * pTotCur < -MAXNEGENERGYFRACTION * sHatCur) {
2381  infoPtr->errorMsg("Warning in TimeShower::rescatterPropagateRecoil: "
2382  "rest frame energy too negative; branching vetoed");
2383  return false;
2384  }
2385 
2386  // Veto negative sHat.
2387  if (sHatCur < 0.0) {
2388  infoPtr->errorMsg("Warning in TimeShower::rescatterPropagateRecoil: "
2389  "sHat became negative; branching vetoed");
2390  return false;
2391  }
2392 
2393  // Line into the new current system
2394  iLink = (isIncoming) ? event[iLink].mother1() :
2395  event[iLink].daughter1();
2396  iSysCur = partonSystemsPtr->getSystemOf(iLink, true);
2397 
2398  if (!isIncoming) iMemCur = (isIncomingA) ? -1 : -2;
2399  else {
2400  iMemCur = -1;
2401  for (int j = 0; j < partonSystemsPtr->sizeOut(iSysCur); j++)
2402  if (partonSystemsPtr->getOut(iSysCur, j) == iLink) {
2403  iMemCur = j;
2404  break;
2405  }
2406  if (iMemCur == -1) {
2407  // This should never happen
2408  infoPtr->errorMsg("Error in TimeShower::rescatterPropagateRecoil: "
2409  "couldn't find parton system; branching vetoed");
2410  return false;
2411  }
2412  }
2413 
2414  pMod = (isIncoming) ? event[iLink].p() + pImbal :
2415  event[iLink].p() - pImbal;
2416  eventMod.push_back(pair <int, Vec4> (iLink, pMod));
2417  systemMod.push_back(pairInt(iSysCur, iMemCur));
2418 
2419  // Calculate sHat of iSysCur
2420  iInCurA = partonSystemsPtr->getInA(iSysCur);
2421  iInCurB = partonSystemsPtr->getInB(iSysCur);
2422  pTotCur = event[iInCurA].p() + event[iInCurB].p();
2423 
2424  // If iMemCur is -1 or -2, then we must have changed the sHat of iSysCur
2425  if (iMemCur < 0) pTotCur += (isIncoming) ? pImbal : -pImbal;
2426  sHatCur = pTotCur.m2Calc();
2427 
2428  // The fixed-up incoming and outgoing partons should not have
2429  // too large a virtuality in relation to the system mass-square.
2430  if (abs(pMod.m2Calc()) > MAXVIRTUALITYFRACTION * sHatCur) {
2431  infoPtr->errorMsg("Warning in TimeShower::rescatterPropagateRecoil: "
2432  "virtuality much larger than sHat; branching vetoed");
2433  return false;
2434  }
2435 
2436  // Outgoing ones should also not have too large negative energy
2437  // in the rest frame of the system.
2438  if (!isIncoming && pMod * pTotCur < -MAXNEGENERGYFRACTION * sHatCur) {
2439  infoPtr->errorMsg("Warning in TimeShower::rescatterPropagateRecoil: "
2440  "rest frame energy too negative; branching vetoed");
2441  return false;
2442  }
2443 
2444  // Veto negative sHat
2445  if (sHatCur < 0.0) {
2446  infoPtr->errorMsg("Warning in TimeShower::rescatterPropagateRecoil: "
2447  "sHat became negative; branching vetoed");
2448  return false;
2449  }
2450 
2451  // Do negative energy veto
2452  if (VETONEGENERGY && pMod.e() < 0.0) {
2453  infoPtr->errorMsg("Warning in TimeShower::rescatterPropagateRecoil: "
2454  "energy became negative; branching vetoed");
2455  return false;
2456  }
2457 
2458  } // for (unsigned int i = 0; i < path.size(); i++)
2459 
2460  // If no vetos by this point, apply the changes to the event record
2461  // An incoming particle with changed momentum is given status code -54,
2462  // an outgoing particle with changed momentum is given status code -55
2463  for (unsigned int i = 0; i < eventMod.size(); i++) {
2464  int idx = eventMod[i].first;
2465  Vec4 &pMod = eventMod[i].second;
2466  int iSys = systemMod[i].first;
2467  int iMem = systemMod[i].second;
2468 
2469  // If incoming to a process then set the copy to be the mother
2470  if (event[idx].isRescatteredIncoming()) {
2471  int mother1 = event[idx].mother1();
2472  idx = event.copy(idx, -54);
2473  event[mother1].daughters(idx, idx);
2474 
2475  // Update beam information if necessary
2476  double eCM = sqrt(m2( beamAPtr->p(), beamBPtr->p()));
2477  if (iMem == -1) {
2478  partonSystemsPtr->setInA(iSys, idx);
2479  (*beamAPtr)[iSys].x((pMod.e() + pMod.pz()) / eCM);
2480  (*beamAPtr)[iSys].m(pMod.mCalc());
2481  (*beamAPtr)[iSys].p(pMod);
2482  (*beamAPtr)[iSys].iPos(idx);
2483  } else if (iMem == -2) {
2484  partonSystemsPtr->setInB(iSys, idx);
2485  (*beamBPtr)[iSys].x((pMod.e() - pMod.pz()) / eCM);
2486  (*beamBPtr)[iSys].m(pMod.mCalc());
2487  (*beamBPtr)[iSys].p(pMod);
2488  (*beamBPtr)[iSys].iPos(idx);
2489  } else {
2490  // This should never happen
2491  infoPtr->errorMsg("Error in TimeShower::rescatterPropagateRecoil: "
2492  "internal bookeeping error");
2493  }
2494 
2495  // Otherwise set the new event record entry to be the daughter
2496  } else {
2497  int daughter1 = event[idx].daughter1();
2498  idx = event.copy(idx, 55);
2499  event[idx].statusNeg();
2500  event[daughter1].mothers(idx, idx);
2501 
2502  partonSystemsPtr->setOut(iSys, iMem, idx);
2503  }
2504 
2505  event[idx].p( eventMod[i].second );
2506  event[idx].m( event[idx].mCalc() );
2507  }
2508 
2509  return true;
2510 }
2511 
2512 
2513 //--------------------------------------------------------------------------
2514 
2515 // Find class of QCD ME correction.
2516 // MEtype classification follow codes in Norrbin article,
2517 // additionally -1 = try to find type, 0 = no ME corrections.
2518 // Warning: not yet tried out to do a correct assignment in
2519 // arbitrary multiparton configurations! ??
2520 
2521 void TimeShower::findMEtype( Event& event, TimeDipoleEnd& dip) {
2522 
2523  // Initial value. Mark if no ME corrections to be applied.
2524  bool setME = true;
2525  if (!doMEcorrections) setME = false;
2526  int iMother = event[dip.iRadiator].mother1();
2527  int iMother2 = event[dip.iRadiator].mother2();
2528 
2529  // Allow ME corrections for Hidden Valley pair in 2 -> 2.
2530  if (dip.isHiddenValley && event[dip.iRecoiler].id()
2531  == -event[dip.iRadiator].id());
2532 
2533  // Else no ME corrections in 2 -> n processes.
2534  else {
2535  if (iMother2 != iMother && iMother2 != 0) setME = false;
2536  if (event[dip.iRecoiler].mother1() != iMother) setME = false;
2537  if (event[dip.iRecoiler].mother2() != iMother2) setME = false;
2538  }
2539 
2540  // No ME corrections for recoiler in initial state.
2541  if (event[dip.iRecoiler].status() < 0) setME = false;
2542 
2543  // No ME corrections for recoiler not in same system
2544  if (dip.system != dip.systemRec) setME = false;
2545 
2546  // Done if no ME to be set.
2547  if (!setME) {
2548  dip.MEtype = 0;
2549  return;
2550  }
2551 
2552  // If no ME partner set, assume it is the recoiler.
2553  if (dip.iMEpartner < 0) dip.iMEpartner = dip.iRecoiler;
2554 
2555  // Now begin processing of colour dipole, including Hidden Valley.
2556  if (dip.colType != 0 || dip.colvType != 0) {
2557  bool isHiddenColour = (dip.colvType != 0);
2558 
2559  // Find daughter types (may or may not be used later on).
2560  int idDau1 = event[dip.iRadiator].id();
2561  int idDau2 = event[dip.iMEpartner].id();
2562  int dau1Type = findMEparticle(idDau1, isHiddenColour);
2563  int dau2Type = findMEparticle(idDau2, isHiddenColour);
2564  int minDauType = min(dau1Type, dau2Type);
2565  int maxDauType = max(dau1Type, dau2Type);
2566 
2567  // Reorder dipole ends in kinematics. Split ME expression in two sides.
2568  dip.MEorder = (dau2Type >= dau1Type);
2569  dip.MEsplit = (maxDauType <= 6);
2570  dip.MEgluinoRec = false;
2571 
2572  // If type already set (or set not to have) then done.
2573  if (minDauType == 0 && dip.MEtype < 0) dip.MEtype = 0;
2574  if (dip.MEtype >= 0) return;
2575  dip.MEtype = 0;
2576 
2577  // For H -> gg -> ggg we found that DGLAP kernels do better than eikonal.
2578  if (dau1Type == 4 && dau2Type == 4) return;
2579 
2580  // Find mother type.
2581  int idMother = 0;
2582  if ( event[dip.iRecoiler].mother1() == iMother && iMother >= 0)
2583  idMother = event[iMother].id();
2584  int motherType = (idMother != 0)
2585  ? findMEparticle(idMother, isHiddenColour) : 0;
2586 
2587  // When a mother if not known then use colour and spin content to guess.
2588  if (motherType == 0) {
2589  int col1 = event[dip.iRadiator].col();
2590  int acol1 = event[dip.iRadiator].acol();
2591  int col2 = event[dip.iMEpartner].col();
2592  int acol2 = event[dip.iMEpartner].acol();
2593  // spinT = 0/1 = integer or half-integer.
2594  int spinT = ( event[dip.iRadiator].spinType()
2595  + event[dip.iMEpartner].spinType() )%2;
2596  // Colour singlet mother.
2597  if ( col1 == acol2 && acol1 == col2 )
2598  motherType = (spinT == 0) ? 7 : 9;
2599  // Colour octet mother.
2600  else if ( (col1 == acol2 && acol1 != 0 && col2 != 0)
2601  || (acol1 == col2 && col1 != 0 && acol2 != 0) )
2602  motherType = (spinT == 0) ? 4 : 5;
2603  // Colour triplet mother.
2604  else if ( (col1 == acol2 && acol1 != col2)
2605  || (acol1 == col2 && col1 != acol2) )
2606  motherType = (spinT == 0) ? 2 : 1;
2607  // If no colours are matched then cannot have common mother, so done.
2608  else return;
2609  }
2610 
2611  // Now start from default, which is eikonal ME corrections,
2612  // and try to find matching ME cases below.
2613  int MEkind = 0;
2614  int MEcombi = 4;
2615  dip.MEmix = 0.5;
2616 
2617  // Hidden Valley with massive gamma_v covered by two special cases.
2618  if (isHiddenColour && brokenHVsym) {
2619  MEkind = (dau2Type == 0 || dau2Type > 6) ? 30 : 31;
2620  dip.MEtype = 5 * MEkind + 1;
2621  return;
2622  }
2623 
2624  // Triplet recoiling against gluino needs enhanced radiation
2625  // to match to matrix elements.
2626  dip.MEgluinoRec = (dau1Type >= 1 && dau1Type <= 3 && dau2Type == 5);
2627 
2628  // Vector/axial vector -> q + qbar.
2629  if (minDauType == 1 && maxDauType == 1 &&
2630  (motherType == 4 || motherType == 7) ) {
2631  MEkind = 2;
2632  if (idMother == 21 || idMother == 22) MEcombi = 1;
2633  else if (idMother == 23 || idDau1 + idDau2 == 0) {
2634  MEcombi = 3;
2635  dip.MEmix = gammaZmix( event, iMother, dip.iRadiator, dip.iRecoiler );
2636  }
2637  else if (idMother == 24) MEcombi = 4;
2638  }
2639  // For chi -> chi q qbar, use V/A -> q qbar as first approximation.
2640  else if (minDauType == 1 && maxDauType == 1 && motherType == 9)
2641  MEkind = 2;
2642 
2643  // q -> q + V.
2644  else if (minDauType == 1 && maxDauType == 7 && motherType == 1)
2645  MEkind = 3;
2646  if (idDau1 == 22 || idDau2 == 22) MEcombi = 1;
2647 
2648  // Scalar/pseudoscalar -> q + qbar; q -> q + S.
2649  else if (minDauType == 1 && maxDauType == 1 && motherType == 8) {
2650  MEkind = 4;
2651  if (idMother == 25 || idMother == 35 || idMother == 37) MEcombi = 1;
2652  else if (idMother == 36) MEcombi = 2;
2653  }
2654  else if (minDauType == 1 && maxDauType == 8 && motherType == 1)
2655  MEkind = 5;
2656 
2657  // V -> ~q + ~qbar; ~q -> ~q + V; S -> ~q + ~qbar; ~q -> ~q + S.
2658  else if (minDauType == 2 && maxDauType == 2 && (motherType == 4
2659  || motherType == 7) ) MEkind = 6;
2660  else if (minDauType == 2 && (maxDauType == 4 || maxDauType == 7)
2661  && motherType == 2) MEkind = 7;
2662  else if (minDauType == 2 && maxDauType == 2 && motherType == 8)
2663  MEkind = 8;
2664  else if (minDauType == 2 && maxDauType == 8 && motherType == 2)
2665  MEkind = 9;
2666 
2667  // chi -> q + ~qbar; ~q -> q + chi; q -> ~q + chi.
2668  else if (minDauType == 1 && maxDauType == 2 && motherType == 9)
2669  MEkind = 10;
2670  else if (minDauType == 1 && maxDauType == 9 && motherType == 2)
2671  MEkind = 11;
2672  else if (minDauType == 2 && maxDauType == 9 && motherType == 1)
2673  MEkind = 12;
2674 
2675  // ~g -> q + ~qbar; ~q -> q + ~g; q -> ~q + ~g.
2676  else if (minDauType == 1 && maxDauType == 2 && motherType == 5)
2677  MEkind = 13;
2678  else if (minDauType == 1 && maxDauType == 5 && motherType == 2)
2679  MEkind = 14;
2680  else if (minDauType == 2 && maxDauType == 5 && motherType == 1)
2681  MEkind = 15;
2682 
2683  // In cases where coloured spin 1 particle involved use spin 0.
2684  // V_coloured -> q + l.
2685  else if (minDauType == 1 && maxDauType == 9 && motherType == 3)
2686  MEkind = 11;
2687  // q -> V_coloured + l;
2688  else if (minDauType == 3 && maxDauType == 9 && motherType == 1)
2689  MEkind = 12;
2690 
2691  // g (+V, S) -> ~g + ~g (eikonal approximation).
2692  else if (minDauType == 5 && maxDauType == 5) MEkind = 16;
2693 
2694  // Save ME type and gamma_5 admixture.
2695  dip.MEtype = 5 * MEkind + MEcombi;
2696 
2697  // Now begin processing of charge dipole - still primitive.
2698  } else if (dip.chgType != 0) {
2699 
2700  // Set defaults for QED case; then possibly done.
2701  dip.MEorder = true;
2702  dip.MEsplit = true;
2703  if (dip.MEtype >= 0) return;
2704 
2705  // So far only ME corrections for q qbar or l lbar.
2706  int idDau1 = event[dip.iRadiator].id();
2707  int idDau2 = event[dip.iMEpartner].id();
2708  if (abs(idDau1) < 9 && abs(idDau2) < 9 && idDau1 * idDau2 < 0) ;
2709  else if (abs(idDau1) > 10 && abs(idDau1) < 19 && abs(idDau2) > 10
2710  && abs(idDau2) < 19 && idDau1 * idDau2 < 0) ;
2711  else { dip.MEtype = 0; return; }
2712 
2713  // Distinguish charge sum != 0 or = 0; in latter assume vector source.
2714  dip.MEtype = 101;
2715  if (idDau1 + idDau2 == 0) dip.MEtype = 102;
2716  dip.MEmix = 1.;
2717  }
2718 
2719 }
2720 
2721 //--------------------------------------------------------------------------
2722 
2723 // Find type of particle for ME type: 0 = unknown, 1 = quark, 2 = squark,
2724 // 3 = spare triplet, 4 = gluon, 5 = gluino, 6 = spare octet,
2725 // 7 = vector boson, 8 = colourless scalar, 9 = colourless spin 1/2.
2726 
2727 int TimeShower::findMEparticle( int id, bool isHiddenColour) {
2728 
2729  // find colour and spin of particle.
2730  int type = 0;
2731  int colType = abs(particleDataPtr->colType(id));
2732  int spinType = particleDataPtr->spinType(id);
2733 
2734  // For hidden valley particle treat HV colour as normal one.
2735  // Note: no need to assign gv/gammav since not in ME.
2736  if (isHiddenColour) {
2737  colType = 0;
2738  int idAbs = abs(id);
2739  if ( (idAbs > 4900000 && idAbs < 4900007)
2740  || (idAbs > 4900010 && idAbs < 4900017)
2741  || idAbs == 4900101) colType = 1;
2742  }
2743 
2744  // Find particle type from colour and spin.
2745  if (colType == 1 && spinType == 2) type = 1;
2746  else if (colType == 1 && spinType == 1) type = 2;
2747  else if (colType == 1) type = 3;
2748  else if (colType == 2 && spinType == 3) type = 4;
2749  else if (colType == 2 && spinType == 2) type = 5;
2750  else if (colType == 2) type = 6;
2751  else if (colType == 0 && spinType == 3) type = 7;
2752  else if (colType == 0 && spinType == 1) type = 8;
2753  else if (colType == 0 && spinType == 2) type = 9;
2754 
2755  // Done.
2756  return type;
2757 
2758 }
2759 
2760 //--------------------------------------------------------------------------
2761 
2762 // Find mixture of V and A in gamma/Z: energy- and flavour-dependent.
2763 
2764 double TimeShower::gammaZmix( Event& event, int iRes, int iDau1, int iDau2) {
2765 
2766  // Try to identify initial flavours; use e+e- as default.
2767  int idIn1 = -11;
2768  int idIn2 = 11;
2769  int iIn1 = (iRes >= 0) ? event[iRes].mother1() : -1;
2770  int iIn2 = (iRes >= 0) ? event[iRes].mother2() : -1;
2771  if (iIn1 >=0) idIn1 = event[iIn1].id();
2772  if (iIn2 >=0) idIn2 = event[iIn1].id();
2773 
2774  // In processes f + g/gamma -> f + Z only need find one fermion.
2775  if (idIn1 == 21 || idIn1 == 22) idIn1 = -idIn2;
2776  if (idIn2 == 21 || idIn2 == 22) idIn2 = -idIn1;
2777 
2778  // Initial flavours and couplings; return if don't make sense.
2779  if (idIn1 + idIn2 != 0 ) return 0.5;
2780  int idInAbs = abs(idIn1);
2781  if (idInAbs == 0 || idInAbs > 18 ) return 0.5;
2782  double ei = coupSMPtr->ef(idInAbs);
2783  double vi = coupSMPtr->vf(idInAbs);
2784  double ai = coupSMPtr->af(idInAbs);
2785 
2786  // Final flavours and couplings; return if don't make sense.
2787  if (event[iDau1].id() + event[iDau2].id() != 0) return 0.5;
2788  int idOutAbs = abs(event[iDau1].id());
2789  if (idOutAbs == 0 || idOutAbs >18 ) return 0.5;
2790  double ef = coupSMPtr->ef(idOutAbs);
2791  double vf = coupSMPtr->vf(idOutAbs);
2792  double af = coupSMPtr->af(idOutAbs);
2793 
2794  // Calculate prefactors for interference and resonance part.
2795  Vec4 psum = event[iDau1].p() + event[iDau2].p();
2796  double sH = psum.m2Calc();
2797  double intNorm = 2. * thetaWRat * sH * (sH - mZ*mZ)
2798  / ( pow2(sH - mZ*mZ) + pow2(sH * gammaZ / mZ) );
2799  double resNorm = pow2(thetaWRat * sH)
2800  / ( pow2(sH - mZ*mZ) + pow2(sH * gammaZ / mZ) );
2801 
2802  // Calculate vector and axial expressions and find mix.
2803  double vect = ei*ei * ef*ef + ei*vi * intNorm * ef*vf
2804  + (vi*vi + ai*ai) * resNorm * vf*vf;
2805  double axiv = (vi*vi + ai*ai) * resNorm * af*af;
2806  return vect / (vect + axiv);
2807 }
2808 
2809 //--------------------------------------------------------------------------
2810 
2811 // Set up to calculate QCD ME correction with calcMEcorr.
2812 // Normally for primary particles, but also from g/gamma -> f fbar.
2813 
2814 double TimeShower::findMEcorr(TimeDipoleEnd* dip, Particle& rad,
2815  Particle& partner, Particle& emt) {
2816 
2817  // Initial values and matrix element kind.
2818  double wtME = 1.;
2819  double wtPS = 1.;
2820  int MEkind = dip->MEtype / 5;
2821  int MEcombi = dip->MEtype % 5;
2822 
2823  // Construct ME variables.
2824  Vec4 sum = rad.p() + partner.p() + emt.p();
2825  double eCMME = sum.mCalc();
2826  double x1 = 2. * (sum * rad.p()) / pow2(eCMME);
2827  double x2 = 2. * (sum * partner.p()) / pow2(eCMME);
2828  double r1 = rad.m() / eCMME;
2829  double r2 = partner.m() / eCMME;
2830  double r3 = 0.;
2831 
2832  // Evaluate kinematics for Hidden Valley with massive gamma_v.
2833  double gammavCorr = 1.;
2834  if (dip->colvType != 0 && brokenHVsym) {
2835  r3 = emt.m() / eCMME;
2836  double x3Tmp = 2. - x1 - x2;
2837  gammavCorr = x3Tmp / (x3Tmp - kRad * (x1 + x3Tmp));
2838  // For Q_v Qbar_v pair correct kinematics to common average mass.
2839  if (MEkind == 31) {
2840  double m2Pair = (rad.p() + partner.p()).m2Calc();
2841  double m2Avg = 0.5 * (rad.m2() + partner.m2())
2842  - 0.25 * pow2(rad.m2() - partner.m2()) / m2Pair;
2843  r1 = sqrt(m2Avg) / eCMME;
2844  r2 = r1;
2845  double xShift = 0.5 * (x1 + x2) * (partner.m2() - rad.m2()) / m2Pair;
2846  x1 += xShift;
2847  x2 -= xShift;
2848  }
2849  }
2850 
2851  // Derived ME variables, suitably protected.
2852  double x1minus = max(XMARGIN, 1. + r1*r1 - r2*r2 - x1);
2853  double x2minus = max(XMARGIN, 1. + r2*r2 - r1*r1 - x2) ;
2854  double x3 = max(XMARGIN, 2. - x1 - x2);
2855 
2856  // Begin processing of QCD dipoles.
2857  if (dip->colType !=0 || dip->colvType != 0) {
2858 
2859  // Evaluate normal ME, for proper order of particles.
2860  if (dip->MEorder)
2861  wtME = calcMEcorr(MEkind, MEcombi, dip->MEmix, x1, x2, r1, r2, r3);
2862  else wtME = calcMEcorr(MEkind, MEcombi, dip->MEmix, x2, x1, r2, r1, r3);
2863 
2864  // Split up total ME when two radiating particles.
2865  if (dip->MEsplit) wtME = wtME * x1minus / x3;
2866 
2867  // Evaluate shower rate to be compared with.
2868  wtPS = 2. / ( x3 * x2minus );
2869  if (dip->MEgluinoRec) wtPS *= 9./4.;
2870  if (dip->colvType != 0 && brokenHVsym) wtPS *= gammavCorr;
2871 
2872  // For generic charge combination currently only massless expression.
2873  // (Masses included only to respect phase space boundaries.)
2874  } else if (dip->chgType !=0 && dip->MEtype == 101) {
2875  double chg1 = particleDataPtr->charge(rad.id());
2876  double chg2 = particleDataPtr->charge(partner.id());
2877  wtME = (x1*x1 + x2*x2) * pow2( chg1 * x1minus / x3
2878  - chg2 * x2minus / x3 );
2879  wtPS = 2. * ( chg1*chg1 * x1minus / x3 + chg2*chg2 * x2minus / x3 );
2880 
2881  // For flavour neutral system assume vector source and include masses.
2882  } else if (dip->chgType !=0 && dip->MEtype == 102) {
2883  wtME = calcMEcorr(2, 1, dip->MEmix, x1, x2, r1, r2) * x1minus / x3;
2884  wtPS = 2. / ( x3 * x2minus );
2885  }
2886  if (wtME > wtPS) infoPtr->errorMsg("Warning in TimeShower::findMEcorr: "
2887  "ME weight above PS one");
2888 
2889  // Return ratio of actual ME to assumed PS rate of emission.
2890  return wtME / wtPS;
2891 }
2892 
2893 //--------------------------------------------------------------------------
2894 
2895 // Matrix elements for gluon (or photon) emission from
2896 // a two-body state; to be used by the parton shower routine.
2897 // Here x_i = 2 E_i/E_cm, r_i = m_i/E_cm and
2898 // 1/sigma_0 d(sigma)/d(x_1)d(x_2) = (alpha-strong/2 pi) * C_F * (this),
2899 // i.e. normalization is such that one recovers the familiar
2900 // (x_1^2 + x_2^2)/((1-x_1)*(1-x_2)) for the massless case.
2901 // Coupling structure:
2902 // kind = 1 : eikonal soft-gluon expression (spin-independent)
2903 // = 2 : V -> q qbar (V = vector/axial vector colour singlet)
2904 // = 3 : q -> q V
2905 // = 4 : S -> q qbar (S = scalar/pseudoscalar colour singlet)
2906 // = 5 : q -> q S
2907 // = 6 : V -> ~q ~qbar (~q = squark)
2908 // = 7 : ~q -> ~q V
2909 // = 8 : S -> ~q ~qbar
2910 // = 9 : ~q -> ~q S
2911 // = 10 : chi -> q ~qbar (chi = neutralino/chargino)
2912 // = 11 : ~q -> q chi
2913 // = 12 : q -> ~q chi
2914 // = 13 : ~g -> q ~qbar
2915 // = 14 : ~q -> q ~g
2916 // = 15 : q -> ~q ~g
2917 // = 16 : (9/4)*(eikonal) for gg -> ~g ~g
2918 // = 30 : Dv -> d qv (Dv= hidden valley fermion, qv= valley scalar)
2919 // = 31 : S -> Dv Dvbar (S=scalar color singlet)
2920 // Note that the order of the decay products is important.
2921 // combi = 1 : pure non-gamma5, i.e. vector/scalar/...
2922 // = 2 : pure gamma5, i.e. axial vector/pseudoscalar/....
2923 // = 3 : mixture mix*(combi=1) + (1-mix)*(combi=2)
2924 // = 4 : mixture (combi=1) +- (combi=2)
2925 
2926 double TimeShower::calcMEcorr( int kind, int combiIn, double mixIn,
2927  double x1, double x2, double r1, double r2, double r3) {
2928 
2929  // Frequent variable combinations.
2930  double x3 = 2. - x1 - x2;
2931  double x1s = x1 * x1;
2932  double x2s = x2 * x2;
2933  double x3s = x3 * x3;
2934  double x1c = x1 * x1s;
2935  double x2c = x2 * x2s;
2936  double x3c = x3 * x3s;
2937  double r1s = r1 * r1;
2938  double r2s = r2 * r2;
2939  double r1c = r1 * r1s;
2940  double r2c = r2 * r2s;
2941  double r1q = r1s * r1s;
2942  double r2q = r2s * r2s;
2943  double prop1 = 1. + r1s - r2s - x1;
2944  double prop2 = 1. + r2s - r1s - x2;
2945  double prop1s = prop1 * prop1;
2946  double prop2s = prop2 * prop2;
2947  double prop12 = prop1 * prop2;
2948  double prop13 = prop1 * x3;
2949  double prop23 = prop2 * x3;
2950 
2951  // Special case: Hidden-Valley massive photon.
2952  double r3s = r3 * r3;
2953  double prop3 = r3s - x3;
2954  double prop3s = prop3 * prop3;
2955  if (kind == 30) prop13 = prop1 * prop3;
2956 
2957  // Check input values. Return zero outside allowed phase space.
2958  if (x1 - 2.*r1 < XMARGIN || prop1 < XMARGIN) return 0.;
2959  if (x2 - 2.*r2 < XMARGIN || prop2 < XMARGIN) return 0.;
2960  // Limits not worked out for r3 > 0.
2961  if (kind != 30 && kind != 31) {
2962  if (x1 + x2 - 1. - pow2(r1+r2) < XMARGIN) return 0.;
2963  // Note: equivalent rewritten form 4. * ( (1. - x1) * (1. - x2)
2964  // * (1. - r1s - r2s - x3) + r1s * (1. - x2s - x3) + r2s
2965  // * (1. - x1s - x3) - pow2(r1s - r2s) ) gives about same result.
2966  if ( (x1s - 4.*r1s) * (x2s - 4.*r2s)
2967  - pow2( 2. * (1. - x1 - x2 + r1s + r2s) + x1*x2 )
2968  < XMARGIN * (XMARGINCOMB + r1 + r2) ) return 0.;
2969  }
2970 
2971  // Initial values; phase space.
2972  int combi = max(1, min(4, combiIn) );
2973  double mix = max(0., min(1., mixIn) );
2974  bool isSet1 = false;
2975  bool isSet2 = false;
2976  bool isSet4 = false;
2977  double ps = sqrtpos( pow2(1. - r1*r1 - r2*r2) - pow2(2. * r1 * r2) );
2978  double rLO = 0., rFO = 0., rLO1 = 0., rFO1 = 0., rLO2 = 0.,
2979  rFO2 = 0., rLO4 = 0., rFO4 = 0.;
2980  double offset = 0;
2981 
2982  // Select which kind of ME to use.
2983  switch (kind) {
2984 
2985  // case 1 is equal to default, i.e. eikonal expression.
2986 
2987  // V -> q qbar (V = gamma*/Z0/W+-/...).
2988  case 2:
2989  if (combi == 1 || combi == 3) {
2990  rLO1 = ps*(2.-r1s-r1q+6.*r1*r2-r2s+2.*r1s*r2s-r2q)/2.;
2991  rFO1 = -(3.+6.*r1s+r1q-6.*r1*r2+6.*r1c*r2-2.*r2s-6.*r1s*r2s
2992  +6.*r1*r2c+r2q-3.*x1+6.*r1*r2*x1+2.*r2s*x1+x1s-2.*r1s*x1s
2993  +3.*r1s*x3+6.*r1*r2*x3-r2s*x3-2.*x1*x3-5.*r1s*x1*x3
2994  +r2s*x1*x3+x1s*x3-3.*x3s-3.*r1s*x3s+r2s*x3s
2995  +2.*x1*x3s+x3c-x2)
2996  /prop2s
2997  -2.*(-3.+r1s-6.*r1*r2+6.*r1c*r2+3.*r2s-4.*r1s*r2s
2998  +6.*r1*r2c+2.*x1+3.*r1s*x1+r2s*x1-x1s-r1s*x1s
2999  -r2s*x1s+4.*x3+2.*r1s*x3+3.*r1*r2*x3-r2s*x3-3.*x1*x3
3000  -2.*r1s*x1*x3+x1s*x3-x3s-r1s*x3s+r1*r2*x3s+x1*x3s)
3001  /prop12
3002  -(-1.+2.*r1s+r1q+6.*r1*r2+6.*r1c*r2-2.*r2s-6.*r1s*r2s
3003  +6.*r1*r2c+r2q-x1-2.*r1s*x1-6.*r1*r2*x1+8.*r2s*x1+x1s
3004  -2.*r2s*x1s-r1s*x3+r2s*x3-r1s*x1*x3+r2s*x1*x3+x1s*x3+x2)
3005  /prop1s;
3006  rFO1 = rFO1/2.;
3007  isSet1 = true;
3008  }
3009  if (combi == 2 || combi == 3) {
3010  rLO2 = ps*(2.-r1s-r1q-6.*r1*r2-r2s+2.*r1s*r2s-r2q)/2.;
3011  rFO2 = -(3.+6.*r1s+r1q+6.*r1*r2-6.*r1c*r2-2.*r2s-6.*r1s*r2s
3012  -6.*r1*r2c+r2q-3.*x1-6.*r1*r2*x1+2.*r2s*x1+x1s-2.*r1s*x1s
3013  +3.*r1s*x3-6.*r1*r2*x3-r2s*x3-2.*x1*x3-5.*r1s*x1*x3
3014  +r2s*x1*x3+x1s*x3-3.*x3s-3.*r1s*x3s+r2s*x3s+2.*x1*x3s+x3c-x2)
3015  /prop2s
3016  -2.*(-3+r1s+6.*r1*r2-6.*r1c*r2+3.*r2s-4.*r1s*r2s-6.*r1*r2c
3017  +2.*x1+3.*r1s*x1+r2s*x1-x1s-r1s*x1s-r2s*x1s+4.*x3+2.*r1s*x3
3018  -3.*r1*r2*x3-r2s*x3-3.*x1*x3-2.*r1s*x1*x3+x1s*x3-x3s-r1s*x3s
3019  -r1*r2*x3s+x1*x3s)
3020  /prop12
3021  -(-1.+2.*r1s+r1q-6.*r1*r2-6.*r1c*r2-2.*r2s-6.*r1s*r2s
3022  -6.*r1*r2c+r2q-x1-2.*r1s*x1+6.*r1*r2*x1+8.*r2s*x1+x1s
3023  -2.*r2s*x1s-r1s*x3+r2s*x3-r1s*x1*x3+r2s*x1*x3+x1s*x3+x2)
3024  /prop1s;
3025  rFO2 = rFO2/2.;
3026  isSet2 = true;
3027  }
3028  if (combi == 4) {
3029  rLO4 = ps*(2.-r1s-r1q-r2s+2.*r1s*r2s-r2q)/2.;
3030  rFO4 = (1.-r1q+6.*r1s*r2s-r2q+x1+3.*r1s*x1-9.*r2s*x1-3.*x1s
3031  -r1s*x1s+3.*r2s*x1s+x1c-x2-r1s*x2+r2s*x2-r1s*x1*x2+r2s*x1*x2
3032  +x1s*x2)
3033  /prop1s
3034  -2.*(1.+r1s+r2s-4.*r1s*r2s+r1s*x1+2.*r2s*x1-x1s-r2s*x1s
3035  +2.*r1s*x2+r2s*x2-3.*x1*x2+x1s*x2-x2s-r1s*x2s+x1*x2s)
3036  /prop12
3037  +(1.-r1q+6.*r1s*r2s-r2q-x1+r1s*x1-r2s*x1+x2-9.*r1s*x2
3038  +3.*r2s*x2+r1s*x1*x2-r2s*x1*x2-3.*x2s+3.*r1s*x2s-r2s*x2s
3039  +x1*x2s+x2c)
3040  /prop2s;
3041  rFO4 = rFO4/2.;
3042  isSet4 = true;
3043  }
3044  break;
3045 
3046  // q -> q V.
3047  case 3:
3048  if (combi == 1 || combi == 3) {
3049  rLO1 = ps*(1.-2.*r1s+r1q+r2s-6.*r1*r2s+r1s*r2s-2.*r2q);
3050  rFO1 = -2.*(-1.+r1-2.*r1s+2.*r1c-r1q+pow5(r1)-r2s+r1*r2s
3051  -5.*r1s*r2s+r1c*r2s-2.*r1*r2q+2.*x1-2.*r1*x1+2.*r1s*x1
3052  -2.*r1c*x1+2.*r2s*x1+5.*r1*r2s*x1+r1s*r2s*x1+2.*r2q*x1
3053  -x1s+r1*x1s-r2s*x1s+3.*x2+4.*r1s*x2+r1q*x2+2.*r2s*x2
3054  +2.*r1s*r2s*x2-4.*x1*x2-2.*r1s*x1*x2-r2s*x1*x2+x1s*x2
3055  -2.*x2s-2.*r1s*x2s+x1*x2s)
3056  /prop23
3057  +(2.*r2s+6.*r1*r2s-6.*r1s*r2s+6.*r1c*r2s+2.*r2q+6.*r1*r2q
3058  -r2s*x1+r1s*r2s*x1-r2q*x1+x2-r1q*x2-3.*r2s*x2-6.*r1*r2s*x2
3059  +9.*r1s*r2s*x2-2.*r2q*x2-x1*x2+r1s*x1*x2-x2s-3.*r1s*x2s
3060  +2.*r2s*x2s+x1*x2s)
3061  /prop2s
3062  +(-4.-8.*r1s-4.*r1q+4.*r2s-4.*r1s*r2s+8.*r2q+9.*x1+10.*r1s*x1
3063  +r1q*x1-3.*r2s*x1+6.*r1*r2s*x1+r1s*r2s*x1-2.*r2q*x1-6.*x1s-
3064  2.*r1s*x1s+x1c+7.*x2+8.*r1s*x2+r1q*x2-7.*r2s*x2+6.*r1*r2s*x2
3065  +r1s*r2s*x2-2.*r2q*x2-9.*x1*x2-3.*r1s*x1*x2+2.*r2s*x1*x2
3066  +2.*x1s*x2-3.*x2s-r1s*x2s+2.*r2s*x2s+x1*x2s)
3067  /x3s;
3068  isSet1 = true;
3069  }
3070  if (combi == 2 || combi == 3) {
3071  rLO2 = ps*(1.-2.*r1s+r1q+r2s+6.*r1*r2s+r1s*r2s-2.*r2q);
3072  rFO2 = 2*(1.+r1+2.*r1s+2.*r1c+r1q+pow5(r1)+r2s+r1*r2s
3073  +5.*r1s*r2s+r1c*r2s-2.*r1*r2q-2.*x1-2.*r1*x1-2.*r1s*x1
3074  -2.*r1c*x1-2.*r2s*x1+5.*r1*r2s*x1-r1s*r2s*x1-2.*r2q*x1+x1s
3075  +r1*x1s+r2s*x1s-3.*x2-4.*r1s*x2-r1q*x2-2.*r2s*x2
3076  -2.*r1s*r2s*x2+4.*x1*x2+2.*r1s*x1*x2+r2s*x1*x2-x1s*x2
3077  +2.*x2s+2.*r1s*x2s-x1*x2s)
3078  /prop23
3079  +(2.*r2s-6.*r1*r2s-6.*r1s*r2s-6.*r1c*r2s+2.*r2q-6.*r1*r2q
3080  -r2s*x1+r1s*r2s*x1-r2q*x1+x2-r1q*x2-3.*r2s*x2+6.*r1*r2s*x2
3081  +9.*r1s*r2s*x2-2.*r2q*x2-x1*x2+r1s*x1*x2-x2s-3.*r1s*x2s
3082  +2.*r2s*x2s+x1*x2s)
3083  /prop2s
3084  +(-4.-8.*r1s-4.*r1q+4.*r2s-4.*r1s*r2s+8.*r2q+9.*x1+10.*r1s*x1
3085  +r1q*x1-3.*r2s*x1-6.*r1*r2s*x1+r1s*r2s*x1-2.*r2q*x1-6.*x1s
3086  -2.*r1s*x1s+x1c+7.*x2+8.*r1s*x2+r1q*x2-7.*r2s*x2-6.*r1*r2s*x2
3087  +r1s*r2s*x2-2.*r2q*x2-9.*x1*x2-3.*r1s*x1*x2+2.*r2s*x1*x2
3088  +2.*x1s*x2-3.*x2s-r1s*x2s+2.*r2s*x2s+x1*x2s)
3089  /x3s;
3090  isSet2 = true;
3091  }
3092  if (combi == 4) {
3093  rLO4 = ps*(1.-2.*r1s+r1q+r2s+r1s*r2s-2.*r2q);
3094  rFO4 = 2*(1.+2.*r1s+r1q+r2s+5.*r1s*r2s-2.*x1-2.*r1s*x1
3095  -2.*r2s*x1-r1s*r2s*x1-2.*r2q*x1+x1s+r2s*x1s-3.*x2-4.*r1s*x2
3096  -r1q*x2-2.*r2s*x2-2.*r1s*r2s*x2+4.*x1*x2+2.*r1s*x1*x2+r2s*x1*x2
3097  -x1s*x2+2.*x2s+2.*r1s*x2s-x1*x2s)
3098  /prop23
3099  +(2.*r2s-6.*r1s*r2s+2.*r2q-r2s*x1+r1s*r2s*x1-r2q*x1+x2-r1q*x2
3100  -3.*r2s*x2+9.*r1s*r2s*x2-2.*r2q*x2-x1*x2+r1s*x1*x2-x2s-3.*r1s*x2s
3101  +2.*r2s*x2s+x1*x2s)
3102  /prop2s
3103  +(-4.-8.*r1s-4.*r1q+4.*r2s-4.*r1s*r2s+8.*r2q+9.*x1+10.*r1s*x1
3104  +r1q*x1-3.*r2s*x1+r1s*r2s*x1-2.*r2q*x1-6.*x1s-2.*r1s*x1s+x1c
3105  +7.*x2+8.*r1s*x2+r1q*x2-7.*r2s*x2+r1s*r2s*x2-2.*r2q*x2-9.*x1*x2
3106  -3.*r1s*x1*x2+2.*r2s*x1*x2+2.*x1s*x2-3.*x2s-r1s*x2s+2.*r2s*x2s
3107  +x1*x2s)
3108  /x3s;
3109  isSet4 = true;
3110  }
3111  break;
3112 
3113  // S -> q qbar (S = h0/H0/A0/H+-/...).
3114  case 4:
3115  if (combi == 1 || combi == 3) {
3116  rLO1 = ps*(1.-r1s-r2s-2.*r1*r2);
3117  rFO1 = -(-1.+r1q-2.*r1*r2-2.*r1c*r2-6.*r1s*r2s-2.*r1*r2c+r2q+x1
3118  -r1s*x1+2.*r1*r2*x1+3.*r2s*x1+x2+r1s*x2-r2s*x2-x1*x2)
3119  /prop1s
3120  -2.*(r1s+r1q-2.*r1c*r2+r2s-6.*r1s*r2s-2.*r1*r2c+r2q-r1s*x1
3121  +r1*r2*x1+2.*r2s*x1+2.*r1s*x2+r1*r2*x2-r2s*x2-x1*x2)
3122  /prop12
3123  -(-1.+r1q-2.*r1*r2-2.*r1c*r2-6.*r1s*r2s-2.*r1*r2c+r2q+x1-r1s*x1
3124  +r2s*x1+x2+3.*r1s*x2+2.*r1*r2*x2-r2s*x2-x1*x2)
3125  /prop2s;
3126  isSet1 = true;
3127  }
3128  if (combi == 2 || combi == 3) {
3129  rLO2 = ps*(1.-r1s-r2s+2.*r1*r2);
3130  rFO2 = -(-1.+r1q+2.*r1*r2+2.*r1c*r2-6.*r1s*r2s+2.*r1*r2c+r2q+x1
3131  -r1s*x1-2.*r1*r2*x1+3.*r2s*x1+x2+r1s*x2-r2s*x2-x1*x2)
3132  /prop1s
3133  -(-1.+r1q+2.*r1*r2+2.*r1c*r2-6.*r1s*r2s+2.*r1*r2c+r2q+x1
3134  -r1s*x1+r2s*x1+x2+3.*r1s*x2-2.*r1*r2*x2-r2s*x2-x1*x2)
3135  /prop2s
3136  +2.*(-r1s-r1q-2.*r1c*r2-r2s+6.*r1s*r2s-2.*r1*r2c-r2q+r1s*x1
3137  +r1*r2*x1-2.*r2s*x1-2.*r1s*x2+r1*r2*x2+r2s*x2+x1*x2)
3138  /prop12;
3139  isSet2 = true;
3140  }
3141  if (combi == 4) {
3142  rLO4 = ps*(1.-r1s-r2s);
3143  rFO4 = -(-1.+r1q-6.*r1s*r2s+r2q+x1-r1s*x1+3.*r2s*x1+x2
3144  +r1s*x2-r2s*x2-x1*x2)
3145  /prop1s
3146  -2.*(r1s+r1q+r2s-6.*r1s*r2s+r2q-r1s*x1
3147  +2.*r2s*x1+2.*r1s*x2-r2s*x2-x1*x2)
3148  /prop12
3149  -(-1.+r1q-6.*r1s*r2s+r2q+x1-r1s*x1+r2s*x1
3150  +x2+3.*r1s*x2-r2s*x2-x1*x2)
3151  /prop2s;
3152  isSet4 = true;
3153  }
3154  break;
3155 
3156  // q -> q S.
3157  case 5:
3158  if (combi == 1 || combi == 3) {
3159  rLO1 = ps*(1.+r1s-r2s+2.*r1);
3160  rFO1 = (4.-4.*r1s+4.*r2s-3.*x1-2.*r1*x1+r1s*x1-r2s*x1-5.*x2
3161  -2.*r1*x2+r1s*x2-r2s*x2+x1*x2+x2s)
3162  /x3s
3163  -2.*(3.-r1-5.*r1s-r1c+3.*r2s+r1*r2s-2.*x1-r1*x1
3164  +r1s*x1-4.*x2+2.*r1s*x2-r2s*x2+x1*x2+x2s)
3165  /prop23
3166  +(2.-2.*r1-6.*r1s-2.*r1c+2.*r2s-2.*r1*r2s-x1+r1s*x1
3167  -r2s*x1-3.*x2+2.*r1*x2+3.*r1s*x2-r2s*x2+x1*x2+x2s)
3168  /prop2s;
3169  isSet1 = true;
3170  }
3171  if (combi == 2 || combi == 3) {
3172  rLO2 = ps*(1.+r1s-r2s-2.*r1);
3173  rFO2 = (4.-4.*r1s+4.*r2s-3.*x1+2.*r1*x1+r1s*x1-r2s*x1-5.*x2
3174  +2.*r1*x2+r1s*x2-r2s*x2+x1*x2+x2s)
3175  /x3s
3176  -2.*(3.+r1-5.*r1s+r1c+3.*r2s-r1*r2s-2.*x1+r1*x1
3177  +r1s*x1-4.*x2+2.*r1s*x2-r2s*x2+x1*x2+x2s)
3178  /prop23
3179  +(2.+2.*r1-6.*r1s+2.*r1c+2.*r2s+2.*r1*r2s-x1+r1s*x1
3180  -r2s*x1-3.*x2-2.*r1*x2+3.*r1s*x2-r2s*x2+x1*x2+x2s)
3181  /prop2s;
3182  isSet2 = true;
3183  }
3184  if (combi == 4) {
3185  rLO4 = ps*(1.+r1s-r2s);
3186  rFO4 = (4.-4.*r1s+4.*r2s-3.*x1+r1s*x1-r2s*x1-5.*x2+r1s*x2
3187  -r2s*x2+x1*x2+x2s)
3188  /x3s
3189  -2.*(3.-5.*r1s+3.*r2s-2.*x1+r1s*x1-4.*x2+2.*r1s*x2
3190  -r2s*x2+x1*x2+x2s)
3191  /prop23
3192  +(2.-6.*r1s+2.*r2s-x1+r1s*x1-r2s*x1-3.*x2+3.*r1s*x2
3193  -r2s*x2+x1*x2+x2s)
3194  /prop2s;
3195  isSet4 = true;
3196  }
3197  break;
3198 
3199  // V -> ~q ~qbar (~q = squark).
3200  case 6:
3201  rLO1 = ps*(1.-2.*r1s+r1q-2.*r2s-2.*r1s*r2s+r2q);
3202  rFO1 = 2.*3.+(1.+r1s+r2s-x1)*(4.*r1s-x1s)
3203  /prop1s
3204  +2.*(-1.-3.*r1s-r2s+x1+x1s*0.5+x2-x1*x2*0.5)
3205  /prop1
3206  +(1.+r1s+r2s-x2)*(4.*r2s-x2s)
3207  /prop2s
3208  +2.*(-1.-r1s-3.*r2s+x1+x2-x1*x2*0.5+x2s*0.5)
3209  /prop2
3210  -(-4.*r1s-4.*r1q-4.*r2s-8.*r1s*r2s-4.*r2q+2.*x1+6.*r1s*x1
3211  +6.*r2s*x1-2.*x1s+2.*x2+6.*r1s*x2+6.*r2s*x2-4.*x1*x2
3212  -2.*r1s*x1*x2-2.*r2s*x1*x2+x1s*x2-2.*x2s+x1*x2s)
3213  /prop12;
3214  isSet1 = true;
3215  break;
3216 
3217  // ~q -> ~q V.
3218  case 7:
3219  rLO1 = ps*(1.-2.*r1s+r1q-2.*r2s-2.*r1s*r2s+r2q);
3220  rFO1 = 16.*r2s-8.*(4.*r2s+2.*r2s*x1+x2+r1s*x2+r2s*x2-x1*x2
3221  -2.*x2s)
3222  /(3.*prop2)
3223  +8.*(1.+r1s+r2s-x2)*(4.*r2s-x2s)
3224  /(3.*prop2s)
3225  +8.*(x1+x2)*(-1.-2.*r1s-r1q-2.*r2s+2.*r1s*r2s-r2q+2.*x1
3226  +2.*r1s*x1+2.*r2s*x1-x1s+2.*x2+2.*r1s*x2+2.*r2s*x2-2.*x1*x2-x2s)
3227  /(3.*x3s)
3228  +8.*(-1.-r1s+r2s-x1)*(2.*r2s*x1+x2+r1s*x2+r2s*x2-x1*x2-x2s)
3229  /(3.*prop2*x3)
3230  -8.*(1.+2.*r1s+r1q+2.*r2s-2.*r1s*r2s+r2q-2.*x1-2.*r1s*x1
3231  -4.*r2s*x1+x1s-3.*x2-3.*r1s*x2-3.*r2s*x2+3.*x1*x2+2.*x2s)
3232  /(3.*x3);
3233  rFO1 = 3.*rFO1/8.;
3234  isSet1 = true;
3235  break;
3236 
3237  // S -> ~q ~qbar.
3238  case 8:
3239  rLO1 = ps;
3240  rFO1 = (-1.-2.*r1s-r1q-2.*r2s+2.*r1s*r2s-r2q+2.*x1+2.*r1s*x1
3241  +2.*r2s*x1-x1s-r2s*x1s+2.*x2+2.*r1s*x2+2.*r2s*x2-3.*x1*x2
3242  -r1s*x1*x2-r2s*x1*x2+x1s*x2-x2s-r1s*x2s+x1*x2s)
3243  /(prop1s*prop2s);
3244  rFO1 = 2.*rFO1;
3245  isSet1 = true;
3246  break;
3247 
3248  // ~q -> ~q S.
3249  case 9:
3250  rLO1 = ps;
3251  rFO1 = (-1.-r1s-r2s+x2)
3252  /prop2s
3253  +(1.+r1s-r2s+x1)
3254  /prop23
3255  -(x1+x2)
3256  /x3s;
3257  isSet1 = true;
3258  break;
3259 
3260  // chi -> q ~qbar (chi = neutralino/chargino).
3261  case 10:
3262  if (combi == 1 || combi == 3) {
3263  rLO1 = ps*(1.+r1s-r2s+2.*r1);
3264  rFO1 = (2.*r1+x1)*(-1.-r1s-r2s+x1)
3265  /prop1s
3266  +2.*(-1.-r1s-2.*r1c-r2s-2.*r1*r2s+3.*x1*0.5+r1*x1
3267  -r1s*x1*0.5-r2s*x1*0.5+x2+r1*x2+r1s*x2-x1*x2*0.5)
3268  /prop12
3269  +(2.-2.*r1-6.*r1s-2.*r1c+2.*r2s-2.*r1*r2s-x1+r1s*x1
3270  -r2s*x1-3.*x2+2.*r1*x2+3.*r1s*x2-r2s*x2+x1*x2+x2s)
3271  /prop2s;
3272  isSet1 = true;
3273  }
3274  if (combi == 2 || combi == 3) {
3275  rLO2 = ps*(1.-2.*r1+r1s-r2s);
3276  rFO2 = (2.*r1-x1)*(1.+r1s+r2s-x1)
3277  /prop1s
3278  +2.*(-1.-r1s+2.*r1c-r2s+2.*r1*r2s+3.*x1*0.5-r1*x1
3279  -r1s*x1*0.5-r2s*x1*0.5+x2-r1*x2+r1s*x2-x1*x2*0.5)
3280  /prop12
3281  +(2.+2.*r1-6.*r1s+2.*r1c+2.*r2s+2.*r1*r2s-x1+r1s*x1
3282  -r2s*x1-3.*x2-2.*r1*x2+3.*r1s*x2-r2s*x2+x1*x2+x2s)/
3283  prop2s;
3284  isSet2 = true;
3285  }
3286  if (combi == 4) {
3287  rLO4 = ps*(1.+r1s-r2s);
3288  rFO4 = x1*(-1.-r1s-r2s+x1)
3289  /prop1s
3290  +2.*(-1.-r1s-r2s+3.*x1*0.5-r1s*x1*0.5-r2s*x1*0.5
3291  +x2+r1s*x2-x1*x2*0.5)
3292  /prop12
3293  +(2.-6.*r1s+2.*r2s-x1+r1s*x1-r2s*x1-3.*x2+3.*r1s*x2
3294  -r2s*x2+x1*x2+x2s)
3295  /prop2s;
3296  isSet4 = true;
3297  }
3298  break;
3299 
3300  // ~q -> q chi.
3301  case 11:
3302  if (combi == 1 || combi == 3) {
3303  rLO1 = ps*(1.-pow2(r1+r2));
3304  rFO1 = (1.+r1s+2.*r1*r2+r2s-x1-x2)*(x1+x2)
3305  /x3s
3306  -(-1.+r1q-2.*r1*r2-2.*r1c*r2-6.*r1s*r2s-2.*r1*r2c+r2q+x1
3307  -r1s*x1+r2s*x1+x2+3.*r1s*x2+2.*r1*r2*x2-r2s*x2-x1*x2)
3308  /prop2s
3309  +(-1.-2.*r1s-r1q-2.*r1*r2-2.*r1c*r2+2.*r1*r2c+r2q+x1+r1s*x1
3310  -2.*r1*r2*x1-3.*r2s*x1+2.*r1s*x2-2.*r2s*x2+x1*x2+x2s)
3311  /prop23;
3312  isSet1 = true;
3313  }
3314  if (combi == 2 || combi == 3) {
3315  rLO2 = ps*(1.-pow2(r1-r2));
3316  rFO2 = (1.+r1s-2.*r1*r2+r2s-x1-x2)*(x1+x2)
3317  /x3s
3318  -(-1.+r1q+2.*r1*r2+2.*r1c*r2-6.*r1s*r2s+2.*r1*r2c+r2q+x1
3319  -r1s*x1+r2s*x1+x2+3.*r1s*x2-2.*r1*r2*x2-r2s*x2-x1*x2)
3320  /prop2s
3321  +(-1.-2.*r1s-r1q+2.*r1*r2+2.*r1c*r2-2.*r1*r2c+r2q+x1+r1s*x1
3322  +2.*r1*r2*x1-3.*r2s*x1+2.*r1s*x2-2.*r2s*x2+x1*x2+x2s)
3323  /prop23;
3324  isSet2 = true;
3325  }
3326  if (combi == 4) {
3327  rLO4 = ps*(1.-r1s-r2s);
3328  rFO4 = (1.+r1s+r2s-x1-x2)*(x1+x2)
3329  /x3s
3330  -(-1.+r1q-6.*r1s*r2s+r2q+x1-r1s*x1+r2s*x1+x2
3331  +3.*r1s*x2-r2s*x2-x1*x2)
3332  /prop2s
3333  +(-1.-2.*r1s-r1q+r2q+x1+r1s*x1-3.*r2s*x1
3334  +2.*r1s*x2-2.*r2s*x2+x1*x2+x2s)
3335  /prop23;
3336  isSet4 = true;
3337  }
3338  break;
3339 
3340  // q -> ~q chi.
3341  case 12:
3342  if (combi == 1 || combi == 3) {
3343  rLO1 = ps*(1.-r1s+r2s+2.*r2);
3344  rFO1 = (2.*r2+x2)*(-1.-r1s-r2s+x2)
3345  /prop2s
3346  +(4.+4.*r1s-4.*r2s-5.*x1-r1s*x1-2.*r2*x1+r2s*x1+x1s
3347  -3.*x2-r1s*x2-2.*r2*x2+r2s*x2+x1*x2)
3348  /x3s
3349  +2.*(-1.-r1s+r2+r1s*r2-r2s-r2c+x1+r2*x1+r2s*x1+2.*x2
3350  +r1s*x2-x1*x2*0.5-x2s*0.5)
3351  /prop23;
3352  isSet1 = true;
3353  }
3354  if (combi == 2 || combi == 3) {
3355  rLO2 = ps*(1.-r1s+r2s-2.*r2);
3356  rFO2 = (2.*r2-x2)*(1.+r1s+r2s-x2)
3357  /prop2s
3358  +(4.+4.*r1s-4.*r2s-5.*x1-r1s*x1+2.*r2*x1+r2s*x1+x1s
3359  -3.*x2-r1s*x2+2.*r2*x2+r2s*x2+x1*x2)
3360  /x3s
3361  +2.*(-1.-r1s-r2-r1s*r2-r2s+r2c+x1-r2*x1+r2s*x1+2.*x2
3362  +r1s*x2-x1*x2*0.5-x2s*0.5)
3363  /prop23;
3364  isSet2 = true;
3365  }
3366  if (combi == 4) {
3367  rLO4 = ps*(1.-r1s+r2s);
3368  rFO4 = x2*(-1.-r1s-r2s+x2)
3369  /prop2s
3370  +(4.+4.*r1s-4.*r2s-5.*x1-r1s*x1+r2s*x1+x1s
3371  -3.*x2-r1s*x2+r2s*x2+x1*x2)
3372  /x3s
3373  +2.*(-1.-r1s-r2s+x1+r2s*x1+2.*x2
3374  +r1s*x2-x1*x2*0.5-x2s*0.5)
3375  /prop23;
3376  isSet4 = true;
3377  }
3378  break;
3379 
3380  // ~g -> q ~qbar.
3381  case 13:
3382  if (combi == 1 || combi == 3) {
3383  rLO1 = ps*(1.+r1s-r2s+2.*r1);
3384  rFO1 = 4.*(2.*r1+x1)*(-1.-r1s-r2s+x1)
3385  /(3.*prop1s)
3386  -(-1.-r1s-2.*r1c-r2s-2.*r1*r2s+3.*x1*0.5+r1*x1-r1s*x1*0.5
3387  -r2s*x1*0.5+x2+r1*x2+r1s*x2-x1*x2*0.5)
3388  /(3.*prop12)
3389  +3.*(-1.+r1-r1s-r1c-r2s+r1*r2s+2.*x1+r2s*x1-x1s*0.5+x2+r1*x2
3390  +r1s*x2-x1*x2*0.5)
3391  /prop13
3392  +3.*(4.-4.*r1s+4.*r2s-3.*x1-2.*r1*x1+r1s*x1-r2s*x1-5.*x2
3393  -2.*r1*x2+r1s*x2-r2s*x2+x1*x2+x2s)
3394  /x3s
3395  -3.*(3.-r1-5.*r1s-r1c+3.*r2s+r1*r2s-2.*x1-r1*x1+r1s*x1
3396  -4.*x2+2.*r1s*x2-r2s*x2+x1*x2+x2s)
3397  /prop23
3398  +4.*(2.-2.*r1-6.*r1s-2.*r1c+2.*r2s-2.*r1*r2s-x1+r1s*x1-r2s*x1
3399  -3.*x2+2.*r1*x2+3.*r1s*x2-r2s*x2+x1*x2+x2s)
3400  /(3.*prop2s);
3401  rFO1 = 3.*rFO1/4.;
3402  isSet1 = true;
3403  }
3404  if (combi == 2 || combi == 3) {
3405  rLO2 = ps*(1.+r1s-r2s-2.*r1);
3406  rFO2 = 4.*(2.*r1-x1)*(1.+r1s+r2s-x1)
3407  /(3.*prop1s)
3408  +3.*(-1.-r1-r1s+r1c-r2s-r1*r2s+2.*x1+r2s*x1-x1s*0.5
3409  +x2-r1*x2+r1s*x2-x1*x2*0.5)
3410  /prop13
3411  +(2.+2.*r1s-4.*r1c+2.*r2s-4.*r1*r2s-3.*x1+2.*r1*x1
3412  +r1s*x1+r2s*x1-2.*x2+2.*r1*x2-2.*r1s*x2+x1*x2)
3413  /(6.*prop12)
3414  +3.*(4.-4.*r1s+4.*r2s-3.*x1+2.*r1*x1+r1s*x1-r2s*x1-5.*x2
3415  +2.*r1*x2+r1s*x2-r2s*x2+x1*x2+x2s)
3416  /x3s
3417  -3.*(3.+r1-5.*r1s+r1c+3.*r2s-r1*r2s-2.*x1+r1*x1+r1s*x1-4.*x2
3418  +2.*r1s*x2-r2s*x2+x1*x2+x2s)
3419  /prop23
3420  +4.*(2.+2.*r1-6.*r1s+2.*r1c+2.*r2s+2.*r1*r2s-x1+r1s*x1-r2s*x1
3421  -3.*x2-2.*r1*x2+3.*r1s*x2-r2s*x2+x1*x2+x2s)
3422  /(3.*prop2s);
3423  rFO2 = 3.*rFO2/4.;
3424  isSet2 = true;
3425  }
3426  if (combi == 4) {
3427  rLO4 = ps*(1.+r1s-r2s);
3428  rFO4 = 8.*x1*(-1.-r1s-r2s+x1)
3429  /(3.*prop1s)
3430  +6.*(-1-r1s-r2s+2.*x1+r2s*x1-x1s*0.5+x2+r1s*x2-x1*x2*0.5)
3431  /prop13
3432  +(2.+2.*r1s+2.*r2s-3.*x1+r1s*x1+r2s*x1-2.*x2-2.*r1s*x2+x1*x2)
3433  /(3.*prop12)
3434  +6.*(4.-4.*r1s+4.*r2s-3.*x1+r1s*x1-r2s*x1-5.*x2+r1s*x2-r2s*x2
3435  +x1*x2+x2s)
3436  /x3s
3437  -6.*(3.-5.*r1s+3.*r2s-2.*x1+r1s*x1-4.*x2+2.*r1s*x2-r2s*x2+x1*x2+x2s)
3438  /prop23
3439  +8.*(2.-6.*r1s+2.*r2s-x1+r1s*x1-r2s*x1-3.*x2+3.*r1s*x2-r2s*x2
3440  +x1*x2+x2s)
3441  /(3.*prop2s);
3442  rFO4 = 3.*rFO4/8.;
3443  isSet4 = true;
3444  }
3445  break;
3446 
3447  // ~q -> q ~g.
3448  case 14:
3449  if (combi == 1 || combi == 3) {
3450  rLO1 = ps*(1.-r1s-r2s-2.*r1*r2);
3451  rFO1 = 64.*(1.+r1s+2.*r1*r2+r2s-x1-x2)*(x1+x2)
3452  /(9.*x3s)
3453  -16.*(-1.+r1q-2.*r1*r2-2.*r1c*r2-6.*r1s*r2s-2.*r1*r2c+r2q
3454  +x1-r1s*x1+2.*r1*r2*x1+3.*r2s*x1+x2+r1s*x2-r2s*x2-x1*x2)
3455  /prop1s
3456  -16.*(r1s+r1q-2.*r1c*r2+r2s-6.*r1s*r2s-2.*r1*r2c+r2q-r1s*x1
3457  +r1*r2*x1+2.*r2s*x1+2.*r1s*x2+r1*r2*x2-r2s*x2-x1*x2)
3458  /prop12
3459  -64.*(-1.+r1q-2.*r1*r2-2.*r1c*r2-6.*r1s*r2s-2.*r1*r2c+r2q+x1
3460  -r1s*x1+r2s*x1+x2+3.*r1s*x2+2.*r1*r2*x2-r2s*x2-x1*x2)
3461  /(9.*prop2s)
3462  +8.*(-1.+r1q-2.*r1*r2+2.*r1c*r2-2.*r2s-2.*r1*r2c-r2q-2.*r1s*x1
3463  +2.*r2s*x1+x1s+x2-3.*r1s*x2-2.*r1*r2*x2+r2s*x2+x1*x2)
3464  /prop13
3465  -8.*(-1.-2.*r1s-r1q-2.*r1*r2-2.*r1c*r2+2.*r1*r2c+r2q+x1+r1s*x1
3466  -2.*r1*r2*x1-3.*r2s*x1+2.*r1s*x2-2.*r2s*x2+x1*x2+x2s)
3467  /(9.*prop23);
3468  rFO1 = 9.*rFO1/64.;
3469  isSet1 = true;
3470  }
3471  if (combi == 2 || combi == 3) {
3472  rLO2 = ps*(1.-r1s-r2s+2.*r1*r2);
3473  rFO2 = 64.*(1.+r1s-2.*r1*r2+r2s-x1-x2)*(x1+x2)
3474  /(9.*x3s)
3475  -16.*(-1.+r1q+2.*r1*r2+2.*r1c*r2-6.*r1s*r2s+2.*r1*r2c+r2q+x1
3476  -r1s*x1-2.*r1*r2*x1+3.*r2s*x1+x2+r1s*x2-r2s*x2-x1*x2)
3477  /prop1s
3478  -64.*(-1.+r1q+2.*r1*r2+2.*r1c*r2-6.*r1s*r2s+2.*r1*r2c+r2q+x1
3479  -r1s*x1+r2s*x1+x2+3.*r1s*x2-2.*r1*r2*x2-r2s*x2-x1*x2)
3480  /(9.*prop2s)
3481  +16.*(-r1s-r1q-2.*r1c*r2-r2s+6.*r1s*r2s-2.*r1*r2c-r2q+r1s*x1
3482  +r1*r2*x1-2.*r2s*x1-2.*r1s*x2+r1*r2*x2+r2s*x2+x1*x2)
3483  /prop12
3484  +8.*(-1.+r1q+2.*r1*r2-2.*r1c*r2-2.*r2s+2.*r1*r2c-r2q-2.*r1s*x1
3485  +2.*r2s*x1+x1s+x2-3.*r1s*x2+2.*r1*r2*x2+r2s*x2+x1*x2)
3486  /prop13
3487  -8.*(-1.-2.*r1s-r1q+2.*r1*r2+2.*r1c*r2-2.*r1*r2c+r2q+x1+r1s*x1+
3488  2.*r1*r2*x1-3.*r2s*x1+2.*r1s*x2-2.*r2s*x2+x1*x2+x2s)
3489  /(9.*prop23);
3490  rFO2 = 9.*rFO2/64.;
3491  isSet2 = true;
3492  }
3493  if (combi == 4) {
3494  rLO4 = ps*(1.-r1s-r2s);
3495  rFO4 = 128.*(1.+r1s+r2s-x1-x2)*(x1+x2)
3496  /(9.*x3s)
3497  -32*(-1.+r1q-6.*r1s*r2s+r2q+x1-r1s*x1+3.*r2s*x1+x2
3498  +r1s*x2-r2s*x2-x1*x2)
3499  /prop1s
3500  -32.*(r1s+r1q+r2s-6.*r1s*r2s+r2q-r1s*x1+2.*r2s*x1+2.*r1s*x2
3501  -r2s*x2-x1*x2)
3502  /prop12
3503  -128.*(-1.+r1q-6.*r1s*r2s+r2q+x1-r1s*x1+r2s*x1+x2+3.*r1s*x2
3504  -r2s*x2-x1*x2)
3505  /(9.*prop2s)
3506  +16.*(-1.+r1q-2.*r2s-r2q-2.*r1s*x1+2.*r2s*x1+x1s
3507  +x2-3.*r1s*x2+r2s*x2+x1*x2)
3508  /prop13
3509  -16.*(-1.-2.*r1s-r1q+r2q+x1+r1s*x1-3.*r2s*x1
3510  +2.*r1s*x2-2.*r2s*x2+x1*x2+x2s)
3511  /(9.*prop23);
3512  rFO4 = 9.*rFO4/128.;
3513  isSet4 = true;
3514  }
3515  break;
3516 
3517  // q -> ~q ~g.
3518  case 15:
3519  if (combi == 1 || combi == 3) {
3520  rLO1 = ps*(1.-r1s+r2s+2.*r2);
3521  rFO1 = 32*(2.*r2+x2)*(-1.-r1s-r2s+x2)
3522  /(9.*prop2s)
3523  +8.*(-1.-r1s-2.*r1s*r2-r2s-2.*r2c+x1+r2*x1+r2s*x1
3524  +3.*x2*0.5-r1s*x2*0.5+r2*x2-r2s*x2*0.5-x1*x2*0.5)
3525  /prop12
3526  +8.*(2.+2.*r1s-2.*r2-2.*r1s*r2-6.*r2s-2.*r2c-3.*x1-r1s*x1
3527  +2.*r2*x1+3.*r2s*x1+x1s-x2-r1s*x2+r2s*x2+x1*x2)
3528  /prop1s
3529  +32.*(4.+4.*r1s-4.*r2s-5.*x1-r1s*x1-2.*r2*x1+r2s*x1+x1s
3530  -3.*x2-r1s*x2-2.*r2*x2+r2s*x2+x1*x2)
3531  /(9.*x3s)
3532  -8.*(3.+3.*r1s-r2+r1s*r2-5.*r2s-r2c-4.*x1-r1s*x1
3533  +2.*r2s*x1+x1s-2.*x2-r2*x2+r2s*x2+x1*x2)
3534  /prop13
3535  -8.*(-1.-r1s+r2+r1s*r2-r2s-r2c+x1+r2*x1+r2s*x1+2.*x2+r1s*x2
3536  -x1*x2*0.5-x2s*0.5)
3537  /(9.*prop23);
3538  rFO1 = 9.*rFO1/32.;
3539  isSet1 = true;
3540  }
3541  if (combi == 2 || combi == 3) {
3542  rLO2 = ps*(1.-r1s+r2s-2.*r2);
3543  rFO2 = 32*(2.*r2-x2)*(1.+r1s+r2s-x2)
3544  /(9.*prop2s)
3545  +8.*(-1.-r1s+2.*r1s*r2-r2s+2.*r2c+x1-r2*x1+r2s*x1
3546  +3.*x2*0.5-r1s*x2*0.5-r2*x2-r2s*x2*0.5-x1*x2*0.5)
3547  /prop12
3548  +8.*(2.+2.*r1s+2.*r2+2.*r1s*r2-6.*r2s+2.*r2c-3.*x1-r1s*x1
3549  -2.*r2*x1+3.*r2s*x1+x1s-x2-r1s*x2+r2s*x2+x1*x2)
3550  /prop1s
3551  -8.*(3.+3.*r1s+r2-r1s*r2-5.*r2s+r2c-4.*x1-r1s*x1+2.*r2s*x1+x1s
3552  -2.*x2+r2*x2+r2s*x2+x1*x2)
3553  /prop13
3554  +32*(4.+4.*r1s-4.*r2s-5.*x1-r1s*x1+2.*r2*x1+r2s*x1
3555  +x1s-3.*x2-r1s*x2+2.*r2*x2+r2s*x2+x1*x2)
3556  /(9.*x3s)
3557  -8.*(-1.-r1s-r2-r1s*r2-r2s+r2c+x1-r2*x1+r2s*x1+2.*x2+r1s*x2
3558  -x1*x2*0.5-x2s*0.5)
3559  /(9.*prop23);
3560  rFO2 = 9.*rFO2/32.;
3561  isSet2 = true;
3562  }
3563  if (combi == 4) {
3564  rLO4 = ps*(1.-r1s+r2s);
3565  rFO4 = 64.*x2*(-1.-r1s-r2s+x2)
3566  /(9.*prop2s)
3567  +16.*(-1.-r1s-r2s+x1+r2s*x1+3.*x2*0.5-r1s*x2*0.5
3568  -r2s*x2*0.5-x1*x2*0.5)
3569  /prop12
3570  -16.*(3.+3.*r1s-5.*r2s-4.*x1-r1s*x1+2.*r2s*x1+x1s-2.*x2+r2s*x2
3571  +x1*x2)
3572  /prop13
3573  +64.*(4.+4.*r1s-4.*r2s-5.*x1-r1s*x1+r2s*x1+x1s-3.*x2
3574  -r1s*x2+r2s*x2+x1*x2)
3575  /(9.*x3s)
3576  +16.*(2.+2.*r1s-6.*r2s-3.*x1-r1s*x1+3.*r2s*x1+x1s
3577  -x2-r1s*x2+r2s*x2+x1*x2)
3578  /prop1s
3579  -16.*(-1.-r1s-r2s+x1+r2s*x1+2.*x2+r1s*x2-x1*x2*0.5-x2s*0.5)
3580  /(9.*prop23);
3581  rFO4 = 9.*rFO4/64.;
3582  isSet4 = true;
3583  }
3584  break;
3585 
3586  // g -> ~g ~g. Use (9/4)*eikonal. May be changed in the future.
3587  case 16:
3588  rLO = ps;
3589  if (combi == 2) offset = x3s;
3590  else if (combi == 3) offset = mix * x3s;
3591  else if (combi == 4) offset = 0.5 * x3s;
3592  rFO = ps * 4.5 * ( (x1+x2-1.+offset-r1s-r2s)/prop12
3593  - r1s/prop2s - r2s/prop1s );
3594  break;
3595 
3596  // Dv -> qv d.
3597  case 30:
3598  rLO = ps*(1.-r1s+r2s+2.*r2);
3599  rFO = ( 0.5*r3s + 2.*r1q + 0.5*r2s*r3s + r2*r3s - 2.*r1s
3600  - 0.5*r1s*r3s - 2.*r1s*r2s - 4.*r1s*r2 ) / prop2s
3601  + ( -2. + 2.*r2q + 2.*r1q + 2.*r2s*r3s - 4.*r2 + 2.*r2*r3s
3602  + 4.*r2*r2s - 4.*r1s*r2s - 4.*r1s*r2 ) /prop23
3603  + ( -2. - 0.5*r3s - 2.*r2s - 4.*r2 + 2.*r1s ) / prop2
3604  + ( -2. - r3s - 2.*r2s - r2s*r3s - 4.*r2 - 2.*r2*r3s
3605  + 2.*r1s + r1s*r3s ) / prop3s
3606  + ( -1. - r3s - r2s - 4.*r2 + r1s - x2 ) / prop3
3607  + 1.;
3608  break;
3609 
3610  // S -> Dv Dvbar
3611  case 31:
3612  rLO = ps*(1.-4.*r1s);
3613  rFO = (r3s + 2.*r1s) * (-1. + 4.*r1s) * (1./prop1s + 1./prop2s)
3614  + (-1. + 8.*r1s - x2) / prop1
3615  + (-1. + 8.*r1s - x1) / prop2
3616  + 2. * (1. - 6.*r1s + 8.*r1q + 4.*r3s*r1s) / prop12
3617  + 2.;
3618  break;
3619 
3620  // Eikonal expression for kind == 1; also acts as default.
3621  default:
3622  rLO = ps;
3623  if (combi == 2) offset = x3s;
3624  else if (combi == 3) offset = mix * x3s;
3625  else if (combi == 4) offset = 0.5 * x3s;
3626  rFO = ps * 2. * ( (x1+x2-1.+offset-r1s-r2s)/prop12
3627  - r1s/prop2s - r2s/prop1s );
3628  break;
3629 
3630  // End of ME cases.
3631  }
3632 
3633  // Find relevant leading and first order expressions.
3634  if (combi == 1 && isSet1) {
3635  rLO = rLO1;
3636  rFO = rFO1; }
3637  else if (combi == 2 && isSet2) {
3638  rLO = rLO2;
3639  rFO = rFO2; }
3640  else if (combi == 3 && isSet1 && isSet2) {
3641  rLO = mix * rLO1 + (1.-mix) * rLO2;
3642  rFO = mix * rFO1 + (1.-mix) * rFO2; }
3643  else if (isSet4) {
3644  rLO = rLO4;
3645  rFO = rFO4; }
3646  else if (combi == 4 && isSet1 && isSet2) {
3647  rLO = 0.5 * (rLO1 + rLO2);
3648  rFO = 0.5 * (rFO1 + rFO2); }
3649  else if (isSet1) {
3650  rLO = rLO1;
3651  rFO = rFO1; }
3652 
3653  // Return ratio of first to leading order cross section.
3654  return rFO / rLO;
3655 }
3656 
3657 //--------------------------------------------------------------------------
3658 
3659 // Find coefficient of azimuthal asymmetry from gluon polarization.
3660 
3661 void TimeShower::findAsymPol( Event& event, TimeDipoleEnd* dip) {
3662 
3663  // Default is no asymmetry. Only gluons are studied.
3664  dip->asymPol = 0.;
3665  dip->iAunt = 0;
3666  int iRad = dip->iRadiator;
3667  if (!doPhiPolAsym || event[iRad].id() != 21) return;
3668 
3669  // Trace grandmother via possibly intermediate recoil copies.
3670  int iMother = event.iTopCopy(iRad);
3671  int iGrandM = event[iMother].mother1();
3672 
3673  // If grandmother in initial state of hard scattering,
3674  // then only keep gg and qq initial states.
3675  int statusGrandM = event[iGrandM].status();
3676  bool isHardProc = (statusGrandM == -21 || statusGrandM == -31);
3677  if (isHardProc) {
3678  if (event[iGrandM + 1].status() != statusGrandM) return;
3679  if (event[iGrandM].isGluon() && event[iGrandM + 1].isGluon());
3680  else if (event[iGrandM].isQuark() && event[iGrandM + 1].isQuark());
3681  else return;
3682  }
3683 
3684  // Set aunt by history or, for hard scattering, by colour flow.
3685  if (isHardProc) dip->iAunt = dip->iRecoiler;
3686  else dip->iAunt = (event[iGrandM].daughter1() == iMother)
3687  ? event[iGrandM].daughter2() : event[iGrandM].daughter1();
3688 
3689  // Coefficient from gluon production (approximate z by energy).
3690  // For hard process arbitrarily put z = 1/2.
3691  double zProd = (isHardProc) ? 0.5 : event[iRad].e()
3692  / (event[iRad].e() + event[dip->iAunt].e());
3693  if (event[iGrandM].isGluon()) dip->asymPol = pow2( (1. - zProd)
3694  / (1. - zProd * (1. - zProd) ) );
3695  else dip->asymPol = 2. * (1. - zProd) / (1. + pow2(1. - zProd) );
3696 
3697  // Coefficients from gluon decay.
3698  if (dip->flavour == 21) dip->asymPol *= pow2( (1. - dip->z)
3699  / (1. - dip->z * (1. - dip->z) ) );
3700  else dip->asymPol *= -2. * dip->z *( 1. - dip->z )
3701  / (1. - 2. * dip->z * (1. - dip->z) );
3702 
3703 }
3704 
3705 //--------------------------------------------------------------------------
3706 
3707 // Print the list of dipoles.
3708 
3709 void TimeShower::list(ostream& os) const {
3710 
3711  // Header.
3712  os << "\n -------- PYTHIA TimeShower Dipole Listing ----------------"
3713  << "--------------------------------------------- \n \n i rad"
3714  << " rec pTmax col chg gam oni hv isr sys sysR typ"
3715  << "e MErec mix ord spl ~gR \n" << fixed << setprecision(3);
3716 
3717  // Loop over dipole list and print it.
3718  for (int i = 0; i < int(dipEnd.size()); ++i)
3719  os << setw(5) << i << setw(7) << dipEnd[i].iRadiator
3720  << setw(7) << dipEnd[i].iRecoiler << setw(12) << dipEnd[i].pTmax
3721  << setw(5) << dipEnd[i].colType << setw(5) << dipEnd[i].chgType
3722  << setw(5) << dipEnd[i].gamType << setw(5) << dipEnd[i].isOctetOnium
3723  << setw(5) << dipEnd[i].isHiddenValley << setw(5) << dipEnd[i].isrType
3724  << setw(5) << dipEnd[i].system << setw(5) << dipEnd[i].systemRec
3725  << setw(5) << dipEnd[i].MEtype << setw(7) << dipEnd[i].iMEpartner
3726  << setw(8) << dipEnd[i].MEmix << setw(5) << dipEnd[i].MEorder
3727  << setw(5) << dipEnd[i].MEsplit << setw(5) << dipEnd[i].MEgluinoRec
3728  << "\n";
3729 
3730  // Done.
3731  os << "\n -------- End PYTHIA TimeShower Dipole Listing ------------"
3732  << "---------------------------------------------" << endl;
3733 
3734 }
3735 
3736 //==========================================================================
3737 
3738 } // end namespace Pythia8
3739 
Definition: beam.h:43
Definition: AgUStep.h:26