Line data Source code
1 : // TimeShower.cc is a part of the PYTHIA event generator.
2 : // Copyright (C) 2015 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 "Pythia8/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 : // Minimal allowed c and b quark masses, for flavour thresholds.
22 : const double TimeShower::MCMIN = 1.2;
23 : const double TimeShower::MBMIN = 4.0;
24 :
25 : // For small x approximate 1 - sqrt(1 - x) by x/2.
26 : const double TimeShower::SIMPLIFYROOT = 1e-8;
27 :
28 : // Do not allow x too close to 0 or 1 in matrix element expressions.
29 : // Warning: cuts into phase space for E_CM > 2 * pTmin * sqrt(1/XMARGIN),
30 : // i.e. will become problem roughly for E_CM > 10^6 GeV.
31 : const double TimeShower::XMARGIN = 1e-12;
32 : const double TimeShower::XMARGINCOMB = 1e-4;
33 :
34 : // Lower limit on PDF value in order to avoid division by zero.
35 : const double TimeShower::TINYPDF = 1e-10;
36 :
37 : // Big starting value in search for smallest invariant-mass pair.
38 : const double TimeShower::LARGEM2 = 1e20;
39 :
40 : // In g -> q qbar or gamma -> f fbar require m2_pair > this * m2_q/f.
41 : const double TimeShower::THRESHM2 = 4.004;
42 :
43 : // Never pick pT so low that alphaS is evaluated too close to Lambda_3.
44 : const double TimeShower::LAMBDA3MARGIN = 1.1;
45 :
46 : // Rescatter: rescattering + ISR + FSR + primordial kT can lead to
47 : // systems not locally conserving momentum.
48 : // Fix up momentum in intermediate systems with rescattering
49 : const bool TimeShower::FIXRESCATTER = true;
50 : // Veto negative energies when using FIXRESCATTER option.
51 : const bool TimeShower::VETONEGENERGY = false;
52 : // Do not allow too large time- or spacelike virtualities in fixing-up.
53 : const double TimeShower::MAXVIRTUALITYFRACTION = 0.5;
54 : // Do not allow too large negative spacelike energy in system rest frame.
55 : const double TimeShower::MAXNEGENERGYFRACTION = 0.7;
56 :
57 : // Fudge extra weight for overestimation of weak shower t-channel correction.
58 : const double TimeShower::WEAKPSWEIGHT = 5.;
59 :
60 : // Extra overestimate of g -> q qbar branching rate for DGLAP comparison.
61 : const double TimeShower::WG2QEXTRA = 20.;
62 :
63 : //--------------------------------------------------------------------------
64 :
65 : // Initialize alphaStrong, alphaEM and related pTmin parameters.
66 :
67 : void TimeShower::init( BeamParticle* beamAPtrIn,
68 : BeamParticle* beamBPtrIn) {
69 :
70 : // Store input pointers for future use.
71 0 : beamAPtr = beamAPtrIn;
72 0 : beamBPtr = beamBPtrIn;
73 :
74 : // Main flags.
75 0 : doQCDshower = settingsPtr->flag("TimeShower:QCDshower");
76 0 : doQEDshowerByQ = settingsPtr->flag("TimeShower:QEDshowerByQ");
77 0 : doQEDshowerByL = settingsPtr->flag("TimeShower:QEDshowerByL");
78 0 : doQEDshowerByGamma = settingsPtr->flag("TimeShower:QEDshowerByGamma");
79 0 : doWeakShower = settingsPtr->flag("TimeShower:weakShower");
80 0 : doMEcorrections = settingsPtr->flag("TimeShower:MEcorrections");
81 0 : doMEafterFirst = settingsPtr->flag("TimeShower:MEafterFirst");
82 0 : doPhiPolAsym = settingsPtr->flag("TimeShower:phiPolAsym");
83 0 : doInterleave = settingsPtr->flag("TimeShower:interleave");
84 0 : allowBeamRecoil = settingsPtr->flag("TimeShower:allowBeamRecoil");
85 0 : dampenBeamRecoil = settingsPtr->flag("TimeShower:dampenBeamRecoil");
86 0 : recoilToColoured = settingsPtr->flag("TimeShower:recoilToColoured");
87 0 : allowMPIdipole = settingsPtr->flag("TimeShower:allowMPIdipole");
88 :
89 : // Matching in pT of hard interaction or MPI to shower evolution.
90 0 : pTmaxMatch = settingsPtr->mode("TimeShower:pTmaxMatch");
91 0 : pTdampMatch = settingsPtr->mode("TimeShower:pTdampMatch");
92 0 : pTmaxFudge = settingsPtr->parm("TimeShower:pTmaxFudge");
93 0 : pTmaxFudgeMPI = settingsPtr->parm("TimeShower:pTmaxFudgeMPI");
94 0 : pTdampFudge = settingsPtr->parm("TimeShower:pTdampFudge");
95 :
96 : // Charm and bottom mass thresholds.
97 0 : mc = max( MCMIN, particleDataPtr->m0(4));
98 0 : mb = max( MBMIN, particleDataPtr->m0(5));
99 0 : m2c = mc * mc;
100 0 : m2b = mb * mb;
101 :
102 : // Parameters of scale choices.
103 0 : renormMultFac = settingsPtr->parm("TimeShower:renormMultFac");
104 0 : factorMultFac = settingsPtr->parm("TimeShower:factorMultFac");
105 0 : useFixedFacScale = settingsPtr->flag("TimeShower:useFixedFacScale");
106 0 : fixedFacScale2 = pow2(settingsPtr->parm("TimeShower:fixedFacScale"));
107 :
108 : // Parameters of alphaStrong generation.
109 0 : alphaSvalue = settingsPtr->parm("TimeShower:alphaSvalue");
110 0 : alphaSorder = settingsPtr->mode("TimeShower:alphaSorder");
111 0 : alphaSnfmax = settingsPtr->mode("StandardModel:alphaSnfmax");
112 0 : alphaSuseCMW = settingsPtr->flag("TimeShower:alphaSuseCMW");
113 0 : alphaS2pi = 0.5 * alphaSvalue / M_PI;
114 :
115 : // Initialize alphaStrong generation.
116 0 : alphaS.init( alphaSvalue, alphaSorder, alphaSnfmax, alphaSuseCMW);
117 :
118 : // Lambda for 5, 4 and 3 flavours.
119 0 : Lambda3flav = alphaS.Lambda3();
120 0 : Lambda4flav = alphaS.Lambda4();
121 0 : Lambda5flav = alphaS.Lambda5();
122 0 : Lambda5flav2 = pow2(Lambda5flav);
123 0 : Lambda4flav2 = pow2(Lambda4flav);
124 0 : Lambda3flav2 = pow2(Lambda3flav);
125 :
126 : // Parameters of QCD evolution. Warn if pTmin must be raised.
127 0 : nGluonToQuark = settingsPtr->mode("TimeShower:nGluonToQuark");
128 0 : weightGluonToQuark = settingsPtr->mode("TimeShower:weightGluonToQuark");
129 0 : scaleGluonToQuark = settingsPtr->parm("TimeShower:scaleGluonToQuark");
130 0 : extraGluonToQuark = (weightGluonToQuark%4 == 3) ? WG2QEXTRA : 1.;
131 0 : pTcolCutMin = settingsPtr->parm("TimeShower:pTmin");
132 0 : if (pTcolCutMin > LAMBDA3MARGIN * Lambda3flav / sqrt(renormMultFac))
133 0 : pTcolCut = pTcolCutMin;
134 : else {
135 0 : pTcolCut = LAMBDA3MARGIN * Lambda3flav / sqrt(renormMultFac);
136 0 : ostringstream newPTcolCut;
137 0 : newPTcolCut << fixed << setprecision(3) << pTcolCut;
138 0 : infoPtr->errorMsg("Warning in TimeShower::init: pTmin too low",
139 0 : ", raised to " + newPTcolCut.str() );
140 0 : infoPtr->setTooLowPTmin(true);
141 0 : }
142 0 : pT2colCut = pow2(pTcolCut);
143 :
144 : // Parameters of alphaEM generation.
145 0 : alphaEMorder = settingsPtr->mode("TimeShower:alphaEMorder");
146 :
147 : // Initialize alphaEM generation.
148 0 : alphaEM.init( alphaEMorder, settingsPtr);
149 :
150 : // Parameters of QED evolution.
151 0 : nGammaToQuark = settingsPtr->mode("TimeShower:nGammaToQuark");
152 0 : nGammaToLepton = settingsPtr->mode("TimeShower:nGammaToLepton");
153 0 : pTchgQCut = settingsPtr->parm("TimeShower:pTminChgQ");
154 0 : pT2chgQCut = pow2(pTchgQCut);
155 0 : pTchgLCut = settingsPtr->parm("TimeShower:pTminChgL");
156 0 : pT2chgLCut = pow2(pTchgLCut);
157 0 : mMaxGamma = settingsPtr->parm("TimeShower:mMaxGamma");
158 0 : m2MaxGamma = pow2(mMaxGamma);
159 :
160 : // Parameters of weak evolution.
161 0 : weakMode = settingsPtr->mode("TimeShower:weakShowerMode");
162 0 : pTweakCut = settingsPtr->parm("TimeShower:pTminWeak");
163 0 : pT2weakCut = pow2(pTweakCut);
164 0 : weakEnhancement = settingsPtr->parm("WeakShower:enhancement");
165 0 : singleWeakEmission = settingsPtr->flag("WeakShower:singleEmission");
166 0 : vetoWeakJets = settingsPtr->flag("WeakShower:vetoWeakJets");
167 0 : vetoWeakDeltaR2 = pow2(settingsPtr->parm("WeakShower:vetoWeakDeltaR"));
168 :
169 : // Consisteny check for gamma -> f fbar variables.
170 0 : if (nGammaToQuark <= 0 && nGammaToLepton <= 0) doQEDshowerByGamma = false;
171 :
172 : // Possibility of a global recoil stategy, e.g. for MC@NLO.
173 0 : globalRecoil = settingsPtr->flag("TimeShower:globalRecoil");
174 0 : nMaxGlobalRecoil = settingsPtr->mode("TimeShower:nMaxGlobalRecoil");
175 : // Number of splittings produced with global recoil.
176 0 : nMaxGlobalBranch = settingsPtr->mode("TimeShower:nMaxGlobalBranch");
177 : // Number of partons in Born-like events, to distinguish between S and H.
178 0 : nFinalBorn = settingsPtr->mode("TimeShower:nPartonsInBorn");
179 : // Flag to allow to start from a scale smaller than scalup.
180 0 : globalRecoilMode = settingsPtr->mode("TimeShower:globalRecoilMode");
181 : // Flag to allow to start from a scale smaller than scalup.
182 0 : limitMUQ = settingsPtr->flag("TimeShower:limitPTmaxGlobal");
183 :
184 : // Fraction and colour factor of gluon emission off onium octat state.
185 0 : octetOniumFraction = settingsPtr->parm("TimeShower:octetOniumFraction");
186 0 : octetOniumColFac = settingsPtr->parm("TimeShower:octetOniumColFac");
187 :
188 : // Z0 and W+- properties needed for gamma/Z0 mixing and weak showers.
189 0 : mZ = particleDataPtr->m0(23);
190 0 : gammaZ = particleDataPtr->mWidth(23);
191 0 : thetaWRat = 1. / (16. * coupSMPtr->sin2thetaW()
192 0 : * coupSMPtr->cos2thetaW());
193 0 : mW = particleDataPtr->m0(24);
194 0 : gammaW = particleDataPtr->mWidth(24);
195 :
196 : // May have to fix up recoils related to rescattering.
197 0 : allowRescatter = settingsPtr->flag("PartonLevel:MPI")
198 0 : && settingsPtr->flag("MultipartonInteractions:allowRescatter");
199 :
200 : // Hidden Valley scenario with further shower activity.
201 0 : doHVshower = settingsPtr->flag("HiddenValley:FSR");
202 0 : nCHV = settingsPtr->mode("HiddenValley:Ngauge");
203 0 : alphaHVfix = settingsPtr->parm("HiddenValley:alphaFSR");
204 0 : pThvCut = settingsPtr->parm("HiddenValley:pTminFSR");
205 0 : pT2hvCut = pThvCut * pThvCut;
206 0 : CFHV = (nCHV == 1) ? 1. : (nCHV * nCHV - 1.)/(2. * nCHV);
207 0 : idHV = (nCHV == 1) ? 4900022 : 4900021;
208 0 : mHV = particleDataPtr->m0(idHV);
209 0 : brokenHVsym = (nCHV == 1 && mHV > 0.);
210 :
211 : // Possibility of two predetermined hard emissions in event.
212 0 : doSecondHard = settingsPtr->flag("SecondHard:generate");
213 :
214 : // Possibility to allow user veto of emission step.
215 0 : canVetoEmission = (userHooksPtr != 0)
216 0 : ? userHooksPtr->canVetoFSREmission() : false;
217 :
218 : // Set initial value, just in case.
219 0 : dopTdamp = false;
220 0 : pT2damp = 0.;
221 :
222 : // Default values for the weak shower.
223 0 : hasWeaklyRadiated = false;
224 :
225 0 : }
226 :
227 : //--------------------------------------------------------------------------
228 :
229 : // Find whether to limit maximum scale of emissions.
230 : // Also allow for dampening at factorization or renormalization scale.
231 :
232 : bool TimeShower::limitPTmax( Event& event, double Q2Fac, double Q2Ren) {
233 :
234 : // Find whether to limit pT. Begin by user-set cases.
235 : bool dopTlimit = false;
236 0 : dopTlimit1 = dopTlimit2 = false;
237 : int nHeavyCol = 0;
238 0 : if (pTmaxMatch == 1) dopTlimit = dopTlimit1 = dopTlimit2 = true;
239 0 : else if (pTmaxMatch == 2) dopTlimit = dopTlimit1 = dopTlimit2 = false;
240 :
241 : // Always restrict SoftQCD processes.
242 0 : else if (infoPtr->isNonDiffractive() || infoPtr->isDiffractiveA()
243 0 : || infoPtr->isDiffractiveB() || infoPtr->isDiffractiveC() )
244 0 : dopTlimit = dopTlimit1 = dopTlimit2 = true;
245 :
246 : // Look if any quark (u, d, s, c, b), gluon or photon in final state.
247 : // Also count number of heavy coloured particles, like top.
248 : else {
249 : int n21 = 0;
250 : int iBegin = 5;
251 0 : if (infoPtr->isHardDiffractive()) iBegin = 9;
252 0 : for (int i = iBegin; i < event.size(); ++i) {
253 0 : if (event[i].status() == -21) ++n21;
254 0 : else if (n21 == 0) {
255 0 : int idAbs = event[i].idAbs();
256 0 : if (idAbs <= 5 || idAbs == 21 || idAbs == 22) dopTlimit1 = true;
257 0 : if ( (event[i].col() != 0 || event[i].acol() != 0)
258 0 : && idAbs > 5 && idAbs != 21 ) ++nHeavyCol;
259 0 : } else if (n21 == 2) {
260 0 : int idAbs = event[i].idAbs();
261 0 : if (idAbs <= 5 || idAbs == 21 || idAbs == 22) dopTlimit2 = true;
262 0 : }
263 : }
264 0 : dopTlimit = (doSecondHard) ? (dopTlimit1 && dopTlimit2) : dopTlimit1;
265 : }
266 :
267 : // Dampening at factorization or renormalization scale; only for hardest.
268 0 : dopTdamp = false;
269 0 : pT2damp = 0.;
270 0 : if (!dopTlimit1 && (pTdampMatch == 1 || pTdampMatch == 2)) {
271 0 : dopTdamp = true;
272 0 : pT2damp = pow2(pTdampFudge) * ((pTdampMatch == 1) ? Q2Fac : Q2Ren);
273 0 : }
274 0 : if (!dopTlimit1 && nHeavyCol > 1 && (pTdampMatch == 3 || pTdampMatch == 4)) {
275 0 : dopTdamp = true;
276 0 : pT2damp = pow2(pTdampFudge) * ((pTdampMatch == 3) ? Q2Fac : Q2Ren);
277 0 : }
278 :
279 : // Done.
280 0 : return dopTlimit;
281 :
282 : }
283 :
284 : //--------------------------------------------------------------------------
285 :
286 : // Top-level routine to do a full time-like shower in resonance decay.
287 :
288 : int TimeShower::shower( int iBeg, int iEnd, Event& event, double pTmax,
289 : int nBranchMax) {
290 :
291 : // Add new system, automatically with two empty beam slots.
292 0 : int iSys = partonSystemsPtr->addSys();
293 :
294 : // Loop over allowed range to find all final-state particles.
295 0 : Vec4 pSum;
296 0 : for (int i = iBeg; i <= iEnd; ++i) if (event[i].isFinal()) {
297 0 : partonSystemsPtr->addOut( iSys, i);
298 0 : pSum += event[i].p();
299 0 : }
300 0 : partonSystemsPtr->setSHat( iSys, pSum.m2Calc() );
301 :
302 : // Let prepare routine do the setup.
303 0 : dopTlimit1 = true;
304 0 : dopTlimit2 = true;
305 0 : dopTdamp = false;
306 0 : hasWeaklyRadiated = false;
307 0 : prepare( iSys, event, true);
308 :
309 : // Begin evolution down in pT from hard pT scale.
310 : int nBranch = 0;
311 0 : pTLastBranch = 0.;
312 0 : do {
313 0 : double pTtimes = pTnext( event, pTmax, 0.);
314 :
315 : // Do a final-state emission (if allowed).
316 0 : if (pTtimes > 0.) {
317 0 : if (branch( event)) {
318 0 : ++nBranch;
319 0 : pTLastBranch = pTtimes;
320 0 : }
321 : pTmax = pTtimes;
322 0 : }
323 :
324 : // Keep on evolving until nothing is left to be done.
325 : else pTmax = 0.;
326 0 : } while (pTmax > 0. && (nBranchMax <= 0 || nBranch < nBranchMax));
327 :
328 : // Return number of emissions that were performed.
329 0 : return nBranch;
330 :
331 0 : }
332 :
333 : //--------------------------------------------------------------------------
334 :
335 : // Top-level routine for QED radiation in hadronic decay to two leptons.
336 : // Intentionally only does photon radiation, i.e. no photon branchings.
337 :
338 : int TimeShower::showerQED( int i1, int i2, Event& event, double pTmax) {
339 :
340 : // Add new system, automatically with two empty beam slots.
341 0 : int iSys = partonSystemsPtr->addSys();
342 0 : partonSystemsPtr->addOut( iSys, i1);
343 0 : partonSystemsPtr->addOut( iSys, i2);
344 0 : partonSystemsPtr->setSHat( iSys, m2(event[i1], event[i2]) );
345 :
346 : // Charge type of two leptons tells whether MEtype is gamma*/Z0 or W+-.
347 0 : int iChg1 = event[i1].chargeType();
348 0 : int iChg2 = event[i2].chargeType();
349 0 : int MEtype = (iChg1 + iChg2 == 0) ? 102 : 101;
350 :
351 : // Fill dipole-ends list.
352 0 : dipEnd.resize(0);
353 0 : if (iChg1 != 0) dipEnd.push_back( TimeDipoleEnd(i1, i2, pTmax,
354 : 0, iChg1, 0, 0, 0, iSys, MEtype, i2) );
355 0 : if (iChg2 != 0) dipEnd.push_back( TimeDipoleEnd(i2, i1, pTmax,
356 : 0, iChg2, 0, 0, 0, iSys, MEtype, i1) );
357 :
358 : // Begin evolution down in pT from hard pT scale.
359 : int nBranch = 0;
360 0 : pTLastBranch = 0.;
361 0 : do {
362 :
363 : // Begin loop over all possible radiating dipole ends.
364 0 : dipSel = 0;
365 0 : iDipSel = -1;
366 : double pT2sel = 0.;
367 0 : for (int iDip = 0; iDip < int(dipEnd.size()); ++iDip) {
368 0 : TimeDipoleEnd& dip = dipEnd[iDip];
369 :
370 : // Dipole properties.
371 0 : dip.mRad = event[dip.iRadiator].m();
372 0 : dip.mRec = event[dip.iRecoiler].m();
373 0 : dip.mDip = m( event[dip.iRadiator], event[dip.iRecoiler] );
374 0 : dip.m2Rad = pow2(dip.mRad);
375 0 : dip.m2Rec = pow2(dip.mRec);
376 0 : dip.m2Dip = pow2(dip.mDip);
377 :
378 : // Find maximum evolution scale for dipole.
379 0 : dip.m2DipCorr = pow2(dip.mDip - dip.mRec) - dip.m2Rad;
380 0 : double pTbegDip = min( pTmax, dip.pTmax );
381 0 : double pT2begDip = min( pow2(pTbegDip), 0.25 * dip.m2DipCorr);
382 :
383 : // Do QED evolution where relevant.
384 0 : dip.pT2 = 0.;
385 0 : if (pT2begDip > pT2sel) {
386 0 : pT2nextQED( pT2begDip, pT2sel, dip, event);
387 :
388 : // Update if found larger pT than current maximum. End dipole loop.
389 0 : if (dip.pT2 > pT2sel) {
390 : pT2sel = dip.pT2;
391 0 : dipSel = &dip;
392 0 : iDipSel = iDip;
393 0 : }
394 : }
395 0 : }
396 0 : double pTsel = (dipSel == 0) ? 0. : sqrt(pT2sel);
397 :
398 : // Do a final-state emission (if allowed).
399 0 : if (pTsel > 0.) {
400 :
401 : // Find initial radiator and recoiler particles in dipole branching.
402 0 : int iRadBef = dipSel->iRadiator;
403 0 : int iRecBef = dipSel->iRecoiler;
404 0 : Particle& radBef = event[iRadBef];
405 0 : Particle& recBef = event[iRecBef];
406 0 : Vec4 pRadBef = event[iRadBef].p();
407 0 : Vec4 pRecBef = event[iRecBef].p();
408 :
409 : // Construct kinematics in dipole rest frame; massless emitter.
410 0 : double pTorig = sqrt( dipSel->pT2);
411 0 : double eRadPlusEmt = 0.5 * (dipSel->m2Dip + dipSel->m2 - dipSel->m2Rec)
412 0 : / dipSel->mDip;
413 0 : double e2RadPlusEmt = pow2(eRadPlusEmt);
414 0 : double pzRadPlusEmt = 0.5 * sqrtpos( pow2(dipSel->m2Dip - dipSel->m2
415 0 : - dipSel->m2Rec) - 4. * dipSel->m2 * dipSel->m2Rec ) / dipSel->mDip;
416 0 : double pT2corr = dipSel->m2 * (e2RadPlusEmt * dipSel->z
417 0 : * (1. - dipSel->z) - 0.25 * dipSel->m2) / pow2(pzRadPlusEmt);
418 0 : double pTcorr = sqrtpos( pT2corr );
419 0 : double pzRad = (e2RadPlusEmt * dipSel->z - 0.5 * dipSel->m2)
420 0 : / pzRadPlusEmt;
421 0 : double pzEmt = (e2RadPlusEmt * (1. - dipSel->z)
422 0 : - 0.5 * dipSel->m2) / pzRadPlusEmt;
423 0 : double mRad = dipSel->mRad;
424 0 : double mEmt = 0.;
425 :
426 : // Kinematics reduction for radiator mass.
427 0 : double m2Ratio = dipSel->m2Rad / dipSel->m2;
428 0 : pTorig *= 1. - m2Ratio;
429 0 : pTcorr *= 1. - m2Ratio;
430 0 : pzRad += pzEmt * m2Ratio;
431 0 : pzEmt *= 1. - m2Ratio;
432 :
433 : // Store kinematics of branching in dipole rest frame.
434 0 : double phi = 2. * M_PI * rndmPtr->flat();
435 0 : Vec4 pRad = Vec4( pTcorr * cos(phi), pTcorr * sin(phi), pzRad,
436 0 : sqrt( pow2(pTcorr) + pow2(pzRad) + pow2(mRad) ) );
437 0 : Vec4 pEmt = Vec4( -pRad.px(), -pRad.py(), pzEmt,
438 0 : sqrt( pow2(pTcorr) + pow2(pzEmt) + pow2(mEmt) ) );
439 0 : Vec4 pRec = Vec4( 0., 0., -pzRadPlusEmt,
440 0 : sqrt( pow2(pzRadPlusEmt) + dipSel->m2Rec ) );
441 :
442 : // Rotate and boost dipole products to the event frame.
443 0 : RotBstMatrix M;
444 0 : M.fromCMframe(pRadBef, pRecBef);
445 0 : pRad.rotbst(M);
446 0 : pEmt.rotbst(M);
447 0 : pRec.rotbst(M);
448 :
449 : // Define new particles from dipole branching.
450 0 : Particle rad = Particle(radBef.id(), 51, iRadBef, 0, 0, 0,
451 0 : radBef.col(), radBef.acol(), pRad, mRad, pTsel);
452 0 : Particle emt = Particle(22, 51, iRadBef, 0, 0, 0,
453 0 : 0, 0, pEmt, mEmt, pTsel);
454 0 : Particle rec = Particle(recBef.id(), 52, iRecBef, iRecBef, 0, 0,
455 0 : recBef.col(), recBef.acol(), pRec, dipSel->mRec, pTsel);
456 :
457 : // ME corrections can lead to branching being rejected.
458 0 : if (dipSel->MEtype == 0
459 0 : || findMEcorr( dipSel, rad, rec, emt, false) > rndmPtr->flat() ) {
460 :
461 : // Shower may occur at a displaced vertex, or for unstable particle.
462 0 : if (radBef.hasVertex()) {
463 0 : rad.vProd( radBef.vProd() );
464 0 : emt.vProd( radBef.vProd() );
465 0 : }
466 0 : if (recBef.hasVertex()) rec.vProd( recBef.vProd() );
467 0 : rad.tau( event[iRadBef].tau() );
468 0 : rec.tau( event[iRecBef].tau() );
469 :
470 : // Put new particles into the event record.
471 0 : int iRad = event.append(rad);
472 0 : int iEmt = event.append(emt);
473 0 : event[iRadBef].statusNeg();
474 0 : event[iRadBef].daughters( iRad, iEmt);
475 0 : int iRec = event.append(rec);
476 0 : event[iRecBef].statusNeg();
477 0 : event[iRecBef].daughters( iRec, iRec);
478 :
479 : // Update to new dipole ends.
480 0 : dipSel->iRadiator = iRad;
481 0 : dipSel->iRecoiler = iRec;
482 0 : dipSel->pTmax = pTsel;
483 :
484 : // Update other dipoles that also involved the radiator or recoiler.
485 0 : for (int i = 0; i < int(dipEnd.size()); ++i) if (i != iDipSel) {
486 0 : if (dipEnd[i].iRadiator == iRadBef) dipEnd[i].iRadiator = iRad;
487 0 : if (dipEnd[i].iRecoiler == iRadBef) dipEnd[i].iRecoiler = iRad;
488 0 : if (dipEnd[i].iMEpartner == iRadBef) dipEnd[i].iMEpartner = iRad;
489 0 : if (dipEnd[i].iRadiator == iRecBef) dipEnd[i].iRadiator = iRec;
490 0 : if (dipEnd[i].iRecoiler == iRecBef) dipEnd[i].iRecoiler = iRec;
491 0 : if (dipEnd[i].iMEpartner == iRecBef) dipEnd[i].iMEpartner = iRec;
492 : }
493 :
494 : // Done with branching
495 0 : ++nBranch;
496 0 : pTLastBranch = pTsel;
497 0 : }
498 0 : pTmax = pTsel;
499 0 : }
500 :
501 : // Keep on evolving until nothing is left to be done.
502 0 : else pTmax = 0.;
503 0 : } while (pTmax > 0.);
504 :
505 : // Return number of emissions that were performed.
506 0 : return nBranch;
507 :
508 : }
509 :
510 : //--------------------------------------------------------------------------
511 :
512 : // Global recoil: reset counters and store locations of outgoing partons.
513 :
514 : void TimeShower::prepareGlobal( Event& event) {
515 :
516 : // Global recoils: reset some counters.
517 0 : nGlobal = 0;
518 0 : nHard = 0;
519 0 : nProposed.clear();
520 0 : hardPartons.resize(0);
521 0 : nFinalBorn = settingsPtr->mode("TimeShower:nPartonsInBorn");
522 :
523 : // Global recoils: store positions of hard outgoing partons.
524 : // No global recoil for H events.
525 : int nHeavyCol = 0;
526 0 : if (globalRecoil) {
527 0 : for (int i = 0; i < event.size(); ++i) {
528 0 : if (event[i].isFinal() && event[i].colType() != 0)
529 0 : hardPartons.push_back(i);
530 0 : if ( event[i].isFinal() && event[i].idAbs() > 5 && event[i].idAbs() != 21
531 0 : && (event[i].col() != 0 || event[i].acol() != 0))
532 0 : ++nHeavyCol;
533 : }
534 0 : nHard = hardPartons.size();
535 0 : if (nFinalBorn > 0 && nHard > nFinalBorn) {
536 0 : hardPartons.resize(0);
537 0 : nHard = 0;
538 0 : }
539 : }
540 :
541 : // Reset nFinalBorn on an event-by-event basis.
542 0 : string nNow = infoPtr->getEventAttribute("npNLO",true);
543 0 : if (nNow != "" && nFinalBorn == -1){
544 0 : nFinalBorn = max(0, atoi((char*)nNow.c_str()));
545 : // Add number of heavy colored objects in lowest multiplicity state.
546 0 : nFinalBorn += nHeavyCol;
547 0 : }
548 :
549 0 : }
550 :
551 : //--------------------------------------------------------------------------
552 :
553 : // Prepare system for evolution; identify ME.
554 :
555 : void TimeShower::prepare( int iSys, Event& event, bool limitPTmaxIn) {
556 :
557 : // Reset W/Z radiation flag at first call for new event.
558 0 : if (iSys == 0) hasWeaklyRadiated = false;
559 :
560 : // Reset dipole-ends list for first interaction and for resonance decays.
561 0 : int iInA = partonSystemsPtr->getInA(iSys);
562 0 : int iInB = partonSystemsPtr->getInB(iSys);
563 0 : if (iSys == 0 || iInA == 0) dipEnd.resize(0);
564 0 : int dipEndSizeBeg = dipEnd.size();
565 :
566 : // No dipoles for 2 -> 1 processes.
567 0 : if (partonSystemsPtr->sizeOut(iSys) < 2) return;
568 :
569 : // In case of DPS overwrite limitPTmaxIn by saved value.
570 0 : if (doSecondHard && iSys == 0) limitPTmaxIn = dopTlimit1;
571 0 : if (doSecondHard && iSys == 1) limitPTmaxIn = dopTlimit2;
572 :
573 : // Reset number of proposed splittings. Used for global recoil.
574 : // First check if this system belongs to the hard scattering.
575 : bool isHard = false;
576 0 : for (int i = 0; i < partonSystemsPtr->sizeOut(iSys); ++i) {
577 0 : int ii = partonSystemsPtr->getOut( iSys, i);
578 0 : for (int iHard = 0; iHard < int(hardPartons.size()); ++iHard) {
579 0 : if ( event[ii].isAncestor(hardPartons[iHard])
580 0 : || ii == hardPartons[iHard]){
581 : isHard = true;
582 0 : break;
583 : }
584 : }
585 0 : if (isHard) break;
586 0 : }
587 : // If the system belongs to the hard scattering, initialise
588 : // counter of proposed emissions.
589 0 : if (isHard && nProposed.find(iSys) == nProposed.end() )
590 0 : nProposed.insert(make_pair(iSys,0));
591 :
592 : // Loop through final state of system to find possible dipole ends.
593 0 : for (int i = 0; i < partonSystemsPtr->sizeOut(iSys); ++i) {
594 0 : int iRad = partonSystemsPtr->getOut( iSys, i);
595 :
596 0 : if (event[iRad].isFinal() && event[iRad].scale() > 0.) {
597 :
598 : // Identify colour octet onium state. Check whether QCD shower allowed.
599 0 : int idRad = event[iRad].id();
600 0 : int idRadAbs = abs(idRad);
601 0 : bool isOctetOnium = particleDataPtr->isOctetHadron(idRad);
602 0 : bool doQCD = doQCDshower;
603 0 : if (doQCD && isOctetOnium)
604 0 : doQCD = (rndmPtr->flat() < octetOniumFraction);
605 :
606 : // Find dipole end formed by colour index.
607 0 : int colTag = event[iRad].col();
608 0 : if (doQCD && colTag > 0) setupQCDdip( iSys, i, colTag, 1, event,
609 0 : isOctetOnium, limitPTmaxIn);
610 :
611 : // Find dipole end formed by anticolour index.
612 0 : int acolTag = event[iRad].acol();
613 0 : if (doQCD && acolTag > 0) setupQCDdip( iSys, i, acolTag, -1, event,
614 0 : isOctetOnium, limitPTmaxIn);
615 :
616 : // Find "charge-dipole" and "photon-dipole" ends.
617 0 : int chgType = event[iRad].chargeType();
618 0 : bool doChgDip = (chgType != 0)
619 0 : && ( ( doQEDshowerByQ && event[iRad].isQuark() )
620 0 : || ( doQEDshowerByL && event[iRad].isLepton() ) );
621 0 : int gamType = (idRad == 22) ? 1 : 0;
622 0 : bool doGamDip = (gamType == 1) && doQEDshowerByGamma;
623 0 : if (doChgDip || doGamDip) setupQEDdip( iSys, i, chgType, gamType,
624 0 : event, limitPTmaxIn);
625 :
626 : // Find weak diple ends.
627 0 : if (doWeakShower && (iSys == 0 || !partonSystemsPtr->hasInAB(iSys))
628 0 : && (event[iRad].isQuark() || event[iRad].isLepton())) {
629 0 : if (weakMode == 0 || weakMode == 1)
630 0 : setupWeakdip( iSys, i, 1, event, limitPTmaxIn);
631 0 : if (weakMode == 0 || weakMode == 2)
632 0 : setupWeakdip( iSys, i, 2, event, limitPTmaxIn);
633 : }
634 :
635 : // Find Hidden Valley dipole ends.
636 0 : bool isHVrad = (idRadAbs > 4900000 && idRadAbs < 4900007)
637 0 : || (idRadAbs > 4900010 && idRadAbs < 4900017)
638 0 : || idRadAbs == 4900101;
639 0 : if (doHVshower && isHVrad) setupHVdip( iSys, i, event, limitPTmaxIn);
640 :
641 : // End loop over system final state. Have now found the dipole ends.
642 0 : }
643 : }
644 :
645 : // Loop through dipole ends to find matrix element corrections.
646 0 : for (int iDip = dipEndSizeBeg; iDip < int(dipEnd.size()); ++iDip)
647 0 : findMEtype( event, dipEnd[iDip]);
648 :
649 : // Update dipole list after a multiparton interactions rescattering.
650 0 : if (iSys > 0 && ( (iInA > 0 && event[iInA].status() == -34)
651 0 : || (iInB > 0 && event[iInB].status() == -34) ) )
652 0 : rescatterUpdate( iSys, event);
653 :
654 0 : }
655 :
656 : //--------------------------------------------------------------------------
657 :
658 : // Update dipole list after a multiparton interactions rescattering.
659 :
660 : void TimeShower::rescatterUpdate( int iSys, Event& event) {
661 :
662 : // Loop over two incoming partons in system; find their rescattering mother.
663 : // (iOut is outgoing from old system = incoming iIn of rescattering system.)
664 0 : for (int iResc = 0; iResc < 2; ++iResc) {
665 0 : int iIn = (iResc == 0) ? partonSystemsPtr->getInA(iSys)
666 0 : : partonSystemsPtr->getInB(iSys);
667 0 : if (iIn == 0 || event[iIn].status() != -34) continue;
668 0 : int iOut = event[iIn].mother1();
669 :
670 : // Loop over all dipoles.
671 0 : int dipEndSize = dipEnd.size();
672 0 : for (int iDip = 0; iDip < dipEndSize; ++iDip) {
673 0 : TimeDipoleEnd& dipNow = dipEnd[iDip];
674 :
675 : // Kill dipoles where rescattered parton is radiator.
676 0 : if (dipNow.iRadiator == iOut) {
677 0 : dipNow.colType = 0;
678 0 : dipNow.chgType = 0;
679 0 : dipNow.gamType = 0;
680 0 : continue;
681 : }
682 : // No matrix element for dipoles between scatterings.
683 0 : if (dipNow.iMEpartner == iOut) {
684 0 : dipNow.MEtype = 0;
685 0 : dipNow.iMEpartner = -1;
686 0 : }
687 :
688 : // Update dipoles where outgoing rescattered parton is recoiler.
689 0 : if (dipNow.iRecoiler == iOut) {
690 0 : int iRad = dipNow.iRadiator;
691 :
692 : // Colour dipole: recoil in final state, initial state or new.
693 0 : if (dipNow.colType > 0) {
694 0 : int colTag = event[iRad].col();
695 : bool done = false;
696 0 : for (int i = 0; i < partonSystemsPtr->sizeOut(iSys); ++i) {
697 0 : int iRecNow = partonSystemsPtr->getOut( iSys, i);
698 0 : if (event[iRecNow].acol() == colTag) {
699 0 : dipNow.iRecoiler = iRecNow;
700 0 : dipNow.systemRec = iSys;
701 0 : dipNow.MEtype = 0;
702 : done = true;
703 0 : break;
704 : }
705 0 : }
706 0 : if (!done) {
707 0 : int iIn2 = (iResc == 0) ? partonSystemsPtr->getInB(iSys)
708 0 : : partonSystemsPtr->getInA(iSys);
709 0 : if (event[iIn2].col() == colTag) {
710 0 : dipNow.iRecoiler = iIn2;
711 0 : dipNow.systemRec = iSys;
712 0 : dipNow.MEtype = 0;
713 0 : int isrType = event[iIn2].mother1();
714 : // This line in case mother is a rescattered parton.
715 0 : while (isrType > 2 + beamOffset)
716 0 : isrType = event[isrType].mother1();
717 0 : if (isrType > 2) isrType -= beamOffset;
718 0 : dipNow.isrType = isrType;
719 : done = true;
720 0 : }
721 0 : }
722 : // If above options failed, then create new dipole.
723 0 : if (!done) {
724 0 : int iRadNow = partonSystemsPtr->getIndexOfOut(dipNow.system, iRad);
725 0 : if (iRadNow != -1)
726 0 : setupQCDdip(dipNow.system, iRadNow, event[iRad].col(), 1,
727 0 : event, dipNow.isOctetOnium, true);
728 : else
729 0 : infoPtr->errorMsg("Warning in TimeShower::rescatterUpdate: "
730 : "failed to locate radiator in system");
731 :
732 0 : dipNow.colType = 0;
733 0 : dipNow.chgType = 0;
734 0 : dipNow.gamType = 0;
735 :
736 0 : infoPtr->errorMsg("Warning in TimeShower::rescatterUpdate: "
737 : "failed to locate new recoiling colour partner");
738 0 : }
739 :
740 : // Anticolour dipole: recoil in final state, initial state or new.
741 0 : } else if (dipNow.colType < 0) {
742 0 : int acolTag = event[iRad].acol();
743 : bool done = false;
744 0 : for (int i = 0; i < partonSystemsPtr->sizeOut(iSys); ++i) {
745 0 : int iRecNow = partonSystemsPtr->getOut( iSys, i);
746 0 : if (event[iRecNow].col() == acolTag) {
747 0 : dipNow.iRecoiler = iRecNow;
748 0 : dipNow.systemRec = iSys;
749 0 : dipNow.MEtype = 0;
750 : done = true;
751 0 : break;
752 : }
753 0 : }
754 0 : if (!done) {
755 0 : int iIn2 = (iResc == 0) ? partonSystemsPtr->getInB(iSys)
756 0 : : partonSystemsPtr->getInA(iSys);
757 0 : if (event[iIn2].acol() == acolTag) {
758 0 : dipNow.iRecoiler = iIn2;
759 0 : dipNow.systemRec = iSys;
760 0 : dipNow.MEtype = 0;
761 0 : int isrType = event[iIn2].mother1();
762 : // This line in case mother is a rescattered parton.
763 0 : while (isrType > 2 + beamOffset)
764 0 : isrType = event[isrType].mother1();
765 0 : if (isrType > 2) isrType -= beamOffset;
766 0 : dipNow.isrType = isrType;
767 : done = true;
768 0 : }
769 0 : }
770 : // If above options failed, then create new dipole.
771 0 : if (!done) {
772 0 : int iRadNow = partonSystemsPtr->getIndexOfOut(dipNow.system, iRad);
773 0 : if (iRadNow != -1)
774 0 : setupQCDdip(dipNow.system, iRadNow, event[iRad].acol(), -1,
775 0 : event, dipNow.isOctetOnium, true);
776 : else
777 0 : infoPtr->errorMsg("Warning in TimeShower::rescatterUpdate: "
778 : "failed to locate radiator in system");
779 :
780 0 : dipNow.colType = 0;
781 0 : dipNow.chgType = 0;
782 0 : dipNow.gamType = 0;
783 :
784 0 : infoPtr->errorMsg("Warning in TimeShower::rescatterUpdate: "
785 : "failed to locate new recoiling colour partner");
786 0 : }
787 :
788 : // Charge or photon dipoles: same flavour in final or initial state.
789 0 : } else if (dipNow.chgType != 0 || dipNow.gamType != 0) {
790 0 : int idTag = event[dipNow.iRecoiler].id();
791 : bool done = false;
792 0 : for (int i = 0; i < partonSystemsPtr->sizeOut(iSys); ++i) {
793 0 : int iRecNow = partonSystemsPtr->getOut( iSys, i);
794 0 : if (event[iRecNow].id() == idTag) {
795 0 : dipNow.iRecoiler = iRecNow;
796 0 : dipNow.systemRec = iSys;
797 0 : dipNow.MEtype = 0;
798 : done = true;
799 0 : break;
800 : }
801 0 : }
802 0 : if (!done) {
803 0 : int iIn2 = (iResc == 0) ? partonSystemsPtr->getInB(iSys)
804 0 : : partonSystemsPtr->getInA(iSys);
805 0 : if (event[iIn2].id() == -idTag) {
806 0 : dipNow.iRecoiler = iIn2;
807 0 : dipNow.systemRec = iSys;
808 0 : dipNow.MEtype = 0;
809 0 : int isrType = event[iIn2].mother1();
810 : // This line in case mother is a rescattered parton.
811 0 : while (isrType > 2 + beamOffset)
812 0 : isrType = event[isrType].mother1();
813 0 : if (isrType > 2) isrType -= beamOffset;
814 0 : dipNow.isrType = isrType;
815 : done = true;
816 0 : }
817 0 : }
818 : // If above options failed, then create new dipole
819 0 : if (!done) {
820 0 : int iRadNow = partonSystemsPtr->getIndexOfOut(dipNow.system, iRad);
821 0 : if (iRadNow != -1)
822 0 : setupQEDdip(dipNow.system, iRadNow, dipNow.chgType,
823 0 : dipNow.gamType, event, true);
824 : else
825 0 : infoPtr->errorMsg("Warning in TimeShower::rescatterUpdate: "
826 : "failed to locate radiator in system");
827 :
828 0 : dipNow.colType = 0;
829 0 : dipNow.chgType = 0;
830 0 : dipNow.gamType = 0;
831 :
832 0 : infoPtr->errorMsg("Warning in TimeShower::rescatterUpdate: "
833 : "failed to locate new recoiling charge partner");
834 0 : }
835 0 : }
836 0 : }
837 :
838 : // End of loop over dipoles and two incoming sides.
839 0 : }
840 0 : }
841 :
842 0 : }
843 :
844 : //--------------------------------------------------------------------------
845 :
846 : // Update dipole list after each ISR emission (so not used for resonances).
847 :
848 : void TimeShower::update( int iSys, Event& event, bool hasWeakRad) {
849 :
850 : // Start list of rescatterers that gave further changed systems in ISR.
851 0 : vector<int> iRescatterer;
852 :
853 : // Find new and old positions of incoming partons in the system.
854 0 : vector<int> iNew, iOld;
855 0 : iNew.push_back( partonSystemsPtr->getInA(iSys) );
856 0 : iOld.push_back( event[iNew[0]].daughter2() );
857 0 : iNew.push_back( partonSystemsPtr->getInB(iSys) );
858 0 : iOld.push_back( event[iNew[1]].daughter2() );
859 :
860 : // Ditto for outgoing partons, except the newly created one.
861 0 : int sizeOut = partonSystemsPtr->sizeOut(iSys) - 1;
862 0 : for (int i = 0; i < sizeOut; ++i) {
863 0 : int iNow = partonSystemsPtr->getOut(iSys, i);
864 0 : iNew.push_back( iNow );
865 0 : iOld.push_back( event[iNow].mother1() );
866 : // Add non-final to list of rescatterers.
867 0 : if (!event[iNow].isFinal()) iRescatterer.push_back( iNow );
868 0 : }
869 0 : int iNewNew = partonSystemsPtr->getOut(iSys, sizeOut);
870 :
871 : // Swap beams to let 0 be side on which branching occured.
872 0 : if (event[iNew[0]].status() != -41) {
873 0 : swap( iNew[0], iNew[1]);
874 0 : swap( iOld[0], iOld[1]);
875 0 : }
876 :
877 : // Loop over all dipole ends belonging to the system
878 : // or to the recoil system, if different.
879 0 : for (int iDip = 0; iDip < int(dipEnd.size()); ++iDip)
880 0 : if (dipEnd[iDip].system == iSys || dipEnd[iDip].systemRec == iSys) {
881 0 : TimeDipoleEnd& dipNow = dipEnd[iDip];
882 :
883 : // Replace radiator (always in final state so simple).
884 0 : for (int i = 2; i < 2 + sizeOut; ++i)
885 0 : if (dipNow.iRadiator == iOld[i]) {
886 0 : dipNow.iRadiator = iNew[i];
887 0 : break;
888 : }
889 :
890 : // Replace ME partner (always in final state, if exists, so simple).
891 0 : for (int i = 2; i < 2 + sizeOut; ++i)
892 0 : if (dipNow.iMEpartner == iOld[i]) {
893 0 : dipNow.iMEpartner = iNew[i];
894 0 : break;
895 : }
896 :
897 : // Recoiler: by default pick old one, only moved. Note excluded beam.
898 : int iRec = 0;
899 0 : if (dipNow.systemRec == iSys) {
900 0 : for (int i = 1; i < 2 + sizeOut; ++i)
901 0 : if (dipNow.iRecoiler == iOld[i]) {
902 0 : iRec = iNew[i];
903 0 : break;
904 : }
905 :
906 : // QCD recoiler: check if colour hooks up with new final parton.
907 0 : if ( dipNow.colType > 0
908 0 : && event[dipNow.iRadiator].col() == event[iNewNew].acol() ) {
909 : iRec = iNewNew;
910 0 : dipNow.isrType = 0;
911 0 : }
912 0 : if ( dipNow.colType < 0
913 0 : && event[dipNow.iRadiator].acol() == event[iNewNew].col() ) {
914 : iRec = iNewNew;
915 0 : dipNow.isrType = 0;
916 0 : }
917 :
918 : // QCD recoiler: check if colour hooks up with new beam parton.
919 0 : if ( iRec == 0 && dipNow.colType > 0
920 0 : && event[dipNow.iRadiator].col() == event[iNew[0]].col() )
921 0 : iRec = iNew[0];
922 0 : if ( iRec == 0 && dipNow.colType < 0
923 0 : && event[dipNow.iRadiator].acol() == event[iNew[0]].acol() )
924 0 : iRec = iNew[0];
925 :
926 : // QED/photon recoiler: either to new particle or remains to beam.
927 0 : if ( iRec == 0 && (dipNow.chgType != 0 || dipNow.gamType != 0) ) {
928 0 : if ( event[iNew[0]].chargeType() == 0 ) {
929 : iRec = iNewNew;
930 0 : dipNow.isrType = 0;
931 0 : } else {
932 0 : iRec = iNew[0];
933 : }
934 : }
935 :
936 : // Recoiler in another system: keep it as is.
937 0 : } else iRec = dipNow.iRecoiler;
938 :
939 : // Done. Kill dipole if failed to find new recoiler.
940 0 : dipNow.iRecoiler = iRec;
941 0 : if ( iRec == 0 && (dipNow.colType != 0 || dipNow.chgType != 0
942 0 : || dipNow.gamType != 0) ) {
943 0 : dipNow.colType = 0;
944 0 : dipNow.chgType = 0;
945 0 : dipNow.gamType = 0;
946 0 : infoPtr->errorMsg("Error in TimeShower::update: "
947 : "failed to locate new recoiling partner");
948 0 : }
949 :
950 : // Kill weak dipoles if ISR emitted W/Z
951 : // and only a single weak emission is allowed.
952 0 : if (hasWeakRad && singleWeakEmission && dipNow.weakType != 0)
953 0 : dipNow.weakType = 0;
954 0 : }
955 :
956 : // Set the weak radiated variable to true if already radiated.
957 0 : if (hasWeakRad) hasWeaklyRadiated = true;
958 :
959 : // Find new dipole end formed by colour index.
960 0 : int colTag = event[iNewNew].col();
961 0 : if (doQCDshower && colTag > 0)
962 0 : setupQCDdip( iSys, sizeOut, colTag, 1, event, false, true);
963 :
964 : // Find new dipole end formed by anticolour index.
965 0 : int acolTag = event[iNewNew].acol();
966 0 : if (doQCDshower && acolTag > 0)
967 0 : setupQCDdip( iSys, sizeOut, acolTag, -1, event, false, true);
968 :
969 :
970 : // Find new "charge-dipole" and "photon-dipole" ends.
971 0 : int chgType = event[iNewNew].chargeType();
972 0 : bool doChgDip = (chgType != 0)
973 0 : && ( ( doQEDshowerByQ && event[iNewNew].isQuark() )
974 0 : || ( doQEDshowerByL && event[iNewNew].isLepton() ) );
975 0 : int gamType = (event[iNewNew].id() == 22) ? 1 : 0;
976 0 : bool doGamDip = (gamType == 1) && doQEDshowerByGamma;
977 0 : if (doChgDip || doGamDip)
978 0 : setupQEDdip( iSys, sizeOut, chgType, gamType, event, true);
979 :
980 : // Find new weak dipole.
981 : // Uses the size of dipEnd to tell whether a new dipole is added.
982 0 : unsigned int nDips = dipEnd.size();
983 0 : if (doWeakShower && (event[iNewNew].isQuark() || event[iNewNew].isLepton())
984 0 : && !(hasWeaklyRadiated && singleWeakEmission)
985 0 : && (iSys == 0 || !partonSystemsPtr->hasInAB(iSys))) {
986 :
987 0 : if (weakMode == 0 || weakMode == 1)
988 0 : setupWeakdip( iSys, sizeOut, 1, event, true);
989 : // If added new dipole update the ME correction and me partner.
990 0 : if (nDips != dipEnd.size()) {
991 0 : nDips = dipEnd.size();
992 0 : dipEnd.back().MEtype = 200;
993 0 : dipEnd.back().iMEpartner = dipEnd.back().iRecoiler;
994 0 : }
995 :
996 0 : if (weakMode == 0 || weakMode == 2)
997 0 : setupWeakdip( iSys, sizeOut, 2, event, true);
998 : // If added new dipole, update the ME correction and me partner.
999 0 : if (nDips != dipEnd.size()) {
1000 0 : nDips = dipEnd.size();
1001 0 : dipEnd.back().MEtype = 205;
1002 0 : dipEnd.back().iMEpartner = dipEnd.back().iRecoiler;
1003 0 : }
1004 : }
1005 :
1006 : // Start iterate over list of rescatterers - may be empty.
1007 : int iRescNow = -1;
1008 0 : while (++iRescNow < int(iRescatterer.size())) {
1009 :
1010 : // Identify systems that rescatterers belong to.
1011 0 : int iOutNew = iRescatterer[iRescNow];
1012 0 : int iInNew = event[iOutNew].daughter1();
1013 0 : int iSysResc = partonSystemsPtr->getSystemOf(iInNew, true);
1014 :
1015 : // Find new and old positions of incoming partons in the system.
1016 0 : iNew.resize(0);
1017 0 : iOld.resize(0);
1018 0 : iNew.push_back( partonSystemsPtr->getInA(iSysResc) );
1019 0 : iOld.push_back( event[iNew[0]].daughter1() );
1020 0 : iNew.push_back( partonSystemsPtr->getInB(iSysResc) );
1021 0 : iOld.push_back( event[iNew[1]].daughter1() );
1022 :
1023 : // Ditto for outgoing partons.
1024 0 : sizeOut = partonSystemsPtr->sizeOut(iSysResc);
1025 0 : for (int i = 0; i < sizeOut; ++i) {
1026 0 : int iNow = partonSystemsPtr->getOut(iSysResc, i);
1027 0 : iNew.push_back( iNow );
1028 0 : iOld.push_back( event[iNow].mother1() );
1029 : // Add non-final to list of rescatterers.
1030 0 : if (!event[iNow].isFinal()) iRescatterer.push_back( iNow );
1031 0 : }
1032 :
1033 : // Loop over all dipole ends belonging to the system
1034 : // or to the recoil system, if different.
1035 0 : for (int iDip = 0; iDip < int(dipEnd.size()); ++iDip)
1036 0 : if (dipEnd[iDip].system == iSysResc
1037 0 : || dipEnd[iDip].systemRec == iSysResc) {
1038 0 : TimeDipoleEnd& dipNow = dipEnd[iDip];
1039 :
1040 : // Replace radiator (always in final state so simple).
1041 0 : for (int i = 2; i < 2 + sizeOut; ++i)
1042 0 : if (dipNow.iRadiator == iOld[i]) {
1043 0 : dipNow.iRadiator = iNew[i];
1044 0 : break;
1045 : }
1046 :
1047 : // Replace ME partner (always in final state, if exists, so simple).
1048 0 : for (int i = 2; i < 2 + sizeOut; ++i)
1049 0 : if (dipNow.iMEpartner == iOld[i]) {
1050 0 : dipNow.iMEpartner = iNew[i];
1051 0 : break;
1052 : }
1053 :
1054 : // Replace recoiler.
1055 0 : for (int i = 0; i < 2 + sizeOut; ++i)
1056 0 : if (dipNow.iRecoiler == iOld[i]) {
1057 0 : dipNow.iRecoiler = iNew[i];
1058 0 : break;
1059 : }
1060 0 : }
1061 :
1062 : // End iterate over list of rescatterers.
1063 : }
1064 :
1065 0 : }
1066 :
1067 : //--------------------------------------------------------------------------
1068 :
1069 : // Setup a dipole end for a QCD colour charge.
1070 :
1071 : void TimeShower::setupQCDdip( int iSys, int i, int colTag, int colSign,
1072 : Event& event, bool isOctetOnium, bool limitPTmaxIn) {
1073 :
1074 : // Initial values. Find if allowed to hook up beams.
1075 0 : int iRad = partonSystemsPtr->getOut(iSys, i);
1076 0 : int iRec = 0;
1077 0 : int sizeAllA = partonSystemsPtr->sizeAll(iSys);
1078 0 : int sizeOut = partonSystemsPtr->sizeOut(iSys);
1079 0 : int sizeAll = ( allowBeamRecoil ) ? sizeAllA : sizeOut;
1080 0 : int sizeIn = sizeAll - sizeOut;
1081 0 : int sizeInA = sizeAllA - sizeIn - sizeOut;
1082 0 : int iOffset = i + sizeAllA - sizeOut;
1083 : bool otherSystemRec = false;
1084 0 : bool allowInitial = (partonSystemsPtr->hasInAB(iSys)) ? true : false;
1085 : // PS dec 2010: possibility to allow for several recoilers and each with
1086 : // flexible normalization
1087 : bool isFlexible = false;
1088 : double flexFactor = 1.0;
1089 0 : vector<int> iRecVec(0);
1090 :
1091 : // Colour: other end by same index in beam or opposite in final state.
1092 : // Exclude rescattered incoming and not final outgoing.
1093 0 : if (colSign > 0)
1094 0 : for (int j = 0; j < sizeAll; ++j) if (j + sizeInA != iOffset) {
1095 0 : int iRecNow = partonSystemsPtr->getAll(iSys, j + sizeInA);
1096 0 : if ( ( j < sizeIn && event[iRecNow].col() == colTag
1097 0 : && !event[iRecNow].isRescatteredIncoming() )
1098 0 : || ( j >= sizeIn && event[iRecNow].acol() == colTag
1099 0 : && event[iRecNow].isFinal() ) ) {
1100 0 : iRec = iRecNow;
1101 0 : break;
1102 : }
1103 0 : }
1104 :
1105 : // Anticolour: other end by same index in beam or opposite in final state.
1106 : // Exclude rescattered incoming and not final outgoing.
1107 0 : if (colSign < 0)
1108 0 : for (int j = 0; j < sizeAll; ++j) if (j + sizeInA != iOffset) {
1109 0 : int iRecNow = partonSystemsPtr->getAll(iSys, j + sizeInA);
1110 0 : if ( ( j < sizeIn && event[iRecNow].acol() == colTag
1111 0 : && !event[iRecNow].isRescatteredIncoming() )
1112 0 : || ( j >= sizeIn && event[iRecNow].col() == colTag
1113 0 : && event[iRecNow].isFinal() ) ) {
1114 0 : iRec = iRecNow;
1115 0 : break;
1116 : }
1117 0 : }
1118 :
1119 : // Resonance decays (= no instate):
1120 : // other end to nearest recoiler in same system final state,
1121 : // by (p_i + p_j)^2 - (m_i + m_j)^2 = 2 (p_i p_j - m_i m_j).
1122 : // (junction colours more involved, so keep track if junction colour)
1123 : bool hasJunction = false;
1124 0 : if (iRec == 0 && !allowInitial) {
1125 0 : for (int iJun = 0; iJun < event.sizeJunction(); ++ iJun) {
1126 : // For types 1&2, all legs in final state
1127 : // For types 3&4, two legs in final state
1128 : // For types 5&6, one leg in final state
1129 0 : int iBeg = (event.kindJunction(iJun)-1)/2;
1130 0 : for (int iLeg = iBeg; iLeg < 3; ++iLeg)
1131 0 : if (event.endColJunction( iJun, iLeg) == colTag) hasJunction = true;
1132 : }
1133 : double ppMin = LARGEM2;
1134 0 : for (int j = 0; j < sizeOut; ++j) if (j != i) {
1135 0 : int iRecNow = partonSystemsPtr->getOut(iSys, j);
1136 0 : if (!event[iRecNow].isFinal()) continue;
1137 0 : double ppNow = event[iRecNow].p() * event[iRad].p()
1138 0 : - event[iRecNow].m() * event[iRad].m();
1139 0 : if (ppNow < ppMin) {
1140 0 : iRec = iRecNow;
1141 : ppMin = ppNow;
1142 0 : }
1143 0 : }
1144 0 : }
1145 :
1146 : // If no success then look for matching (anti)colour anywhere in final state.
1147 0 : if ( iRec == 0 || (!doInterleave && allowMPIdipole
1148 0 : && !event[iRec].isFinal()) ) {
1149 0 : for (int j = 0; j < event.size(); ++j) if (event[j].isFinal()) {
1150 0 : if ( (colSign > 0 && event[j].acol() == colTag)
1151 0 : || (colSign < 0 && event[j].col() == colTag) ) {
1152 0 : iRec = j;
1153 : otherSystemRec = true;
1154 0 : break;
1155 : }
1156 : }
1157 :
1158 : // If no success then look for match to non-rescattered in initial state.
1159 0 : if (iRec == 0 && allowInitial) {
1160 0 : for (int iSysR = 0; iSysR < partonSystemsPtr->sizeSys(); ++iSysR)
1161 0 : if (iSysR != iSys) {
1162 0 : int j = partonSystemsPtr->getInA(iSysR);
1163 0 : if (j > 0 && event[j].isRescatteredIncoming()) j = 0;
1164 0 : if (j > 0 && ( (colSign > 0 && event[j].col() == colTag)
1165 0 : || (colSign < 0 && event[j].acol() == colTag) ) ) {
1166 0 : iRec = j;
1167 : otherSystemRec = true;
1168 0 : break;
1169 : }
1170 0 : j = partonSystemsPtr->getInB(iSysR);
1171 0 : if (j > 0 && event[j].isRescatteredIncoming()) j = 0;
1172 0 : if (j > 0 && ( (colSign > 0 && event[j].col() == colTag)
1173 0 : || (colSign < 0 && event[j].acol() == colTag) ) ) {
1174 0 : iRec = j;
1175 : otherSystemRec = true;
1176 0 : break;
1177 : }
1178 0 : }
1179 0 : }
1180 : }
1181 :
1182 : // Junctions (PS&ND dec 2010)
1183 : // For types 1&2: all legs in final state
1184 : // half-strength dipoles between all legs
1185 : // For types 3&4, two legs in final state
1186 : // full-strength dipole between final-state legs
1187 : // For types 5&6, one leg in final state
1188 : // no final-state dipole end
1189 :
1190 0 : if (hasJunction) {
1191 0 : for (int iJun = 0; iJun < event.sizeJunction(); ++ iJun) {
1192 0 : int kindJun = event.kindJunction(iJun);
1193 0 : int iBeg = (kindJun-1)/2;
1194 0 : for (int iLeg = iBeg; iLeg < 3; ++iLeg) {
1195 0 : if (event.endColJunction( iJun, iLeg) == colTag) {
1196 : // For types 5&6, no other leg to recoil against. Switch off if
1197 : // no other particles at all, since radiation then handled by ISR.
1198 : // Example: qq -> ~t* : no radiation off ~t*
1199 : // Allow radiation + recoil if unconnected partners available
1200 : // Example: qq -> ~t* -> tbar ~chi0 : allow radiation off tbar,
1201 : // with ~chi0 as recoiler
1202 0 : if (kindJun >= 5) {
1203 0 : if (sizeOut == 1) return;
1204 0 : else break;
1205 : }
1206 : // For junction types 3 & 4, span one full-strength dipole
1207 : // (only look inside same decay system)
1208 0 : else if (kindJun >= 3) {
1209 0 : int iLegRec = 3-iLeg;
1210 0 : int colTagRec = event.endColJunction( iJun, iLegRec);
1211 0 : for (int j = 0; j < sizeOut; ++j) if (j != i) {
1212 0 : int iRecNow = partonSystemsPtr->getOut(iSys, j);
1213 0 : if (!event[iRecNow].isFinal()) continue;
1214 0 : if ( (colSign > 0 && event[iRecNow].col() == colTagRec)
1215 0 : || (colSign < 0 && event[iRecNow].acol() == colTagRec) ) {
1216 : // Only accept if staying inside same system
1217 0 : iRec = iRecNow;
1218 0 : break;
1219 : }
1220 0 : }
1221 0 : }
1222 : // For junction types 1 & 2, span two half-strength dipoles
1223 : // (only look inside same decay system)
1224 : else {
1225 : // Loop over two half-strength dipole connections
1226 0 : for (int jLeg = 1; jLeg <= 2; jLeg++) {
1227 0 : int iLegRec = (iLeg + jLeg) % 3;
1228 0 : int colTagRec = event.endColJunction( iJun, iLegRec);
1229 0 : for (int j = 0; j < sizeOut; ++j) if (j != i) {
1230 0 : int iRecNow = partonSystemsPtr->getOut(iSys, j);
1231 0 : if (!event[iRecNow].isFinal()) continue;
1232 0 : if ( (colSign > 0 && event[iRecNow].col() == colTagRec)
1233 0 : || (colSign < 0 && event[iRecNow].acol() == colTagRec) ) {
1234 : // Store recoilers in temporary array
1235 0 : iRecVec.push_back(iRecNow);
1236 : // Set iRec != 0 for checks below
1237 0 : iRec = iRecNow;
1238 0 : }
1239 0 : }
1240 : }
1241 :
1242 : } // End if-then-else of junction kinds
1243 :
1244 : } // End if leg has right color tag
1245 : } // End of loop over junction legs
1246 0 : } // End loop over junctions
1247 :
1248 : } // End main junction if
1249 :
1250 : // If fail, then other end to nearest recoiler in same system final state,
1251 : // by (p_i + p_j)^2 - (m_i + m_j)^2 = 2 (p_i p_j - m_i m_j).
1252 0 : if (iRec == 0) {
1253 : double ppMin = LARGEM2;
1254 0 : for (int j = 0; j < sizeOut; ++j) if (j != i) {
1255 0 : int iRecNow = partonSystemsPtr->getOut(iSys, j);
1256 0 : if (!event[iRecNow].isFinal()) continue;
1257 0 : double ppNow = event[iRecNow].p() * event[iRad].p()
1258 0 : - event[iRecNow].m() * event[iRad].m();
1259 0 : if (ppNow < ppMin) {
1260 0 : iRec = iRecNow;
1261 : ppMin = ppNow;
1262 0 : }
1263 0 : }
1264 0 : }
1265 :
1266 : // If fail, then other end to nearest recoiler in any system final state,
1267 : // by (p_i + p_j)^2 - (m_i + m_j)^2 = 2 (p_i p_j - m_i m_j).
1268 0 : if (iRec == 0) {
1269 : double ppMin = LARGEM2;
1270 0 : for (int iRecNow = 0; iRecNow < event.size(); ++iRecNow)
1271 0 : if (iRecNow != iRad && event[iRecNow].isFinal()) {
1272 0 : double ppNow = event[iRecNow].p() * event[iRad].p()
1273 0 : - event[iRecNow].m() * event[iRad].m();
1274 0 : if (ppNow < ppMin) {
1275 0 : iRec = iRecNow;
1276 : otherSystemRec = true;
1277 : ppMin = ppNow;
1278 0 : }
1279 0 : }
1280 0 : }
1281 :
1282 : // PS dec 2010: make sure iRec is stored in iRecVec
1283 0 : if (iRecVec.size() == 0 && iRec != 0) iRecVec.push_back(iRec);
1284 :
1285 : // Remove any zero recoilers from normalization
1286 0 : int nRec = iRecVec.size();
1287 0 : for (unsigned int mRec = 0; mRec < iRecVec.size(); ++mRec)
1288 0 : if (iRecVec[mRec] <= 0) nRec--;
1289 0 : if (nRec >= 2) {
1290 : isFlexible = true;
1291 0 : flexFactor = 1.0/nRec;
1292 0 : }
1293 :
1294 : // Check for failure to locate any recoiler
1295 0 : if ( nRec <= 0 ) {
1296 0 : infoPtr->errorMsg("Error in TimeShower::setupQCDdip: "
1297 : "failed to locate any recoiling partner");
1298 0 : return;
1299 : }
1300 :
1301 : // Store dipole colour end(s).
1302 0 : for (unsigned int mRec = 0; mRec < iRecVec.size(); ++mRec) {
1303 0 : iRec = iRecVec[mRec];
1304 0 : if (iRec <= 0) continue;
1305 : // Max scale either by parton scale or by half dipole mass.
1306 0 : double pTmax = event[iRad].scale();
1307 0 : if (limitPTmaxIn) {
1308 0 : if (iSys == 0 || (iSys == 1 && doSecondHard)) pTmax *= pTmaxFudge;
1309 0 : else if (sizeIn > 0) pTmax *= pTmaxFudgeMPI;
1310 0 : } else pTmax = 0.5 * m( event[iRad], event[iRec]);
1311 0 : int colType = (event[iRad].id() == 21) ? 2 * colSign : colSign;
1312 0 : int isrType = (event[iRec].isFinal()) ? 0 : event[iRec].mother1();
1313 : // This line in case mother is a rescattered parton.
1314 0 : while (isrType > 2 + beamOffset) isrType = event[isrType].mother1();
1315 0 : if (isrType > 2) isrType -= beamOffset;
1316 0 : dipEnd.push_back( TimeDipoleEnd( iRad, iRec, pTmax,
1317 0 : colType, 0, 0, 0, isrType, iSys, -1, -1, 0, isOctetOnium) );
1318 :
1319 : // If hooked up with other system then find which.
1320 0 : if (otherSystemRec) {
1321 0 : int systemRec = partonSystemsPtr->getSystemOf(iRec, true);
1322 0 : if (systemRec >= 0) dipEnd.back().systemRec = systemRec;
1323 0 : dipEnd.back().MEtype = 0;
1324 0 : }
1325 :
1326 : // PS dec 2010
1327 : // If non-unity (flexible) normalization, set normalization factor
1328 0 : if (isFlexible) {
1329 0 : dipEnd.back().isFlexible = true;
1330 0 : dipEnd.back().flexFactor = flexFactor;
1331 0 : }
1332 0 : }
1333 :
1334 0 : }
1335 :
1336 : //--------------------------------------------------------------------------
1337 :
1338 : // Setup a dipole end for a QED colour charge or a photon.
1339 : // No failsafe choice of recoiler, so gradually widen search.
1340 :
1341 : void TimeShower::setupQEDdip( int iSys, int i, int chgType, int gamType,
1342 : Event& event, bool limitPTmaxIn) {
1343 :
1344 : // Initial values. Find if allowed to hook up beams.
1345 0 : int iRad = partonSystemsPtr->getOut(iSys, i);
1346 0 : int idRad = event[iRad].id();
1347 : int iRec = 0;
1348 0 : int sizeAllA = partonSystemsPtr->sizeAll(iSys);
1349 0 : int sizeOut = partonSystemsPtr->sizeOut(iSys);
1350 0 : int sizeAll = ( allowBeamRecoil ) ? sizeAllA : sizeOut;
1351 0 : int sizeIn = sizeAll - sizeOut;
1352 0 : int sizeInA = sizeAllA - sizeIn - sizeOut;
1353 0 : int iOffset = i + sizeAllA - sizeOut;
1354 : double ppMin = LARGEM2;
1355 : bool hasRescattered = false;
1356 : bool otherSystemRec = false;
1357 :
1358 : // Find nearest same- (opposide-) flavour recoiler in initial (final)
1359 : // state of same system, excluding rescattered (in or out) partons.
1360 : // Also find if system is involved in rescattering.
1361 : // Note: (p_i + p_j)2 - (m_i + m_j)2 = 2 (p_i p_j - m_i m_j).
1362 0 : for (int j = 0; j < sizeAll; ++j) if (j + sizeInA != iOffset) {
1363 0 : int iRecNow = partonSystemsPtr->getAll(iSys, j + sizeInA);
1364 0 : if ( (j < sizeIn && !event[iRecNow].isRescatteredIncoming())
1365 0 : || (j >= sizeIn && event[iRecNow].isFinal()) ) {
1366 0 : if ( (j < sizeIn && event[iRecNow].id() == idRad)
1367 0 : || (j >= sizeIn && event[iRecNow].id() == -idRad) ) {
1368 0 : double ppNow = event[iRecNow].p() * event[iRad].p()
1369 0 : - event[iRecNow].m() * event[iRad].m();
1370 0 : if (ppNow < ppMin) {
1371 : iRec = iRecNow;
1372 : ppMin = ppNow;
1373 0 : }
1374 0 : }
1375 : } else hasRescattered = true;
1376 0 : }
1377 :
1378 : // If rescattering then find nearest opposite-flavour recoiler
1379 : // anywhere in final state.
1380 0 : if (iRec == 0 && hasRescattered) {
1381 0 : for (int iRecNow = 0; iRecNow < event.size(); ++iRecNow)
1382 0 : if (event[iRecNow].id() == -idRad && event[iRecNow].isFinal()) {
1383 0 : double ppNow = event[iRecNow].p() * event[iRad].p()
1384 0 : - event[iRecNow].m() * event[iRad].m();
1385 0 : if (ppNow < ppMin) {
1386 : iRec = iRecNow;
1387 : ppMin = ppNow;
1388 : otherSystemRec = true;
1389 0 : }
1390 0 : }
1391 0 : }
1392 :
1393 : // Find nearest recoiler in same system, charge-squared-weighted,
1394 : // including initial state, but excluding rescatterer.
1395 0 : if (iRec == 0)
1396 0 : for (int j = 0; j < sizeAll; ++j) if (j + sizeInA != iOffset) {
1397 0 : int iRecNow = partonSystemsPtr->getAll(iSys, j + sizeInA);
1398 0 : int chgTypeRecNow = event[iRecNow].chargeType();
1399 0 : if (chgTypeRecNow == 0) continue;
1400 0 : if ( (j < sizeIn && !event[iRecNow].isRescatteredIncoming())
1401 0 : || (j >= sizeIn && event[iRecNow].isFinal()) ) {
1402 0 : double ppNow = (event[iRecNow].p() * event[iRad].p()
1403 0 : - event[iRecNow].m() * event[iRad].m())
1404 0 : / pow2(chgTypeRecNow);
1405 0 : if (ppNow < ppMin) {
1406 : iRec = iRecNow;
1407 : ppMin = ppNow;
1408 0 : }
1409 0 : }
1410 0 : }
1411 :
1412 : // If rescattering then find nearest recoiler in the final state,
1413 : // charge-squared-weighted.
1414 0 : if (iRec == 0 && hasRescattered) {
1415 0 : for (int iRecNow = 0; iRecNow < event.size(); ++iRecNow)
1416 0 : if (iRecNow != iRad && event[iRecNow].isFinal()) {
1417 0 : int chgTypeRecNow = event[iRecNow].chargeType();
1418 0 : if (chgTypeRecNow != 0 && event[iRecNow].isFinal()) {
1419 0 : double ppNow = (event[iRecNow].p() * event[iRad].p()
1420 0 : - event[iRecNow].m() * event[iRad].m())
1421 0 : / pow2(chgTypeRecNow);
1422 0 : if (ppNow < ppMin) {
1423 : iRec = iRecNow;
1424 : ppMin = ppNow;
1425 : otherSystemRec = true;
1426 0 : }
1427 0 : }
1428 0 : }
1429 0 : }
1430 :
1431 : // Find any nearest recoiler in final state of same system.
1432 0 : if (iRec == 0)
1433 0 : for (int j = 0; j < sizeOut; ++j) if (j != i) {
1434 0 : int iRecNow = partonSystemsPtr->getOut(iSys, j);
1435 0 : double ppNow = event[iRecNow].p() * event[iRad].p()
1436 0 : - event[iRecNow].m() * event[iRad].m();
1437 0 : if (ppNow < ppMin) {
1438 : iRec = iRecNow;
1439 : ppMin = ppNow;
1440 0 : }
1441 0 : }
1442 :
1443 : // Find any nearest recoiler in final state.
1444 0 : if (iRec == 0)
1445 0 : for (int iRecNow = 0; iRecNow < event.size(); ++iRecNow)
1446 0 : if (iRecNow != iRad && event[iRecNow].isFinal()) {
1447 0 : double ppNow = event[iRecNow].p() * event[iRad].p()
1448 0 : - event[iRecNow].m() * event[iRad].m();
1449 0 : if (ppNow < ppMin) {
1450 : iRec = iRecNow;
1451 : ppMin = ppNow;
1452 : otherSystemRec = true;
1453 0 : }
1454 0 : }
1455 :
1456 : // Fill charge-dipole or photon-dipole end.
1457 0 : if (iRec > 0) {
1458 : // Max scale either by parton scale or by half dipole mass.
1459 0 : double pTmax = event[iRad].scale();
1460 0 : if (limitPTmaxIn) {
1461 0 : if (iSys == 0 || (iSys == 1 && doSecondHard)) pTmax *= pTmaxFudge;
1462 0 : else if (sizeIn > 0) pTmax *= pTmaxFudgeMPI;
1463 0 : } else pTmax = 0.5 * m( event[iRad], event[iRec]);
1464 0 : int isrType = (event[iRec].isFinal()) ? 0 : event[iRec].mother1();
1465 : // This line in case mother is a rescattered parton.
1466 0 : while (isrType > 2 + beamOffset) isrType = event[isrType].mother1();
1467 0 : if (isrType > 2) isrType -= beamOffset;
1468 0 : dipEnd.push_back( TimeDipoleEnd(iRad, iRec, pTmax,
1469 : 0, chgType, gamType, 0, isrType, iSys, -1) );
1470 :
1471 : // If hooked up with other system then find which.
1472 0 : if (otherSystemRec) {
1473 0 : int systemRec = partonSystemsPtr->getSystemOf(iRec);
1474 0 : if (systemRec >= 0) dipEnd.back().systemRec = systemRec;
1475 0 : dipEnd.back().MEtype = 0;
1476 0 : }
1477 :
1478 : // Failure to find other end of dipole.
1479 0 : } else {
1480 0 : infoPtr->errorMsg("Error in TimeShower::setupQEDdip: "
1481 : "failed to locate any recoiling partner");
1482 : }
1483 :
1484 0 : }
1485 :
1486 : //--------------------------------------------------------------------------
1487 :
1488 : // Setup a dipole end for weak W or Z emission.
1489 :
1490 : void TimeShower::setupWeakdip( int iSys, int i, int weakType, Event& event,
1491 : bool limitPTmaxIn) {
1492 :
1493 : // Initial values. Find if allowed to hook up beams.
1494 0 : int iRad = partonSystemsPtr->getOut(iSys, i);
1495 0 : int idRad = event[iRad].id();
1496 : int iRec = 0;
1497 0 : int sizeAllA = partonSystemsPtr->sizeAll(iSys);
1498 0 : int sizeOut = partonSystemsPtr->sizeOut(iSys);
1499 : // Only allow weak dipoles to take outgoing particles as recoiler.
1500 : int sizeAll = sizeOut;
1501 : int sizeIn = sizeAll - sizeOut;
1502 0 : int sizeInA = sizeAllA - sizeIn - sizeOut;
1503 0 : int iOffset = i + sizeAllA - sizeOut;
1504 : double ppMin = LARGEM2;
1505 : bool hasRescattered = false;
1506 : bool otherSystemRec = false;
1507 :
1508 : // Find nearest same- (opposide-) flavour recoiler in initial (final)
1509 : // state of same system, excluding rescattered (in or out) partons.
1510 : // Also find if system is involved in rescattering.
1511 : // Note: (p_i + p_j)2 - (m_i + m_j)2 = 2 (p_i p_j - m_i m_j).
1512 0 : for (int j = 0; j < sizeAll; ++j)
1513 0 : if (j + sizeInA != iOffset) {
1514 0 : int iRecNow = partonSystemsPtr->getAll(iSys, j + sizeInA);
1515 0 : if ( (j < sizeIn && !event[iRecNow].isRescatteredIncoming())
1516 0 : || (j >= sizeIn && event[iRecNow].isFinal()) ) {
1517 0 : if ( (j < sizeIn && event[iRecNow].id() == idRad)
1518 0 : || (j >= sizeIn && event[iRecNow].id() == -idRad) ) {
1519 0 : double ppNow = event[iRecNow].p() * event[iRad].p()
1520 0 : - event[iRecNow].m() * event[iRad].m();
1521 0 : if (ppNow < ppMin) {
1522 : iRec = iRecNow;
1523 : ppMin = ppNow;
1524 0 : }
1525 0 : }
1526 : } else hasRescattered = true;
1527 0 : }
1528 :
1529 : // If rescattering then find nearest opposite-flavour recoiler
1530 : // anywhere in final state.
1531 0 : if (iRec == 0 && hasRescattered) {
1532 0 : for (int iRecNow = 0; iRecNow < event.size(); ++iRecNow)
1533 0 : if (event[iRecNow].id() == -idRad && event[iRecNow].isFinal()) {
1534 0 : double ppNow = event[iRecNow].p() * event[iRad].p()
1535 0 : - event[iRecNow].m() * event[iRad].m();
1536 0 : if (ppNow < ppMin) {
1537 : iRec = iRecNow;
1538 : ppMin = ppNow;
1539 : otherSystemRec = true;
1540 0 : }
1541 0 : }
1542 0 : }
1543 :
1544 : // Find nearest recoiler in same system, weak-charge-squared-weighted,
1545 : // including initial state, but excluding rescatterer.
1546 0 : if (iRec == 0)
1547 0 : for (int j = 0; j < sizeAll; ++j) if (j + sizeInA != iOffset) {
1548 0 : int iRecNow = partonSystemsPtr->getAll(iSys, j + sizeInA);
1549 0 : if (abs(event[iRecNow].id()) >= 20 || weakType < 1
1550 0 : || weakType > 2) continue;
1551 : double weakCoupNow = 1.;
1552 0 : if (weakType == 2) weakCoupNow = coupSMPtr->vf2(event[iRecNow].idAbs())
1553 0 : + coupSMPtr->af2(event[iRecNow].idAbs());
1554 0 : if ( (j < sizeIn && !event[iRecNow].isRescatteredIncoming())
1555 0 : || (j >= sizeIn && event[iRecNow].isFinal()) ) {
1556 0 : double ppNow = (event[iRecNow].p() * event[iRad].p()
1557 0 : - event[iRecNow].m() * event[iRad].m()) / weakCoupNow;
1558 0 : if (ppNow < ppMin) {
1559 : iRec = iRecNow;
1560 : ppMin = ppNow;
1561 0 : }
1562 0 : }
1563 0 : }
1564 :
1565 : // If rescattering then find nearest recoiler in the final state,
1566 : // weak-charge-squared-weighted.
1567 0 : if (iRec == 0 && hasRescattered) {
1568 0 : for (int iRecNow = 0; iRecNow < event.size(); ++iRecNow)
1569 0 : if (iRecNow != iRad && event[iRecNow].isFinal()) {
1570 0 : if (abs(event[iRecNow].id()) >= 20 || weakType < 1
1571 0 : || weakType > 2) continue;
1572 : double weakCoupNow = 1.;
1573 0 : if (weakType == 2) weakCoupNow = coupSMPtr->vf2(event[iRecNow].idAbs())
1574 0 : + coupSMPtr->af2(event[iRecNow].idAbs());
1575 0 : double ppNow = (event[iRecNow].p() * event[iRad].p()
1576 0 : - event[iRecNow].m() * event[iRad].m()) / weakCoupNow;
1577 0 : if (ppNow < ppMin) {
1578 : iRec = iRecNow;
1579 : ppMin = ppNow;
1580 : otherSystemRec = true;
1581 0 : }
1582 0 : }
1583 0 : }
1584 :
1585 : // Find any nearest recoiler in final state of same system.
1586 0 : if (iRec == 0)
1587 0 : for (int j = 0; j < sizeOut; ++j) if (j != i) {
1588 0 : int iRecNow = partonSystemsPtr->getOut(iSys, j);
1589 0 : double ppNow = event[iRecNow].p() * event[iRad].p()
1590 0 : - event[iRecNow].m() * event[iRad].m();
1591 0 : if (ppNow < ppMin) {
1592 : iRec = iRecNow;
1593 : ppMin = ppNow;
1594 0 : }
1595 0 : }
1596 :
1597 : // Find any nearest recoiler in final state.
1598 0 : if (iRec == 0)
1599 0 : for (int iRecNow = 0; iRecNow < event.size(); ++iRecNow)
1600 0 : if (iRecNow != iRad && event[iRecNow].isFinal()) {
1601 0 : double ppNow = event[iRecNow].p() * event[iRad].p()
1602 0 : - event[iRecNow].m() * event[iRad].m();
1603 0 : if (ppNow < ppMin) {
1604 : iRec = iRecNow;
1605 : ppMin = ppNow;
1606 : otherSystemRec = true;
1607 0 : }
1608 0 : }
1609 :
1610 : // Fill in weak dipole-end.
1611 0 : if (iRec > 0) {
1612 :
1613 : // Calculate 2 -> 2 kinematics, needed for finding ISR fermion line.
1614 0 : Vec4 p3weak = event[3].p();
1615 0 : Vec4 p4weak = event[4].p();
1616 0 : double tHat = (event[iRad].p() - p3weak).m2Calc();
1617 0 : double uHat = (event[iRad].p() - p4weak).m2Calc();
1618 :
1619 : // Find correct helicity.
1620 0 : int weakPol = (rndmPtr->flat() > 0.5) ? -1 : 1;
1621 : // Check if particle has already gotten a helicity.
1622 0 : if (event[iRad].pol() == 1 || event[iRad].pol() == -1)
1623 0 : weakPol = event[iRad].pol();
1624 : // If particle come from ISR radiation.
1625 0 : else if (event[iRad].statusAbs() > 40) {
1626 0 : if (event[event[iRad].mother1()].idAbs() < 20)
1627 0 : weakPol = event[event[iRad].mother1()].pol();
1628 0 : else if (int(event[iRad].sisterList(true).size()) != 0)
1629 0 : weakPol = event[event[iRad].sisterList(true)[0]].pol();
1630 : }
1631 : // If it is not a 2 to 2 process, always use recoiler.
1632 0 : else if (infoPtr->nFinal() != 2) {
1633 0 : if (event[iRec].pol() == 1 || event[iRec].pol() == -1)
1634 0 : weakPol = event[iRec].pol();
1635 : }
1636 : // If s-channel, choose same spin as recoiler.
1637 0 : else if (idRad == - event[iRec].id()) {
1638 0 : if (event[iRec].pol() == 1 || event[iRec].pol() == -1)
1639 0 : weakPol = event[iRec].pol();
1640 : }
1641 : // if W-decay, choose always left handed.
1642 0 : else if (event[event[iRad].mother1()].idAbs() == 24) weakPol = -1;
1643 : // If four particles of the same type.
1644 0 : else if (idRad == event[iRec].id()) {
1645 0 : if (uHat*uHat/(tHat*tHat + uHat*uHat) > 0.5) weakPol = event[3].pol();
1646 0 : else weakPol = event[4].pol();
1647 : }
1648 : // For different particle types, choose correct fermion line.
1649 0 : else if (event[3].id() == idRad) weakPol = event[3].pol();
1650 0 : else if (event[4].id() == idRad) weakPol = event[4].pol();
1651 : // If weak ISR is turned off, this would try to use polarization
1652 : // that is not set as expected. In this case use random polarization.
1653 0 : if (weakPol > 1) weakPol = (rndmPtr->flat() > 0.5) ? -1 : 1;
1654 0 : event[iRad].pol(weakPol);
1655 :
1656 : // Max scale either by parton scale or by half dipole mass.
1657 0 : double pTmax = event[iRad].scale();
1658 0 : if (limitPTmaxIn) {
1659 0 : if (iSys == 0) pTmax *= pTmaxFudge;
1660 0 : if (iSys > 0 && sizeIn > 0) pTmax *= pTmaxFudgeMPI;
1661 0 : } else pTmax = 0.5 * m( event[iRad], event[iRec]);
1662 0 : int isrType = (event[iRec].isFinal()) ? 0 : event[iRec].mother1();
1663 : // This line in case mother is a rescattered parton.
1664 0 : while (isrType > 2 + beamOffset) isrType = event[isrType].mother1();
1665 0 : if (isrType > 2) isrType -= beamOffset;
1666 : // No right-handed W emission.
1667 :
1668 0 : if (weakType == 1 && weakPol == 1) return;
1669 0 : dipEnd.push_back( TimeDipoleEnd(iRad, iRec, pTmax,
1670 : 0, 0, 0, weakType, isrType, iSys, -1, -1, weakPol) );
1671 :
1672 : // If hooked up with other system then find which.
1673 0 : if (otherSystemRec) {
1674 0 : int systemRec = partonSystemsPtr->getSystemOf(iRec);
1675 0 : if (systemRec >= 0) dipEnd.back().systemRec = systemRec;
1676 0 : dipEnd.back().MEtype = 0;
1677 0 : }
1678 :
1679 : // Failure to find other end of dipole.
1680 0 : } else {
1681 0 : infoPtr->errorMsg("Error in TimeShower::setupWeakdip: "
1682 : "failed to locate any recoiling partner");
1683 : }
1684 0 : }
1685 :
1686 : //--------------------------------------------------------------------------
1687 :
1688 : // Setup a dipole end for a Hidden Valley colour charge.
1689 :
1690 : void TimeShower::setupHVdip( int iSys, int i, Event& event,
1691 : bool limitPTmaxIn) {
1692 :
1693 : // Initial values.
1694 0 : int iRad = partonSystemsPtr->getOut(iSys, i);
1695 : int iRec = 0;
1696 0 : int idRad = event[iRad].id();
1697 0 : int sizeOut = partonSystemsPtr->sizeOut(iSys);
1698 :
1699 : // Hidden Valley colour positive for positive id, and vice versa.
1700 : // Find opposte HV colour in final state of same system.
1701 0 : for (int j = 0; j < sizeOut; ++j) if (j != i) {
1702 0 : int iRecNow = partonSystemsPtr->getOut(iSys, j);
1703 0 : int idRec = event[iRecNow].id();
1704 0 : if ( (abs(idRec) > 4900000 && abs(idRec) < 4900017)
1705 0 : && idRad * idRec < 0) {
1706 : iRec = iRecNow;
1707 0 : break;
1708 : }
1709 0 : }
1710 :
1711 : // Else find heaviest other final-state in same system.
1712 : // (Intended for decays; should mainly be two-body so unique.)
1713 : double mMax = -sqrt(LARGEM2);
1714 0 : if (iRec == 0)
1715 0 : for (int j = 0; j < sizeOut; ++j) if (j != i) {
1716 0 : int iRecNow = partonSystemsPtr->getOut(iSys, j);
1717 0 : if (event[iRecNow].m() > mMax) {
1718 : iRec = iRecNow;
1719 0 : mMax = event[iRecNow].m();
1720 0 : }
1721 0 : }
1722 :
1723 : // Set up dipole end, or report failure.
1724 0 : if (iRec > 0) {
1725 : // Max scale either by parton scale or by half dipole mass.
1726 0 : double pTmax = event[iRad].scale();
1727 0 : if (limitPTmaxIn) {
1728 0 : if (iSys == 0 || (iSys == 1 && doSecondHard)) pTmax *= pTmaxFudge;
1729 0 : } else pTmax = 0.5 * m( event[iRad], event[iRec]);
1730 0 : int colvType = (event[iRad].id() > 0) ? 1 : -1;
1731 0 : dipEnd.push_back( TimeDipoleEnd( iRad, iRec, pTmax, 0, 0, 0, 0, 0,
1732 : iSys, -1, -1, 0, false, true, colvType) );
1733 0 : } else infoPtr->errorMsg("Error in TimeShower::setupHVdip: "
1734 : "failed to locate any recoiling partner");
1735 :
1736 0 : }
1737 :
1738 : //--------------------------------------------------------------------------
1739 :
1740 : // Select next pT in downwards evolution of the existing dipoles.
1741 :
1742 : double TimeShower::pTnext( Event& event, double pTbegAll, double pTendAll,
1743 : bool isFirstTrial) {
1744 :
1745 : // Begin loop over all possible radiating dipole ends.
1746 0 : dipSel = 0;
1747 0 : iDipSel = -1;
1748 0 : double pT2sel = pTendAll * pTendAll;
1749 :
1750 0 : for (int iDip = 0; iDip < int(dipEnd.size()); ++iDip) {
1751 0 : TimeDipoleEnd& dip = dipEnd[iDip];
1752 :
1753 : // Check if this system is part of the hard scattering
1754 : // (including resonance decay products).
1755 : bool hardSystem = true;
1756 0 : bool isQCD = event[dip.iRadiator].colType() != 0;
1757 0 : for (int i = 0; i < partonSystemsPtr->sizeOut(dip.system); ++i) {
1758 0 : int ii = partonSystemsPtr->getOut( dip.system, i);
1759 0 : bool hasHardAncestor = event[ii].statusAbs() < 23;
1760 0 : for (int iHard = 0; iHard < int(hardPartons.size()); ++iHard){
1761 0 : if ( event[ii].isAncestor(hardPartons[iHard])
1762 0 : || ii == hardPartons[iHard]
1763 0 : || (event[ii].status() == 23 && event[ii].colType() == 0) )
1764 0 : hasHardAncestor = true;
1765 : }
1766 0 : if (!hasHardAncestor) hardSystem = false;
1767 : }
1768 :
1769 : // Check if global recoil should be used.
1770 0 : useLocalRecoilNow = !(globalRecoil && hardSystem
1771 0 : && partonSystemsPtr->sizeOut(dip.system) <= nMaxGlobalRecoil);
1772 :
1773 : // Do not use global recoil if the radiator line has already branched.
1774 0 : if (globalRecoilMode == 1 && isQCD) {
1775 0 : if (globalRecoil && hardSystem) useLocalRecoilNow = true;
1776 0 : for (int iHard = 0; iHard < int(hardPartons.size()); ++iHard)
1777 0 : if ( event[dip.iRadiator].isAncestor(hardPartons[iHard]) )
1778 0 : useLocalRecoilNow = false;
1779 : // Check if global recoil should be used.
1780 0 : if ( !globalRecoil || nGlobal >= nMaxGlobalBranch )
1781 0 : useLocalRecoilNow = true;
1782 : // Switch off global recoil after first trial emission.
1783 0 : } else if (globalRecoilMode == 2 && isQCD) {
1784 0 : useLocalRecoilNow = !(globalRecoil && hardSystem
1785 0 : && nProposed.find(dip.system) != nProposed.end()
1786 0 : && nProposed[dip.system] == 0);
1787 : int nFinal = 0;
1788 0 : for (int k = 0; k < int(event.size()); ++k)
1789 0 : if ( event[k].isFinal() && event[k].colType() != 0) nFinal++;
1790 0 : bool isFirst = (nHard == nFinal);
1791 :
1792 : // Switch off global recoil after first emission
1793 0 : if ( globalRecoil && doInterleave && !isFirst )
1794 0 : useLocalRecoilNow = true;
1795 : // No global recoil for H-events.
1796 0 : if ( nFinalBorn > 0 && nHard > nFinalBorn )
1797 0 : useLocalRecoilNow = true;
1798 0 : }
1799 :
1800 : // Dipole properties; normal local recoil.
1801 0 : dip.mRad = event[dip.iRadiator].m();
1802 0 : if (useLocalRecoilNow) {
1803 0 : dip.mRec = event[dip.iRecoiler].m();
1804 0 : dip.mDip = m( event[dip.iRadiator], event[dip.iRecoiler] );
1805 :
1806 : // Dipole properties, alternative global recoil. Squares.
1807 0 : } else {
1808 0 : Vec4 pSumGlobal;
1809 : // Include all particles in all hard systems (hard production system,
1810 : // systems of resonance decay products) in the global recoil momentum.
1811 0 : for (int iS = 0; iS < partonSystemsPtr->sizeSys(); ++iS) {
1812 0 : for (int i = 0; i < partonSystemsPtr->sizeOut(iS); ++i) {
1813 0 : int ii = partonSystemsPtr->getOut( iS, i);
1814 0 : bool hasHardAncestor = event[ii].statusAbs() < 23;
1815 0 : for (int iHard = 0; iHard < int(hardPartons.size()); ++iHard) {
1816 0 : if ( event[ii].isAncestor(hardPartons[iHard])
1817 0 : || ii == hardPartons[iHard]
1818 0 : || (event[ii].status() == 23 && event[ii].colType() == 0) )
1819 0 : hasHardAncestor = true;
1820 : }
1821 0 : if (hasHardAncestor && ii != dip.iRadiator && event[ii].isFinal() )
1822 0 : pSumGlobal += event[ii].p();
1823 : }
1824 : }
1825 0 : dip.mRec = pSumGlobal.mCalc();
1826 0 : dip.mDip = m( event[dip.iRadiator].p(), pSumGlobal);
1827 0 : }
1828 0 : dip.m2Rad = pow2(dip.mRad);
1829 0 : dip.m2Rec = pow2(dip.mRec);
1830 0 : dip.m2Dip = pow2(dip.mDip);
1831 :
1832 : // Find maximum evolution scale for dipole.
1833 0 : dip.m2DipCorr = pow2(dip.mDip - dip.mRec) - dip.m2Rad;
1834 0 : double pTbegDip = min( pTbegAll, dip.pTmax );
1835 0 : double pT2begDip = min( pow2(pTbegDip), 0.25 * dip.m2DipCorr);
1836 :
1837 : // For global recoil, always set the starting scale for first emission.
1838 0 : bool isFirstWimpy = !useLocalRecoilNow && (pTmaxMatch == 1)
1839 0 : && nProposed.find(dip.system) != nProposed.end()
1840 0 : && (nProposed[dip.system] == 0 || isFirstTrial);
1841 0 : double muQ = (infoPtr->scalup() > 0.) ? infoPtr->scalup()
1842 0 : : infoPtr->QFac();
1843 0 : if (isFirstWimpy && !limitMUQ) pT2begDip = pow2(muQ);
1844 0 : else if (isFirstWimpy && limitMUQ) {
1845 : // Find mass of colour dipole.
1846 0 : double mS = event[dip.iRecoiler].m();
1847 0 : double mD = m( event[dip.iRadiator], event[dip.iRecoiler] );
1848 0 : double m2DC = pow2(mD - mS) - pow2(dip.mRad);
1849 : // Choose minimal scale.
1850 0 : pT2begDip = min( pow2(muQ), min(pow2(pTbegDip), 0.25 * m2DC) );
1851 0 : }
1852 :
1853 : // Do not try splitting if the corrected dipole mass is negative.
1854 0 : dip.pT2 = 0.;
1855 0 : if (dip.m2DipCorr < 0.) {
1856 0 : infoPtr->errorMsg("Warning in TimeShower::pTnext: "
1857 : "negative dipole mass.");
1858 0 : continue;
1859 : }
1860 :
1861 : // Do QCD, QED, weak or HV evolution if it makes sense.
1862 0 : if (pT2begDip > pT2sel) {
1863 0 : if (dip.colType != 0)
1864 0 : pT2nextQCD(pT2begDip, pT2sel, dip, event);
1865 0 : else if (dip.chgType != 0 || dip.gamType != 0)
1866 0 : pT2nextQED(pT2begDip, pT2sel, dip, event);
1867 0 : else if (dip.weakType != 0)
1868 0 : pT2nextWeak(pT2begDip, pT2sel, dip, event);
1869 0 : else if (dip.colvType != 0)
1870 0 : pT2nextHV(pT2begDip, pT2sel, dip, event);
1871 :
1872 : // Update if found larger pT than current maximum.
1873 0 : if (dip.pT2 > pT2sel) {
1874 : pT2sel = dip.pT2;
1875 0 : dipSel = &dip;
1876 0 : iDipSel = iDip;
1877 0 : }
1878 : }
1879 0 : }
1880 :
1881 : // Update the number of proposed timelike emissions.
1882 0 : if (dipSel != 0 && nProposed.find(dipSel->system) != nProposed.end())
1883 0 : ++nProposed[dipSel->system];
1884 :
1885 : // Return nonvanishing value if found pT bigger than already found.
1886 0 : return (dipSel == 0) ? 0. : sqrt(pT2sel);
1887 :
1888 0 : }
1889 :
1890 : //--------------------------------------------------------------------------
1891 :
1892 : // Evolve a QCD dipole end.
1893 :
1894 : void TimeShower::pT2nextQCD(double pT2begDip, double pT2sel,
1895 : TimeDipoleEnd& dip, Event& event) {
1896 :
1897 : // Lower cut for evolution. Return if no evolution range.
1898 0 : double pT2endDip = max( pT2sel, pT2colCut );
1899 0 : if (pT2begDip < pT2endDip) return;
1900 :
1901 : // Upper estimate for matrix element weighting and colour factor.
1902 : // Special cases for triplet recoiling against gluino and octet onia.
1903 : // Note that g -> g g and g -> q qbar are split on two sides.
1904 0 : int colTypeAbs = abs(dip.colType);
1905 : double wtPSglue = 2.;
1906 0 : double colFac = (colTypeAbs == 1) ? 4./3. : 3./2.;
1907 0 : if (dip.MEgluinoRec) colFac = 3.;
1908 0 : if (dip.isOctetOnium) colFac *= 0.5 * octetOniumColFac;
1909 : // PS dec 2010. Include possibility for flexible normalization,
1910 : // e.g., for dipoles stretched to junctions or to switch off radiation.
1911 0 : if (dip.isFlexible) colFac *= dip.flexFactor;
1912 0 : double wtPSqqbar = (colTypeAbs == 2)
1913 0 : ? 0.25 * nGluonToQuark * extraGluonToQuark : 0.;
1914 :
1915 : // Variables used inside evolution loop. (Mainly dummy start values.)
1916 0 : dip.pT2 = pT2begDip;
1917 : int nFlavour = 3;
1918 : double zMinAbs = 0.5;
1919 0 : double pT2min = pT2endDip;
1920 : double b0 = 4.5;
1921 0 : double Lambda2 = Lambda3flav2;
1922 : double emitCoefGlue = 0.;
1923 : double emitCoefQqbar = 0.;
1924 : double emitCoefTot = 0.;
1925 : double wt = 0.;
1926 : bool mustFindRange = true;
1927 :
1928 : // Begin evolution loop towards smaller pT values.
1929 0 : do {
1930 :
1931 : // Initialize evolution coefficients at the beginning and
1932 : // reinitialize when crossing c and b flavour thresholds.
1933 0 : if (mustFindRange) {
1934 :
1935 : // Determine overestimated z range; switch at c and b masses.
1936 0 : if (dip.pT2 > m2b) {
1937 : nFlavour = 5;
1938 0 : pT2min = max( m2b, pT2endDip);
1939 : b0 = 23./6.;
1940 0 : Lambda2 = Lambda5flav2;
1941 0 : } else if (dip.pT2 > m2c) {
1942 : nFlavour = 4;
1943 0 : pT2min = max( m2c, pT2endDip);
1944 : b0 = 25./6.;
1945 0 : Lambda2 = Lambda4flav2;
1946 0 : } else {
1947 : nFlavour = 3;
1948 0 : pT2min = pT2endDip;
1949 : b0 = 27./6.;
1950 0 : Lambda2 = Lambda3flav2;
1951 : }
1952 : // A change of renormalization scale expressed by a change of Lambda.
1953 0 : Lambda2 /= renormMultFac;
1954 :
1955 : // Calculate allowed z range; fail if it is too tiny.
1956 0 : zMinAbs = 0.5 - sqrtpos( 0.25 - pT2min / dip.m2DipCorr );
1957 0 : if (zMinAbs < SIMPLIFYROOT) zMinAbs = pT2min / dip.m2DipCorr;
1958 0 : if (zMinAbs > 0.499) { dip.pT2 = 0.; return; }
1959 :
1960 : // Find emission coefficients for X -> X g and g -> q qbar.
1961 0 : emitCoefGlue = wtPSglue * colFac * log(1. / zMinAbs - 1.);
1962 : emitCoefTot = emitCoefGlue;
1963 0 : if (colTypeAbs == 2 && event[dip.iRadiator].id() == 21) {
1964 0 : emitCoefQqbar = wtPSqqbar * (1. - 2. * zMinAbs);
1965 0 : emitCoefTot += emitCoefQqbar;
1966 0 : }
1967 :
1968 : // Initialization done for current range.
1969 : mustFindRange = false;
1970 0 : }
1971 :
1972 : // Pick pT2 (in overestimated z range) for fixed alpha_strong.
1973 0 : if (alphaSorder == 0) {
1974 0 : dip.pT2 = dip.pT2 * pow( rndmPtr->flat(),
1975 0 : 1. / (alphaS2pi * emitCoefTot) );
1976 :
1977 : // Ditto for first-order alpha_strong.
1978 0 : } else if (alphaSorder == 1) {
1979 0 : dip.pT2 = Lambda2 * pow( dip.pT2 / Lambda2,
1980 0 : pow( rndmPtr->flat(), b0 / emitCoefTot) );
1981 :
1982 : // For second order reject by second term in alpha_strong expression.
1983 0 : } else {
1984 0 : do dip.pT2 = Lambda2 * pow( dip.pT2 / Lambda2,
1985 0 : pow( rndmPtr->flat(), b0 / emitCoefTot) );
1986 0 : while (alphaS.alphaS2OrdCorr(renormMultFac * dip.pT2) < rndmPtr->flat()
1987 0 : && dip.pT2 > pT2min);
1988 : }
1989 : wt = 0.;
1990 :
1991 : // If crossed c or b thresholds: continue evolution from threshold.
1992 0 : if (nFlavour == 5 && dip.pT2 < m2b) {
1993 : mustFindRange = true;
1994 0 : dip.pT2 = m2b;
1995 0 : } else if ( nFlavour == 4 && dip.pT2 < m2c) {
1996 : mustFindRange = true;
1997 0 : dip.pT2 = m2c;
1998 :
1999 : // Abort evolution if below cutoff scale, or below another branching.
2000 0 : } else {
2001 0 : if ( dip.pT2 < pT2endDip) { dip.pT2 = 0.; return; }
2002 :
2003 : // Pick kind of branching: X -> X g or g -> q qbar.
2004 0 : dip.flavour = 21;
2005 0 : dip.mFlavour = 0.;
2006 0 : if (colTypeAbs == 2 && emitCoefQqbar > rndmPtr->flat()
2007 0 : * emitCoefTot) dip.flavour = 0;
2008 :
2009 : // Pick z: either dz/(1-z) or flat dz.
2010 0 : if (dip.flavour == 21) {
2011 0 : dip.z = 1. - zMinAbs * pow( 1. / zMinAbs - 1., rndmPtr->flat() );
2012 0 : } else {
2013 0 : dip.z = zMinAbs + (1. - 2. * zMinAbs) * rndmPtr->flat();
2014 : }
2015 :
2016 : // Do not accept branching if outside allowed z range.
2017 0 : double zMin = 0.5 - sqrtpos( 0.25 - dip.pT2 / dip.m2DipCorr );
2018 0 : if (zMin < SIMPLIFYROOT) zMin = dip.pT2 / dip.m2DipCorr;
2019 0 : dip.m2 = dip.m2Rad + dip.pT2 / (dip.z * (1. - dip.z));
2020 0 : if (dip.z > zMin && dip.z < 1. - zMin
2021 0 : && dip.m2 * dip.m2Dip < dip.z * (1. - dip.z)
2022 0 : * pow2(dip.m2Dip + dip.m2 - dip.m2Rec) ) {
2023 :
2024 : // Flavour choice for g -> q qbar.
2025 0 : if (dip.flavour == 0) {
2026 0 : dip.flavour = min(5, 1 + int(nGluonToQuark * rndmPtr->flat()));
2027 0 : dip.mFlavour = particleDataPtr->m0(dip.flavour);
2028 0 : }
2029 :
2030 : // No z weight, except threshold, if to do ME corrections later on.
2031 0 : if (dip.MEtype > 0) {
2032 : wt = 1.;
2033 0 : if (dip.flavour < 10 && dip.m2 < THRESHM2 * pow2(dip.mFlavour))
2034 0 : wt = 0.;
2035 :
2036 : // z weight for X -> X g.
2037 0 : } else if (dip.flavour == 21
2038 0 : && (colTypeAbs == 1 || colTypeAbs == 3) ) {
2039 0 : wt = (1. + pow2(dip.z)) / wtPSglue;
2040 0 : } else if (dip.flavour == 21) {
2041 0 : wt = (1. + pow3(dip.z)) / wtPSglue;
2042 :
2043 : // z weight for g -> q qbar: different options.
2044 0 : } else {
2045 0 : double ratioQ = pow2(dip.mFlavour) / dip.m2;
2046 0 : double betaQ = sqrtpos( 1. - 4. * ratioQ );
2047 0 : if (weightGluonToQuark%4 == 1) {
2048 0 : wt = betaQ * ( pow2(dip.z) + pow2(1. - dip.z) );
2049 0 : } else if (weightGluonToQuark%4 == 2) {
2050 0 : wt = betaQ * ( pow2(dip.z) + pow2(1. - dip.z)
2051 0 : + 8. * ratioQ * dip.z * (1. - dip.z) );
2052 0 : } else {
2053 0 : double m2Rat = dip.m2 / dip.m2DipCorr;
2054 0 : double zCosThe = ((1. + m2Rat) * dip.z - m2Rat) / (1. - m2Rat);
2055 0 : wt = betaQ * ( pow2(zCosThe) + pow2(1. - zCosThe)
2056 0 : + 8. * ratioQ * zCosThe * (1. - zCosThe) )
2057 0 : * (1. + m2Rat) / ((1. - m2Rat) * extraGluonToQuark) ;
2058 0 : if (weightGluonToQuark%4 == 0) wt *= pow3(1. - m2Rat);
2059 0 : }
2060 0 : if (weightGluonToQuark > 4 && alphaSorder > 0)
2061 0 : wt *= log(dip.pT2 / Lambda2)
2062 0 : / log(scaleGluonToQuark * dip.m2 / Lambda2);
2063 : }
2064 :
2065 : // Suppression factors for dipole to beam remnant.
2066 0 : if (dip.isrType != 0 && useLocalRecoilNow) {
2067 0 : BeamParticle& beam = (dip.isrType == 1) ? *beamAPtr : *beamBPtr;
2068 0 : int iSysRec = dip.systemRec;
2069 0 : double xOld = beam[iSysRec].x();
2070 0 : double xNew = xOld * (1. + (dip.m2 - dip.m2Rad) /
2071 0 : (dip.m2Dip - dip.m2Rad));
2072 0 : double xMaxAbs = beam.xMax(iSysRec);
2073 0 : if (xMaxAbs < 0.) {
2074 0 : infoPtr->errorMsg("Warning in TimeShower::pT2nextQCD: "
2075 : "xMaxAbs negative");
2076 0 : return;
2077 : }
2078 :
2079 : // New: Ensure that no x-value larger than unity is picked. Only
2080 : // necessary for imprecise LHE input.
2081 0 : if (xNew > 1.) wt = 0.;
2082 :
2083 : // Firstly reduce by PDF ratio.
2084 0 : if (xNew > xMaxAbs) wt = 0.;
2085 : else {
2086 0 : int idRec = event[dip.iRecoiler].id();
2087 0 : pdfScale2 = (useFixedFacScale) ? fixedFacScale2
2088 0 : : factorMultFac * dip.pT2;
2089 0 : double pdfOld = max ( TINYPDF,
2090 0 : beam.xfISR( iSysRec, idRec, xOld, pdfScale2) );
2091 : double pdfNew =
2092 0 : beam.xfISR( iSysRec, idRec, xNew, pdfScale2);
2093 0 : wt *= min( 1., pdfNew / pdfOld);
2094 : }
2095 :
2096 : // Secondly optionally reduce by 4 pT2_hard / (4 pT2_hard + m2).
2097 0 : if (dampenBeamRecoil) {
2098 0 : double pTpT = sqrt(event[dip.iRadiator].pT2() * dip.pT2);
2099 0 : wt *= pTpT / (pTpT + dip.m2);
2100 0 : }
2101 0 : }
2102 :
2103 : // Optional dampening of large pT values in hard system.
2104 0 : if (dopTdamp && dip.system == 0 && dip.MEtype == 0)
2105 0 : wt *= pT2damp / (dip.pT2 + pT2damp);
2106 : }
2107 0 : }
2108 :
2109 : // Iterate until acceptable pT (or have fallen below pTmin).
2110 0 : } while (wt < rndmPtr->flat());
2111 :
2112 0 : }
2113 :
2114 : //--------------------------------------------------------------------------
2115 :
2116 : // Evolve a QED dipole end, either charged or photon.
2117 :
2118 : void TimeShower::pT2nextQED(double pT2begDip, double pT2sel,
2119 : TimeDipoleEnd& dip, Event& event) {
2120 :
2121 : // Lower cut for evolution. Return if no evolution range.
2122 0 : double pT2chgCut = (dip.chgType != 0 && abs(dip.chgType) != 3)
2123 0 : ? pT2chgQCut : pT2chgLCut;
2124 0 : double pT2endDip = max( pT2sel, pT2chgCut );
2125 0 : if (pT2begDip < pT2endDip) return;
2126 :
2127 : // Emission of photon or photon branching.
2128 0 : bool hasCharge = (dip.chgType != 0);
2129 :
2130 : // Default values.
2131 : double wtPSgam = 0.;
2132 : double chg2Sum = 0.;
2133 : double chg2SumL = 0.;
2134 : double chg2SumQ = 0.;
2135 : double zMinAbs = 0.;
2136 : double emitCoefTot = 0.;
2137 :
2138 : // alpha_em at maximum scale provides upper estimate.
2139 0 : double alphaEMmax = alphaEM.alphaEM(renormMultFac * dip.m2DipCorr);
2140 0 : double alphaEM2pi = alphaEMmax / (2. * M_PI);
2141 :
2142 : // Emission: upper estimate for matrix element weighting; charge factor.
2143 0 : if (hasCharge) {
2144 : wtPSgam = 2.;
2145 0 : double chg2 = pow2(dip.chgType / 3.);
2146 :
2147 : // Determine overestimated z range. Find evolution coefficient.
2148 0 : zMinAbs = 0.5 - sqrtpos( 0.25 - pT2endDip / dip.m2DipCorr );
2149 0 : if (zMinAbs < SIMPLIFYROOT) zMinAbs = pT2endDip / dip.m2DipCorr;
2150 0 : emitCoefTot = alphaEM2pi * chg2 * wtPSgam * log(1. / zMinAbs - 1.);
2151 :
2152 : // Branching: sum of squared charge factors for lepton and quark daughters.
2153 0 : } else {
2154 0 : chg2SumL = max(0, min(3, nGammaToLepton));
2155 0 : if (nGammaToQuark > 4) chg2SumQ = 11. / 9.;
2156 0 : else if (nGammaToQuark > 3) chg2SumQ = 10. / 9.;
2157 0 : else if (nGammaToQuark > 2) chg2SumQ = 6. / 9.;
2158 0 : else if (nGammaToQuark > 1) chg2SumQ = 5. / 9.;
2159 0 : else if (nGammaToQuark > 0) chg2SumQ = 1. / 9.;
2160 :
2161 : // Total sum of squared charge factors. Find evolution coefficient.
2162 0 : chg2Sum = chg2SumL + 3. * chg2SumQ;
2163 0 : emitCoefTot = alphaEM2pi * chg2Sum * extraGluonToQuark;
2164 : }
2165 :
2166 : // Variables used inside evolution loop.
2167 0 : dip.pT2 = pT2begDip;
2168 : double wt;
2169 :
2170 : // Begin evolution loop towards smaller pT values.
2171 0 : do {
2172 :
2173 : // Pick pT2 (in overestimated z range).
2174 0 : dip.pT2 = dip.pT2 * pow(rndmPtr->flat(), 1. / emitCoefTot);
2175 : wt = 0.;
2176 :
2177 : // Abort evolution if below cutoff scale, or below another branching.
2178 0 : if ( dip.pT2 < pT2endDip) { dip.pT2 = 0.; return; }
2179 :
2180 : // Pick z according to dz/(1-z) or flat.
2181 0 : if (hasCharge) dip.z = 1. - zMinAbs
2182 0 : * pow( 1. / zMinAbs - 1., rndmPtr->flat() );
2183 0 : else dip.z = rndmPtr->flat();
2184 :
2185 : // Do not accept branching if outside allowed z range.
2186 0 : double zMin = 0.5 - sqrtpos( 0.25 - dip.pT2 / dip.m2DipCorr );
2187 0 : if (zMin < SIMPLIFYROOT) zMin = dip.pT2 / dip.m2DipCorr;
2188 0 : if (dip.z <= zMin || dip.z >= 1. - zMin) continue;
2189 0 : dip.m2 = dip.m2Rad + dip.pT2 / (dip.z * (1. - dip.z));
2190 0 : if (dip.m2 * dip.m2Dip < dip.z * (1. - dip.z)
2191 0 : * pow2(dip.m2Dip + dip.m2 - dip.m2Rec)
2192 : // For gamma -> f fbar also impose maximum mass.
2193 0 : && (hasCharge || dip.m2 < m2MaxGamma) ) {
2194 :
2195 : // Photon emission: unique flavour choice.
2196 0 : if (hasCharge) {
2197 0 : dip.flavour = 22;
2198 0 : dip.mFlavour = 0.;
2199 :
2200 : // Photon branching: either lepton or quark flavour choice.
2201 0 : } else {
2202 0 : if (rndmPtr->flat() * chg2Sum < chg2SumL)
2203 0 : dip.flavour = 9 + 2 * min(3, 1 + int(chg2SumL * rndmPtr->flat()));
2204 : else {
2205 0 : double rndmQ = 9. * chg2SumQ * rndmPtr->flat();
2206 0 : if (rndmQ < 1.) dip.flavour = 1;
2207 0 : else if (rndmQ < 5.) dip.flavour = 2;
2208 0 : else if (rndmQ < 6.) dip.flavour = 3;
2209 0 : else if (rndmQ < 10.) dip.flavour = 4;
2210 0 : else dip.flavour = 5;
2211 : }
2212 0 : dip.mFlavour = particleDataPtr->m0(dip.flavour);
2213 : }
2214 :
2215 : // No z weight, except threshold, if to do ME corrections later on.
2216 0 : if (dip.MEtype > 0) {
2217 : wt = 1.;
2218 0 : if (dip.flavour < 20 && dip.m2 < THRESHM2 * pow2(dip.mFlavour))
2219 0 : wt = 0.;
2220 :
2221 : // z weight for X -> X gamma.
2222 0 : } else if (hasCharge) {
2223 0 : wt = (1. + pow2(dip.z)) / wtPSgam;
2224 :
2225 : // z weight for gamma -> f fbar; different options.
2226 0 : } else {
2227 0 : double ratioF = pow2(dip.mFlavour) / dip.m2;
2228 0 : double betaF = sqrtpos( 1. - 4. * ratioF );
2229 0 : if (weightGluonToQuark%4 == 1) {
2230 0 : wt = betaF * ( pow2(dip.z) + pow2(1. - dip.z) );
2231 0 : } else if (weightGluonToQuark%4 == 2) {
2232 0 : wt = betaF * ( pow2(dip.z) + pow2(1. - dip.z)
2233 0 : + 8. * ratioF * dip.z * (1. - dip.z) );
2234 0 : } else {
2235 0 : double m2Rat = dip.m2 / dip.m2DipCorr;
2236 0 : double zCosThe = ((1. + m2Rat) * dip.z - m2Rat) / (1. - m2Rat);
2237 0 : wt = betaF * ( pow2(zCosThe) + pow2(1. - zCosThe)
2238 0 : + 8. * ratioF * zCosThe * (1. - zCosThe) )
2239 0 : * (1. + m2Rat) / ((1. - m2Rat) * extraGluonToQuark) ;
2240 0 : if (weightGluonToQuark%4 == 0) wt *= pow3(1. - m2Rat);
2241 0 : }
2242 : }
2243 :
2244 : // Correct to current value of alpha_EM.
2245 0 : double aEMscale = dip.pT2;
2246 0 : if (dip.flavour < 20 && weightGluonToQuark > 4)
2247 0 : aEMscale = scaleGluonToQuark * dip.m2;
2248 0 : double alphaEMnow = alphaEM.alphaEM(renormMultFac * aEMscale);
2249 0 : wt *= (alphaEMnow / alphaEMmax);
2250 :
2251 : // Suppression factors for dipole to beam remnant.
2252 0 : if (dip.isrType != 0 && useLocalRecoilNow) {
2253 0 : BeamParticle& beam = (dip.isrType == 1) ? *beamAPtr : *beamBPtr;
2254 0 : int iSys = dip.system;
2255 0 : double xOld = beam[iSys].x();
2256 0 : double xNew = xOld * (1. + (dip.m2 - dip.m2Rad) /
2257 0 : (dip.m2Dip - dip.m2Rad));
2258 0 : double xMaxAbs = beam.xMax(iSys);
2259 0 : if (xMaxAbs < 0.) {
2260 0 : infoPtr->errorMsg("Warning in TimeShower::pT2nextQED: "
2261 : "xMaxAbs negative");
2262 0 : return;
2263 : }
2264 :
2265 : // New: Ensure that no x-value larger than unity is picked. Only
2266 : // necessary for imprecise LHE input.
2267 0 : if (xNew > 1.) wt = 0.;
2268 :
2269 : // Firstly reduce by PDF ratio.
2270 0 : if (xNew > xMaxAbs) wt = 0.;
2271 : else {
2272 0 : int idRec = event[dip.iRecoiler].id();
2273 0 : pdfScale2 = (useFixedFacScale) ? fixedFacScale2
2274 0 : : factorMultFac * dip.pT2;
2275 0 : double pdfOld = max ( TINYPDF,
2276 0 : beam.xfISR( iSys, idRec, xOld, pdfScale2) );
2277 : double pdfNew =
2278 0 : beam.xfISR( iSys, idRec, xNew, pdfScale2);
2279 0 : wt *= min( 1., pdfNew / pdfOld);
2280 : }
2281 :
2282 : // Secondly optionally reduce by 4 pT2_hard / (4 pT2_hard + m2).
2283 0 : if (dampenBeamRecoil) {
2284 0 : double pT24 = 4. * event[dip.iRadiator].pT2();
2285 0 : wt *= pT24 / (pT24 + dip.m2);
2286 0 : }
2287 0 : }
2288 :
2289 : // Optional dampening of large pT values in hard system.
2290 0 : if (dopTdamp && dip.system == 0 && dip.MEtype == 0)
2291 0 : wt *= pT2damp / (dip.pT2 + pT2damp);
2292 0 : }
2293 :
2294 : // Iterate until acceptable pT (or have fallen below pTmin).
2295 0 : } while (wt < rndmPtr->flat());
2296 :
2297 0 : }
2298 :
2299 : //--------------------------------------------------------------------------
2300 :
2301 : // Evolve a weak-emission dipole end.
2302 :
2303 : void TimeShower::pT2nextWeak(double pT2begDip, double pT2sel,
2304 : TimeDipoleEnd& dip, Event& event) {
2305 :
2306 : // Lower cut for evolution. Return if no evolution range.
2307 0 : double pT2endDip = max( pT2sel, pT2weakCut );
2308 0 : if (pT2begDip < pT2endDip) return;
2309 :
2310 : // Default values.
2311 : double wtPSgam = 0.;
2312 : double zMinAbs = 0.;
2313 : double emitCoefTot = 0.;
2314 :
2315 : // alpha_em at maximum scale provides upper estimate.
2316 0 : double alphaEMmax = alphaEM.alphaEM(renormMultFac * pT2begDip);
2317 0 : double alphaEM2pi = alphaEMmax / (2. * M_PI);
2318 :
2319 : // Emission: upper estimate for matrix element weighting; charge factor.
2320 : wtPSgam = 8.;
2321 :
2322 : // Determine overestimated z range. Find evolution coefficient.
2323 0 : zMinAbs = 0.5 - sqrtpos( 0.25 - pT2endDip / dip.m2DipCorr );
2324 0 : if (zMinAbs < SIMPLIFYROOT) zMinAbs = pT2endDip / dip.m2DipCorr;
2325 :
2326 : // Determine weak coupling.
2327 : double weakCoupling = 0.;
2328 : // W-radiation, with additional factor of two, from only having
2329 : // left-handed fermions.
2330 0 : if (dip.weakType == 1)
2331 0 : weakCoupling = 2. * alphaEM2pi / (4. * coupSMPtr->sin2thetaW());
2332 : // Z-radiation, split between left and right fermions.
2333 0 : else if (dip.weakType == 2 && dip.weakPol == -1)
2334 0 : weakCoupling = alphaEM2pi * thetaWRat
2335 0 : * pow2(2. * coupSMPtr->lf( event[dip.iRadiator].idAbs() ));
2336 : else
2337 0 : weakCoupling = alphaEM2pi * thetaWRat
2338 0 : * pow2(2. * coupSMPtr->rf( event[dip.iRadiator].idAbs() ));
2339 :
2340 : // Variables used inside evolution loop.
2341 0 : emitCoefTot = weakEnhancement * weakCoupling
2342 0 : * wtPSgam * log(1. / zMinAbs - 1.);
2343 : // Fudge factor to correct for weak PS not being an overestimate of ME.
2344 0 : if ( dip.MEtype == 201 || dip.MEtype == 202 || dip.MEtype == 203
2345 0 : || dip.MEtype == 206 || dip.MEtype == 207 || dip.MEtype == 208 )
2346 0 : emitCoefTot *= WEAKPSWEIGHT;
2347 0 : dip.pT2 = pT2begDip;
2348 : double wt;
2349 :
2350 : // Begin evolution loop towards smaller pT values.
2351 0 : do {
2352 : // Pick pT2 (in overestimated z range).
2353 0 : dip.pT2 = dip.pT2 * pow(rndmPtr->flat(), 1. / emitCoefTot);
2354 : wt = 0.;
2355 :
2356 : // Abort evolution if below cutoff scale, or below another branching.
2357 0 : if ( dip.pT2 < pT2endDip) {dip.pT2 = 0.; return; }
2358 :
2359 : // Pick z according to dz/(1-z) or flat.
2360 0 : dip.z = 1. - zMinAbs * pow( 1. / zMinAbs - 1., rndmPtr->flat() );
2361 :
2362 : // Do not accept branching if outside allowed z range.
2363 0 : double zMin = 0.5 - sqrtpos( 0.25 - dip.pT2 / dip.m2DipCorr );
2364 0 : if (zMin < SIMPLIFYROOT) zMin = dip.pT2 / dip.m2DipCorr;
2365 0 : dip.m2 = dip.m2Rad + dip.pT2 / (dip.z * (1. - dip.z));
2366 0 : if (dip.z > zMin && dip.z < 1. - zMin
2367 0 : && dip.m2 * dip.m2Dip < dip.z * (1. - dip.z)
2368 0 : * pow2(dip.m2Dip + dip.m2 - dip.m2Rec) ) {
2369 :
2370 : // Check whether emission of W+ or W-, or else Z0.
2371 0 : if (dip.weakType == 1) {
2372 0 : dip.flavour = (event[dip.iRadiator].id() > 0) ? 24 : -24;
2373 0 : if (event[dip.iRadiator].idAbs() % 2 == 1) dip.flavour = -dip.flavour;
2374 0 : } else if (dip.weakType == 2) dip.flavour = 23;
2375 :
2376 : // Set mass of emitted particle, with Breit-Wigner distribution.
2377 0 : dip.mFlavour = particleDataPtr->mSel( dip.flavour);
2378 :
2379 : // No z weight, except threshold, if to do ME corrections later on.
2380 : // Here no pure shower mode exists, always needs ME corrections.
2381 0 : if (dip.MEtype > 0) wt = 1.;
2382 :
2383 : // Correct to current value of alpha_EM.
2384 0 : double alphaEMnow = alphaEM.alphaEM(renormMultFac * dip.pT2);
2385 0 : wt *= (alphaEMnow / alphaEMmax);
2386 :
2387 : // Suppression factors for dipole to beam remnant.
2388 0 : if (dip.isrType != 0 && useLocalRecoilNow) {
2389 0 : BeamParticle& beam = (dip.isrType == 1) ? *beamAPtr : *beamBPtr;
2390 0 : int iSys = dip.system;
2391 0 : double xOld = beam[iSys].x();
2392 0 : double xNew = xOld * (1. + (dip.m2 - dip.m2Rad) /
2393 0 : (dip.m2Dip - dip.m2Rad));
2394 0 : double xMaxAbs = beam.xMax(iSys);
2395 0 : if (xMaxAbs < 0.) {
2396 0 : infoPtr->errorMsg("Warning in TimeShower::pT2nextWeak: "
2397 : "xMaxAbs negative");
2398 0 : return;
2399 : }
2400 :
2401 : // New: Ensure that no x-value larger than unity is picked. Only
2402 : // necessary for imprecise LHE input.
2403 0 : if (xNew > 1.) wt = 0.;
2404 :
2405 : // Firstly reduce by PDF ratio.
2406 0 : if (xNew > xMaxAbs) wt = 0.;
2407 : else {
2408 0 : int idRec = event[dip.iRecoiler].id();
2409 0 : pdfScale2 = (useFixedFacScale) ? fixedFacScale2
2410 0 : : factorMultFac * dip.pT2;
2411 0 : double pdfOld = max ( TINYPDF,
2412 0 : beam.xfISR( iSys, idRec, xOld, pdfScale2) );
2413 : double pdfNew =
2414 0 : beam.xfISR( iSys, idRec, xNew, pdfScale2);
2415 0 : wt *= min( 1., pdfNew / pdfOld);
2416 : }
2417 : // Secondly optionally reduce by 4 pT2_hard / (4 pT2_hard + m2).
2418 0 : if (dampenBeamRecoil) {
2419 0 : double pT24 = 4. * event[dip.iRadiator].pT2();
2420 0 : wt *= pT24 / (pT24 + dip.m2);
2421 0 : }
2422 0 : }
2423 0 : }
2424 :
2425 : // Optional dampening of large pT values in hard system.
2426 0 : if (dopTdamp && dip.system == 0) wt *= pT2damp / (dip.pT2 + pT2damp);
2427 :
2428 : // Iterate until acceptable pT (or have fallen below pTmin).
2429 0 : } while (wt < rndmPtr->flat());
2430 :
2431 0 : }
2432 :
2433 : //--------------------------------------------------------------------------
2434 :
2435 : // Evolve a Hidden Valley dipole end.
2436 :
2437 : void TimeShower::pT2nextHV(double pT2begDip, double pT2sel,
2438 : TimeDipoleEnd& dip, Event& ) {
2439 :
2440 : // Lower cut for evolution. Return if no evolution range.
2441 0 : double pT2endDip = max( pT2sel, pT2hvCut );
2442 0 : if (pT2begDip < pT2endDip) return;
2443 :
2444 : // C_F * alpha_HV/2 pi.
2445 0 : int colvTypeAbs = abs(dip.colvType);
2446 0 : double colvFac = (colvTypeAbs == 1) ? CFHV : 0.5 * nCHV;
2447 0 : double alphaHV2pi = colvFac * (alphaHVfix / (2. * M_PI));
2448 :
2449 : // Determine overestimated z range. Find evolution coefficient.
2450 0 : double zMinAbs = 0.5 - sqrtpos( 0.25 - pT2endDip / dip.m2DipCorr );
2451 0 : if (zMinAbs < SIMPLIFYROOT) zMinAbs = pT2endDip / dip.m2DipCorr;
2452 0 : double emitCoefTot = alphaHV2pi * 2. * log(1. / zMinAbs - 1.);
2453 :
2454 : // Variables used inside evolution loop.
2455 0 : dip.pT2 = pT2begDip;
2456 : double wt;
2457 :
2458 : // Begin evolution loop towards smaller pT values.
2459 0 : do {
2460 :
2461 : // Pick pT2 (in overestimated z range).
2462 0 : dip.pT2 = dip.pT2 * pow(rndmPtr->flat(), 1. / emitCoefTot);
2463 : wt = 0.;
2464 :
2465 : // Abort evolution if below cutoff scale, or below another branching.
2466 0 : if ( dip.pT2 < pT2endDip) { dip.pT2 = 0.; return; }
2467 :
2468 : // Pick z according to dz/(1-z).
2469 0 : dip.z = 1. - zMinAbs * pow( 1. / zMinAbs - 1., rndmPtr->flat() );
2470 :
2471 : // Do not accept branching if outside allowed z range.
2472 0 : double zMin = 0.5 - sqrtpos( 0.25 - dip.pT2 / dip.m2DipCorr );
2473 0 : if (zMin < SIMPLIFYROOT) zMin = dip.pT2 / dip.m2DipCorr;
2474 0 : dip.m2 = dip.m2Rad + dip.pT2 / (dip.z * (1. - dip.z));
2475 0 : if (dip.z > zMin && dip.z < 1. - zMin
2476 0 : && dip.m2 * dip.m2Dip < dip.z * (1. - dip.z)
2477 0 : * pow2(dip.m2Dip + dip.m2 - dip.m2Rec) ) {
2478 :
2479 : // HV gamma or gluon emission: unique flavour choice.
2480 0 : dip.flavour = idHV;
2481 0 : dip.mFlavour = mHV;
2482 :
2483 : // No z weight, except threshold, if to do ME corrections later on.
2484 0 : if (dip.MEtype > 0) wt = 1.;
2485 :
2486 : // z weight for X -> X g_HV.
2487 0 : else if (colvTypeAbs == 1) wt = (1. + pow2(dip.z)) / 2.;
2488 0 : else wt = (1. + pow3(dip.z)) / 2.;
2489 : }
2490 :
2491 : // Optional dampening of large pT values in hard system.
2492 0 : if (dopTdamp && dip.system == 0 && dip.MEtype == 0)
2493 0 : wt *= pT2damp / (dip.pT2 + pT2damp);
2494 :
2495 : // Iterate until acceptable pT (or have fallen below pTmin).
2496 0 : } while (wt < rndmPtr->flat());
2497 :
2498 0 : }
2499 :
2500 : //--------------------------------------------------------------------------
2501 :
2502 : // ME corrections and kinematics that may give failure.
2503 : // Notation: radBef, recBef = radiator, recoiler before emission,
2504 : // rad, rec, emt = radiator, recoiler, emitted efter emission.
2505 : // (rad, emt distinguished by colour flow for g -> q qbar.)
2506 :
2507 : bool TimeShower::branch( Event& event, bool isInterleaved) {
2508 :
2509 : // Check if this system is part of the hard scattering
2510 : // (including resonance decay products).
2511 : bool hardSystem = true;
2512 0 : bool isQCD = event[dipSel->iRadiator].colType() != 0;
2513 0 : for (int i = 0; i < partonSystemsPtr->sizeOut(dipSel->system); ++i) {
2514 0 : int ii = partonSystemsPtr->getOut( dipSel->system, i);
2515 0 : bool hasHardAncestor = event[ii].statusAbs() < 23;
2516 0 : for (int iHard = 0; iHard < int(hardPartons.size()); ++iHard){
2517 0 : if ( event[ii].isAncestor(hardPartons[iHard])
2518 0 : || ii == hardPartons[iHard]
2519 0 : || (event[ii].status() == 23 && event[ii].colType() == 0))
2520 0 : hasHardAncestor = true;
2521 : }
2522 0 : if (!hasHardAncestor) hardSystem = false;
2523 : }
2524 :
2525 : // Check if global recoil should be used in resonance showers.
2526 0 : useLocalRecoilNow = !(globalRecoil && hardSystem
2527 0 : && partonSystemsPtr->sizeOut(dipSel->system) <= nMaxGlobalRecoil);
2528 :
2529 : // Do not use global recoil if the radiator line has already branched.
2530 0 : if (globalRecoilMode == 1 && isQCD) {
2531 0 : if ( globalRecoil && hardSystem) useLocalRecoilNow = true;
2532 0 : for (int iHard = 0; iHard < int(hardPartons.size()); ++iHard)
2533 0 : if ( event[dipSel->iRadiator].isAncestor(hardPartons[iHard]) )
2534 0 : useLocalRecoilNow = false;
2535 : // Check if global recoil should be used.
2536 0 : if ( !globalRecoil || nGlobal >= nMaxGlobalBranch )
2537 0 : useLocalRecoilNow = true;
2538 :
2539 : // Switch off global recoil after first trial emission
2540 0 : } else if (globalRecoilMode == 2 && isQCD) {
2541 0 : useLocalRecoilNow = !(globalRecoil
2542 0 : && nProposed.find(dipSel->system) != nProposed.end()
2543 0 : && nProposed[dipSel->system] == 1);
2544 : // Check if global recoil should be used.
2545 : int nFinal = 0;
2546 0 : for (int i = 0; i < int(event.size()); ++i)
2547 0 : if ( event[i].isFinal() && event[i].colType() != 0) nFinal++;
2548 0 : bool isFirst = (nHard == nFinal);
2549 0 : if ( globalRecoil && doInterleave && !isFirst )
2550 0 : useLocalRecoilNow = true;
2551 : // No global recoil for H-events.
2552 0 : if ( nFinalBorn > 0 && nHard > nFinalBorn )
2553 0 : useLocalRecoilNow = true;
2554 0 : }
2555 :
2556 : // Check if the first emission should be studied for removal.
2557 0 : bool canMergeFirst = (mergingHooksPtr != 0)
2558 0 : ? mergingHooksPtr->canVetoEmission() : false;
2559 :
2560 : // Find initial radiator and recoiler particles in dipole branching.
2561 0 : int iRadBef = dipSel->iRadiator;
2562 0 : int iRecBef = dipSel->iRecoiler;
2563 0 : Particle& radBef = event[iRadBef];
2564 0 : Particle& recBef = event[iRecBef];
2565 :
2566 : // Find their momenta, with special sum for global recoil.
2567 0 : Vec4 pRadBef = event[iRadBef].p();
2568 0 : Vec4 pRecBef;
2569 0 : vector<int> iGRecBef, iGRec;
2570 0 : if (useLocalRecoilNow) pRecBef = event[iRecBef].p();
2571 : else {
2572 : // Include all particles in all hard systems (hard production system,
2573 : // systems of resonance decay products) in the global recoil momentum.
2574 0 : for (int iS = 0; iS < partonSystemsPtr->sizeSys(); ++iS) {
2575 0 : for (int i = 0; i < partonSystemsPtr->sizeOut(iS); ++i) {
2576 0 : int iG = partonSystemsPtr->getOut( iS, i);
2577 0 : bool hasHardAncestor = event[iG].statusAbs() < 23;
2578 0 : for (int iHard = 0; iHard < int(hardPartons.size()); ++iHard)
2579 0 : if ( event[iG].isAncestor(hardPartons[iHard])
2580 0 : || iG == hardPartons[iHard]
2581 0 : || (event[iG].status() == 23 && event[iG].colType() == 0))
2582 0 : hasHardAncestor = true;
2583 0 : if (hasHardAncestor && iG != dipSel->iRadiator
2584 0 : && event[iG].isFinal() ) {
2585 0 : iGRecBef.push_back(iG);
2586 0 : pRecBef += event[iG].p();
2587 0 : }
2588 0 : }
2589 : }
2590 : }
2591 :
2592 : // Find old incoming momenta for weak shower t-channel ME correction.
2593 0 : Vec4 p3weak = event[3].p();
2594 0 : Vec4 p4weak = event[4].p();
2595 0 : if ( dipSel->MEtype == 201 || dipSel->MEtype == 202
2596 0 : || dipSel->MEtype == 203 || dipSel->MEtype == 206
2597 0 : || dipSel->MEtype == 207 || dipSel->MEtype == 208) {
2598 :
2599 : // Trace back to original mother. MPI not allowed to radiate weakly.
2600 : int i2to2Mother = iRadBef;
2601 0 : while (i2to2Mother != 5 && i2to2Mother != 6 && i2to2Mother != 0)
2602 0 : i2to2Mother = event[i2to2Mother].mother1();
2603 0 : if (i2to2Mother == 0) return false;
2604 :
2605 : // u d -> u d && u g -> u g.
2606 0 : if (event[3].id() != event[4].id()) {
2607 0 : if (event[3].id() == event[i2to2Mother].id());
2608 0 : else if (event[4].id() == event[i2to2Mother].id()) swap(p3weak, p4weak);
2609 : // In case of no match, assign random combination.
2610 0 : else if (rndmPtr->flat() < 0.5) swap(p3weak, p4weak);
2611 : }
2612 : // u u -> u u, assign random combination.
2613 0 : else if (rndmPtr->flat() < 0.5) swap(p3weak, p4weak);
2614 0 : }
2615 :
2616 : // Default flavours and colour tags for new particles in dipole branching.
2617 0 : int idRad = radBef.id();
2618 0 : int idEmt = dipSel->flavour;
2619 0 : int colRad = radBef.col();
2620 0 : int acolRad = radBef.acol();
2621 : int colEmt = 0;
2622 : int acolEmt = 0;
2623 0 : iSysSel = dipSel->system;
2624 0 : int iSysSelRec = dipSel->systemRec;
2625 :
2626 : // Default OK for photon, photon_HV or gluon_HV emission.
2627 0 : if (dipSel->flavour == 22 || dipSel->flavour == idHV) {
2628 : // New colour tag required for gluon emission.
2629 0 : } else if (dipSel->flavour == 21 && dipSel->colType > 0) {
2630 : colEmt = colRad;
2631 0 : colRad = event.nextColTag();
2632 : acolEmt = colRad;
2633 0 : } else if (dipSel->flavour == 21) {
2634 : acolEmt = acolRad;
2635 0 : acolRad = event.nextColTag();
2636 : colEmt = acolRad;
2637 : // New flavours for g -> q qbar; split colours.
2638 0 : } else if (dipSel->colType > 0) {
2639 : idEmt = dipSel->flavour ;
2640 0 : idRad = -idEmt;
2641 : colEmt = colRad;
2642 : colRad = 0;
2643 0 : } else if (dipSel->colType < 0) {
2644 0 : idEmt = -dipSel->flavour ;
2645 : idRad = -idEmt;
2646 : acolEmt = acolRad;
2647 : acolRad = 0;
2648 : // New flavours for gamma -> f fbar, and maybe also colours.
2649 0 : } else if (dipSel->gamType == 1 && rndmPtr->flat() > 0.5) {
2650 0 : idEmt = -dipSel->flavour ;
2651 : idRad = -idEmt;
2652 0 : if (idRad < 10) colRad = event.nextColTag();
2653 : acolEmt = colRad;
2654 0 : } else if (dipSel->gamType == 1) {
2655 0 : idEmt = dipSel->flavour ;
2656 0 : idRad = -idEmt;
2657 0 : if (idEmt < 10) colEmt = event.nextColTag();
2658 : acolRad = colEmt;
2659 0 : }
2660 :
2661 : // Change fermion flavour by W emissions.
2662 : int idRadSv = idRad;
2663 0 : if (abs(idEmt) == 24) {
2664 0 : if (rndmPtr->flat() > coupSMPtr->V2CKMsum(idRad)) return false;
2665 0 : idRad = coupSMPtr->V2CKMpick(idRad);
2666 0 : }
2667 :
2668 : // Construct kinematics in dipole rest frame:
2669 : // begin simple (like g -> g g).
2670 0 : double pTorig = sqrt( dipSel->pT2);
2671 0 : double eRadPlusEmt = 0.5 * (dipSel->m2Dip + dipSel->m2 - dipSel->m2Rec)
2672 0 : / dipSel->mDip;
2673 0 : double e2RadPlusEmt = pow2(eRadPlusEmt);
2674 0 : double pzRadPlusEmt = 0.5 * sqrtpos( pow2(dipSel->m2Dip - dipSel->m2
2675 0 : - dipSel->m2Rec) - 4. * dipSel->m2 * dipSel->m2Rec ) / dipSel->mDip;
2676 0 : double pT2corr = dipSel->m2 * (e2RadPlusEmt * dipSel->z * (1. - dipSel->z)
2677 0 : - 0.25 * dipSel->m2) / pow2(pzRadPlusEmt);
2678 0 : double pTcorr = sqrtpos( pT2corr );
2679 0 : double pzRad = (e2RadPlusEmt * dipSel->z - 0.5 * dipSel->m2)
2680 0 : / pzRadPlusEmt;
2681 0 : double pzEmt = (e2RadPlusEmt * (1. - dipSel->z) - 0.5 * dipSel->m2)
2682 0 : / pzRadPlusEmt;
2683 : // Radiator flavour changed if W emission, so find new mass.
2684 0 : double mRad = (idRad == idRadSv) ? dipSel->mRad
2685 0 : : particleDataPtr->m0(idRad);
2686 0 : double m2Rad = pow2(mRad);
2687 0 : double mEmt = 0.;
2688 :
2689 : // Kinematics reduction for f -> f W/Z when m_f > 0 (and m_W/Z > 0)
2690 : // or q -> q gamma_v when m_q > 0 and m_gamma_v > 0.
2691 0 : if ( dipSel->weakType != 0
2692 0 : || (abs(dipSel->colvType) == 1 && dipSel->mFlavour > 0.) ) {
2693 0 : mEmt = dipSel->mFlavour;
2694 0 : if (pow2(mRad + mEmt) > dipSel->m2) return false;
2695 0 : double m2Emt = pow2(mEmt);
2696 0 : double lambda = sqrtpos( pow2(dipSel->m2 - m2Rad - m2Emt)
2697 0 : - 4. * m2Rad * m2Emt );
2698 0 : kRad = 0.5 * (dipSel->m2 - lambda + m2Emt - m2Rad)
2699 0 : / dipSel->m2;
2700 0 : kEmt = 0.5 * (dipSel->m2 - lambda + m2Rad - m2Emt)
2701 0 : / dipSel->m2;
2702 0 : pTorig *= 1. - kRad - kEmt;
2703 0 : pTcorr *= 1. - kRad - kEmt;
2704 0 : double pzMove = kRad * pzRad - kEmt * pzEmt;
2705 0 : pzRad -= pzMove;
2706 0 : pzEmt += pzMove;
2707 :
2708 : // Kinematics reduction for q -> q g/gamma/g_HV when m_q > 0.
2709 0 : } else if (abs(dipSel->colType) == 1 || dipSel->chgType != 0
2710 0 : || abs(dipSel->colvType) == 1) {
2711 0 : pTorig *= 1. - dipSel->m2Rad / dipSel->m2;
2712 0 : pTcorr *= 1. - dipSel->m2Rad / dipSel->m2;
2713 0 : pzRad += pzEmt * dipSel->m2Rad / dipSel->m2;
2714 0 : pzEmt *= 1. - dipSel->m2Rad / dipSel->m2;
2715 :
2716 : // Kinematics reduction for g -> q qbar or gamma -> f fbar when m_f > 0;
2717 0 : } else if (abs(dipSel->flavour) < 20) {
2718 0 : mEmt = dipSel->mFlavour;
2719 0 : mRad = mEmt;
2720 0 : double beta = sqrtpos( 1. - 4. * pow2(mEmt) / dipSel->m2 );
2721 0 : pTorig *= beta;
2722 0 : pTcorr *= beta;
2723 0 : pzRad = 0.5 * ( (1. + beta) * pzRad + (1. - beta) * pzEmt );
2724 0 : pzEmt = pzRadPlusEmt - pzRad;
2725 0 : }
2726 :
2727 : // Reject g emission where mass effects have reduced pT below cutoff.
2728 0 : if (idEmt == 21 && pTorig < pTcolCut) return false;
2729 :
2730 : // Find rest frame and angles of original dipole.
2731 0 : RotBstMatrix M;
2732 0 : M.fromCMframe(pRadBef, pRecBef);
2733 :
2734 : // Evaluate coefficient of azimuthal asymmetry from gluon polarization.
2735 0 : findAsymPol( event, dipSel);
2736 :
2737 : // Begin construction of new dipole kinematics: pick azimuthal angle.
2738 0 : Vec4 pRad, pEmt, pRec;
2739 : double wtPhi = 1.;
2740 0 : do {
2741 0 : double phi = 2. * M_PI * rndmPtr->flat();
2742 :
2743 : // Define kinematics of branching in dipole rest frame.
2744 0 : pRad = Vec4( pTcorr * cos(phi), pTcorr * sin(phi), pzRad,
2745 0 : sqrt( pow2(pTcorr) + pow2(pzRad) + pow2(mRad) ) );
2746 0 : pEmt = Vec4( -pRad.px(), -pRad.py(), pzEmt,
2747 0 : sqrt( pow2(pTcorr) + pow2(pzEmt) + pow2(mEmt) ) );
2748 0 : pRec = Vec4( 0., 0., -pzRadPlusEmt, sqrt( pow2(pzRadPlusEmt)
2749 0 : + dipSel->m2Rec ) );
2750 :
2751 : // Rotate and boost dipole products to the event frame.
2752 0 : pRad.rotbst(M);
2753 0 : pEmt.rotbst(M);
2754 0 : pRec.rotbst(M);
2755 :
2756 : // New: To avoid instabilities for violent boosts, ensure that an incoming
2757 : // recoiler always has zero px and py.
2758 0 : if (dipSel->isrType != 0) {
2759 0 : if (abs(pRec.px()) > 0.) {
2760 0 : double phixx = pRec.phi();
2761 0 : RotBstMatrix rot_by_pphi;
2762 0 : rot_by_pphi.rot(0.,-phixx);
2763 0 : pRec.rotbst( rot_by_pphi);
2764 0 : double thetaxx = pRec.theta();
2765 0 : if ( pRec.px() < 0. ) thetaxx *= -1.;
2766 0 : if ( pRec.pz() < 0.) thetaxx += M_PI;
2767 0 : RotBstMatrix rot_by_ptheta;
2768 0 : rot_by_ptheta.rot(-thetaxx, 0.);
2769 0 : pRec.rotbst( rot_by_ptheta );
2770 0 : }
2771 : }
2772 :
2773 : // Azimuthal phi weighting: loop to new phi value if required.
2774 0 : if (dipSel->asymPol != 0.) {
2775 0 : Vec4 pAunt = event[dipSel->iAunt].p();
2776 0 : double cosPhi = cosphi( pRad, pAunt, pRadBef );
2777 0 : wtPhi = ( 1. + dipSel->asymPol * (2. * pow2(cosPhi) - 1.) )
2778 0 : / ( 1. + abs(dipSel->asymPol) );
2779 0 : }
2780 0 : } while (wtPhi < rndmPtr->flat()) ;
2781 :
2782 : // Kinematics when recoiler is initial-state parton.
2783 0 : int isrTypeNow = dipSel->isrType;
2784 : int isrTypeSave = isrTypeNow;
2785 0 : if (!useLocalRecoilNow) isrTypeNow = 0;
2786 0 : if (isrTypeNow != 0) pRec = 2. * recBef.p() - pRec;
2787 :
2788 : // New: Return if the x-value for the incoming recoiler is nonsense.
2789 0 : if ( isrTypeNow != 0 && 2.*pRec.e()/event[0].m() > 1. ) {
2790 0 : infoPtr->errorMsg("Error in TimeShower::branch: "
2791 : "Larger than unity Bjorken x value");
2792 0 : return false;
2793 : }
2794 :
2795 : // PS dec 2010: check if radiator has flexible normalization
2796 0 : bool isFlexible = dipSel->isFlexible;
2797 :
2798 : // Define new particles from dipole branching.
2799 0 : double pTsel = sqrt(dipSel->pT2);
2800 0 : Particle rad = Particle(idRad, 51, iRadBef, 0, 0, 0,
2801 0 : colRad, acolRad, pRad, mRad, pTsel);
2802 0 : Particle emt = Particle(idEmt, 51, iRadBef, 0, 0, 0,
2803 0 : colEmt, acolEmt, pEmt, mEmt, pTsel);
2804 :
2805 : // Recoiler either in final or in initial state
2806 0 : Particle rec = (isrTypeNow == 0)
2807 0 : ? Particle(recBef.id(), 52, iRecBef, iRecBef, 0, 0,
2808 0 : recBef.col(), recBef.acol(), pRec, dipSel->mRec, pTsel)
2809 0 : : Particle(recBef.id(), -53, 0, 0, iRecBef, iRecBef,
2810 0 : recBef.col(), recBef.acol(), pRec, 0., 0.);
2811 :
2812 : // Special checks to set weak particles status equal to 56.
2813 : // This is needed for decaying the particles. Also set polarisation.
2814 0 : if (emt.idAbs() == 23 || emt.idAbs() == 24) {
2815 0 : emt.status(56);
2816 0 : event[iRadBef].pol( dipSel->weakPol );
2817 0 : rad.pol( dipSel->weakPol );
2818 0 : }
2819 :
2820 : // ME corrections can lead to branching being rejected.
2821 0 : if (dipSel->MEtype > 0) {
2822 0 : Particle& partner = (dipSel->iMEpartner == iRecBef)
2823 0 : ? rec : event[dipSel->iMEpartner];
2824 0 : if ( findMEcorr( dipSel, rad, partner, emt) < rndmPtr->flat() )
2825 0 : return false;
2826 0 : if (dipSel->MEtype >= 200 && dipSel->MEtype <= 210
2827 0 : && findMEcorrWeak( dipSel, rad.p(), partner.p(), emt.p(), p3weak, p4weak,
2828 0 : event[iRadBef].p(), event[iRecBef].p()) < rndmPtr->flat() )
2829 0 : return false;
2830 0 : }
2831 :
2832 : // Rescatter: if the recoiling partner is not in the same system
2833 : // as the radiator, fix up intermediate systems (can lead
2834 : // to emissions being vetoed)
2835 0 : if (allowRescatter && FIXRESCATTER && isInterleaved
2836 0 : && iSysSel != iSysSelRec) {
2837 0 : Vec4 pNew = rad.p() + emt.p();
2838 0 : if (!rescatterPropagateRecoil(event, pNew)) return false;
2839 0 : }
2840 :
2841 : // Save properties to be restored in case of user-hook veto of emission.
2842 0 : int eventSizeOld = event.size();
2843 0 : int iRadStatusV = event[iRadBef].status();
2844 0 : int iRadDau1V = event[iRadBef].daughter1();
2845 0 : int iRadDau2V = event[iRadBef].daughter2();
2846 0 : int iRecStatusV = event[iRecBef].status();
2847 0 : int iRecMot1V = event[iRecBef].mother1();
2848 0 : int iRecMot2V = event[iRecBef].mother2();
2849 0 : int iRecDau1V = event[iRecBef].daughter1();
2850 0 : int iRecDau2V = event[iRecBef].daughter2();
2851 0 : int beamOff1 = 1 + beamOffset;
2852 0 : int beamOff2 = 2 + beamOffset;
2853 0 : int ev1Dau1V = event[beamOff1].daughter1();
2854 0 : int ev2Dau1V = event[beamOff2].daughter1();
2855 :
2856 : // Shower may occur at a displaced vertex.
2857 0 : if (radBef.hasVertex()) {
2858 0 : rad.vProd( radBef.vProd() );
2859 0 : emt.vProd( radBef.vProd() );
2860 : }
2861 0 : if (recBef.hasVertex()) rec.vProd( recBef.vProd() );
2862 :
2863 : // Put new particles into the event record.
2864 : // Mark original dipole partons as branched and set daughters/mothers.
2865 0 : int iRad = event.append(rad);
2866 0 : int iEmt = event.append(emt);
2867 0 : event[iRadBef].statusNeg();
2868 0 : event[iRadBef].daughters( iRad, iEmt);
2869 0 : int iRec = 0;
2870 0 : if (useLocalRecoilNow) {
2871 0 : iRec = event.append(rec);
2872 0 : if (isrTypeNow == 0) {
2873 0 : event[iRecBef].statusNeg();
2874 0 : event[iRecBef].daughters( iRec, iRec);
2875 0 : } else {
2876 0 : event[iRecBef].mothers( iRec, iRec);
2877 0 : event[iRec].mothers( iRecMot1V, iRecMot2V);
2878 0 : if (iRecMot1V == beamOff1) event[beamOff1].daughter1( iRec);
2879 0 : if (iRecMot1V == beamOff2) event[beamOff2].daughter1( iRec);
2880 : }
2881 :
2882 : // Global recoil: need to find relevant rotation+boost for recoilers:
2883 : // boost+rotate to rest frame, boost along z axis, rotate+boost back.
2884 : } else {
2885 0 : RotBstMatrix MG = M;
2886 0 : MG.invert();
2887 0 : double pzRecBef = -0.5 * sqrtpos( pow2(dipSel->m2Dip - dipSel->m2Rad
2888 0 : - dipSel->m2Rec) - 4. * dipSel->m2Rad * dipSel->m2Rec ) / dipSel->mDip;
2889 0 : double eRecBef = sqrt( pow2(pzRecBef) + dipSel->m2Rec);
2890 0 : double pzRecAft = -pzRadPlusEmt;
2891 0 : double eRecAft = sqrt( pow2(pzRecAft) + dipSel->m2Rec);
2892 0 : MG.bst( Vec4(0., 0., pzRecBef, eRecBef), Vec4(0., 0., pzRecAft, eRecAft) );
2893 0 : MG.rotbst( M);
2894 :
2895 : // Global recoil: copy particles, and rotate+boost momenta (not vertices).
2896 0 : for (int iG = 0; iG < int(iGRecBef.size()); ++iG) {
2897 0 : iRec = event.copy( iGRecBef[iG], 52);
2898 0 : iGRec.push_back( iRec);
2899 0 : Vec4 pGRec = event[iRec].p();
2900 0 : pGRec.rotbst( MG);
2901 0 : event[iRec].p( pGRec);
2902 0 : }
2903 0 : }
2904 :
2905 : // Allow veto of branching. If so restore event record to before emission.
2906 0 : bool inResonance = (partonSystemsPtr->getInA(iSysSel) == 0) ? true : false;
2907 0 : if ( (canVetoEmission && userHooksPtr->doVetoFSREmission( eventSizeOld,
2908 0 : event, iSysSel, inResonance))
2909 0 : || (canMergeFirst && mergingHooksPtr->doVetoEmission( event )) ) {
2910 0 : event.popBack( event.size() - eventSizeOld);
2911 0 : event[iRadBef].status( iRadStatusV);
2912 0 : event[iRadBef].daughters( iRadDau1V, iRadDau2V);
2913 0 : if (useLocalRecoilNow && isrTypeNow == 0) {
2914 0 : event[iRecBef].status( iRecStatusV);
2915 0 : event[iRecBef].daughters( iRecDau1V, iRecDau2V);
2916 0 : } else if (useLocalRecoilNow) {
2917 0 : event[iRecBef].mothers( iRecMot1V, iRecMot2V);
2918 0 : if (iRecMot1V == beamOff1) event[beamOff1].daughter1( ev1Dau1V);
2919 0 : if (iRecMot1V == beamOff2) event[beamOff2].daughter1( ev2Dau1V);
2920 : } else {
2921 0 : for (int iG = 0; iG < int(iGRecBef.size()); ++iG) {
2922 0 : event[iGRecBef[iG]].statusPos();
2923 0 : event[iGRecBef[iG]].daughters( 0, 0);
2924 : }
2925 : }
2926 0 : return false;
2927 : }
2928 :
2929 : // For global recoil restore the one nominal recoiler, for bookkeeping.
2930 0 : if (!useLocalRecoilNow) {
2931 0 : iRec = iRecBef;
2932 0 : for (int iG = 0; iG < int(iGRecBef.size()); ++iG)
2933 0 : if (iGRecBef[iG] == iRecBef) iRec = iGRec[iG];
2934 0 : }
2935 :
2936 : // For initial-state recoiler also update beam and sHat info.
2937 0 : if (isrTypeNow != 0) {
2938 0 : BeamParticle& beamRec = (isrTypeNow == 1) ? *beamAPtr : *beamBPtr;
2939 0 : double xOld = beamRec[iSysSelRec].x();
2940 0 : double xRec = 2. * pRec.e() / (beamAPtr->e() + beamBPtr->e());
2941 0 : beamRec[iSysSelRec].iPos( iRec);
2942 0 : beamRec[iSysSelRec].x( xRec);
2943 0 : partonSystemsPtr->setSHat( iSysSelRec,
2944 0 : partonSystemsPtr->getSHat(iSysSelRec) * xRec / xOld);
2945 0 : }
2946 :
2947 : // For global recoil: if everything went as expected, remove the line
2948 : // from the list of "hard lines" that are allowed to use global recoil.
2949 0 : if ( !useLocalRecoilNow || nGlobal >= nMaxGlobalBranch) {
2950 : bool doRemove=true;
2951 0 : while ( doRemove ) {
2952 : bool hasRemoved = false;
2953 0 : for (int iHard = 0; iHard < int(hardPartons.size()); ++iHard)
2954 0 : if ( event[dipSel->iRadiator].isAncestor(hardPartons[iHard]) ) {
2955 0 : hardPartons.erase( hardPartons.begin() + iHard );
2956 : hasRemoved = true;
2957 0 : break;
2958 : }
2959 0 : doRemove = hasRemoved;
2960 : }
2961 0 : }
2962 :
2963 : // Update number of splittings that have been produced with global recoil.
2964 0 : if ( !useLocalRecoilNow ) ++nGlobal;
2965 :
2966 : // Photon emission: update to new dipole ends; add new photon "dipole".
2967 0 : if (dipSel->flavour == 22) {
2968 0 : dipSel->iRadiator = iRad;
2969 0 : dipSel->iRecoiler = iRec;
2970 : // When recoiler was uncharged particle, in resonance decays,
2971 : // assign recoil to emitted photons.
2972 0 : if (recoilToColoured && inResonance && event[iRec].chargeType() == 0)
2973 0 : dipSel->iRecoiler = iEmt;
2974 0 : dipSel->pTmax = pTsel;
2975 0 : if (doQEDshowerByGamma) dipEnd.push_back( TimeDipoleEnd(iEmt, iRad,
2976 0 : pTsel, 0, 0, 1, 0, 0, iSysSel, 0) );
2977 :
2978 : // Gluon emission: update both dipole ends and add two new ones.
2979 0 : } else if (dipSel->flavour == 21) {
2980 0 : dipSel->iRadiator = iRad;
2981 0 : dipSel->iRecoiler = iEmt;
2982 0 : dipSel->systemRec = iSysSel;
2983 0 : dipSel->isrType = 0;
2984 0 : dipSel->pTmax = pTsel;
2985 : // Optionally also kill ME corrections after first emission.
2986 0 : if (!doMEafterFirst) dipSel->MEtype = 0;
2987 : // PS dec 2010: check normalization of radiating dipole
2988 : // Dipole corresponding to the newly created color tag has normal strength
2989 0 : double flexFactor = (isFlexible) ? dipSel->flexFactor : 1.0;
2990 0 : dipSel->isFlexible = false;
2991 0 : for (int i = 0; i < int(dipEnd.size()); ++i) {
2992 0 : if (dipEnd[i].iRadiator == iRecBef && dipEnd[i].iRecoiler == iRadBef
2993 0 : && dipEnd[i].colType != 0) {
2994 0 : dipEnd[i].iRadiator = iRec;
2995 0 : dipEnd[i].iRecoiler = iEmt;
2996 : // Optionally also kill ME corrections after first emission.
2997 0 : if (!doMEafterFirst) dipEnd[i].MEtype = 0;
2998 : // Strive to match colour to anticolour inside closed system.
2999 0 : if ( !isFlexible && dipEnd[i].colType * dipSel->colType > 0)
3000 0 : dipEnd[i].iRecoiler = iRad;
3001 0 : dipEnd[i].pTmax = pTsel;
3002 : // PS dec 2010: if the (iRadBef,iRecBef) dipole was flexible, the
3003 : // same should be true for this (opposite) end. If so, this end keeps
3004 : // the modified normalization, so we shouldn't need to do anything.
3005 0 : }
3006 : // Weak shower can have gluons as recoiler. Always choose
3007 : // the outgoing gluon that produces the highest invariant mass.
3008 0 : if (event[iRadBef].id() == 21 && dipEnd[i].iRecoiler == iRadBef
3009 0 : && dipEnd[i].weakType != 0) {
3010 0 : double m1 = (event[iRad].p()+event[dipEnd[i].iRadiator].p()).m2Calc();
3011 0 : double m2 = (event[iEmt].p()+event[dipEnd[i].iRadiator].p()).m2Calc();
3012 0 : dipEnd[i].iRecoiler = (m1 > m2) ? iRad : iEmt;
3013 0 : }
3014 : }
3015 0 : int colType = (dipSel->colType > 0) ? 2 : -2 ;
3016 : // When recoiler was uncoloured particle, in resonance decays,
3017 : // assign recoil to coloured particle.
3018 0 : int iRecMod = iRec;
3019 0 : if (recoilToColoured && inResonance && event[iRec].col() == 0
3020 0 : && event[iRec].acol() == 0) iRecMod = iRad;
3021 0 : dipEnd.push_back( TimeDipoleEnd(iEmt, iRecMod, pTsel,
3022 0 : colType, 0, 0, 0, isrTypeSave, iSysSel, 0));
3023 0 : dipEnd.back().systemRec = iSysSelRec;
3024 : // PS dec 2010: the (iEmt,iRec) dipole "inherits" flexible normalization
3025 0 : if (isFlexible) {
3026 0 : dipEnd.back().isFlexible = true;
3027 0 : dipEnd.back().flexFactor = flexFactor;
3028 0 : }
3029 0 : dipEnd.push_back( TimeDipoleEnd(iEmt, iRad, pTsel,
3030 0 : -colType, 0, 0, 0, 0, iSysSel, 0));
3031 :
3032 : // Gluon branching to q qbar: update current dipole and other of gluon.
3033 0 : } else if (dipSel->colType != 0) {
3034 0 : for (int i = 0; i < int(dipEnd.size()); ++i) {
3035 : // Strive to match colour to anticolour inside closed system.
3036 0 : if ( !isFlexible && dipEnd[i].iRecoiler == iRadBef
3037 0 : && dipEnd[i].colType * dipSel->colType < 0 )
3038 0 : dipEnd[i].iRecoiler = iEmt;
3039 0 : if (dipEnd[i].iRadiator == iRadBef && abs(dipEnd[i].colType) == 2) {
3040 0 : dipEnd[i].colType /= 2;
3041 0 : if (dipEnd[i].system != dipEnd[i].systemRec) continue;
3042 :
3043 : // Note: gluino -> quark + squark gives a deeper radiation dip than
3044 : // the more obvious alternative photon decay, so is more realistic.
3045 0 : dipEnd[i].MEtype = 66;
3046 0 : if (&dipEnd[i] == dipSel) dipEnd[i].iMEpartner = iRad;
3047 0 : else dipEnd[i].iMEpartner = iEmt;
3048 : }
3049 : // Choose recoiler to Z/W to get largest mass.
3050 0 : if (event[iRadBef].id() == 21 && dipEnd[i].iRecoiler == iRadBef
3051 0 : && dipEnd[i].weakType != 0) {
3052 0 : double m1 = (event[iRad].p()+event[dipEnd[i].iRadiator].p()).m2Calc();
3053 0 : double m2 = (event[iEmt].p()+event[dipEnd[i].iRadiator].p()).m2Calc();
3054 0 : dipEnd[i].iRecoiler = (m1 > m2) ? iRad : iEmt;
3055 0 : }
3056 : }
3057 0 : dipSel->iRadiator = iEmt;
3058 0 : dipSel->iRecoiler = iRec;
3059 0 : dipSel->pTmax = pTsel;
3060 :
3061 : // Gluon branching to q qbar: also add two charge dipole ends.
3062 : // Note: gluino -> quark + squark gives a deeper radiation dip than
3063 : // the more obvious alternative photon decay, so is more realistic.
3064 0 : if (doQEDshowerByQ) {
3065 0 : int chgType = event[iRad].chargeType();
3066 0 : dipEnd.push_back( TimeDipoleEnd(iRad, iEmt, pTsel,
3067 0 : 0, chgType, 0, 0, 0, iSysSel, 66, iEmt));
3068 0 : dipEnd.push_back( TimeDipoleEnd(iEmt, iRad, pTsel,
3069 0 : 0, -chgType, 0, 0, 0, iSysSel, 66, iRad));
3070 0 : }
3071 :
3072 : // Gluon branching to q qbar: also add weak dipoles.
3073 : // Randomly decided whether to use left or right quarks.
3074 0 : if (doWeakShower && iSysSel == 0 &&
3075 0 : !(hasWeaklyRadiated && singleWeakEmission)) {
3076 0 : int weakPol = (rndmPtr->flat() > 0.5) ? -1 : 1;
3077 0 : event[iRad].pol(weakPol);
3078 0 : event[iEmt].pol(weakPol);
3079 0 : if ((weakMode == 0 || weakMode == 1) && weakPol == -1) {
3080 0 : dipEnd.push_back( TimeDipoleEnd(iRad, iEmt, pTsel,
3081 0 : 0, 0, 0, 1, 0, iSysSel, 200, iEmt, weakPol) );
3082 0 : dipEnd.push_back( TimeDipoleEnd(iEmt, iRad, pTsel,
3083 0 : 0, 0, 0, 1, 0, iSysSel, 200, iRad, weakPol) );
3084 : }
3085 0 : if (weakMode == 0 || weakMode == 2) {
3086 0 : dipEnd.push_back( TimeDipoleEnd(iRad, iEmt, pTsel,
3087 0 : 0, 0, 0, 2, 0, iSysSel, 205, iEmt, weakPol) );
3088 0 : dipEnd.push_back( TimeDipoleEnd(iEmt, iRad, pTsel,
3089 0 : 0, 0, 0, 2, 0, iSysSel, 205, iRad, weakPol) );
3090 : }
3091 0 : }
3092 :
3093 : // Photon branching to f fbar: inactivate photon "dipole";
3094 : // optionally add new charge and colour dipole ends.
3095 : // (But not W or Z ends, since W/Z are heavier than gamma*.)
3096 0 : } else if (dipSel->gamType != 0) {
3097 0 : dipSel->gamType = 0;
3098 0 : int chgType = event[iRad].chargeType();
3099 0 : int colType = event[iRad].colType();
3100 : // MEtype = 102 for charge in vector decay.
3101 0 : if ( chgType != 0 && ( ( doQEDshowerByQ && colType != 0 )
3102 0 : || ( doQEDshowerByL && colType == 0 ) ) ) {
3103 0 : dipEnd.push_back( TimeDipoleEnd(iRad, iEmt, pTsel,
3104 0 : 0, chgType, 0, 0, 0, iSysSel, 102, iEmt) );
3105 0 : dipEnd.push_back( TimeDipoleEnd(iEmt, iRad, pTsel,
3106 0 : 0, -chgType, 0, 0, 0, iSysSel, 102, iRad) );
3107 : }
3108 : // MEtype = 11 for colour in vector decay.
3109 0 : if (colType != 0 && doQCDshower) {
3110 0 : dipEnd.push_back( TimeDipoleEnd(iRad, iEmt, pTsel,
3111 0 : colType, 0, 0, 0, 0, iSysSel, 11, iEmt) );
3112 0 : dipEnd.push_back( TimeDipoleEnd(iEmt, iRad, pTsel,
3113 0 : -colType, 0, 0, 0, 0, iSysSel, 11, iRad) );
3114 : }
3115 :
3116 : // Photon_HV emission: update to new dipole ends.
3117 0 : } else if (dipSel->flavour == 4900022) {
3118 0 : dipSel->iRadiator = iRad;
3119 0 : dipSel->iRecoiler = iRec;
3120 0 : dipSel->pTmax = pTsel;
3121 :
3122 : // Gluon_HV emission: update to new dipole ends.
3123 0 : } else if (dipSel->flavour == 4900021) {
3124 0 : dipSel->iRadiator = iRad;
3125 0 : dipSel->iRecoiler = iEmt;
3126 0 : dipSel->pTmax = pTsel;
3127 0 : for (int i = 0; i < int(dipEnd.size()); ++i)
3128 0 : if (dipEnd[i].iRadiator == iRecBef && dipEnd[i].iRecoiler == iRadBef
3129 0 : && dipEnd[i].isHiddenValley) {
3130 0 : dipEnd[i].iRadiator = iRec;
3131 0 : dipEnd[i].iRecoiler = iEmt;
3132 0 : dipEnd[i].pTmax = pTsel;
3133 0 : }
3134 0 : int colvType = (dipSel->colvType > 0) ? 2 : -2 ;
3135 0 : dipEnd.push_back( TimeDipoleEnd(iEmt, iRec, pTsel,
3136 0 : 0, 0, 0, 0, isrTypeSave, iSysSel, 0, -1, 0, false, true, colvType) );
3137 0 : dipEnd.back().systemRec = iSysSelRec;
3138 0 : dipEnd.push_back( TimeDipoleEnd(iEmt, iRad, pTsel,
3139 0 : 0, 0, 0, 0, 0, iSysSel, 0, -1, 0, false, true, -colvType) );
3140 :
3141 : // W/Z emission, if only a single weak emission is allowed.
3142 0 : } else if (dipSel->weakType != 0) {
3143 0 : hasWeaklyRadiated = true;
3144 0 : if (singleWeakEmission)
3145 0 : for (int i = 0; i < int(dipEnd.size()); ++i) dipEnd[i].weakType = 0;
3146 : }
3147 :
3148 : // Copy or set lifetime for new final state.
3149 0 : if (event[iRad].id() == event[iRadBef].id()) {
3150 0 : event[iRad].tau( event[iRadBef].tau() );
3151 0 : } else {
3152 0 : event[iRad].tau( event[iRad].tau0() * rndmPtr->exp() );
3153 0 : event[iEmt].tau( event[iEmt].tau0() * rndmPtr->exp() );
3154 : }
3155 0 : event[iRec].tau( event[iRecBef].tau() );
3156 :
3157 : // Now update other dipoles that also involved the radiator or recoiler.
3158 0 : for (int i = 0; i < int(dipEnd.size()); ++i) {
3159 : // PS dec 2010: if radiator was flexible and now is normal, there may
3160 : // be other flexible dipoles that need updating.
3161 0 : if (isFlexible && !dipSel->isFlexible && dipEnd[i].isFlexible) {
3162 0 : if (dipEnd[i].iRecoiler == iRadBef) dipEnd[i].iRecoiler = iEmt;
3163 0 : if (dipEnd[i].iRadiator == iRadBef) {
3164 0 : dipEnd[i].iRadiator = iEmt;
3165 0 : if (dipEnd[i].colType == 1 && dipSel->flavour == 21)
3166 0 : dipEnd[i].colType = 2;
3167 0 : if (dipEnd[i].colType ==-1 && dipSel->flavour == 21)
3168 0 : dipEnd[i].colType =-2;
3169 : }
3170 : }
3171 0 : if (dipEnd[i].iRadiator == iRadBef) dipEnd[i].iRadiator = iRad;
3172 0 : if (dipEnd[i].iRecoiler == iRadBef) dipEnd[i].iRecoiler = iRad;
3173 0 : if (dipEnd[i].iMEpartner == iRadBef) dipEnd[i].iMEpartner = iRad;
3174 0 : if (useLocalRecoilNow) {
3175 0 : if (dipEnd[i].iRadiator == iRecBef) dipEnd[i].iRadiator = iRec;
3176 0 : if (dipEnd[i].iRecoiler == iRecBef) dipEnd[i].iRecoiler = iRec;
3177 0 : if (dipEnd[i].iMEpartner == iRecBef) dipEnd[i].iMEpartner = iRec;
3178 : } else {
3179 0 : for (int iG = 0; iG < int(iGRecBef.size()); ++iG) {
3180 0 : if (dipEnd[i].iRadiator == iGRecBef[iG])
3181 0 : dipEnd[i].iRadiator = iGRec[iG];
3182 0 : if (dipEnd[i].iRecoiler == iGRecBef[iG])
3183 0 : dipEnd[i].iRecoiler = iGRec[iG];
3184 0 : if (dipEnd[i].iMEpartner == iGRecBef[iG])
3185 0 : dipEnd[i].iMEpartner = iGRec[iG];
3186 : }
3187 : }
3188 : }
3189 :
3190 : // PS Apr 2011
3191 : // Update any junctions downstream of this branching (if necessary)
3192 : // (This happens, e.g., via LHEF, when adding showers to intermediate
3193 : // coloured resonances whose decays involved junctions)
3194 0 : for (int iJun = 0; iJun < event.sizeJunction(); iJun++) {
3195 : // Number of incoming colour lines for this junction.
3196 0 : int nIncoming = (event.kindJunction(iJun)-1)/2;
3197 : // Check radiator colour or anticolour, depending on junction kind
3198 : // (if junction, incoming = anticolours, and vice versa)
3199 : int colChk = 0;
3200 0 : colChk = ( event.kindJunction(iJun) % 2 == 0 )
3201 0 : ? event[iRadBef].col() : event[iRadBef].acol();
3202 : // Loop over incoming junction ends
3203 0 : for (int iCol = 0; iCol < nIncoming; iCol++) {
3204 0 : int colJun = event.colJunction( iJun, iCol);
3205 : // If match, update junction end with new upstream (anti)colour
3206 0 : if (colJun == colChk) {
3207 : int colNew = 0;
3208 0 : if ( event.kindJunction(iJun) % 2 == 0 ) colNew = colRad;
3209 : else colNew = acolRad;
3210 0 : event.colJunction( iJun, iCol, colNew );
3211 0 : }
3212 : }
3213 : }
3214 :
3215 : // Finally update the list of all partons in all systems.
3216 0 : partonSystemsPtr->replace(iSysSel, iRadBef, iRad);
3217 0 : partonSystemsPtr->addOut(iSysSel, iEmt);
3218 0 : if (useLocalRecoilNow)
3219 0 : partonSystemsPtr->replace(iSysSelRec, iRecBef, iRec);
3220 : else {
3221 0 : for (int iG = 0; iG < int(iGRecBef.size()); ++iG)
3222 0 : partonSystemsPtr->replace(iSysSel, iGRecBef[iG], iGRec[iG]);
3223 : }
3224 :
3225 : // Done.
3226 0 : return true;
3227 :
3228 0 : }
3229 :
3230 : //--------------------------------------------------------------------------
3231 :
3232 : // Rescatter: If a dipole stretches between two different systems, those
3233 : // systems will no longer locally conserve momentum. These
3234 : // imbalances become problematic when ISR or primordial kT
3235 : // is switched on as these steps involve Lorentz boosts.
3236 : //
3237 : // 'rescatterPropagateRecoil' tries to fix momentum in all
3238 : // systems by propogating recoil momentum through all
3239 : // intermediate systems. As the momentum transfer is already
3240 : // defined, this can lead to internal lines gaining a
3241 : // virtuality.
3242 :
3243 : // Useful definitions for a pair of integers and a vector of pairs
3244 : typedef pair < int, int > pairInt;
3245 : typedef vector < pairInt > vectorPairInt;
3246 :
3247 : //--------------------------------------------------------------------------
3248 :
3249 : // findParentSystems
3250 : // Utility routine to find all parent systems of a given system
3251 : // Returns a vector of pairs of integers with:
3252 : // a) The system index, including the starting system (negative
3253 : // if (b) points to a parent system, positive if (b) points
3254 : // to a daughter system
3255 : // b) The event record index that is the path out of the system
3256 : // (if forwards == false, this is an incoming parton to the
3257 : // system, and is +ve if side A or -ve if side B,
3258 : // if forwards == true, this is an outgoing parton from the
3259 : // system).
3260 : // Returns as empty vector on failure
3261 : // Note: this assumes single rescattering only and therefore only
3262 : // one possible parent system
3263 :
3264 : inline vectorPairInt findParentSystems(const int sys,
3265 : Event& event, PartonSystems* partonSystemsPtr, bool forwards) {
3266 :
3267 0 : vectorPairInt parentSystems;
3268 0 : parentSystems.reserve(10);
3269 :
3270 : int iSysCur = sys;
3271 0 : while (true) {
3272 : // Get two incoming partons
3273 0 : int iInA = partonSystemsPtr->getInA(iSysCur);
3274 0 : int iInB = partonSystemsPtr->getInB(iSysCur);
3275 :
3276 : // Check if either of these links to another system
3277 0 : int iIn = 0;
3278 0 : if (event[iInA].isRescatteredIncoming()) iIn = iInA;
3279 0 : if (event[iInB].isRescatteredIncoming()) iIn = -iInB;
3280 :
3281 : // Save the current system to the vector
3282 0 : parentSystems.push_back( pairInt(-iSysCur, iIn) );
3283 0 : if (iIn == 0) break;
3284 :
3285 0 : int iInAbs = abs(iIn);
3286 0 : int iMother = event[iInAbs].mother1();
3287 0 : iSysCur = partonSystemsPtr->getSystemOf(iMother);
3288 0 : if (iSysCur == -1) {
3289 0 : parentSystems.clear();
3290 0 : break;
3291 : }
3292 0 : } // while (true)
3293 :
3294 : // If forwards is set, change all event record indices to go to daughter
3295 : // systems rather than parent systems
3296 0 : if (forwards) {
3297 0 : vectorPairInt::reverse_iterator rit;
3298 0 : for (rit = parentSystems.rbegin(); rit < (parentSystems.rend() - 1);
3299 0 : ++rit) {
3300 0 : pairInt &cur = *rit;
3301 0 : pairInt &next = *(rit + 1);
3302 0 : cur.first = -cur.first;
3303 0 : cur.second = (next.second < 0) ? -event[abs(next.second)].mother1() :
3304 0 : event[abs(next.second)].mother1();
3305 : }
3306 0 : }
3307 :
3308 : return parentSystems;
3309 0 : }
3310 :
3311 : //--------------------------------------------------------------------------
3312 :
3313 : // rescatterPropagateRecoil
3314 : // Fix up momentum in all intermediate systems when radiator and recoiler
3315 : // systems are different. The strategy is to look at all parent systems
3316 : // from the radiator system and the recoiler system and find where they
3317 : // intersect.
3318 :
3319 : bool TimeShower::rescatterPropagateRecoil( Event& event, Vec4& pNew) {
3320 :
3321 : // Some useful variables for later
3322 0 : int iRadBef = dipSel->iRadiator;
3323 0 : iSysSel = dipSel->system;
3324 0 : int iSysSelRec = dipSel->systemRec;
3325 0 : Vec4 pImbal = pNew - event[iRadBef].p();
3326 :
3327 : // Store changes locally at first in case we veto the branching
3328 : // eventMod stores index into the event record and new 4-vector
3329 0 : vector < pair < int, Vec4 > > eventMod;
3330 0 : eventMod.reserve(10);
3331 : // systemMod stores system index (iSys) and system-parton index (iMem)
3332 : // iMem >= 0 - index into outgoing partons (iOut)
3333 : // iMem == -1 - incoming A
3334 : // iMem == -2 - incoming B
3335 0 : vectorPairInt systemMod;
3336 0 : systemMod.reserve(10);
3337 :
3338 : // Find all parent systems from radiating and recoiling systems
3339 0 : vectorPairInt radParent = findParentSystems(iSysSel, event,
3340 0 : partonSystemsPtr, false);
3341 0 : vectorPairInt recParent = findParentSystems(iSysSelRec, event,
3342 0 : partonSystemsPtr, true);
3343 0 : if (radParent.size() == 0 || recParent.size() == 0) {
3344 : // This should never happen
3345 0 : infoPtr->errorMsg("Error in TimeShower::rescatterPropagateRecoil: "
3346 : "couldn't find parent system; branching vetoed");
3347 0 : return false;
3348 : }
3349 : // Find the system that connects radiating and recoiling system
3350 : bool foundPath = false;
3351 : unsigned int iRadP = 0;
3352 : unsigned int iRecP = 0;
3353 0 : for (iRadP = 0; iRadP < radParent.size(); iRadP++) {
3354 0 : for (iRecP = 0; iRecP < recParent.size(); iRecP++)
3355 0 : if (abs(radParent[iRadP].first) == abs(recParent[iRecP].first)) {
3356 : foundPath = true;
3357 0 : break;
3358 : }
3359 0 : if (foundPath) break;
3360 : }
3361 0 : if (!foundPath) {
3362 : // Can fail e.g. for QED dipoles where there is no connection
3363 : // between radiator and recoiler systems
3364 0 : infoPtr->errorMsg("Warning in TimeShower::rescatterPropagateRecoil: "
3365 : "couldn't find recoil path; branching vetoed");
3366 0 : return false;
3367 : }
3368 :
3369 : // Join together to form complete path from radiating system
3370 : // to recoiling system
3371 0 : vectorPairInt path;
3372 0 : if (radParent.size() > 1)
3373 0 : path.assign(radParent.begin(), radParent.begin() + iRadP);
3374 0 : if (recParent.size() > 1)
3375 0 : path.insert(path.end(), recParent.rend() - iRecP - 1,
3376 0 : recParent.rend() - 1);
3377 :
3378 : // Follow the path fixing up momenta as we go
3379 0 : for (unsigned int i = 0; i < path.size(); i++) {
3380 : // Line out of the current system
3381 0 : bool isIncoming = (path[i].first < 0) ? true : false;
3382 0 : int iSysCur = abs(path[i].first);
3383 0 : bool isIncomingA = (path[i].second > 0) ? true : false;
3384 0 : int iLink = abs(path[i].second);
3385 :
3386 0 : int iMemCur;
3387 0 : if (isIncoming) iMemCur = (isIncomingA) ? -1 : -2;
3388 : else {
3389 0 : iMemCur = -1;
3390 0 : for (int j = 0; j < partonSystemsPtr->sizeOut(iSysCur); j++)
3391 0 : if (partonSystemsPtr->getOut(iSysCur, j) == iLink) {
3392 0 : iMemCur = j;
3393 0 : break;
3394 : }
3395 0 : if (iMemCur == -1) {
3396 : // This should never happen
3397 0 : infoPtr->errorMsg("Error in TimeShower::rescatterPropagateRecoil: "
3398 : "couldn't find parton system; branching vetoed");
3399 0 : return false;
3400 : }
3401 : }
3402 :
3403 0 : Vec4 pMod = (isIncoming) ? event[iLink].p() + pImbal :
3404 0 : event[iLink].p() - pImbal;
3405 0 : eventMod.push_back(pair <int, Vec4> (iLink, pMod));
3406 0 : systemMod.push_back(pairInt(iSysCur, iMemCur));
3407 :
3408 : // Calculate sHat of iSysCur
3409 0 : int iInCurA = partonSystemsPtr->getInA(iSysCur);
3410 0 : int iInCurB = partonSystemsPtr->getInB(iSysCur);
3411 0 : Vec4 pTotCur = event[iInCurA].p() + event[iInCurB].p();
3412 :
3413 : // If iMemCur is -1 or -2, then we must have changed the sHat of iSysCur
3414 0 : if (iMemCur < 0) pTotCur += (isIncoming) ? pImbal : -pImbal;
3415 0 : double sHatCur = pTotCur.m2Calc();
3416 :
3417 : // The fixed-up incoming and outgoing partons should not have
3418 : // too large a virtuality in relation to the system mass-square.
3419 0 : if (abs(pMod.m2Calc()) > MAXVIRTUALITYFRACTION * sHatCur) {
3420 0 : infoPtr->errorMsg("Warning in TimeShower::rescatterPropagateRecoil: "
3421 : "virtuality much larger than sHat; branching vetoed");
3422 0 : return false;
3423 : }
3424 :
3425 : // Outgoing ones should also not have too large negative energy
3426 : // in the rest frame of the system.
3427 0 : if (!isIncoming && pMod * pTotCur < -MAXNEGENERGYFRACTION * sHatCur) {
3428 0 : infoPtr->errorMsg("Warning in TimeShower::rescatterPropagateRecoil: "
3429 : "rest frame energy too negative; branching vetoed");
3430 0 : return false;
3431 : }
3432 :
3433 : // Veto negative sHat.
3434 0 : if (sHatCur < 0.0) {
3435 0 : infoPtr->errorMsg("Warning in TimeShower::rescatterPropagateRecoil: "
3436 : "sHat became negative; branching vetoed");
3437 0 : return false;
3438 : }
3439 :
3440 : // Line into the new current system
3441 0 : iLink = (isIncoming) ? event[iLink].mother1() :
3442 0 : event[iLink].daughter1();
3443 0 : iSysCur = partonSystemsPtr->getSystemOf(iLink, true);
3444 :
3445 0 : if (!isIncoming) iMemCur = (isIncomingA) ? -1 : -2;
3446 : else {
3447 0 : iMemCur = -1;
3448 0 : for (int j = 0; j < partonSystemsPtr->sizeOut(iSysCur); j++)
3449 0 : if (partonSystemsPtr->getOut(iSysCur, j) == iLink) {
3450 0 : iMemCur = j;
3451 0 : break;
3452 : }
3453 0 : if (iMemCur == -1) {
3454 : // This should never happen
3455 0 : infoPtr->errorMsg("Error in TimeShower::rescatterPropagateRecoil: "
3456 : "couldn't find parton system; branching vetoed");
3457 0 : return false;
3458 : }
3459 : }
3460 :
3461 0 : pMod = (isIncoming) ? event[iLink].p() + pImbal :
3462 0 : event[iLink].p() - pImbal;
3463 0 : eventMod.push_back(pair <int, Vec4> (iLink, pMod));
3464 0 : systemMod.push_back(pairInt(iSysCur, iMemCur));
3465 :
3466 : // Calculate sHat of iSysCur
3467 0 : iInCurA = partonSystemsPtr->getInA(iSysCur);
3468 0 : iInCurB = partonSystemsPtr->getInB(iSysCur);
3469 0 : pTotCur = event[iInCurA].p() + event[iInCurB].p();
3470 :
3471 : // If iMemCur is -1 or -2, then we must have changed the sHat of iSysCur
3472 0 : if (iMemCur < 0) pTotCur += (isIncoming) ? pImbal : -pImbal;
3473 0 : sHatCur = pTotCur.m2Calc();
3474 :
3475 : // The fixed-up incoming and outgoing partons should not have
3476 : // too large a virtuality in relation to the system mass-square.
3477 0 : if (abs(pMod.m2Calc()) > MAXVIRTUALITYFRACTION * sHatCur) {
3478 0 : infoPtr->errorMsg("Warning in TimeShower::rescatterPropagateRecoil: "
3479 : "virtuality much larger than sHat; branching vetoed");
3480 0 : return false;
3481 : }
3482 :
3483 : // Outgoing ones should also not have too large negative energy
3484 : // in the rest frame of the system.
3485 0 : if (!isIncoming && pMod * pTotCur < -MAXNEGENERGYFRACTION * sHatCur) {
3486 0 : infoPtr->errorMsg("Warning in TimeShower::rescatterPropagateRecoil: "
3487 : "rest frame energy too negative; branching vetoed");
3488 0 : return false;
3489 : }
3490 :
3491 : // Veto negative sHat
3492 0 : if (sHatCur < 0.0) {
3493 0 : infoPtr->errorMsg("Warning in TimeShower::rescatterPropagateRecoil: "
3494 : "sHat became negative; branching vetoed");
3495 0 : return false;
3496 : }
3497 :
3498 : // Do negative energy veto
3499 : if (VETONEGENERGY && pMod.e() < 0.0) {
3500 : infoPtr->errorMsg("Warning in TimeShower::rescatterPropagateRecoil: "
3501 : "energy became negative; branching vetoed");
3502 : return false;
3503 : }
3504 :
3505 0 : } // for (unsigned int i = 0; i < path.size(); i++)
3506 :
3507 : // If no vetos by this point, apply the changes to the event record
3508 : // An incoming particle with changed momentum is given status code -54,
3509 : // an outgoing particle with changed momentum is given status code -55
3510 0 : for (unsigned int i = 0; i < eventMod.size(); i++) {
3511 0 : int idx = eventMod[i].first;
3512 0 : Vec4 &pMod = eventMod[i].second;
3513 0 : int iSys = systemMod[i].first;
3514 0 : int iMem = systemMod[i].second;
3515 :
3516 : // If incoming to a process then set the copy to be the mother
3517 0 : if (event[idx].isRescatteredIncoming()) {
3518 0 : int mother1 = event[idx].mother1();
3519 0 : idx = event.copy(idx, -54);
3520 0 : event[mother1].daughters(idx, idx);
3521 :
3522 : // Update beam information if necessary
3523 0 : double eCM = sqrt(m2( beamAPtr->p(), beamBPtr->p()));
3524 0 : if (iMem == -1) {
3525 0 : partonSystemsPtr->setInA(iSys, idx);
3526 0 : (*beamAPtr)[iSys].x((pMod.e() + pMod.pz()) / eCM);
3527 0 : (*beamAPtr)[iSys].m(pMod.mCalc());
3528 0 : (*beamAPtr)[iSys].p(pMod);
3529 0 : (*beamAPtr)[iSys].iPos(idx);
3530 0 : } else if (iMem == -2) {
3531 0 : partonSystemsPtr->setInB(iSys, idx);
3532 0 : (*beamBPtr)[iSys].x((pMod.e() - pMod.pz()) / eCM);
3533 0 : (*beamBPtr)[iSys].m(pMod.mCalc());
3534 0 : (*beamBPtr)[iSys].p(pMod);
3535 0 : (*beamBPtr)[iSys].iPos(idx);
3536 0 : } else {
3537 : // This should never happen
3538 0 : infoPtr->errorMsg("Error in TimeShower::rescatterPropagateRecoil: "
3539 : "internal bookeeping error");
3540 : }
3541 :
3542 : // Otherwise set the new event record entry to be the daughter
3543 0 : } else {
3544 0 : int daughter1 = event[idx].daughter1();
3545 0 : idx = event.copy(idx, 55);
3546 0 : event[idx].statusNeg();
3547 0 : event[daughter1].mothers(idx, idx);
3548 :
3549 0 : partonSystemsPtr->setOut(iSys, iMem, idx);
3550 : }
3551 :
3552 0 : event[idx].p( eventMod[i].second );
3553 0 : event[idx].m( event[idx].mCalc() );
3554 : }
3555 :
3556 0 : return true;
3557 0 : }
3558 :
3559 :
3560 : //--------------------------------------------------------------------------
3561 :
3562 : // Find class of QCD ME correction.
3563 : // MEtype classification follow codes in Norrbin article,
3564 : // additionally -1 = try to find type, 0 = no ME corrections.
3565 : // Warning: not yet tried out to do a correct assignment in
3566 : // arbitrary multiparton configurations! ??
3567 :
3568 : void TimeShower::findMEtype( Event& event, TimeDipoleEnd& dip) {
3569 :
3570 : // Initial value. Mark if no ME corrections to be applied.
3571 : bool setME = true;
3572 0 : if (!doMEcorrections) setME = false;
3573 0 : int iMother = event[dip.iRadiator].mother1();
3574 0 : int iMother2 = event[dip.iRadiator].mother2();
3575 :
3576 : // Allow ME corrections for Hidden Valley pair in 2 -> 2.
3577 0 : if (dip.isHiddenValley && event[dip.iRecoiler].id()
3578 0 : == -event[dip.iRadiator].id());
3579 :
3580 : // Allow ME corrections for all weak branchings.
3581 0 : else if (dip.weakType != 0);
3582 :
3583 : // Else no ME corrections in 2 -> n processes.
3584 : else {
3585 0 : if (iMother2 != iMother && iMother2 != 0) setME = false;
3586 0 : if (event[dip.iRecoiler].mother1() != iMother) setME = false;
3587 0 : if (event[dip.iRecoiler].mother2() != iMother2) setME = false;
3588 : }
3589 :
3590 : // No ME corrections for recoiler in initial state.
3591 0 : if (event[dip.iRecoiler].status() < 0) setME = false;
3592 :
3593 : // No ME corrections for recoiler not in same system
3594 0 : if (dip.system != dip.systemRec) setME = false;
3595 :
3596 : // Done if no ME to be set.
3597 0 : if (!setME) {
3598 0 : dip.MEtype = 0;
3599 0 : return;
3600 : }
3601 :
3602 : // If no ME partner set, assume it is the recoiler.
3603 0 : if (dip.iMEpartner < 0) dip.iMEpartner = dip.iRecoiler;
3604 :
3605 : // Now begin processing of colour dipole, including Hidden Valley.
3606 0 : if (dip.colType != 0 || dip.colvType != 0) {
3607 0 : bool isHiddenColour = (dip.colvType != 0);
3608 :
3609 : // Find daughter types (may or may not be used later on).
3610 0 : int idDau1 = event[dip.iRadiator].id();
3611 0 : int idDau2 = event[dip.iMEpartner].id();
3612 0 : int dau1Type = findMEparticle(idDau1, isHiddenColour);
3613 0 : int dau2Type = findMEparticle(idDau2, isHiddenColour);
3614 0 : int minDauType = min(dau1Type, dau2Type);
3615 0 : int maxDauType = max(dau1Type, dau2Type);
3616 :
3617 : // Reorder dipole ends in kinematics. Split ME expression in two sides.
3618 0 : dip.MEorder = (dau2Type >= dau1Type);
3619 0 : dip.MEsplit = (maxDauType <= 6);
3620 0 : dip.MEgluinoRec = false;
3621 :
3622 : // If type already set (or set not to have) then done.
3623 0 : if (minDauType == 0 && dip.MEtype < 0) dip.MEtype = 0;
3624 0 : if (dip.MEtype >= 0) return;
3625 0 : dip.MEtype = 0;
3626 :
3627 : // For H -> gg -> ggg we found that DGLAP kernels do better than eikonal.
3628 0 : if (dau1Type == 4 && dau2Type == 4) return;
3629 :
3630 : // Find mother type.
3631 : int idMother = 0;
3632 0 : if ( event[dip.iRecoiler].mother1() == iMother && iMother >= 0)
3633 0 : idMother = event[iMother].id();
3634 0 : int motherType = (idMother != 0)
3635 0 : ? findMEparticle(idMother, isHiddenColour) : 0;
3636 :
3637 : // When a mother if not known then use colour and spin content to guess.
3638 0 : if (motherType == 0) {
3639 0 : int col1 = event[dip.iRadiator].col();
3640 0 : int acol1 = event[dip.iRadiator].acol();
3641 0 : int col2 = event[dip.iMEpartner].col();
3642 0 : int acol2 = event[dip.iMEpartner].acol();
3643 : // spinT = 0/1 = integer or half-integer.
3644 0 : int spinT = ( event[dip.iRadiator].spinType()
3645 0 : + event[dip.iMEpartner].spinType() )%2;
3646 : // Colour singlet mother.
3647 0 : if ( col1 == acol2 && acol1 == col2 )
3648 0 : motherType = (spinT == 0) ? 7 : 9;
3649 : // Colour octet mother.
3650 0 : else if ( (col1 == acol2 && acol1 != 0 && col2 != 0)
3651 0 : || (acol1 == col2 && col1 != 0 && acol2 != 0) )
3652 0 : motherType = (spinT == 0) ? 4 : 5;
3653 : // Colour triplet mother.
3654 0 : else if ( (col1 == acol2 && acol1 != col2)
3655 0 : || (acol1 == col2 && col1 != acol2) )
3656 0 : motherType = (spinT == 0) ? 2 : 1;
3657 : // If no colours are matched then cannot have common mother, so done.
3658 0 : else return;
3659 0 : }
3660 :
3661 : // Now start from default, which is eikonal ME corrections,
3662 : // and try to find matching ME cases below.
3663 : int MEkind = 0;
3664 : int MEcombi = 4;
3665 0 : dip.MEmix = 0.5;
3666 :
3667 : // Hidden Valley with massive gamma_v covered by two special cases.
3668 0 : if (isHiddenColour && brokenHVsym) {
3669 0 : MEkind = (dau2Type == 0 || dau2Type > 6) ? 30 : 31;
3670 0 : dip.MEtype = 5 * MEkind + 1;
3671 0 : return;
3672 : }
3673 :
3674 : // Triplet recoiling against gluino needs enhanced radiation
3675 : // to match to matrix elements.
3676 0 : dip.MEgluinoRec = (dau1Type >= 1 && dau1Type <= 3 && dau2Type == 5);
3677 :
3678 : // Vector/axial vector -> q + qbar.
3679 0 : if (minDauType == 1 && maxDauType == 1 &&
3680 0 : (motherType == 4 || motherType == 7) ) {
3681 : MEkind = 2;
3682 0 : if (idMother == 21 || idMother == 22) MEcombi = 1;
3683 0 : else if (idMother == 23 || idDau1 + idDau2 == 0) {
3684 : MEcombi = 3;
3685 0 : dip.MEmix = gammaZmix( event, iMother, dip.iRadiator, dip.iRecoiler );
3686 0 : }
3687 0 : else if (idMother == 24) MEcombi = 4;
3688 : }
3689 : // For chi -> chi q qbar, use V/A -> q qbar as first approximation.
3690 0 : else if (minDauType == 1 && maxDauType == 1 && motherType == 9)
3691 0 : MEkind = 2;
3692 :
3693 : // q -> q + V.
3694 0 : else if (minDauType == 1 && maxDauType == 7 && motherType == 1)
3695 0 : MEkind = 3;
3696 0 : if (idDau1 == 22 || idDau2 == 22) MEcombi = 1;
3697 :
3698 : // Scalar/pseudoscalar -> q + qbar; q -> q + S.
3699 0 : else if (minDauType == 1 && maxDauType == 1 && motherType == 8) {
3700 : MEkind = 4;
3701 0 : if (idMother == 25 || idMother == 35 || idMother == 37) MEcombi = 1;
3702 0 : else if (idMother == 36) MEcombi = 2;
3703 : }
3704 0 : else if (minDauType == 1 && maxDauType == 8 && motherType == 1)
3705 0 : MEkind = 5;
3706 :
3707 : // V -> ~q + ~qbar; ~q -> ~q + V; S -> ~q + ~qbar; ~q -> ~q + S.
3708 0 : else if (minDauType == 2 && maxDauType == 2 && (motherType == 4
3709 0 : || motherType == 7) ) MEkind = 6;
3710 0 : else if (minDauType == 2 && (maxDauType == 4 || maxDauType == 7)
3711 0 : && motherType == 2) MEkind = 7;
3712 0 : else if (minDauType == 2 && maxDauType == 2 && motherType == 8)
3713 0 : MEkind = 8;
3714 0 : else if (minDauType == 2 && maxDauType == 8 && motherType == 2)
3715 0 : MEkind = 9;
3716 :
3717 : // chi -> q + ~qbar; ~q -> q + chi; q -> ~q + chi.
3718 0 : else if (minDauType == 1 && maxDauType == 2 && motherType == 9)
3719 0 : MEkind = 10;
3720 0 : else if (minDauType == 1 && maxDauType == 9 && motherType == 2)
3721 0 : MEkind = 11;
3722 0 : else if (minDauType == 2 && maxDauType == 9 && motherType == 1)
3723 0 : MEkind = 12;
3724 :
3725 : // ~g -> q + ~qbar; ~q -> q + ~g; q -> ~q + ~g.
3726 0 : else if (minDauType == 1 && maxDauType == 2 && motherType == 5)
3727 0 : MEkind = 13;
3728 0 : else if (minDauType == 1 && maxDauType == 5 && motherType == 2)
3729 0 : MEkind = 14;
3730 0 : else if (minDauType == 2 && maxDauType == 5 && motherType == 1)
3731 0 : MEkind = 15;
3732 :
3733 : // In cases where coloured spin 1 particle involved use spin 0.
3734 : // V_coloured -> q + l.
3735 0 : else if (minDauType == 1 && maxDauType == 9 && motherType == 3)
3736 0 : MEkind = 11;
3737 : // q -> V_coloured + l;
3738 0 : else if (minDauType == 3 && maxDauType == 9 && motherType == 1)
3739 0 : MEkind = 12;
3740 :
3741 : // g (+V, S) -> ~g + ~g (eikonal approximation).
3742 0 : else if (minDauType == 5 && maxDauType == 5) MEkind = 16;
3743 :
3744 : // Save ME type and gamma_5 admixture.
3745 0 : dip.MEtype = 5 * MEkind + MEcombi;
3746 :
3747 : // Now begin processing of charge dipole - still primitive.
3748 0 : } else if (dip.chgType != 0) {
3749 :
3750 : // Set defaults for QED case; then possibly done.
3751 0 : dip.MEorder = true;
3752 0 : dip.MEsplit = true;
3753 0 : if (dip.MEtype >= 0) return;
3754 :
3755 : // So far only ME corrections for q qbar or l lbar.
3756 0 : int idDau1 = event[dip.iRadiator].id();
3757 0 : int idDau2 = event[dip.iMEpartner].id();
3758 0 : if (abs(idDau1) < 9 && abs(idDau2) < 9 && idDau1 * idDau2 < 0) ;
3759 0 : else if (abs(idDau1) > 10 && abs(idDau1) < 19 && abs(idDau2) > 10
3760 0 : && abs(idDau2) < 19 && idDau1 * idDau2 < 0) ;
3761 0 : else { dip.MEtype = 0; return; }
3762 :
3763 : // Distinguish charge sum != 0 or = 0; in latter assume vector source.
3764 0 : dip.MEtype = 101;
3765 0 : if (idDau1 + idDau2 == 0) dip.MEtype = 102;
3766 0 : dip.MEmix = 1.;
3767 0 : }
3768 :
3769 : // Identify 2 -> 2 processes for weak corrections.
3770 0 : else if (dip.weakType == 1) {
3771 0 : if (event[dip.iRadiator].id() == -event[dip.iRecoiler].id()
3772 0 : || event[event[dip.iRadiator].mother1()].idAbs() == 24
3773 0 : || infoPtr->nFinal() != 2) dip.MEtype = 200;
3774 0 : else if (event[dip.iRadiator].idAbs() == 21
3775 0 : || event[dip.iRecoiler].idAbs() == 21) dip.MEtype = 201;
3776 0 : else if (event[dip.iRadiator].id() == event[dip.iRecoiler].id())
3777 0 : dip.MEtype = 202;
3778 0 : else dip.MEtype = 203;
3779 0 : } else if (dip.weakType == 2) {
3780 0 : if (event[dip.iRadiator].id() == -event[dip.iRecoiler].id()
3781 0 : || event[event[dip.iRadiator].mother1()].idAbs() == 24) dip.MEtype = 205;
3782 0 : else if (event[dip.iRadiator].idAbs() == 21
3783 0 : || event[dip.iRecoiler].idAbs() == 21) dip.MEtype = 206;
3784 0 : else if (event[dip.iRadiator].id() == event[dip.iRecoiler].id())
3785 0 : dip.MEtype = 207;
3786 0 : else dip.MEtype = 208;
3787 : }
3788 :
3789 0 : }
3790 :
3791 : //--------------------------------------------------------------------------
3792 :
3793 : // Find type of particle for ME type: 0 = unknown, 1 = quark, 2 = squark,
3794 : // 3 = spare triplet, 4 = gluon, 5 = gluino, 6 = spare octet,
3795 : // 7 = vector boson, 8 = colourless scalar, 9 = colourless spin 1/2.
3796 :
3797 : int TimeShower::findMEparticle( int id, bool isHiddenColour) {
3798 :
3799 : // find colour and spin of particle.
3800 : int type = 0;
3801 0 : int colType = abs(particleDataPtr->colType(id));
3802 0 : int spinType = particleDataPtr->spinType(id);
3803 :
3804 : // For hidden valley particle treat HV colour as normal one.
3805 : // Note: no need to assign gv/gammav since not in ME.
3806 0 : if (isHiddenColour) {
3807 : colType = 0;
3808 0 : int idAbs = abs(id);
3809 0 : if ( (idAbs > 4900000 && idAbs < 4900007)
3810 0 : || (idAbs > 4900010 && idAbs < 4900017)
3811 0 : || idAbs == 4900101) colType = 1;
3812 0 : }
3813 :
3814 : // Find particle type from colour and spin.
3815 0 : if (colType == 1 && spinType == 2) type = 1;
3816 0 : else if (colType == 1 && spinType == 1) type = 2;
3817 0 : else if (colType == 1) type = 3;
3818 0 : else if (colType == 2 && spinType == 3) type = 4;
3819 0 : else if (colType == 2 && spinType == 2) type = 5;
3820 0 : else if (colType == 2) type = 6;
3821 0 : else if (colType == 0 && spinType == 3) type = 7;
3822 0 : else if (colType == 0 && spinType == 1) type = 8;
3823 0 : else if (colType == 0 && spinType == 2) type = 9;
3824 :
3825 : // Done.
3826 0 : return type;
3827 :
3828 : }
3829 :
3830 : //--------------------------------------------------------------------------
3831 :
3832 : // Find mixture of V and A in gamma/Z: energy- and flavour-dependent.
3833 :
3834 : double TimeShower::gammaZmix( Event& event, int iRes, int iDau1, int iDau2) {
3835 :
3836 : // Try to identify initial flavours; use e+e- as default.
3837 : int idIn1 = -11;
3838 : int idIn2 = 11;
3839 0 : int iIn1 = (iRes >= 0) ? event[iRes].mother1() : -1;
3840 0 : int iIn2 = (iRes >= 0) ? event[iRes].mother2() : -1;
3841 0 : if (iIn1 >=0) idIn1 = event[iIn1].id();
3842 0 : if (iIn2 >=0) idIn2 = event[iIn1].id();
3843 :
3844 : // In processes f + g/gamma -> f + Z only need find one fermion.
3845 0 : if (idIn1 == 21 || idIn1 == 22) idIn1 = -idIn2;
3846 0 : if (idIn2 == 21 || idIn2 == 22) idIn2 = -idIn1;
3847 :
3848 : // Initial flavours and couplings; return if don't make sense.
3849 0 : if (idIn1 + idIn2 != 0 ) return 0.5;
3850 0 : int idInAbs = abs(idIn1);
3851 0 : if (idInAbs == 0 || idInAbs > 18 ) return 0.5;
3852 0 : double ei = coupSMPtr->ef(idInAbs);
3853 0 : double vi = coupSMPtr->vf(idInAbs);
3854 0 : double ai = coupSMPtr->af(idInAbs);
3855 :
3856 : // Final flavours and couplings; return if don't make sense.
3857 0 : if (event[iDau1].id() + event[iDau2].id() != 0) return 0.5;
3858 0 : int idOutAbs = abs(event[iDau1].id());
3859 0 : if (idOutAbs == 0 || idOutAbs >18 ) return 0.5;
3860 0 : double ef = coupSMPtr->ef(idOutAbs);
3861 0 : double vf = coupSMPtr->vf(idOutAbs);
3862 0 : double af = coupSMPtr->af(idOutAbs);
3863 :
3864 : // Calculate prefactors for interference and resonance part.
3865 0 : Vec4 psum = event[iDau1].p() + event[iDau2].p();
3866 0 : double sH = psum.m2Calc();
3867 0 : double intNorm = 2. * thetaWRat * sH * (sH - mZ*mZ)
3868 0 : / ( pow2(sH - mZ*mZ) + pow2(sH * gammaZ / mZ) );
3869 0 : double resNorm = pow2(thetaWRat * sH)
3870 0 : / ( pow2(sH - mZ*mZ) + pow2(sH * gammaZ / mZ) );
3871 :
3872 : // Calculate vector and axial expressions and find mix.
3873 0 : double vect = ei*ei * ef*ef + ei*vi * intNorm * ef*vf
3874 0 : + (vi*vi + ai*ai) * resNorm * vf*vf;
3875 0 : double axiv = (vi*vi + ai*ai) * resNorm * af*af;
3876 0 : return vect / (vect + axiv);
3877 0 : }
3878 :
3879 : //--------------------------------------------------------------------------
3880 :
3881 : // Set up to calculate QCD ME correction with calcMEcorr.
3882 : // Normally for primary particles, but also from g/gamma -> f fbar.
3883 :
3884 : double TimeShower::findMEcorr(TimeDipoleEnd* dip, Particle& rad,
3885 : Particle& partner, Particle& emt, bool cutEdge) {
3886 :
3887 : // Initial values and matrix element kind.
3888 : double wtME = 1.;
3889 : double wtPS = 1.;
3890 0 : int MEkind = dip->MEtype / 5;
3891 0 : int MEcombi = dip->MEtype % 5;
3892 :
3893 : // Construct ME variables.
3894 0 : Vec4 sum = rad.p() + partner.p() + emt.p();
3895 0 : double eCMME = sum.mCalc();
3896 0 : double x1 = 2. * (sum * rad.p()) / pow2(eCMME);
3897 0 : double x2 = 2. * (sum * partner.p()) / pow2(eCMME);
3898 0 : double r1 = rad.m() / eCMME;
3899 0 : double r2 = partner.m() / eCMME;
3900 : double r3 = 0.;
3901 :
3902 : // Evaluate kinematics for Hidden Valley with massive gamma_v.
3903 : double gammavCorr = 1.;
3904 0 : if (dip->colvType != 0 && brokenHVsym) {
3905 0 : r3 = emt.m() / eCMME;
3906 0 : double x3Tmp = 2. - x1 - x2;
3907 0 : gammavCorr = x3Tmp / (x3Tmp - kRad * (x1 + x3Tmp));
3908 : // For Q_v Qbar_v pair correct kinematics to common average mass.
3909 0 : if (MEkind == 31) {
3910 0 : double m2Pair = (rad.p() + partner.p()).m2Calc();
3911 0 : double m2Avg = 0.5 * (rad.m2() + partner.m2())
3912 0 : - 0.25 * pow2(rad.m2() - partner.m2()) / m2Pair;
3913 0 : r1 = sqrt(m2Avg) / eCMME;
3914 : r2 = r1;
3915 0 : double xShift = 0.5 * (x1 + x2) * (partner.m2() - rad.m2()) / m2Pair;
3916 0 : x1 += xShift;
3917 0 : x2 -= xShift;
3918 0 : }
3919 0 : }
3920 :
3921 : // Derived ME variables, suitably protected.
3922 : double x1minus, x2minus, x3;
3923 0 : if (cutEdge) {
3924 0 : x1minus = max(XMARGIN, 1. + r1*r1 - r2*r2 - x1);
3925 0 : x2minus = max(XMARGIN, 1. + r2*r2 - r1*r1 - x2) ;
3926 0 : x3 = max(XMARGIN, 2. - x1 - x2);
3927 0 : } else {
3928 0 : x1minus = max(XMARGIN*XMARGIN, 1. + r1*r1 - r2*r2 - x1);
3929 0 : x2minus = max(XMARGIN*XMARGIN, 1. + r2*r2 - r1*r1 - x2) ;
3930 0 : x3 = max(XMARGIN*XMARGIN, 2. - x1 - x2);
3931 : }
3932 :
3933 : // Begin processing of QCD dipoles.
3934 0 : if (dip->colType !=0 || dip->colvType != 0) {
3935 :
3936 : // Evaluate normal ME, for proper order of particles.
3937 0 : if (dip->MEorder) wtME = calcMEcorr(MEkind, MEcombi, dip->MEmix,
3938 : x1, x2, r1, r2, r3, cutEdge);
3939 0 : else wtME = calcMEcorr(MEkind, MEcombi, dip->MEmix,
3940 : x2, x1, r2, r1, r3, cutEdge);
3941 :
3942 : // Split up total ME when two radiating particles.
3943 0 : if (dip->MEsplit) wtME = wtME * x1minus / x3;
3944 :
3945 : // Evaluate shower rate to be compared with.
3946 0 : wtPS = 2. / ( x3 * x2minus );
3947 0 : if (dip->MEgluinoRec) wtPS *= 9./4.;
3948 0 : if (dip->colvType != 0 && brokenHVsym) wtPS *= gammavCorr;
3949 :
3950 : // For generic charge combination currently only massless expression.
3951 : // (Masses included only to respect phase space boundaries.)
3952 0 : } else if (dip->chgType !=0 && dip->MEtype == 101) {
3953 0 : double chg1 = particleDataPtr->charge(rad.id());
3954 0 : double chg2 = particleDataPtr->charge(partner.id());
3955 0 : wtME = (x1*x1 + x2*x2) * pow2( chg1 * x1minus / x3
3956 0 : - chg2 * x2minus / x3 );
3957 0 : wtPS = 2. * ( chg1*chg1 * x1minus / x3 + chg2*chg2 * x2minus / x3 );
3958 :
3959 : // For flavour neutral system assume vector source and include masses.
3960 0 : } else if (dip->chgType !=0 && dip->MEtype == 102) {
3961 0 : wtME = calcMEcorr(2, 1, dip->MEmix, x1, x2, r1, r2, 0., cutEdge)
3962 0 : * x1minus / x3;
3963 0 : wtPS = 2. / ( x3 * x2minus );
3964 0 : }
3965 :
3966 : // Weak W and Z emissions, currently using same matrix element.
3967 : // The s-channel corrections are handled with simple MEs.
3968 0 : else if (dip->MEtype == 200 || dip->MEtype == 205) {
3969 0 : r3 = emt.m() / eCMME;
3970 0 : wtME = calcMEcorr(32, 1, dip->MEmix, x1, x2, r1, r2, r3, cutEdge)
3971 0 : * x1minus / x3;
3972 0 : wtPS = 8. / (x3 * x2minus);
3973 0 : wtPS *= x3 / (x3 - kRad * (x1 + x3));
3974 0 : }
3975 : // The t-channel corrections are handled separately in findMEweak.
3976 0 : else if (dip->MEtype == 201 || dip->MEtype == 202
3977 0 : || dip->MEtype == 203 || dip->MEtype == 205
3978 0 : || dip->MEtype == 206 || dip->MEtype == 207) return 1.;
3979 :
3980 : // Return ratio of actual ME to assumed PS rate of emission.
3981 0 : if (wtME > wtPS) infoPtr->errorMsg("Warning in TimeShower::findMEcorr: "
3982 : "ME weight above PS one");
3983 0 : return wtME / wtPS;
3984 :
3985 0 : }
3986 :
3987 : //--------------------------------------------------------------------------
3988 :
3989 : // Matrix elements for gluon (or photon) emission from
3990 : // a two-body state; to be used by the parton shower routine.
3991 : // Here x_i = 2 E_i/E_cm, r_i = m_i/E_cm and
3992 : // 1/sigma_0 d(sigma)/d(x_1)d(x_2) = (alpha-strong/2 pi) * C_F * (this),
3993 : // i.e. normalization is such that one recovers the familiar
3994 : // (x_1^2 + x_2^2)/((1-x_1)*(1-x_2)) for the massless case.
3995 : // Coupling structure:
3996 : // kind = 1 : eikonal soft-gluon expression (spin-independent)
3997 : // = 2 : V -> q qbar (V = vector/axial vector colour singlet)
3998 : // = 3 : q -> q V
3999 : // = 4 : S -> q qbar (S = scalar/pseudoscalar colour singlet)
4000 : // = 5 : q -> q S
4001 : // = 6 : V -> ~q ~qbar (~q = squark)
4002 : // = 7 : ~q -> ~q V
4003 : // = 8 : S -> ~q ~qbar
4004 : // = 9 : ~q -> ~q S
4005 : // = 10 : chi -> q ~qbar (chi = neutralino/chargino)
4006 : // = 11 : ~q -> q chi
4007 : // = 12 : q -> ~q chi
4008 : // = 13 : ~g -> q ~qbar
4009 : // = 14 : ~q -> q ~g
4010 : // = 15 : q -> ~q ~g
4011 : // = 16 : (9/4)*(eikonal) for gg -> ~g ~g
4012 : // = 30 : Dv -> d qv (Dv= hidden valley fermion, qv= valley scalar)
4013 : // = 31 : S -> Dv Dvbar (S=scalar color singlet)
4014 : // Note that the order of the decay products is important.
4015 : // combi = 1 : pure non-gamma5, i.e. vector/scalar/...
4016 : // = 2 : pure gamma5, i.e. axial vector/pseudoscalar/....
4017 : // = 3 : mixture mix*(combi=1) + (1-mix)*(combi=2)
4018 : // = 4 : mixture (combi=1) +- (combi=2)
4019 :
4020 : double TimeShower::calcMEcorr( int kind, int combiIn, double mixIn,
4021 : double x1, double x2, double r1, double r2, double r3, bool cutEdge) {
4022 :
4023 : // Frequent variable combinations.
4024 0 : double x3 = 2. - x1 - x2;
4025 0 : double x1s = x1 * x1;
4026 0 : double x2s = x2 * x2;
4027 0 : double x3s = x3 * x3;
4028 0 : double x1c = x1 * x1s;
4029 0 : double x2c = x2 * x2s;
4030 0 : double x3c = x3 * x3s;
4031 0 : double r1s = r1 * r1;
4032 0 : double r2s = r2 * r2;
4033 0 : double r1c = r1 * r1s;
4034 0 : double r2c = r2 * r2s;
4035 0 : double r1q = r1s * r1s;
4036 0 : double r2q = r2s * r2s;
4037 0 : double prop1 = 1. + r1s - r2s - x1;
4038 0 : double prop2 = 1. + r2s - r1s - x2;
4039 0 : double prop1s = prop1 * prop1;
4040 0 : double prop2s = prop2 * prop2;
4041 0 : double prop12 = prop1 * prop2;
4042 0 : double prop13 = prop1 * x3;
4043 0 : double prop23 = prop2 * x3;
4044 :
4045 : // Special case: Hidden-Valley massive photon.
4046 0 : double r3s = r3 * r3;
4047 0 : double prop3 = r3s - x3;
4048 0 : double prop3s = prop3 * prop3;
4049 0 : if (kind == 30) prop13 = prop1 * prop3;
4050 :
4051 : // Check input values. Return zero outside allowed phase space.
4052 0 : if (cutEdge) {
4053 0 : if (x1 - 2.*r1 < XMARGIN || prop1 < XMARGIN) return 0.;
4054 0 : if (x2 - 2.*r2 < XMARGIN || prop2 < XMARGIN) return 0.;
4055 : // Limits not worked out for r3 > 0.
4056 0 : if (kind != 30 && kind != 31) {
4057 0 : if (x1 + x2 - 1. - pow2(r1+r2) < XMARGIN) return 0.;
4058 : // Note: equivalent rewritten form 4. * ( (1. - x1) * (1. - x2)
4059 : // * (1. - r1s - r2s - x3) + r1s * (1. - x2s - x3) + r2s
4060 : // * (1. - x1s - x3) - pow2(r1s - r2s) ) gives about same result.
4061 0 : if ( (x1s - 4.*r1s) * (x2s - 4.*r2s)
4062 0 : - pow2( 2. * (1. - x1 - x2 + r1s + r2s) + x1*x2 )
4063 0 : < XMARGIN * (XMARGINCOMB + r1 + r2) ) return 0.;
4064 : }
4065 : }
4066 :
4067 : // Initial values; phase space.
4068 0 : int combi = max(1, min(4, combiIn) );
4069 0 : double mix = max(0., min(1., mixIn) );
4070 : bool isSet1 = false;
4071 : bool isSet2 = false;
4072 : bool isSet4 = false;
4073 0 : double ps = sqrtpos( pow2(1. - r1*r1 - r2*r2) - pow2(2. * r1 * r2) );
4074 : double rLO = 0., rFO = 0., rLO1 = 0., rFO1 = 0., rLO2 = 0.,
4075 : rFO2 = 0., rLO4 = 0., rFO4 = 0.;
4076 : double offset = 0;
4077 :
4078 : // Select which kind of ME to use.
4079 0 : switch (kind) {
4080 :
4081 : // case 1 is equal to default, i.e. eikonal expression.
4082 :
4083 : // V -> q qbar (V = gamma*/Z0/W+-/...).
4084 : case 2:
4085 0 : if (combi == 1 || combi == 3) {
4086 0 : rLO1 = ps*(2.-r1s-r1q+6.*r1*r2-r2s+2.*r1s*r2s-r2q)/2.;
4087 0 : rFO1 = -(3.+6.*r1s+r1q-6.*r1*r2+6.*r1c*r2-2.*r2s-6.*r1s*r2s
4088 0 : +6.*r1*r2c+r2q-3.*x1+6.*r1*r2*x1+2.*r2s*x1+x1s-2.*r1s*x1s
4089 0 : +3.*r1s*x3+6.*r1*r2*x3-r2s*x3-2.*x1*x3-5.*r1s*x1*x3
4090 0 : +r2s*x1*x3+x1s*x3-3.*x3s-3.*r1s*x3s+r2s*x3s
4091 0 : +2.*x1*x3s+x3c-x2)
4092 0 : /prop2s
4093 0 : -2.*(-3.+r1s-6.*r1*r2+6.*r1c*r2+3.*r2s-4.*r1s*r2s
4094 0 : +6.*r1*r2c+2.*x1+3.*r1s*x1+r2s*x1-x1s-r1s*x1s
4095 0 : -r2s*x1s+4.*x3+2.*r1s*x3+3.*r1*r2*x3-r2s*x3-3.*x1*x3
4096 0 : -2.*r1s*x1*x3+x1s*x3-x3s-r1s*x3s+r1*r2*x3s+x1*x3s)
4097 0 : /prop12
4098 0 : -(-1.+2.*r1s+r1q+6.*r1*r2+6.*r1c*r2-2.*r2s-6.*r1s*r2s
4099 0 : +6.*r1*r2c+r2q-x1-2.*r1s*x1-6.*r1*r2*x1+8.*r2s*x1+x1s
4100 0 : -2.*r2s*x1s-r1s*x3+r2s*x3-r1s*x1*x3+r2s*x1*x3+x1s*x3+x2)
4101 0 : /prop1s;
4102 0 : rFO1 = rFO1/2.;
4103 : isSet1 = true;
4104 0 : }
4105 0 : if (combi == 2 || combi == 3) {
4106 0 : rLO2 = ps*(2.-r1s-r1q-6.*r1*r2-r2s+2.*r1s*r2s-r2q)/2.;
4107 0 : rFO2 = -(3.+6.*r1s+r1q+6.*r1*r2-6.*r1c*r2-2.*r2s-6.*r1s*r2s
4108 0 : -6.*r1*r2c+r2q-3.*x1-6.*r1*r2*x1+2.*r2s*x1+x1s-2.*r1s*x1s
4109 0 : +3.*r1s*x3-6.*r1*r2*x3-r2s*x3-2.*x1*x3-5.*r1s*x1*x3
4110 0 : +r2s*x1*x3+x1s*x3-3.*x3s-3.*r1s*x3s+r2s*x3s+2.*x1*x3s+x3c-x2)
4111 0 : /prop2s
4112 0 : -2.*(-3+r1s+6.*r1*r2-6.*r1c*r2+3.*r2s-4.*r1s*r2s-6.*r1*r2c
4113 0 : +2.*x1+3.*r1s*x1+r2s*x1-x1s-r1s*x1s-r2s*x1s+4.*x3+2.*r1s*x3
4114 0 : -3.*r1*r2*x3-r2s*x3-3.*x1*x3-2.*r1s*x1*x3+x1s*x3-x3s-r1s*x3s
4115 0 : -r1*r2*x3s+x1*x3s)
4116 0 : /prop12
4117 0 : -(-1.+2.*r1s+r1q-6.*r1*r2-6.*r1c*r2-2.*r2s-6.*r1s*r2s
4118 0 : -6.*r1*r2c+r2q-x1-2.*r1s*x1+6.*r1*r2*x1+8.*r2s*x1+x1s
4119 0 : -2.*r2s*x1s-r1s*x3+r2s*x3-r1s*x1*x3+r2s*x1*x3+x1s*x3+x2)
4120 0 : /prop1s;
4121 0 : rFO2 = rFO2/2.;
4122 : isSet2 = true;
4123 0 : }
4124 0 : if (combi == 4) {
4125 0 : rLO4 = ps*(2.-r1s-r1q-r2s+2.*r1s*r2s-r2q)/2.;
4126 0 : rFO4 = (1.-r1q+6.*r1s*r2s-r2q+x1+3.*r1s*x1-9.*r2s*x1-3.*x1s
4127 0 : -r1s*x1s+3.*r2s*x1s+x1c-x2-r1s*x2+r2s*x2-r1s*x1*x2+r2s*x1*x2
4128 0 : +x1s*x2)
4129 0 : /prop1s
4130 0 : -2.*(1.+r1s+r2s-4.*r1s*r2s+r1s*x1+2.*r2s*x1-x1s-r2s*x1s
4131 0 : +2.*r1s*x2+r2s*x2-3.*x1*x2+x1s*x2-x2s-r1s*x2s+x1*x2s)
4132 0 : /prop12
4133 0 : +(1.-r1q+6.*r1s*r2s-r2q-x1+r1s*x1-r2s*x1+x2-9.*r1s*x2
4134 0 : +3.*r2s*x2+r1s*x1*x2-r2s*x1*x2-3.*x2s+3.*r1s*x2s-r2s*x2s
4135 0 : +x1*x2s+x2c)
4136 0 : /prop2s;
4137 0 : rFO4 = rFO4/2.;
4138 : isSet4 = true;
4139 0 : }
4140 : break;
4141 :
4142 : // q -> q V.
4143 : case 3:
4144 0 : if (combi == 1 || combi == 3) {
4145 0 : rLO1 = ps*(1.-2.*r1s+r1q+r2s-6.*r1*r2s+r1s*r2s-2.*r2q);
4146 0 : rFO1 = -2.*(-1.+r1-2.*r1s+2.*r1c-r1q+pow5(r1)-r2s+r1*r2s
4147 0 : -5.*r1s*r2s+r1c*r2s-2.*r1*r2q+2.*x1-2.*r1*x1+2.*r1s*x1
4148 0 : -2.*r1c*x1+2.*r2s*x1+5.*r1*r2s*x1+r1s*r2s*x1+2.*r2q*x1
4149 0 : -x1s+r1*x1s-r2s*x1s+3.*x2+4.*r1s*x2+r1q*x2+2.*r2s*x2
4150 0 : +2.*r1s*r2s*x2-4.*x1*x2-2.*r1s*x1*x2-r2s*x1*x2+x1s*x2
4151 0 : -2.*x2s-2.*r1s*x2s+x1*x2s)
4152 0 : /prop23
4153 0 : +(2.*r2s+6.*r1*r2s-6.*r1s*r2s+6.*r1c*r2s+2.*r2q+6.*r1*r2q
4154 0 : -r2s*x1+r1s*r2s*x1-r2q*x1+x2-r1q*x2-3.*r2s*x2-6.*r1*r2s*x2
4155 0 : +9.*r1s*r2s*x2-2.*r2q*x2-x1*x2+r1s*x1*x2-x2s-3.*r1s*x2s
4156 0 : +2.*r2s*x2s+x1*x2s)
4157 0 : /prop2s
4158 0 : +(-4.-8.*r1s-4.*r1q+4.*r2s-4.*r1s*r2s+8.*r2q+9.*x1+10.*r1s*x1
4159 0 : +r1q*x1-3.*r2s*x1+6.*r1*r2s*x1+r1s*r2s*x1-2.*r2q*x1-6.*x1s-
4160 0 : 2.*r1s*x1s+x1c+7.*x2+8.*r1s*x2+r1q*x2-7.*r2s*x2+6.*r1*r2s*x2
4161 0 : +r1s*r2s*x2-2.*r2q*x2-9.*x1*x2-3.*r1s*x1*x2+2.*r2s*x1*x2
4162 0 : +2.*x1s*x2-3.*x2s-r1s*x2s+2.*r2s*x2s+x1*x2s)
4163 0 : /x3s;
4164 : isSet1 = true;
4165 0 : }
4166 0 : if (combi == 2 || combi == 3) {
4167 0 : rLO2 = ps*(1.-2.*r1s+r1q+r2s+6.*r1*r2s+r1s*r2s-2.*r2q);
4168 0 : rFO2 = 2*(1.+r1+2.*r1s+2.*r1c+r1q+pow5(r1)+r2s+r1*r2s
4169 0 : +5.*r1s*r2s+r1c*r2s-2.*r1*r2q-2.*x1-2.*r1*x1-2.*r1s*x1
4170 0 : -2.*r1c*x1-2.*r2s*x1+5.*r1*r2s*x1-r1s*r2s*x1-2.*r2q*x1+x1s
4171 0 : +r1*x1s+r2s*x1s-3.*x2-4.*r1s*x2-r1q*x2-2.*r2s*x2
4172 0 : -2.*r1s*r2s*x2+4.*x1*x2+2.*r1s*x1*x2+r2s*x1*x2-x1s*x2
4173 0 : +2.*x2s+2.*r1s*x2s-x1*x2s)
4174 0 : /prop23
4175 0 : +(2.*r2s-6.*r1*r2s-6.*r1s*r2s-6.*r1c*r2s+2.*r2q-6.*r1*r2q
4176 0 : -r2s*x1+r1s*r2s*x1-r2q*x1+x2-r1q*x2-3.*r2s*x2+6.*r1*r2s*x2
4177 0 : +9.*r1s*r2s*x2-2.*r2q*x2-x1*x2+r1s*x1*x2-x2s-3.*r1s*x2s
4178 0 : +2.*r2s*x2s+x1*x2s)
4179 0 : /prop2s
4180 0 : +(-4.-8.*r1s-4.*r1q+4.*r2s-4.*r1s*r2s+8.*r2q+9.*x1+10.*r1s*x1
4181 0 : +r1q*x1-3.*r2s*x1-6.*r1*r2s*x1+r1s*r2s*x1-2.*r2q*x1-6.*x1s
4182 0 : -2.*r1s*x1s+x1c+7.*x2+8.*r1s*x2+r1q*x2-7.*r2s*x2-6.*r1*r2s*x2
4183 0 : +r1s*r2s*x2-2.*r2q*x2-9.*x1*x2-3.*r1s*x1*x2+2.*r2s*x1*x2
4184 0 : +2.*x1s*x2-3.*x2s-r1s*x2s+2.*r2s*x2s+x1*x2s)
4185 0 : /x3s;
4186 : isSet2 = true;
4187 0 : }
4188 0 : if (combi == 4) {
4189 0 : rLO4 = ps*(1.-2.*r1s+r1q+r2s+r1s*r2s-2.*r2q);
4190 0 : rFO4 = 2*(1.+2.*r1s+r1q+r2s+5.*r1s*r2s-2.*x1-2.*r1s*x1
4191 0 : -2.*r2s*x1-r1s*r2s*x1-2.*r2q*x1+x1s+r2s*x1s-3.*x2-4.*r1s*x2
4192 0 : -r1q*x2-2.*r2s*x2-2.*r1s*r2s*x2+4.*x1*x2+2.*r1s*x1*x2+r2s*x1*x2
4193 0 : -x1s*x2+2.*x2s+2.*r1s*x2s-x1*x2s)
4194 0 : /prop23
4195 0 : +(2.*r2s-6.*r1s*r2s+2.*r2q-r2s*x1+r1s*r2s*x1-r2q*x1+x2-r1q*x2
4196 0 : -3.*r2s*x2+9.*r1s*r2s*x2-2.*r2q*x2-x1*x2+r1s*x1*x2-x2s-3.*r1s*x2s
4197 0 : +2.*r2s*x2s+x1*x2s)
4198 0 : /prop2s
4199 0 : +(-4.-8.*r1s-4.*r1q+4.*r2s-4.*r1s*r2s+8.*r2q+9.*x1+10.*r1s*x1
4200 0 : +r1q*x1-3.*r2s*x1+r1s*r2s*x1-2.*r2q*x1-6.*x1s-2.*r1s*x1s+x1c
4201 0 : +7.*x2+8.*r1s*x2+r1q*x2-7.*r2s*x2+r1s*r2s*x2-2.*r2q*x2-9.*x1*x2
4202 0 : -3.*r1s*x1*x2+2.*r2s*x1*x2+2.*x1s*x2-3.*x2s-r1s*x2s+2.*r2s*x2s
4203 0 : +x1*x2s)
4204 0 : /x3s;
4205 : isSet4 = true;
4206 0 : }
4207 : break;
4208 :
4209 : // S -> q qbar (S = h0/H0/A0/H+-/...).
4210 : case 4:
4211 0 : if (combi == 1 || combi == 3) {
4212 0 : rLO1 = ps*(1.-r1s-r2s-2.*r1*r2);
4213 0 : rFO1 = -(-1.+r1q-2.*r1*r2-2.*r1c*r2-6.*r1s*r2s-2.*r1*r2c+r2q+x1
4214 0 : -r1s*x1+2.*r1*r2*x1+3.*r2s*x1+x2+r1s*x2-r2s*x2-x1*x2)
4215 0 : /prop1s
4216 0 : -2.*(r1s+r1q-2.*r1c*r2+r2s-6.*r1s*r2s-2.*r1*r2c+r2q-r1s*x1
4217 0 : +r1*r2*x1+2.*r2s*x1+2.*r1s*x2+r1*r2*x2-r2s*x2-x1*x2)
4218 0 : /prop12
4219 0 : -(-1.+r1q-2.*r1*r2-2.*r1c*r2-6.*r1s*r2s-2.*r1*r2c+r2q+x1-r1s*x1
4220 0 : +r2s*x1+x2+3.*r1s*x2+2.*r1*r2*x2-r2s*x2-x1*x2)
4221 0 : /prop2s;
4222 : isSet1 = true;
4223 0 : }
4224 0 : if (combi == 2 || combi == 3) {
4225 0 : rLO2 = ps*(1.-r1s-r2s+2.*r1*r2);
4226 0 : rFO2 = -(-1.+r1q+2.*r1*r2+2.*r1c*r2-6.*r1s*r2s+2.*r1*r2c+r2q+x1
4227 0 : -r1s*x1-2.*r1*r2*x1+3.*r2s*x1+x2+r1s*x2-r2s*x2-x1*x2)
4228 0 : /prop1s
4229 0 : -(-1.+r1q+2.*r1*r2+2.*r1c*r2-6.*r1s*r2s+2.*r1*r2c+r2q+x1
4230 0 : -r1s*x1+r2s*x1+x2+3.*r1s*x2-2.*r1*r2*x2-r2s*x2-x1*x2)
4231 0 : /prop2s
4232 0 : +2.*(-r1s-r1q-2.*r1c*r2-r2s+6.*r1s*r2s-2.*r1*r2c-r2q+r1s*x1
4233 0 : +r1*r2*x1-2.*r2s*x1-2.*r1s*x2+r1*r2*x2+r2s*x2+x1*x2)
4234 0 : /prop12;
4235 : isSet2 = true;
4236 0 : }
4237 0 : if (combi == 4) {
4238 0 : rLO4 = ps*(1.-r1s-r2s);
4239 0 : rFO4 = -(-1.+r1q-6.*r1s*r2s+r2q+x1-r1s*x1+3.*r2s*x1+x2
4240 0 : +r1s*x2-r2s*x2-x1*x2)
4241 0 : /prop1s
4242 0 : -2.*(r1s+r1q+r2s-6.*r1s*r2s+r2q-r1s*x1
4243 0 : +2.*r2s*x1+2.*r1s*x2-r2s*x2-x1*x2)
4244 0 : /prop12
4245 0 : -(-1.+r1q-6.*r1s*r2s+r2q+x1-r1s*x1+r2s*x1
4246 0 : +x2+3.*r1s*x2-r2s*x2-x1*x2)
4247 0 : /prop2s;
4248 : isSet4 = true;
4249 0 : }
4250 : break;
4251 :
4252 : // q -> q S.
4253 : case 5:
4254 0 : if (combi == 1 || combi == 3) {
4255 0 : rLO1 = ps*(1.+r1s-r2s+2.*r1);
4256 0 : rFO1 = (4.-4.*r1s+4.*r2s-3.*x1-2.*r1*x1+r1s*x1-r2s*x1-5.*x2
4257 0 : -2.*r1*x2+r1s*x2-r2s*x2+x1*x2+x2s)
4258 0 : /x3s
4259 0 : -2.*(3.-r1-5.*r1s-r1c+3.*r2s+r1*r2s-2.*x1-r1*x1
4260 0 : +r1s*x1-4.*x2+2.*r1s*x2-r2s*x2+x1*x2+x2s)
4261 0 : /prop23
4262 0 : +(2.-2.*r1-6.*r1s-2.*r1c+2.*r2s-2.*r1*r2s-x1+r1s*x1
4263 0 : -r2s*x1-3.*x2+2.*r1*x2+3.*r1s*x2-r2s*x2+x1*x2+x2s)
4264 0 : /prop2s;
4265 : isSet1 = true;
4266 0 : }
4267 0 : if (combi == 2 || combi == 3) {
4268 0 : rLO2 = ps*(1.+r1s-r2s-2.*r1);
4269 0 : rFO2 = (4.-4.*r1s+4.*r2s-3.*x1+2.*r1*x1+r1s*x1-r2s*x1-5.*x2
4270 0 : +2.*r1*x2+r1s*x2-r2s*x2+x1*x2+x2s)
4271 0 : /x3s
4272 0 : -2.*(3.+r1-5.*r1s+r1c+3.*r2s-r1*r2s-2.*x1+r1*x1
4273 0 : +r1s*x1-4.*x2+2.*r1s*x2-r2s*x2+x1*x2+x2s)
4274 0 : /prop23
4275 0 : +(2.+2.*r1-6.*r1s+2.*r1c+2.*r2s+2.*r1*r2s-x1+r1s*x1
4276 0 : -r2s*x1-3.*x2-2.*r1*x2+3.*r1s*x2-r2s*x2+x1*x2+x2s)
4277 0 : /prop2s;
4278 : isSet2 = true;
4279 0 : }
4280 0 : if (combi == 4) {
4281 0 : rLO4 = ps*(1.+r1s-r2s);
4282 0 : rFO4 = (4.-4.*r1s+4.*r2s-3.*x1+r1s*x1-r2s*x1-5.*x2+r1s*x2
4283 0 : -r2s*x2+x1*x2+x2s)
4284 0 : /x3s
4285 0 : -2.*(3.-5.*r1s+3.*r2s-2.*x1+r1s*x1-4.*x2+2.*r1s*x2
4286 0 : -r2s*x2+x1*x2+x2s)
4287 0 : /prop23
4288 0 : +(2.-6.*r1s+2.*r2s-x1+r1s*x1-r2s*x1-3.*x2+3.*r1s*x2
4289 0 : -r2s*x2+x1*x2+x2s)
4290 0 : /prop2s;
4291 : isSet4 = true;
4292 0 : }
4293 : break;
4294 :
4295 : // V -> ~q ~qbar (~q = squark).
4296 : case 6:
4297 0 : rLO1 = ps*(1.-2.*r1s+r1q-2.*r2s-2.*r1s*r2s+r2q);
4298 0 : rFO1 = 2.*3.+(1.+r1s+r2s-x1)*(4.*r1s-x1s)
4299 0 : /prop1s
4300 0 : +2.*(-1.-3.*r1s-r2s+x1+x1s*0.5+x2-x1*x2*0.5)
4301 0 : /prop1
4302 0 : +(1.+r1s+r2s-x2)*(4.*r2s-x2s)
4303 0 : /prop2s
4304 0 : +2.*(-1.-r1s-3.*r2s+x1+x2-x1*x2*0.5+x2s*0.5)
4305 0 : /prop2
4306 0 : -(-4.*r1s-4.*r1q-4.*r2s-8.*r1s*r2s-4.*r2q+2.*x1+6.*r1s*x1
4307 0 : +6.*r2s*x1-2.*x1s+2.*x2+6.*r1s*x2+6.*r2s*x2-4.*x1*x2
4308 0 : -2.*r1s*x1*x2-2.*r2s*x1*x2+x1s*x2-2.*x2s+x1*x2s)
4309 0 : /prop12;
4310 : isSet1 = true;
4311 0 : break;
4312 :
4313 : // ~q -> ~q V.
4314 : case 7:
4315 0 : rLO1 = ps*(1.-2.*r1s+r1q-2.*r2s-2.*r1s*r2s+r2q);
4316 0 : rFO1 = 16.*r2s-8.*(4.*r2s+2.*r2s*x1+x2+r1s*x2+r2s*x2-x1*x2
4317 0 : -2.*x2s)
4318 0 : /(3.*prop2)
4319 0 : +8.*(1.+r1s+r2s-x2)*(4.*r2s-x2s)
4320 0 : /(3.*prop2s)
4321 0 : +8.*(x1+x2)*(-1.-2.*r1s-r1q-2.*r2s+2.*r1s*r2s-r2q+2.*x1
4322 0 : +2.*r1s*x1+2.*r2s*x1-x1s+2.*x2+2.*r1s*x2+2.*r2s*x2-2.*x1*x2-x2s)
4323 0 : /(3.*x3s)
4324 0 : +8.*(-1.-r1s+r2s-x1)*(2.*r2s*x1+x2+r1s*x2+r2s*x2-x1*x2-x2s)
4325 0 : /(3.*prop2*x3)
4326 0 : -8.*(1.+2.*r1s+r1q+2.*r2s-2.*r1s*r2s+r2q-2.*x1-2.*r1s*x1
4327 0 : -4.*r2s*x1+x1s-3.*x2-3.*r1s*x2-3.*r2s*x2+3.*x1*x2+2.*x2s)
4328 0 : /(3.*x3);
4329 0 : rFO1 = 3.*rFO1/8.;
4330 : isSet1 = true;
4331 0 : break;
4332 :
4333 : // S -> ~q ~qbar.
4334 : case 8:
4335 : rLO1 = ps;
4336 0 : rFO1 = (-1.-2.*r1s-r1q-2.*r2s+2.*r1s*r2s-r2q+2.*x1+2.*r1s*x1
4337 0 : +2.*r2s*x1-x1s-r2s*x1s+2.*x2+2.*r1s*x2+2.*r2s*x2-3.*x1*x2
4338 0 : -r1s*x1*x2-r2s*x1*x2+x1s*x2-x2s-r1s*x2s+x1*x2s)
4339 0 : /(prop1s*prop2s);
4340 0 : rFO1 = 2.*rFO1;
4341 : isSet1 = true;
4342 0 : break;
4343 :
4344 : // ~q -> ~q S.
4345 : case 9:
4346 : rLO1 = ps;
4347 0 : rFO1 = (-1.-r1s-r2s+x2)
4348 0 : /prop2s
4349 0 : +(1.+r1s-r2s+x1)
4350 0 : /prop23
4351 0 : -(x1+x2)
4352 0 : /x3s;
4353 : isSet1 = true;
4354 0 : break;
4355 :
4356 : // chi -> q ~qbar (chi = neutralino/chargino).
4357 : case 10:
4358 0 : if (combi == 1 || combi == 3) {
4359 0 : rLO1 = ps*(1.+r1s-r2s+2.*r1);
4360 0 : rFO1 = (2.*r1+x1)*(-1.-r1s-r2s+x1)
4361 0 : /prop1s
4362 0 : +2.*(-1.-r1s-2.*r1c-r2s-2.*r1*r2s+3.*x1*0.5+r1*x1
4363 0 : -r1s*x1*0.5-r2s*x1*0.5+x2+r1*x2+r1s*x2-x1*x2*0.5)
4364 0 : /prop12
4365 0 : +(2.-2.*r1-6.*r1s-2.*r1c+2.*r2s-2.*r1*r2s-x1+r1s*x1
4366 0 : -r2s*x1-3.*x2+2.*r1*x2+3.*r1s*x2-r2s*x2+x1*x2+x2s)
4367 0 : /prop2s;
4368 : isSet1 = true;
4369 0 : }
4370 0 : if (combi == 2 || combi == 3) {
4371 0 : rLO2 = ps*(1.-2.*r1+r1s-r2s);
4372 0 : rFO2 = (2.*r1-x1)*(1.+r1s+r2s-x1)
4373 0 : /prop1s
4374 0 : +2.*(-1.-r1s+2.*r1c-r2s+2.*r1*r2s+3.*x1*0.5-r1*x1
4375 0 : -r1s*x1*0.5-r2s*x1*0.5+x2-r1*x2+r1s*x2-x1*x2*0.5)
4376 0 : /prop12
4377 0 : +(2.+2.*r1-6.*r1s+2.*r1c+2.*r2s+2.*r1*r2s-x1+r1s*x1
4378 0 : -r2s*x1-3.*x2-2.*r1*x2+3.*r1s*x2-r2s*x2+x1*x2+x2s)/
4379 : prop2s;
4380 : isSet2 = true;
4381 0 : }
4382 0 : if (combi == 4) {
4383 0 : rLO4 = ps*(1.+r1s-r2s);
4384 0 : rFO4 = x1*(-1.-r1s-r2s+x1)
4385 0 : /prop1s
4386 0 : +2.*(-1.-r1s-r2s+3.*x1*0.5-r1s*x1*0.5-r2s*x1*0.5
4387 0 : +x2+r1s*x2-x1*x2*0.5)
4388 0 : /prop12
4389 0 : +(2.-6.*r1s+2.*r2s-x1+r1s*x1-r2s*x1-3.*x2+3.*r1s*x2
4390 0 : -r2s*x2+x1*x2+x2s)
4391 0 : /prop2s;
4392 : isSet4 = true;
4393 0 : }
4394 : break;
4395 :
4396 : // ~q -> q chi.
4397 : case 11:
4398 0 : if (combi == 1 || combi == 3) {
4399 0 : rLO1 = ps*(1.-pow2(r1+r2));
4400 0 : rFO1 = (1.+r1s+2.*r1*r2+r2s-x1-x2)*(x1+x2)
4401 0 : /x3s
4402 0 : -(-1.+r1q-2.*r1*r2-2.*r1c*r2-6.*r1s*r2s-2.*r1*r2c+r2q+x1
4403 0 : -r1s*x1+r2s*x1+x2+3.*r1s*x2+2.*r1*r2*x2-r2s*x2-x1*x2)
4404 0 : /prop2s
4405 0 : +(-1.-2.*r1s-r1q-2.*r1*r2-2.*r1c*r2+2.*r1*r2c+r2q+x1+r1s*x1
4406 0 : -2.*r1*r2*x1-3.*r2s*x1+2.*r1s*x2-2.*r2s*x2+x1*x2+x2s)
4407 0 : /prop23;
4408 : isSet1 = true;
4409 0 : }
4410 0 : if (combi == 2 || combi == 3) {
4411 0 : rLO2 = ps*(1.-pow2(r1-r2));
4412 0 : rFO2 = (1.+r1s-2.*r1*r2+r2s-x1-x2)*(x1+x2)
4413 0 : /x3s
4414 0 : -(-1.+r1q+2.*r1*r2+2.*r1c*r2-6.*r1s*r2s+2.*r1*r2c+r2q+x1
4415 0 : -r1s*x1+r2s*x1+x2+3.*r1s*x2-2.*r1*r2*x2-r2s*x2-x1*x2)
4416 0 : /prop2s
4417 0 : +(-1.-2.*r1s-r1q+2.*r1*r2+2.*r1c*r2-2.*r1*r2c+r2q+x1+r1s*x1
4418 0 : +2.*r1*r2*x1-3.*r2s*x1+2.*r1s*x2-2.*r2s*x2+x1*x2+x2s)
4419 0 : /prop23;
4420 : isSet2 = true;
4421 0 : }
4422 0 : if (combi == 4) {
4423 0 : rLO4 = ps*(1.-r1s-r2s);
4424 0 : rFO4 = (1.+r1s+r2s-x1-x2)*(x1+x2)
4425 0 : /x3s
4426 0 : -(-1.+r1q-6.*r1s*r2s+r2q+x1-r1s*x1+r2s*x1+x2
4427 0 : +3.*r1s*x2-r2s*x2-x1*x2)
4428 0 : /prop2s
4429 0 : +(-1.-2.*r1s-r1q+r2q+x1+r1s*x1-3.*r2s*x1
4430 0 : +2.*r1s*x2-2.*r2s*x2+x1*x2+x2s)
4431 0 : /prop23;
4432 : isSet4 = true;
4433 0 : }
4434 : break;
4435 :
4436 : // q -> ~q chi.
4437 : case 12:
4438 0 : if (combi == 1 || combi == 3) {
4439 0 : rLO1 = ps*(1.-r1s+r2s+2.*r2);
4440 0 : rFO1 = (2.*r2+x2)*(-1.-r1s-r2s+x2)
4441 0 : /prop2s
4442 0 : +(4.+4.*r1s-4.*r2s-5.*x1-r1s*x1-2.*r2*x1+r2s*x1+x1s
4443 0 : -3.*x2-r1s*x2-2.*r2*x2+r2s*x2+x1*x2)
4444 0 : /x3s
4445 0 : +2.*(-1.-r1s+r2+r1s*r2-r2s-r2c+x1+r2*x1+r2s*x1+2.*x2
4446 0 : +r1s*x2-x1*x2*0.5-x2s*0.5)
4447 0 : /prop23;
4448 : isSet1 = true;
4449 0 : }
4450 0 : if (combi == 2 || combi == 3) {
4451 0 : rLO2 = ps*(1.-r1s+r2s-2.*r2);
4452 0 : rFO2 = (2.*r2-x2)*(1.+r1s+r2s-x2)
4453 0 : /prop2s
4454 0 : +(4.+4.*r1s-4.*r2s-5.*x1-r1s*x1+2.*r2*x1+r2s*x1+x1s
4455 0 : -3.*x2-r1s*x2+2.*r2*x2+r2s*x2+x1*x2)
4456 0 : /x3s
4457 0 : +2.*(-1.-r1s-r2-r1s*r2-r2s+r2c+x1-r2*x1+r2s*x1+2.*x2
4458 0 : +r1s*x2-x1*x2*0.5-x2s*0.5)
4459 0 : /prop23;
4460 : isSet2 = true;
4461 0 : }
4462 0 : if (combi == 4) {
4463 0 : rLO4 = ps*(1.-r1s+r2s);
4464 0 : rFO4 = x2*(-1.-r1s-r2s+x2)
4465 0 : /prop2s
4466 0 : +(4.+4.*r1s-4.*r2s-5.*x1-r1s*x1+r2s*x1+x1s
4467 0 : -3.*x2-r1s*x2+r2s*x2+x1*x2)
4468 0 : /x3s
4469 0 : +2.*(-1.-r1s-r2s+x1+r2s*x1+2.*x2
4470 0 : +r1s*x2-x1*x2*0.5-x2s*0.5)
4471 0 : /prop23;
4472 : isSet4 = true;
4473 0 : }
4474 : break;
4475 :
4476 : // ~g -> q ~qbar.
4477 : case 13:
4478 0 : if (combi == 1 || combi == 3) {
4479 0 : rLO1 = ps*(1.+r1s-r2s+2.*r1);
4480 0 : rFO1 = 4.*(2.*r1+x1)*(-1.-r1s-r2s+x1)
4481 0 : /(3.*prop1s)
4482 0 : -(-1.-r1s-2.*r1c-r2s-2.*r1*r2s+3.*x1*0.5+r1*x1-r1s*x1*0.5
4483 0 : -r2s*x1*0.5+x2+r1*x2+r1s*x2-x1*x2*0.5)
4484 0 : /(3.*prop12)
4485 0 : +3.*(-1.+r1-r1s-r1c-r2s+r1*r2s+2.*x1+r2s*x1-x1s*0.5+x2+r1*x2
4486 0 : +r1s*x2-x1*x2*0.5)
4487 0 : /prop13
4488 0 : +3.*(4.-4.*r1s+4.*r2s-3.*x1-2.*r1*x1+r1s*x1-r2s*x1-5.*x2
4489 0 : -2.*r1*x2+r1s*x2-r2s*x2+x1*x2+x2s)
4490 0 : /x3s
4491 0 : -3.*(3.-r1-5.*r1s-r1c+3.*r2s+r1*r2s-2.*x1-r1*x1+r1s*x1
4492 0 : -4.*x2+2.*r1s*x2-r2s*x2+x1*x2+x2s)
4493 0 : /prop23
4494 0 : +4.*(2.-2.*r1-6.*r1s-2.*r1c+2.*r2s-2.*r1*r2s-x1+r1s*x1-r2s*x1
4495 0 : -3.*x2+2.*r1*x2+3.*r1s*x2-r2s*x2+x1*x2+x2s)
4496 0 : /(3.*prop2s);
4497 0 : rFO1 = 3.*rFO1/4.;
4498 : isSet1 = true;
4499 0 : }
4500 0 : if (combi == 2 || combi == 3) {
4501 0 : rLO2 = ps*(1.+r1s-r2s-2.*r1);
4502 0 : rFO2 = 4.*(2.*r1-x1)*(1.+r1s+r2s-x1)
4503 0 : /(3.*prop1s)
4504 0 : +3.*(-1.-r1-r1s+r1c-r2s-r1*r2s+2.*x1+r2s*x1-x1s*0.5
4505 0 : +x2-r1*x2+r1s*x2-x1*x2*0.5)
4506 0 : /prop13
4507 0 : +(2.+2.*r1s-4.*r1c+2.*r2s-4.*r1*r2s-3.*x1+2.*r1*x1
4508 0 : +r1s*x1+r2s*x1-2.*x2+2.*r1*x2-2.*r1s*x2+x1*x2)
4509 0 : /(6.*prop12)
4510 0 : +3.*(4.-4.*r1s+4.*r2s-3.*x1+2.*r1*x1+r1s*x1-r2s*x1-5.*x2
4511 0 : +2.*r1*x2+r1s*x2-r2s*x2+x1*x2+x2s)
4512 0 : /x3s
4513 0 : -3.*(3.+r1-5.*r1s+r1c+3.*r2s-r1*r2s-2.*x1+r1*x1+r1s*x1-4.*x2
4514 0 : +2.*r1s*x2-r2s*x2+x1*x2+x2s)
4515 0 : /prop23
4516 0 : +4.*(2.+2.*r1-6.*r1s+2.*r1c+2.*r2s+2.*r1*r2s-x1+r1s*x1-r2s*x1
4517 0 : -3.*x2-2.*r1*x2+3.*r1s*x2-r2s*x2+x1*x2+x2s)
4518 0 : /(3.*prop2s);
4519 0 : rFO2 = 3.*rFO2/4.;
4520 : isSet2 = true;
4521 0 : }
4522 0 : if (combi == 4) {
4523 0 : rLO4 = ps*(1.+r1s-r2s);
4524 0 : rFO4 = 8.*x1*(-1.-r1s-r2s+x1)
4525 0 : /(3.*prop1s)
4526 0 : +6.*(-1-r1s-r2s+2.*x1+r2s*x1-x1s*0.5+x2+r1s*x2-x1*x2*0.5)
4527 0 : /prop13
4528 0 : +(2.+2.*r1s+2.*r2s-3.*x1+r1s*x1+r2s*x1-2.*x2-2.*r1s*x2+x1*x2)
4529 0 : /(3.*prop12)
4530 0 : +6.*(4.-4.*r1s+4.*r2s-3.*x1+r1s*x1-r2s*x1-5.*x2+r1s*x2-r2s*x2
4531 0 : +x1*x2+x2s)
4532 0 : /x3s
4533 0 : -6.*(3.-5.*r1s+3.*r2s-2.*x1+r1s*x1-4.*x2+2.*r1s*x2-r2s*x2+x1*x2+x2s)
4534 0 : /prop23
4535 0 : +8.*(2.-6.*r1s+2.*r2s-x1+r1s*x1-r2s*x1-3.*x2+3.*r1s*x2-r2s*x2
4536 0 : +x1*x2+x2s)
4537 0 : /(3.*prop2s);
4538 0 : rFO4 = 3.*rFO4/8.;
4539 : isSet4 = true;
4540 0 : }
4541 : break;
4542 :
4543 : // ~q -> q ~g.
4544 : case 14:
4545 0 : if (combi == 1 || combi == 3) {
4546 0 : rLO1 = ps*(1.-r1s-r2s-2.*r1*r2);
4547 0 : rFO1 = 64.*(1.+r1s+2.*r1*r2+r2s-x1-x2)*(x1+x2)
4548 0 : /(9.*x3s)
4549 0 : -16.*(-1.+r1q-2.*r1*r2-2.*r1c*r2-6.*r1s*r2s-2.*r1*r2c+r2q
4550 0 : +x1-r1s*x1+2.*r1*r2*x1+3.*r2s*x1+x2+r1s*x2-r2s*x2-x1*x2)
4551 0 : /prop1s
4552 0 : -16.*(r1s+r1q-2.*r1c*r2+r2s-6.*r1s*r2s-2.*r1*r2c+r2q-r1s*x1
4553 0 : +r1*r2*x1+2.*r2s*x1+2.*r1s*x2+r1*r2*x2-r2s*x2-x1*x2)
4554 0 : /prop12
4555 0 : -64.*(-1.+r1q-2.*r1*r2-2.*r1c*r2-6.*r1s*r2s-2.*r1*r2c+r2q+x1
4556 0 : -r1s*x1+r2s*x1+x2+3.*r1s*x2+2.*r1*r2*x2-r2s*x2-x1*x2)
4557 0 : /(9.*prop2s)
4558 0 : +8.*(-1.+r1q-2.*r1*r2+2.*r1c*r2-2.*r2s-2.*r1*r2c-r2q-2.*r1s*x1
4559 0 : +2.*r2s*x1+x1s+x2-3.*r1s*x2-2.*r1*r2*x2+r2s*x2+x1*x2)
4560 0 : /prop13
4561 0 : -8.*(-1.-2.*r1s-r1q-2.*r1*r2-2.*r1c*r2+2.*r1*r2c+r2q+x1+r1s*x1
4562 0 : -2.*r1*r2*x1-3.*r2s*x1+2.*r1s*x2-2.*r2s*x2+x1*x2+x2s)
4563 0 : /(9.*prop23);
4564 0 : rFO1 = 9.*rFO1/64.;
4565 : isSet1 = true;
4566 0 : }
4567 0 : if (combi == 2 || combi == 3) {
4568 0 : rLO2 = ps*(1.-r1s-r2s+2.*r1*r2);
4569 0 : rFO2 = 64.*(1.+r1s-2.*r1*r2+r2s-x1-x2)*(x1+x2)
4570 0 : /(9.*x3s)
4571 0 : -16.*(-1.+r1q+2.*r1*r2+2.*r1c*r2-6.*r1s*r2s+2.*r1*r2c+r2q+x1
4572 0 : -r1s*x1-2.*r1*r2*x1+3.*r2s*x1+x2+r1s*x2-r2s*x2-x1*x2)
4573 0 : /prop1s
4574 0 : -64.*(-1.+r1q+2.*r1*r2+2.*r1c*r2-6.*r1s*r2s+2.*r1*r2c+r2q+x1
4575 0 : -r1s*x1+r2s*x1+x2+3.*r1s*x2-2.*r1*r2*x2-r2s*x2-x1*x2)
4576 0 : /(9.*prop2s)
4577 0 : +16.*(-r1s-r1q-2.*r1c*r2-r2s+6.*r1s*r2s-2.*r1*r2c-r2q+r1s*x1
4578 0 : +r1*r2*x1-2.*r2s*x1-2.*r1s*x2+r1*r2*x2+r2s*x2+x1*x2)
4579 0 : /prop12
4580 0 : +8.*(-1.+r1q+2.*r1*r2-2.*r1c*r2-2.*r2s+2.*r1*r2c-r2q-2.*r1s*x1
4581 0 : +2.*r2s*x1+x1s+x2-3.*r1s*x2+2.*r1*r2*x2+r2s*x2+x1*x2)
4582 0 : /prop13
4583 0 : -8.*(-1.-2.*r1s-r1q+2.*r1*r2+2.*r1c*r2-2.*r1*r2c+r2q+x1+r1s*x1+
4584 0 : 2.*r1*r2*x1-3.*r2s*x1+2.*r1s*x2-2.*r2s*x2+x1*x2+x2s)
4585 0 : /(9.*prop23);
4586 0 : rFO2 = 9.*rFO2/64.;
4587 : isSet2 = true;
4588 0 : }
4589 0 : if (combi == 4) {
4590 0 : rLO4 = ps*(1.-r1s-r2s);
4591 0 : rFO4 = 128.*(1.+r1s+r2s-x1-x2)*(x1+x2)
4592 0 : /(9.*x3s)
4593 0 : -32*(-1.+r1q-6.*r1s*r2s+r2q+x1-r1s*x1+3.*r2s*x1+x2
4594 0 : +r1s*x2-r2s*x2-x1*x2)
4595 0 : /prop1s
4596 0 : -32.*(r1s+r1q+r2s-6.*r1s*r2s+r2q-r1s*x1+2.*r2s*x1+2.*r1s*x2
4597 0 : -r2s*x2-x1*x2)
4598 0 : /prop12
4599 0 : -128.*(-1.+r1q-6.*r1s*r2s+r2q+x1-r1s*x1+r2s*x1+x2+3.*r1s*x2
4600 0 : -r2s*x2-x1*x2)
4601 0 : /(9.*prop2s)
4602 0 : +16.*(-1.+r1q-2.*r2s-r2q-2.*r1s*x1+2.*r2s*x1+x1s
4603 0 : +x2-3.*r1s*x2+r2s*x2+x1*x2)
4604 0 : /prop13
4605 0 : -16.*(-1.-2.*r1s-r1q+r2q+x1+r1s*x1-3.*r2s*x1
4606 0 : +2.*r1s*x2-2.*r2s*x2+x1*x2+x2s)
4607 0 : /(9.*prop23);
4608 0 : rFO4 = 9.*rFO4/128.;
4609 : isSet4 = true;
4610 0 : }
4611 : break;
4612 :
4613 : // q -> ~q ~g.
4614 : case 15:
4615 0 : if (combi == 1 || combi == 3) {
4616 0 : rLO1 = ps*(1.-r1s+r2s+2.*r2);
4617 0 : rFO1 = 32*(2.*r2+x2)*(-1.-r1s-r2s+x2)
4618 0 : /(9.*prop2s)
4619 0 : +8.*(-1.-r1s-2.*r1s*r2-r2s-2.*r2c+x1+r2*x1+r2s*x1
4620 0 : +3.*x2*0.5-r1s*x2*0.5+r2*x2-r2s*x2*0.5-x1*x2*0.5)
4621 0 : /prop12
4622 0 : +8.*(2.+2.*r1s-2.*r2-2.*r1s*r2-6.*r2s-2.*r2c-3.*x1-r1s*x1
4623 0 : +2.*r2*x1+3.*r2s*x1+x1s-x2-r1s*x2+r2s*x2+x1*x2)
4624 0 : /prop1s
4625 0 : +32.*(4.+4.*r1s-4.*r2s-5.*x1-r1s*x1-2.*r2*x1+r2s*x1+x1s
4626 0 : -3.*x2-r1s*x2-2.*r2*x2+r2s*x2+x1*x2)
4627 0 : /(9.*x3s)
4628 0 : -8.*(3.+3.*r1s-r2+r1s*r2-5.*r2s-r2c-4.*x1-r1s*x1
4629 0 : +2.*r2s*x1+x1s-2.*x2-r2*x2+r2s*x2+x1*x2)
4630 0 : /prop13
4631 0 : -8.*(-1.-r1s+r2+r1s*r2-r2s-r2c+x1+r2*x1+r2s*x1+2.*x2+r1s*x2
4632 0 : -x1*x2*0.5-x2s*0.5)
4633 0 : /(9.*prop23);
4634 0 : rFO1 = 9.*rFO1/32.;
4635 : isSet1 = true;
4636 0 : }
4637 0 : if (combi == 2 || combi == 3) {
4638 0 : rLO2 = ps*(1.-r1s+r2s-2.*r2);
4639 0 : rFO2 = 32*(2.*r2-x2)*(1.+r1s+r2s-x2)
4640 0 : /(9.*prop2s)
4641 0 : +8.*(-1.-r1s+2.*r1s*r2-r2s+2.*r2c+x1-r2*x1+r2s*x1
4642 0 : +3.*x2*0.5-r1s*x2*0.5-r2*x2-r2s*x2*0.5-x1*x2*0.5)
4643 0 : /prop12
4644 0 : +8.*(2.+2.*r1s+2.*r2+2.*r1s*r2-6.*r2s+2.*r2c-3.*x1-r1s*x1
4645 0 : -2.*r2*x1+3.*r2s*x1+x1s-x2-r1s*x2+r2s*x2+x1*x2)
4646 0 : /prop1s
4647 0 : -8.*(3.+3.*r1s+r2-r1s*r2-5.*r2s+r2c-4.*x1-r1s*x1+2.*r2s*x1+x1s
4648 0 : -2.*x2+r2*x2+r2s*x2+x1*x2)
4649 0 : /prop13
4650 0 : +32*(4.+4.*r1s-4.*r2s-5.*x1-r1s*x1+2.*r2*x1+r2s*x1
4651 0 : +x1s-3.*x2-r1s*x2+2.*r2*x2+r2s*x2+x1*x2)
4652 0 : /(9.*x3s)
4653 0 : -8.*(-1.-r1s-r2-r1s*r2-r2s+r2c+x1-r2*x1+r2s*x1+2.*x2+r1s*x2
4654 0 : -x1*x2*0.5-x2s*0.5)
4655 0 : /(9.*prop23);
4656 0 : rFO2 = 9.*rFO2/32.;
4657 : isSet2 = true;
4658 0 : }
4659 0 : if (combi == 4) {
4660 0 : rLO4 = ps*(1.-r1s+r2s);
4661 0 : rFO4 = 64.*x2*(-1.-r1s-r2s+x2)
4662 0 : /(9.*prop2s)
4663 0 : +16.*(-1.-r1s-r2s+x1+r2s*x1+3.*x2*0.5-r1s*x2*0.5
4664 0 : -r2s*x2*0.5-x1*x2*0.5)
4665 0 : /prop12
4666 0 : -16.*(3.+3.*r1s-5.*r2s-4.*x1-r1s*x1+2.*r2s*x1+x1s-2.*x2+r2s*x2
4667 0 : +x1*x2)
4668 0 : /prop13
4669 0 : +64.*(4.+4.*r1s-4.*r2s-5.*x1-r1s*x1+r2s*x1+x1s-3.*x2
4670 0 : -r1s*x2+r2s*x2+x1*x2)
4671 0 : /(9.*x3s)
4672 0 : +16.*(2.+2.*r1s-6.*r2s-3.*x1-r1s*x1+3.*r2s*x1+x1s
4673 0 : -x2-r1s*x2+r2s*x2+x1*x2)
4674 0 : /prop1s
4675 0 : -16.*(-1.-r1s-r2s+x1+r2s*x1+2.*x2+r1s*x2-x1*x2*0.5-x2s*0.5)
4676 0 : /(9.*prop23);
4677 0 : rFO4 = 9.*rFO4/64.;
4678 : isSet4 = true;
4679 0 : }
4680 : break;
4681 :
4682 : // g -> ~g ~g. Use (9/4)*eikonal. May be changed in the future.
4683 : case 16:
4684 : rLO = ps;
4685 0 : if (combi == 2) offset = x3s;
4686 0 : else if (combi == 3) offset = mix * x3s;
4687 0 : else if (combi == 4) offset = 0.5 * x3s;
4688 0 : rFO = ps * 4.5 * ( (x1+x2-1.+offset-r1s-r2s)/prop12
4689 0 : - r1s/prop2s - r2s/prop1s );
4690 0 : break;
4691 :
4692 : // Dv -> qv d.
4693 : case 30:
4694 0 : rLO = ps*(1.-r1s+r2s+2.*r2);
4695 0 : rFO = ( 0.5*r3s + 2.*r1q + 0.5*r2s*r3s + r2*r3s - 2.*r1s
4696 0 : - 0.5*r1s*r3s - 2.*r1s*r2s - 4.*r1s*r2 ) / prop2s
4697 0 : + ( -2. + 2.*r2q + 2.*r1q + 2.*r2s*r3s - 4.*r2 + 2.*r2*r3s
4698 0 : + 4.*r2*r2s - 4.*r1s*r2s - 4.*r1s*r2 ) /prop23
4699 0 : + ( -2. - 0.5*r3s - 2.*r2s - 4.*r2 + 2.*r1s ) / prop2
4700 0 : + ( -2. - r3s - 2.*r2s - r2s*r3s - 4.*r2 - 2.*r2*r3s
4701 0 : + 2.*r1s + r1s*r3s ) / prop3s
4702 0 : + ( -1. - r3s - r2s - 4.*r2 + r1s - x2 ) / prop3
4703 0 : + 1.;
4704 0 : break;
4705 :
4706 : // S -> Dv Dvbar
4707 : case 31:
4708 0 : rLO = ps*(1.-4.*r1s);
4709 0 : rFO = (r3s + 2.*r1s) * (-1. + 4.*r1s) * (1./prop1s + 1./prop2s)
4710 0 : + (-1. + 8.*r1s - x2) / prop1
4711 0 : + (-1. + 8.*r1s - x1) / prop2
4712 0 : + 2. * (1. - 6.*r1s + 8.*r1q + 4.*r3s*r1s) / prop12
4713 0 : + 2.;
4714 0 : break;
4715 :
4716 : // q -> q~ W
4717 : case 32:
4718 : rLO = 1.;
4719 0 : rFO = (2. * r3s * r3s + 2. * r3s * (x1 + x2) + x1s + x2s) / prop12
4720 0 : - r3s / prop1s - r3s / prop2s;
4721 0 : break;
4722 :
4723 : // q -> q Z
4724 : case 33:
4725 : rLO = 1.;
4726 0 : rFO = (2. * r3s * r3s + 2. * r3s * (x1 + x2) + x1s + x2s) / prop12
4727 0 : - r3s / prop1s - r3s / prop2s;
4728 0 : break;
4729 :
4730 : // Eikonal expression for kind == 1; also acts as default.
4731 : default:
4732 : rLO = ps;
4733 0 : if (combi == 2) offset = x3s;
4734 0 : else if (combi == 3) offset = mix * x3s;
4735 0 : else if (combi == 4) offset = 0.5 * x3s;
4736 0 : rFO = ps * 2. * ( (x1+x2-1.+offset-r1s-r2s)/prop12
4737 0 : - r1s/prop2s - r2s/prop1s );
4738 0 : break;
4739 :
4740 : // End of ME cases.
4741 : }
4742 :
4743 : // Find relevant leading and first order expressions.
4744 0 : if (combi == 1 && isSet1) {
4745 : rLO = rLO1;
4746 0 : rFO = rFO1; }
4747 0 : else if (combi == 2 && isSet2) {
4748 : rLO = rLO2;
4749 0 : rFO = rFO2; }
4750 0 : else if (combi == 3 && isSet1 && isSet2) {
4751 0 : rLO = mix * rLO1 + (1.-mix) * rLO2;
4752 0 : rFO = mix * rFO1 + (1.-mix) * rFO2; }
4753 0 : else if (isSet4) {
4754 : rLO = rLO4;
4755 0 : rFO = rFO4; }
4756 0 : else if (combi == 4 && isSet1 && isSet2) {
4757 0 : rLO = 0.5 * (rLO1 + rLO2);
4758 0 : rFO = 0.5 * (rFO1 + rFO2); }
4759 0 : else if (isSet1) {
4760 : rLO = rLO1;
4761 0 : rFO = rFO1; }
4762 :
4763 : // Return ratio of first to leading order cross section.
4764 0 : return rFO / rLO;
4765 0 : }
4766 :
4767 : //--------------------------------------------------------------------------
4768 :
4769 : // Return the ME corrections for weak t-channel processes.
4770 :
4771 : double TimeShower::findMEcorrWeak(TimeDipoleEnd* dip,Vec4 rad,
4772 : Vec4 rec, Vec4 emt,Vec4 p3,Vec4 p4,Vec4 radBef, Vec4 recBef) {
4773 :
4774 : // Check that it is weak emission.
4775 0 : if (dip->MEtype > 210 || dip->MEtype < 200) return 1.;
4776 :
4777 : // Remove double counting. Only implemented for QCD hard processes
4778 : // and for the first emission.
4779 : bool cut = false;
4780 0 : if (infoPtr->nISR() + infoPtr->nFSRinProc() == 0
4781 0 : && infoPtr->code() > 110 && infoPtr->code() < 130
4782 0 : && vetoWeakJets) {
4783 0 : double d = emt.pT2();
4784 0 : if (rad.pT2() < d) {d = rad.pT2(); cut = true;}
4785 0 : if (rec.pT2() < d) {d = rec.pT2(); cut = true;}
4786 :
4787 : // Always check for combination of radiator and emitted.
4788 0 : double dij = min(rad.pT2(),emt.pT2())
4789 0 : * pow2(RRapPhi(rad,emt)) / vetoWeakDeltaR2;
4790 0 : if (dij < d) {
4791 : d = dij;
4792 : cut = false;
4793 0 : }
4794 :
4795 : // Check for angle between recoiler and radiator, if quark anti-quark pair,
4796 : // or if the recoiler is a gluon.
4797 0 : if (dip->MEtype == 200 || dip->MEtype == 205 ||
4798 0 : dip->MEtype == 201 || dip->MEtype == 206) {
4799 0 : dij = min(rad.pT2(),rec.pT2()) * pow2(RRapPhi(rad,rec))
4800 0 : / vetoWeakDeltaR2;
4801 0 : if (dij < d) {
4802 : d = dij;
4803 : cut = true;
4804 0 : }
4805 : }
4806 : // Check for angle between recoiler and emitted, if recoiler is a quark.
4807 0 : if (dip->MEtype == 200 || dip->MEtype == 205 ||
4808 0 : dip->MEtype == 202 || dip->MEtype == 207 ||
4809 0 : dip->MEtype == 203 || dip->MEtype == 208) {
4810 0 : dij = min(emt.pT2(),rec.pT2()) * pow2(RRapPhi(emt,rec))
4811 0 : / vetoWeakDeltaR2;
4812 0 : if (dij < d) {
4813 : d = dij;
4814 : cut = false;
4815 0 : }
4816 : }
4817 0 : if (cut) return 0.;
4818 0 : }
4819 :
4820 : // Check that MEtype is t-channel weak emission.
4821 0 : if ( dip->MEtype != 201 && dip->MEtype != 202 && dip->MEtype != 203
4822 0 : && dip->MEtype != 206 && dip->MEtype != 207 && dip->MEtype != 208)
4823 0 : return 1;
4824 :
4825 : // Rescaling of incoming partons p3 and p4.
4826 0 : double scaleFactor2 = (rad + rec + emt).m2Calc() / (p3 + p4).m2Calc();
4827 0 : double scaleFactor = sqrt(scaleFactor2);
4828 0 : p3 *= scaleFactor;
4829 0 : p4 *= scaleFactor;
4830 :
4831 : // Longitudinal boost to rest frame of incoming partons of hard interaction.
4832 0 : RotBstMatrix rot2to2frame;
4833 0 : rot2to2frame.bstback(p3 + p4);
4834 0 : p3.rotbst(rot2to2frame);
4835 0 : p4.rotbst(rot2to2frame);
4836 0 : rad.rotbst(rot2to2frame);
4837 0 : emt.rotbst(rot2to2frame);
4838 0 : rec.rotbst(rot2to2frame);
4839 0 : recBef.rotbst(rot2to2frame);
4840 0 : radBef.rotbst(rot2to2frame);
4841 :
4842 : // Further boost to rest frame of outgoing state.
4843 0 : RotBstMatrix rot2to3frame;
4844 0 : rot2to3frame.bstback(rad + emt + rec);
4845 0 : rad.rotbst(rot2to3frame);
4846 0 : emt.rotbst(rot2to3frame);
4847 0 : rec.rotbst(rot2to3frame);
4848 0 : recBef.rotbst(rot2to3frame);
4849 0 : radBef.rotbst(rot2to3frame);
4850 :
4851 : // Kinematical quantities.
4852 0 : double sHat = (p3 + p4).m2Calc();
4853 0 : double tHat = (radBef - p3).m2Calc();
4854 0 : double uHat = (recBef - p3).m2Calc();
4855 0 : double z = dip->z;
4856 0 : double pT2 = dip->pT2;
4857 0 : double Q2 = pT2 / (z*(1.-z));
4858 :
4859 : // ME weight. Prefactor mainly from Jacobian.
4860 0 : double wt = 2. * pT2 / z * (Q2+sHat)/sHat * (1. - kRad - kEmt) / 4.;
4861 0 : if (dip->MEtype == 201 || dip->MEtype == 206)
4862 0 : wt *= weakShowerMEs.getTchanneluGuGZME( p3, p4, rec, emt, rad)
4863 0 : / weakShowerMEs.getTchanneluGuGME( sHat, tHat, uHat);
4864 0 : else if (dip->MEtype == 202 || dip->MEtype == 207)
4865 0 : wt *= weakShowerMEs.getTchannelududZME( p3, p4, emt, rec, rad)
4866 0 : / weakShowerMEs.getTchanneluuuuME( sHat, tHat, uHat);
4867 0 : else if (dip->MEtype == 203 || dip->MEtype == 208)
4868 0 : wt *= weakShowerMEs.getTchannelududZME( p3, p4, emt, rec, rad)
4869 0 : / weakShowerMEs.getTchannelududME( sHat, tHat, uHat);
4870 :
4871 : // Split of ME into an ISR part and FSR part.
4872 0 : wt *= abs((-emt + p3).m2Calc()) / ((emt + rad).m2Calc()
4873 0 : + abs((-p3 + emt).m2Calc()));
4874 :
4875 : // Correction for previous fudge-factor enhancement of weak emission rate.
4876 0 : wt /= WEAKPSWEIGHT;
4877 0 : if (wt > 1.) infoPtr->errorMsg("Warning in TimeShower::findMEcorrWeak: "
4878 : "weight is above unity");
4879 : return wt;
4880 :
4881 0 : }
4882 :
4883 : //--------------------------------------------------------------------------
4884 :
4885 : // Find coefficient of azimuthal asymmetry from gluon polarization.
4886 :
4887 : void TimeShower::findAsymPol( Event& event, TimeDipoleEnd* dip) {
4888 :
4889 : // Default is no asymmetry. Only gluons are studied.
4890 0 : dip->asymPol = 0.;
4891 0 : dip->iAunt = 0;
4892 0 : int iRad = dip->iRadiator;
4893 0 : if (!doPhiPolAsym || event[iRad].id() != 21) return;
4894 :
4895 : // Trace grandmother via possibly intermediate recoil copies.
4896 0 : int iMother = event[iRad].iTopCopy();
4897 0 : int iGrandM = event[iMother].mother1();
4898 :
4899 : // If grandmother in initial state of hard scattering,
4900 : // then only keep gg and qq initial states.
4901 0 : int statusGrandM = event[iGrandM].status();
4902 0 : bool isHardProc = (statusGrandM == -21 || statusGrandM == -31);
4903 0 : if (isHardProc) {
4904 0 : if (event[iGrandM + 1].status() != statusGrandM) return;
4905 0 : if (event[iGrandM].isGluon() && event[iGrandM + 1].isGluon());
4906 0 : else if (event[iGrandM].isQuark() && event[iGrandM + 1].isQuark());
4907 0 : else return;
4908 : }
4909 :
4910 : // Set aunt by history or, for hard scattering, by colour flow.
4911 0 : if (isHardProc) dip->iAunt = dip->iRecoiler;
4912 0 : else dip->iAunt = (event[iGrandM].daughter1() == iMother)
4913 0 : ? event[iGrandM].daughter2() : event[iGrandM].daughter1();
4914 :
4915 : // Coefficient from gluon production (approximate z by energy).
4916 : // For hard process arbitrarily put z = 1/2.
4917 0 : double zProd = (isHardProc) ? 0.5 : event[iRad].e()
4918 0 : / (event[iRad].e() + event[dip->iAunt].e());
4919 0 : if (event[iGrandM].isGluon()) dip->asymPol = pow2( (1. - zProd)
4920 0 : / (1. - zProd * (1. - zProd) ) );
4921 0 : else dip->asymPol = 2. * (1. - zProd) / (1. + pow2(1. - zProd) );
4922 :
4923 : // Coefficients from gluon decay.
4924 0 : if (dip->flavour == 21) dip->asymPol *= pow2( (1. - dip->z)
4925 0 : / (1. - dip->z * (1. - dip->z) ) );
4926 0 : else dip->asymPol *= -2. * dip->z *( 1. - dip->z )
4927 0 : / (1. - 2. * dip->z * (1. - dip->z) );
4928 :
4929 0 : }
4930 :
4931 : //--------------------------------------------------------------------------
4932 :
4933 : // Print the list of dipoles.
4934 :
4935 : void TimeShower::list(ostream& os) const {
4936 :
4937 : // Header.
4938 0 : os << "\n -------- PYTHIA TimeShower Dipole Listing ----------------"
4939 0 : << "------------------------------------------------------- \n \n "
4940 0 : << " i rad rec pTmax col chg gam weak oni hv is"
4941 0 : << "r sys sysR type MErec mix ord spl ~gR pol \n"
4942 0 : << fixed << setprecision(3);
4943 :
4944 : // Loop over dipole list and print it.
4945 0 : for (int i = 0; i < int(dipEnd.size()); ++i)
4946 0 : os << setw(5) << i << setw(7) << dipEnd[i].iRadiator
4947 0 : << setw(7) << dipEnd[i].iRecoiler << setw(12) << dipEnd[i].pTmax
4948 0 : << setw(5) << dipEnd[i].colType << setw(5) << dipEnd[i].chgType
4949 0 : << setw(5) << dipEnd[i].gamType << setw(5) << dipEnd[i].weakType
4950 0 : << setw(5) << dipEnd[i].isOctetOnium
4951 0 : << setw(5) << dipEnd[i].isHiddenValley << setw(5) << dipEnd[i].isrType
4952 0 : << setw(5) << dipEnd[i].system << setw(5) << dipEnd[i].systemRec
4953 0 : << setw(5) << dipEnd[i].MEtype << setw(7) << dipEnd[i].iMEpartner
4954 0 : << setw(8) << dipEnd[i].MEmix << setw(5) << dipEnd[i].MEorder
4955 0 : << setw(5) << dipEnd[i].MEsplit << setw(5) << dipEnd[i].MEgluinoRec
4956 0 : << setw(5) << dipEnd[i].weakPol << "\n";
4957 :
4958 : // Done.
4959 0 : os << "\n -------- End PYTHIA TimeShower Dipole Listing ------------"
4960 0 : << "-------------------------------------------------------" << endl;
4961 :
4962 0 : }
4963 :
4964 : //==========================================================================
4965 :
4966 : } // end namespace Pythia8
|