Line data Source code
1 : // SigmaEW.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
7 : // electroweak simulation classes (including photon processes).
8 :
9 : #include "Pythia8/SigmaEW.h"
10 :
11 : namespace Pythia8 {
12 :
13 : //==========================================================================
14 :
15 : // Sigma2qg2qgamma class.
16 : // Cross section for q g -> q gamma.
17 :
18 : //--------------------------------------------------------------------------
19 :
20 : // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
21 :
22 : void Sigma2qg2qgamma::sigmaKin() {
23 :
24 : // Calculate kinematics dependence.
25 0 : sigUS = (1./3.) * (sH2 + uH2) / (-sH * uH);
26 :
27 : // Answer.
28 0 : sigma0 = (M_PI/sH2) * alpS * alpEM * sigUS;
29 :
30 0 : }
31 :
32 : //--------------------------------------------------------------------------
33 :
34 : // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
35 :
36 : double Sigma2qg2qgamma::sigmaHat() {
37 :
38 : // Incoming flavour gives charge factor.
39 0 : int idNow = (id2 == 21) ? id1 : id2;
40 0 : double eNow = couplingsPtr->ef( abs(idNow) );
41 0 : return sigma0 * pow2(eNow);
42 :
43 0 : }
44 :
45 : //--------------------------------------------------------------------------
46 :
47 : // Select identity, colour and anticolour.
48 :
49 : void Sigma2qg2qgamma::setIdColAcol() {
50 :
51 : // Construct outgoing flavours.
52 0 : id3 = (id1 == 21) ? 22 : id1;
53 0 : id4 = (id2 == 21) ? 22 : id2;
54 0 : setId( id1, id2, id3, id4);
55 :
56 : // Colour flow topology. Swap if first is gluon, or when antiquark.
57 0 : setColAcol( 1, 0, 2, 1, 2, 0, 0, 0);
58 0 : if (id1 == 21) swapCol1234();
59 0 : if (id1 < 0 || id2 < 0) swapColAcol();
60 :
61 0 : }
62 :
63 : //==========================================================================
64 :
65 : // Sigma2qqbar2ggamma class.
66 : // Cross section for q qbar -> g gamma.
67 :
68 : //--------------------------------------------------------------------------
69 :
70 : // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
71 :
72 : void Sigma2qqbar2ggamma::sigmaKin() {
73 :
74 : // Calculate kinematics dependence.
75 0 : double sigTU = (8./9.) * (tH2 + uH2) / (tH * uH);
76 :
77 : // Answer.
78 0 : sigma0 = (M_PI/sH2) * alpS * alpEM * sigTU;
79 :
80 0 : }
81 :
82 : //--------------------------------------------------------------------------
83 :
84 : // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
85 :
86 : double Sigma2qqbar2ggamma::sigmaHat() {
87 :
88 : // Incoming flavour gives charge factor.
89 0 : double eNow = couplingsPtr->ef( abs(id1) );
90 0 : return sigma0 * pow2(eNow);
91 :
92 0 : }
93 :
94 : //--------------------------------------------------------------------------
95 :
96 : // Select identity, colour and anticolour.
97 :
98 : void Sigma2qqbar2ggamma::setIdColAcol() {
99 :
100 : // Outgoing flavours trivial.
101 0 : setId( id1, id2, 21, 22);
102 :
103 : // One colour flow topology. Swap if first is antiquark.
104 0 : setColAcol( 1, 0, 0, 2, 1, 2, 0, 0);
105 0 : if (id1 < 0) swapColAcol();
106 :
107 0 : }
108 :
109 : //==========================================================================
110 :
111 : // Sigma2gg2ggamma class.
112 : // Cross section for g g -> g gamma.
113 : // Proceeds through a quark box, by default using 5 massless quarks.
114 :
115 : //--------------------------------------------------------------------------
116 :
117 : // Initialize process, especially parton-flux object.
118 :
119 : void Sigma2gg2ggamma::initProc() {
120 :
121 : // Maximum quark flavour in loop.
122 0 : int nQuarkLoop = settingsPtr->mode("PromptPhoton:nQuarkLoop");
123 :
124 : // Calculate charge factor from the allowed quarks in the box.
125 0 : chargeSum = - 1./3. + 2./3. - 1./3.;
126 0 : if (nQuarkLoop >= 4) chargeSum += 2./3.;
127 0 : if (nQuarkLoop >= 5) chargeSum -= 1./3.;
128 0 : if (nQuarkLoop >= 6) chargeSum += 2./3.;
129 :
130 0 : }
131 :
132 : //--------------------------------------------------------------------------
133 :
134 : // Evaluate d(sigmaHat)/d(tHat).
135 :
136 : void Sigma2gg2ggamma::sigmaKin() {
137 :
138 : // Logarithms of Mandelstam variable ratios.
139 0 : double logST = log( -sH / tH );
140 0 : double logSU = log( -sH / uH );
141 0 : double logTU = log( tH / uH );
142 :
143 : // Real and imaginary parts of separate amplitudes.
144 0 : double b0stuRe = 1. + (tH - uH) / sH * logTU
145 0 : + 0.5 * (tH2 + uH2) / sH2 * (pow2(logTU) + pow2(M_PI));
146 0 : double b0stuIm = 0.;
147 0 : double b0tsuRe = 1. + (sH - uH) / tH * logSU
148 0 : + 0.5 * (sH2 + uH2) / tH2 * pow2(logSU);
149 0 : double b0tsuIm = -M_PI * ( (sH - uH) / tH + (sH2 + uH2) / tH2 * logSU);
150 0 : double b0utsRe = 1. + (sH - tH) / uH * logST
151 0 : + 0.5 * (sH2 + tH2) / uH2 * pow2(logST);
152 0 : double b0utsIm = -M_PI * ( (sH - tH) / uH + (sH2 + tH2) / uH2 * logST);
153 0 : double b1stuRe = -1.;
154 0 : double b1stuIm = 0.;
155 0 : double b2stuRe = -1.;
156 0 : double b2stuIm = 0.;
157 :
158 : // Calculate kinematics dependence.
159 0 : double sigBox = pow2(b0stuRe) + pow2(b0stuIm) + pow2(b0tsuRe)
160 0 : + pow2(b0tsuIm) + pow2(b0utsRe) + pow2(b0utsIm) + 4. * pow2(b1stuRe)
161 0 : + 4. * pow2(b1stuIm) + pow2(b2stuRe) + pow2(b2stuIm);
162 :
163 : // Answer.
164 0 : sigma = (5. / (192. * M_PI * sH2)) * pow2(chargeSum)
165 0 : * pow3(alpS) * alpEM * sigBox;
166 :
167 0 : }
168 :
169 : //--------------------------------------------------------------------------
170 :
171 : // Select identity, colour and anticolour.
172 :
173 : void Sigma2gg2ggamma::setIdColAcol() {
174 :
175 : // Flavours and colours are trivial.
176 0 : setId( id1, id2, 21, 22);
177 0 : setColAcol( 1, 2, 2, 3, 1, 3, 0, 0);
178 0 : if (rndmPtr->flat() > 0.5) swapColAcol();
179 :
180 0 : }
181 :
182 : //==========================================================================
183 :
184 : // Sigma2ffbar2gammagamma class.
185 : // Cross section for q qbar -> gamma gamma.
186 :
187 : //--------------------------------------------------------------------------
188 :
189 : // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
190 :
191 : void Sigma2ffbar2gammagamma::sigmaKin() {
192 :
193 : // Calculate kinematics dependence.
194 0 : sigTU = 2. * (tH2 + uH2) / (tH * uH);
195 :
196 : // Answer contains factor 1/2 from identical photons.
197 0 : sigma0 = (M_PI/sH2) * pow2(alpEM) * 0.5 * sigTU;
198 :
199 0 : }
200 :
201 : //--------------------------------------------------------------------------
202 :
203 : // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
204 :
205 : double Sigma2ffbar2gammagamma::sigmaHat() {
206 :
207 : // Incoming flavour gives charge and colour factors.
208 0 : double eNow = couplingsPtr->ef( abs(id1) );
209 0 : double colFac = (abs(id1) < 9) ? 1. / 3. : 1.;
210 0 : return sigma0 * pow4(eNow) * colFac;
211 :
212 0 : }
213 :
214 : //--------------------------------------------------------------------------
215 :
216 : // Select identity, colour and anticolour.
217 :
218 : void Sigma2ffbar2gammagamma::setIdColAcol() {
219 :
220 : // Outgoing flavours trivial.
221 0 : setId( id1, id2, 22, 22);
222 :
223 : // No colours at all or one flow topology. Swap if first is antiquark.
224 0 : if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
225 0 : else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
226 0 : if (id1 < 0) swapColAcol();
227 :
228 0 : }
229 :
230 : //==========================================================================
231 :
232 : // Sigma2gg2gammagamma class.
233 : // Cross section for g g -> gamma gamma.
234 : // Proceeds through a quark box, by default using 5 massless quarks.
235 :
236 : //--------------------------------------------------------------------------
237 :
238 : // Initialize process.
239 :
240 : void Sigma2gg2gammagamma::initProc() {
241 :
242 : // Maximum quark flavour in loop.
243 0 : int nQuarkLoop = settingsPtr->mode("PromptPhoton:nQuarkLoop");
244 :
245 : // Calculate charge factor from the allowed quarks in the box.
246 0 : charge2Sum = 1./9. + 4./9. + 1./9.;
247 0 : if (nQuarkLoop >= 4) charge2Sum += 4./9.;
248 0 : if (nQuarkLoop >= 5) charge2Sum += 1./9.;
249 0 : if (nQuarkLoop >= 6) charge2Sum += 4./9.;
250 :
251 0 : }
252 :
253 : //--------------------------------------------------------------------------
254 :
255 : // Evaluate d(sigmaHat)/d(tHat).
256 :
257 : void Sigma2gg2gammagamma::sigmaKin() {
258 :
259 : // Logarithms of Mandelstam variable ratios.
260 0 : double logST = log( -sH / tH );
261 0 : double logSU = log( -sH / uH );
262 0 : double logTU = log( tH / uH );
263 :
264 : // Real and imaginary parts of separate amplitudes.
265 0 : double b0stuRe = 1. + (tH - uH) / sH * logTU
266 0 : + 0.5 * (tH2 + uH2) / sH2 * (pow2(logTU) + pow2(M_PI));
267 0 : double b0stuIm = 0.;
268 0 : double b0tsuRe = 1. + (sH - uH) / tH * logSU
269 0 : + 0.5 * (sH2 + uH2) / tH2 * pow2(logSU);
270 0 : double b0tsuIm = -M_PI * ( (sH - uH) / tH + (sH2 + uH2) / tH2 * logSU);
271 0 : double b0utsRe = 1. + (sH - tH) / uH * logST
272 0 : + 0.5 * (sH2 + tH2) / uH2 * pow2(logST);
273 0 : double b0utsIm = -M_PI * ( (sH - tH) / uH + (sH2 + tH2) / uH2 * logST);
274 0 : double b1stuRe = -1.;
275 0 : double b1stuIm = 0.;
276 0 : double b2stuRe = -1.;
277 0 : double b2stuIm = 0.;
278 :
279 : // Calculate kinematics dependence.
280 0 : double sigBox = pow2(b0stuRe) + pow2(b0stuIm) + pow2(b0tsuRe)
281 0 : + pow2(b0tsuIm) + pow2(b0utsRe) + pow2(b0utsIm) + 4. * pow2(b1stuRe)
282 0 : + 4. * pow2(b1stuIm) + pow2(b2stuRe) + pow2(b2stuIm);
283 :
284 : // Answer contains factor 1/2 from identical photons.
285 0 : sigma = (0.5 / (16. * M_PI * sH2)) * pow2(charge2Sum)
286 0 : * pow2(alpS) * pow2(alpEM) * sigBox;
287 :
288 0 : }
289 :
290 : //--------------------------------------------------------------------------
291 :
292 : // Select identity, colour and anticolour.
293 :
294 : void Sigma2gg2gammagamma::setIdColAcol() {
295 :
296 : // Flavours and colours are trivial.
297 0 : setId( id1, id2, 22, 22);
298 0 : setColAcol( 1, 2, 2, 1, 0, 0, 0, 0);
299 :
300 0 : }
301 :
302 : //==========================================================================
303 :
304 : // Sigma2ff2fftgmZ class.
305 : // Cross section for f f' -> f f' via t-channel gamma*/Z0 exchange
306 : // (f is quark or lepton).
307 :
308 : //--------------------------------------------------------------------------
309 :
310 : // Initialize process.
311 :
312 : void Sigma2ff2fftgmZ::initProc() {
313 :
314 : // Store Z0 mass for propagator. Common coupling factor.
315 0 : gmZmode = settingsPtr->mode("WeakZ0:gmZmode");
316 0 : mZ = particleDataPtr->m0(23);
317 0 : mZS = mZ*mZ;
318 0 : thetaWRat = 1. / (16. * couplingsPtr->sin2thetaW()
319 0 : * couplingsPtr->cos2thetaW());
320 :
321 0 : }
322 :
323 : //--------------------------------------------------------------------------
324 :
325 : // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
326 :
327 : void Sigma2ff2fftgmZ::sigmaKin() {
328 :
329 : // Cross section part common for all incoming flavours.
330 0 : double sigma0 = (M_PI / sH2) * pow2(alpEM);
331 :
332 : // Kinematical functions for gamma-gamma, gamma-Z and Z-Z parts.
333 0 : sigmagmgm = sigma0 * 2. * (sH2 + uH2) / tH2;
334 0 : sigmagmZ = sigma0 * 4. * thetaWRat * sH2 / (tH * (tH - mZS));
335 0 : sigmaZZ = sigma0 * 2. * pow2(thetaWRat) * sH2 / pow2(tH - mZS);
336 0 : if (gmZmode == 1) {sigmagmZ = 0.; sigmaZZ = 0.;}
337 0 : if (gmZmode == 2) {sigmagmgm = 0.; sigmagmZ = 0.;}
338 :
339 0 : }
340 :
341 : //--------------------------------------------------------------------------
342 :
343 : // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
344 :
345 : double Sigma2ff2fftgmZ::sigmaHat() {
346 :
347 : // Couplings for current flavour combination.
348 0 : int id1Abs = abs(id1);
349 0 : double e1 = couplingsPtr->ef(id1Abs);
350 0 : double v1 = couplingsPtr->vf(id1Abs);
351 0 : double a1 = couplingsPtr->af(id1Abs);
352 0 : int id2Abs = abs(id2);
353 0 : double e2 = couplingsPtr->ef(id2Abs);
354 0 : double v2 = couplingsPtr->vf(id2Abs);
355 0 : double a2 = couplingsPtr->af(id2Abs);
356 :
357 : // Distinguish same-sign and opposite-sign fermions.
358 0 : double epsi = (id1 * id2 > 0) ? 1. : -1.;
359 :
360 : // Flavour-dependent cross section.
361 0 : double sigma = sigmagmgm * pow2(e1 * e2)
362 0 : + sigmagmZ * e1 * e2 * (v1 * v2 * (1. + uH2 / sH2)
363 0 : + a1 * a2 * epsi * (1. - uH2 / sH2))
364 0 : + sigmaZZ * ((v1*v1 + a1*a1) * (v2*v2 + a2*a2) * (1. + uH2 / sH2)
365 0 : + 4. * v1 * a1 * v2 * a2 * epsi * (1. - uH2 / sH2));
366 :
367 : // Spin-state extra factor 2 per incoming neutrino.
368 0 : if (id1Abs == 12 || id1Abs == 14 || id1Abs == 16) sigma *= 2.;
369 0 : if (id2Abs == 12 || id2Abs == 14 || id2Abs == 16) sigma *= 2.;
370 :
371 : // Answer.
372 0 : return sigma;
373 :
374 : }
375 :
376 : //--------------------------------------------------------------------------
377 :
378 : // Select identity, colour and anticolour.
379 :
380 : void Sigma2ff2fftgmZ::setIdColAcol() {
381 :
382 : // Trivial flavours: out = in.
383 0 : setId( id1, id2, id1, id2);
384 :
385 : // Colour flow topologies. Swap when antiquarks.
386 0 : if (abs(id1) < 9 && abs(id2) < 9 && id1*id2 > 0)
387 0 : setColAcol( 1, 0, 2, 0, 1, 0, 2, 0);
388 0 : else if (abs(id1) < 9 && abs(id2) < 9)
389 0 : setColAcol( 1, 0, 0, 2, 1, 0, 0, 2);
390 0 : else if (abs(id1) < 9) setColAcol( 1, 0, 0, 0, 1, 0, 0, 0);
391 0 : else if (abs(id2) < 9) setColAcol( 0, 0, 1, 0, 0, 0, 1, 0);
392 0 : else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
393 0 : if ( (abs(id1) < 9 && id1 < 0) || (abs(id1) > 10 && id2 < 0) )
394 0 : swapColAcol();
395 :
396 0 : }
397 :
398 : //==========================================================================
399 :
400 : // Sigma2ff2fftW class.
401 : // Cross section for f_1 f_2 -> f_3 f_4 via t-channel W+- exchange
402 : // (f is quark or lepton).
403 :
404 : //--------------------------------------------------------------------------
405 :
406 : // Initialize process.
407 :
408 : void Sigma2ff2fftW::initProc() {
409 :
410 : // Store W+- mass for propagator. Common coupling factor.
411 0 : mW = particleDataPtr->m0(24);
412 0 : mWS = mW*mW;
413 0 : thetaWRat = 1. / (4. * couplingsPtr->sin2thetaW());
414 :
415 0 : }
416 :
417 : //--------------------------------------------------------------------------
418 :
419 : // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
420 :
421 : void Sigma2ff2fftW::sigmaKin() {
422 :
423 : // Cross section part common for all incoming flavours.
424 0 : sigma0 = (M_PI / sH2) * pow2(alpEM * thetaWRat)
425 0 : * 4. * sH2 / pow2(tH - mWS);
426 :
427 0 : }
428 :
429 : //--------------------------------------------------------------------------
430 :
431 : // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
432 :
433 : double Sigma2ff2fftW::sigmaHat() {
434 :
435 : // Some flavour combinations not possible.
436 0 : int id1Abs = abs(id1);
437 0 : int id2Abs = abs(id2);
438 0 : if ( (id1Abs%2 == id2Abs%2 && id1 * id2 > 0)
439 0 : || (id1Abs%2 != id2Abs%2 && id1 * id2 < 0) ) return 0.;
440 :
441 : // Basic cross section.
442 0 : double sigma = sigma0;
443 0 : if (id1 * id2 < 0) sigma *= uH2 / sH2;
444 :
445 : // CKM factors for final states.
446 0 : sigma *= couplingsPtr->V2CKMsum(id1Abs) * couplingsPtr->V2CKMsum(id2Abs);
447 :
448 : // Spin-state extra factor 2 per incoming neutrino.
449 0 : if (id1Abs == 12 || id1Abs == 14 || id1Abs == 16) sigma *= 2.;
450 0 : if (id2Abs == 12 || id2Abs == 14 || id2Abs == 16) sigma *= 2.;
451 :
452 : // Answer.
453 : return sigma;
454 :
455 0 : }
456 :
457 : //--------------------------------------------------------------------------
458 :
459 : // Select identity, colour and anticolour.
460 :
461 : void Sigma2ff2fftW::setIdColAcol() {
462 :
463 : // Pick out-flavours by relative CKM weights.
464 0 : id3 = couplingsPtr->V2CKMpick(id1);
465 0 : id4 = couplingsPtr->V2CKMpick(id2);
466 0 : setId( id1, id2, id3, id4);
467 :
468 : // Colour flow topologies. Swap when antiquarks.
469 0 : if (abs(id1) < 9 && abs(id2) < 9 && id1*id2 > 0)
470 0 : setColAcol( 1, 0, 2, 0, 1, 0, 2, 0);
471 0 : else if (abs(id1) < 9 && abs(id2) < 9)
472 0 : setColAcol( 1, 0, 0, 2, 1, 0, 0, 2);
473 0 : else if (abs(id1) < 9) setColAcol( 1, 0, 0, 0, 1, 0, 0, 0);
474 0 : else if (abs(id2) < 9) setColAcol( 0, 0, 1, 0, 0, 0, 1, 0);
475 0 : else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
476 0 : if ( (abs(id1) < 9 && id1 < 0) || (abs(id1) > 10 && id2 < 0) )
477 0 : swapColAcol();
478 :
479 0 : }
480 :
481 :
482 : //==========================================================================
483 :
484 : // Sigma2qq2QqtW class.
485 : // Cross section for q q' -> Q q" via t-channel W+- exchange.
486 : // Related to Sigma2ff2ffViaW class, but with massive matrix elements.
487 :
488 : //--------------------------------------------------------------------------
489 :
490 : // Initialize process.
491 :
492 : void Sigma2qq2QqtW::initProc() {
493 :
494 : // Process name.
495 0 : nameSave = "q q -> Q q (t-channel W+-)";
496 0 : if (idNew == 4) nameSave = "q q -> c q (t-channel W+-)";
497 0 : if (idNew == 5) nameSave = "q q -> b q (t-channel W+-)";
498 0 : if (idNew == 6) nameSave = "q q -> t q (t-channel W+-)";
499 0 : if (idNew == 7) nameSave = "q q -> b' q (t-channel W+-)";
500 0 : if (idNew == 8) nameSave = "q q -> t' q (t-channel W+-)";
501 :
502 : // Store W+- mass for propagator. Common coupling factor.
503 0 : mW = particleDataPtr->m0(24);
504 0 : mWS = mW*mW;
505 0 : thetaWRat = 1. / (4. * couplingsPtr->sin2thetaW());
506 :
507 : // Secondary open width fractions, relevant for top (or heavier).
508 0 : openFracPos = particleDataPtr->resOpenFrac(idNew);
509 0 : openFracNeg = particleDataPtr->resOpenFrac(-idNew);
510 :
511 0 : }
512 :
513 : //--------------------------------------------------------------------------
514 :
515 : // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
516 :
517 : void Sigma2qq2QqtW::sigmaKin() {
518 :
519 : // Cross section part common for all incoming flavours.
520 0 : sigma0 = (M_PI / sH2) * pow2(alpEM * thetaWRat) * 4. / pow2(tH - mWS);
521 :
522 0 : }
523 :
524 : //--------------------------------------------------------------------------
525 :
526 : // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
527 :
528 : double Sigma2qq2QqtW::sigmaHat() {
529 :
530 : // Some flavour combinations not possible.
531 0 : int id1Abs = abs(id1);
532 0 : int id2Abs = abs(id2);
533 0 : bool diff12 = (id1Abs%2 != id2Abs%2);
534 0 : if ( (!diff12 && id1 * id2 > 0)
535 0 : || ( diff12 && id1 * id2 < 0) ) return 0.;
536 :
537 : // Basic cross section.
538 0 : double sigma = sigma0;
539 0 : sigma *= (id1 * id2 > 0) ? sH * (sH - s3) : uH * (uH - s3);
540 :
541 : // Secondary width if t or tbar produced on either side.
542 0 : double openFrac1 = (id1 > 0) ? openFracPos : openFracNeg;
543 0 : double openFrac2 = (id2 > 0) ? openFracPos : openFracNeg;
544 :
545 : // CKM factors for final states; further impossible case.
546 0 : bool diff1N = (id1Abs%2 != idNew%2);
547 0 : bool diff2N = (id2Abs%2 != idNew%2);
548 0 : if (diff1N && diff2N)
549 0 : sigma *= ( couplingsPtr->V2CKMid(id1Abs, idNew) * openFrac1
550 0 : * couplingsPtr->V2CKMsum(id2Abs) + couplingsPtr->V2CKMsum(id1Abs)
551 0 : * couplingsPtr->V2CKMid(id2Abs, idNew) * openFrac2 );
552 0 : else if (diff1N)
553 0 : sigma *= couplingsPtr->V2CKMid(id1Abs, idNew) * openFrac1
554 0 : * couplingsPtr->V2CKMsum(id2Abs);
555 0 : else if (diff2N)
556 0 : sigma *= couplingsPtr->V2CKMsum(id1Abs)
557 0 : * couplingsPtr->V2CKMid(id2Abs, idNew) * openFrac2;
558 : else sigma = 0.;
559 :
560 : // Spin-state extra factor 2 per incoming neutrino.
561 0 : if (id1Abs == 12 || id1Abs == 14 || id1Abs == 16) sigma *= 2.;
562 0 : if (id2Abs == 12 || id2Abs == 14 || id2Abs == 16) sigma *= 2.;
563 :
564 : // Answer.
565 : return sigma;
566 :
567 0 : }
568 :
569 : //--------------------------------------------------------------------------
570 :
571 : // Select identity, colour and anticolour.
572 :
573 : void Sigma2qq2QqtW::setIdColAcol() {
574 :
575 : // For topologies like d dbar -> (t/c/u) (t/c/u)bar pick side.
576 0 : int id1Abs = abs(id1);
577 0 : int id2Abs = abs(id2);
578 : int side = 1;
579 0 : if ( (id1Abs + idNew)%2 == 1 && (id2Abs + idNew)%2 == 1 ) {
580 0 : double prob1 = couplingsPtr->V2CKMid(id1Abs, idNew)
581 0 : * couplingsPtr->V2CKMsum(id2Abs);
582 0 : prob1 *= (id1 > 0) ? openFracPos : openFracNeg;
583 0 : double prob2 = couplingsPtr->V2CKMid(id2Abs, idNew)
584 0 : * couplingsPtr->V2CKMsum(id1Abs);
585 0 : prob2 *= (id2 > 0) ? openFracPos : openFracNeg;
586 0 : if (prob2 > rndmPtr->flat() * (prob1 + prob2)) side = 2;
587 0 : }
588 0 : else if ((id2Abs + idNew)%2 == 1) side = 2;
589 :
590 : // Pick out-flavours by relative CKM weights.
591 0 : if (side == 1) {
592 : // q q' -> t q" : correct order from start.
593 0 : id3 = (id1 > 0) ? idNew : -idNew;
594 0 : id4 = couplingsPtr->V2CKMpick(id2);
595 0 : setId( id1, id2, id3, id4);
596 0 : } else {
597 : // q q' -> q" t : stored as t q" so swap tHat <-> uHat.
598 0 : swapTU = true;
599 0 : id3 = couplingsPtr->V2CKMpick(id1);
600 0 : id4 = (id2 > 0) ? idNew : -idNew;
601 0 : setId( id1, id2, id4, id3);
602 : }
603 :
604 : // Colour flow topologies. Swap when antiquarks on side 1.
605 0 : if (side == 1 && id1 * id2 > 0) setColAcol( 1, 0, 2, 0, 1, 0, 2, 0);
606 0 : else if (id1 * id2 > 0) setColAcol( 1, 0, 2, 0, 2, 0, 1, 0);
607 0 : else if (side == 1) setColAcol( 1, 0, 0, 2, 1, 0, 0, 2);
608 0 : else setColAcol( 1, 0, 0, 2, 0, 2, 1, 0);
609 0 : if (id1 < 0) swapColAcol();
610 :
611 0 : }
612 :
613 : //--------------------------------------------------------------------------
614 :
615 : // Evaluate weight for decay angles of W in top decay.
616 :
617 : double Sigma2qq2QqtW::weightDecay( Event& process, int iResBeg,
618 : int iResEnd) {
619 :
620 : // For top decay hand over to standard routine, else done.
621 0 : if (idNew == 6 && process[process[iResBeg].mother1()].idAbs() == 6)
622 0 : return weightTopDecay( process, iResBeg, iResEnd);
623 0 : else return 1.;
624 :
625 0 : }
626 :
627 : //==========================================================================
628 :
629 : // Sigma1ffbar2gmZ class.
630 : // Cross section for f fbar -> gamma*/Z0 (f is quark or lepton).
631 :
632 : //--------------------------------------------------------------------------
633 :
634 : // Initialize process.
635 :
636 : void Sigma1ffbar2gmZ::initProc() {
637 :
638 : // Allow to pick only gamma* or Z0 part of full gamma*/Z0 expression.
639 0 : gmZmode = settingsPtr->mode("WeakZ0:gmZmode");
640 :
641 : // Store Z0 mass and width for propagator.
642 0 : mRes = particleDataPtr->m0(23);
643 0 : GammaRes = particleDataPtr->mWidth(23);
644 0 : m2Res = mRes*mRes;
645 0 : GamMRat = GammaRes / mRes;
646 0 : thetaWRat = 1. / (16. * couplingsPtr->sin2thetaW()
647 0 : * couplingsPtr->cos2thetaW());
648 :
649 : // Set pointer to particle properties and decay table.
650 0 : particlePtr = particleDataPtr->particleDataEntryPtr(23);
651 :
652 0 : }
653 :
654 : //--------------------------------------------------------------------------
655 :
656 : // Evaluate sigmaHat(sHat), part independent of incoming flavour.
657 :
658 : void Sigma1ffbar2gmZ::sigmaKin() {
659 :
660 : // Common coupling factors.
661 0 : double colQ = 3. * (1. + alpS / M_PI);
662 :
663 : // Reset quantities to sum. Declare variables in loop.
664 0 : gamSum = 0.;
665 0 : intSum = 0.;
666 0 : resSum = 0.;
667 : int idAbs, onMode;
668 0 : double mf, mr, psvec, psaxi, betaf, ef2, efvf, vf2af2, colf;
669 :
670 : // Loop over all Z0 decay channels.
671 0 : for (int i = 0; i < particlePtr->sizeChannels(); ++i) {
672 0 : idAbs = abs( particlePtr->channel(i).product(0) );
673 :
674 : // Only contributions from three fermion generations, except top.
675 0 : if ( (idAbs > 0 && idAbs < 6) || ( idAbs > 10 && idAbs < 17)) {
676 0 : mf = particleDataPtr->m0(idAbs);
677 :
678 : // Check that above threshold. Phase space.
679 0 : if (mH > 2. * mf + MASSMARGIN) {
680 0 : mr = pow2(mf / mH);
681 0 : betaf = sqrtpos(1. - 4. * mr);
682 0 : psvec = betaf * (1. + 2. * mr);
683 0 : psaxi = pow3(betaf);
684 :
685 : // Combine phase space with couplings.
686 0 : ef2 = couplingsPtr->ef2(idAbs) * psvec;
687 0 : efvf = couplingsPtr->efvf(idAbs) * psvec;
688 0 : vf2af2 = couplingsPtr->vf2(idAbs) * psvec
689 0 : + couplingsPtr->af2(idAbs) * psaxi;
690 0 : colf = (idAbs < 6) ? colQ : 1.;
691 :
692 : // Store sum of combinations. For outstate only open channels.
693 0 : onMode = particlePtr->channel(i).onMode();
694 0 : if (onMode == 1 || onMode == 2) {
695 0 : gamSum += colf * ef2;
696 0 : intSum += colf * efvf;
697 0 : resSum += colf * vf2af2;
698 0 : }
699 :
700 : // End loop over fermions.
701 : }
702 : }
703 : }
704 :
705 : // Calculate prefactors for gamma/interference/Z0 cross section terms.
706 0 : gamProp = 4. * M_PI * pow2(alpEM) / (3. * sH);
707 0 : intProp = gamProp * 2. * thetaWRat * sH * (sH - m2Res)
708 0 : / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
709 0 : resProp = gamProp * pow2(thetaWRat * sH)
710 0 : / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
711 :
712 : // Optionally only keep gamma* or Z0 term.
713 0 : if (gmZmode == 1) {intProp = 0.; resProp = 0.;}
714 0 : if (gmZmode == 2) {gamProp = 0.; intProp = 0.;}
715 :
716 0 : }
717 :
718 : //--------------------------------------------------------------------------
719 :
720 : // Evaluate sigmaHat(sHat), including incoming flavour dependence.
721 :
722 : double Sigma1ffbar2gmZ::sigmaHat() {
723 :
724 : // Combine gamma, interference and Z0 parts.
725 0 : int idAbs = abs(id1);
726 0 : double sigma = couplingsPtr->ef2(idAbs) * gamProp * gamSum
727 0 : + couplingsPtr->efvf(idAbs) * intProp * intSum
728 0 : + couplingsPtr->vf2af2(idAbs) * resProp * resSum;
729 :
730 : // Colour factor. Answer.
731 0 : if (idAbs < 9) sigma /= 3.;
732 0 : return sigma;
733 :
734 : }
735 :
736 : //--------------------------------------------------------------------------
737 :
738 : // Select identity, colour and anticolour.
739 :
740 : void Sigma1ffbar2gmZ::setIdColAcol() {
741 :
742 : // Flavours trivial.
743 0 : setId( id1, id2, 23);
744 :
745 : // Colour flow topologies. Swap when antiquarks.
746 0 : if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0);
747 0 : else setColAcol( 0, 0, 0, 0, 0, 0);
748 0 : if (id1 < 0) swapColAcol();
749 :
750 0 : }
751 :
752 : //--------------------------------------------------------------------------
753 :
754 : // Evaluate weight for gamma*/Z0 decay angle.
755 :
756 : double Sigma1ffbar2gmZ::weightDecay( Event& process, int iResBeg,
757 : int iResEnd) {
758 :
759 : // Z should sit in entry 5.
760 0 : if (iResBeg != 5 || iResEnd != 5) return 1.;
761 :
762 : // Couplings for in- and out-flavours.
763 0 : int idInAbs = process[3].idAbs();
764 0 : double ei = couplingsPtr->ef(idInAbs);
765 0 : double vi = couplingsPtr->vf(idInAbs);
766 0 : double ai = couplingsPtr->af(idInAbs);
767 0 : int idOutAbs = process[6].idAbs();
768 0 : double ef = couplingsPtr->ef(idOutAbs);
769 0 : double vf = couplingsPtr->vf(idOutAbs);
770 0 : double af = couplingsPtr->af(idOutAbs);
771 :
772 : // Phase space factors. (One power of beta left out in formulae.)
773 0 : double mf = process[6].m();
774 0 : double mr = mf*mf / sH;
775 0 : double betaf = sqrtpos(1. - 4. * mr);
776 :
777 : // Coefficients of angular expression.
778 0 : double coefTran = ei*ei * gamProp * ef*ef + ei * vi * intProp * ef * vf
779 0 : + (vi*vi + ai*ai) * resProp * (vf*vf + pow2(betaf) * af*af);
780 0 : double coefLong = 4. * mr * ( ei*ei * gamProp * ef*ef
781 0 : + ei * vi * intProp * ef * vf + (vi*vi + ai*ai) * resProp * vf*vf );
782 0 : double coefAsym = betaf * ( ei * ai * intProp * ef * af
783 0 : + 4. * vi * ai * resProp * vf * af );
784 :
785 : // Flip asymmetry for in-fermion + out-antifermion.
786 0 : if (process[3].id() * process[6].id() < 0) coefAsym = -coefAsym;
787 :
788 : // Reconstruct decay angle and weight for it.
789 0 : double cosThe = (process[3].p() - process[4].p())
790 0 : * (process[7].p() - process[6].p()) / (sH * betaf);
791 0 : double wtMax = 2. * (coefTran + abs(coefAsym));
792 0 : double wt = coefTran * (1. + pow2(cosThe))
793 0 : + coefLong * (1. - pow2(cosThe)) + 2. * coefAsym * cosThe;
794 :
795 : // Done.
796 0 : return (wt / wtMax);
797 :
798 0 : }
799 :
800 : //==========================================================================
801 :
802 : // Sigma1ffbar2W class.
803 : // Cross section for f fbar' -> W+- (f is quark or lepton).
804 :
805 : //--------------------------------------------------------------------------
806 :
807 : // Initialize process.
808 :
809 : void Sigma1ffbar2W::initProc() {
810 :
811 : // Store W+- mass and width for propagator.
812 0 : mRes = particleDataPtr->m0(24);
813 0 : GammaRes = particleDataPtr->mWidth(24);
814 0 : m2Res = mRes*mRes;
815 0 : GamMRat = GammaRes / mRes;
816 0 : thetaWRat = 1. / (12. * couplingsPtr->sin2thetaW());
817 :
818 : // Set pointer to particle properties and decay table.
819 0 : particlePtr = particleDataPtr->particleDataEntryPtr(24);
820 :
821 0 : }
822 :
823 : //--------------------------------------------------------------------------
824 :
825 : // Evaluate sigmaHat(sHat), part independent of incoming flavour.
826 :
827 : void Sigma1ffbar2W::sigmaKin() {
828 :
829 : // Set up Breit-Wigner. Cross section for W+ and W- separately.
830 0 : double sigBW = 12. * M_PI / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
831 0 : double preFac = alpEM * thetaWRat * mH;
832 0 : sigma0Pos = preFac * sigBW * particlePtr->resWidthOpen(24, mH);
833 0 : sigma0Neg = preFac * sigBW * particlePtr->resWidthOpen(-24, mH);
834 :
835 0 : }
836 :
837 : //--------------------------------------------------------------------------
838 :
839 : // Evaluate sigmaHat(sHat), including incoming flavour dependence.
840 :
841 : double Sigma1ffbar2W::sigmaHat() {
842 :
843 : // Secondary width for W+ or W-. CKM and colour factors.
844 0 : int idUp = (abs(id1)%2 == 0) ? id1 : id2;
845 0 : double sigma = (idUp > 0) ? sigma0Pos : sigma0Neg;
846 0 : if (abs(id1) < 9) sigma *= couplingsPtr->V2CKMid(abs(id1), abs(id2)) / 3.;
847 :
848 : // Answer.
849 0 : return sigma;
850 :
851 : }
852 :
853 : //--------------------------------------------------------------------------
854 :
855 : // Select identity, colour and anticolour.
856 :
857 : void Sigma1ffbar2W::setIdColAcol() {
858 :
859 : // Sign of outgoing W.
860 0 : int sign = 1 - 2 * (abs(id1)%2);
861 0 : if (id1 < 0) sign = -sign;
862 0 : setId( id1, id2, 24 * sign);
863 :
864 : // Colour flow topologies. Swap when antiquarks.
865 0 : if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0);
866 0 : else setColAcol( 0, 0, 0, 0, 0, 0);
867 0 : if (id1 < 0) swapColAcol();
868 :
869 0 : }
870 :
871 : //--------------------------------------------------------------------------
872 :
873 : // Evaluate weight for W decay angle.
874 :
875 : double Sigma1ffbar2W::weightDecay( Event& process, int iResBeg,
876 : int iResEnd) {
877 :
878 : // W should sit in entry 5.
879 0 : if (iResBeg != 5 || iResEnd != 5) return 1.;
880 :
881 : // Phase space factors.
882 0 : double mr1 = pow2(process[6].m()) / sH;
883 0 : double mr2 = pow2(process[7].m()) / sH;
884 0 : double betaf = sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2);
885 :
886 : // Sign of asymmetry.
887 0 : double eps = (process[3].id() * process[6].id() > 0) ? 1. : -1.;
888 :
889 : // Reconstruct decay angle and weight for it.
890 0 : double cosThe = (process[3].p() - process[4].p())
891 0 : * (process[7].p() - process[6].p()) / (sH * betaf);
892 : double wtMax = 4.;
893 0 : double wt = pow2(1. + betaf * eps * cosThe) - pow2(mr1 - mr2);
894 :
895 : // Done.
896 0 : return (wt / wtMax);
897 :
898 0 : }
899 :
900 : //==========================================================================
901 :
902 : // Sigma2ffbar2ffbarsgm class.
903 : // Cross section f fbar -> gamma* -> f' fbar', for multiparton interactions.
904 :
905 : //--------------------------------------------------------------------------
906 :
907 : // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
908 :
909 : void Sigma2ffbar2ffbarsgm::sigmaKin() {
910 :
911 : // Pick new flavour. Allow three leptons and five quarks.
912 0 : double colQ = 1. + (alpS / M_PI);
913 0 : double flavWt = 3. + colQ * 11. / 3.;
914 0 : double flavRndm = rndmPtr->flat() * flavWt;
915 0 : if (flavRndm < 3.) {
916 0 : if (flavRndm < 1.) idNew = 11;
917 0 : else if (flavRndm < 2.) idNew = 13;
918 0 : else idNew = 15;
919 : } else {
920 0 : flavRndm = 3. * (flavRndm - 3.) / colQ;
921 0 : if (flavRndm < 4.) idNew = 2;
922 0 : else if (flavRndm < 8.) idNew = 4;
923 0 : else if (flavRndm < 9.) idNew = 1;
924 0 : else if (flavRndm < 10.) idNew = 3;
925 0 : else idNew = 5;
926 : }
927 0 : double mNew = particleDataPtr->m0(idNew);
928 0 : double m2New = mNew*mNew;
929 :
930 : // Calculate kinematics dependence. Give correct mass factors for
931 : // tHat, uHat defined as if massless kinematics, d(sigma)/d(Omega)
932 : // = beta (1 + cos^2(theta) + (1 - beta^2) sin^2(theta)).
933 : // Special case related to phase space form in multiparton interactions.
934 : double sigS = 0.;
935 0 : if (sH > 4. * m2New) {
936 0 : double beta = sqrt(1. - 4. * m2New / sH);
937 0 : sigS = beta * (2.* (tH2 + uH2) + 4. * (1. - beta * beta) * tH * uH)
938 0 : / sH2;
939 0 : }
940 :
941 : // Answer is proportional to number of outgoing flavours.
942 0 : sigma0 = (M_PI/sH2) * pow2(alpEM) * sigS * flavWt;
943 :
944 0 : }
945 :
946 : //--------------------------------------------------------------------------
947 :
948 : // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
949 :
950 : double Sigma2ffbar2ffbarsgm::sigmaHat() {
951 :
952 : // Charge and colour factors.
953 0 : double eNow = couplingsPtr->ef( abs(id1) );
954 0 : double sigma = sigma0 * pow2(eNow);
955 0 : if (abs(id1) < 9) sigma /= 3.;
956 :
957 : // Answer.
958 0 : return sigma;
959 :
960 0 : }
961 :
962 : //--------------------------------------------------------------------------
963 :
964 : // Select identity, colour and anticolour.
965 :
966 : void Sigma2ffbar2ffbarsgm::setIdColAcol() {
967 :
968 : // Set outgoing flavours.
969 0 : id3 = (id1 > 0) ? idNew : -idNew;
970 0 : setId( id1, id2, id3, -id3);
971 :
972 : // Colour flow topologies. Swap when antiquarks.
973 0 : if (abs(id1) < 9 && idNew < 9) setColAcol( 1, 0, 0, 1, 2, 0, 0, 2);
974 0 : else if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
975 0 : else if (idNew < 9) setColAcol( 0, 0, 0, 0, 1, 0, 0, 1);
976 0 : else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
977 0 : if (id1 < 0) swapColAcol();
978 :
979 0 : }
980 :
981 : //==========================================================================
982 :
983 : // Sigma2ffbar2ffbarsgmZ class.
984 : // Cross section f fbar -> gamma*/Z0 -> f' fbar',
985 : // i.e. gamma*/Z0 decay as part of the hard process.
986 :
987 : //--------------------------------------------------------------------------
988 :
989 : // Initialize process.
990 :
991 : void Sigma2ffbar2ffbarsgmZ::initProc() {
992 :
993 : // Allow to pick only gamma* or Z0 part of full gamma*/Z0 expression.
994 0 : gmZmode = settingsPtr->mode("WeakZ0:gmZmode");
995 :
996 : // Store Z0 mass and width for propagator.
997 0 : mRes = particleDataPtr->m0(23);
998 0 : GammaRes = particleDataPtr->mWidth(23);
999 0 : m2Res = mRes*mRes;
1000 0 : GamMRat = GammaRes / mRes;
1001 0 : thetaWRat = 1. / (16. * couplingsPtr->sin2thetaW()
1002 0 : * couplingsPtr->cos2thetaW());
1003 :
1004 : // Set pointer to particle properties and decay table.
1005 0 : particlePtr = particleDataPtr->particleDataEntryPtr(23);
1006 :
1007 0 : }
1008 :
1009 : //--------------------------------------------------------------------------
1010 :
1011 : // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
1012 :
1013 : void Sigma2ffbar2ffbarsgmZ::sigmaKin() {
1014 :
1015 : // Common coupling factor.
1016 0 : colQ = 3. * (1. + alpS / M_PI);
1017 :
1018 : // Reset vectors and sums. Declare variables in loop.
1019 0 : idVec.resize(0);
1020 0 : gamT.resize(0);
1021 0 : gamL.resize(0);
1022 0 : intT.resize(0);
1023 0 : intL.resize(0);
1024 0 : intA.resize(0);
1025 0 : resT.resize(0);
1026 0 : resL.resize(0);
1027 0 : resA.resize(0);
1028 0 : gamSumT = 0.;
1029 0 : gamSumL = 0.;
1030 0 : intSumT = 0.;
1031 0 : intSumL = 0.;
1032 0 : intSumA = 0.;
1033 0 : resSumT = 0.;
1034 0 : resSumL = 0.;
1035 0 : resSumA = 0.;
1036 0 : int onMode, idAbs;
1037 0 : double mf, mr, betaf, ef, vf, af, colf, gamTf, gamLf, intTf, intLf,
1038 : intAf, resTf, resLf, resAf;
1039 :
1040 : // Loop over all Z0 decay channels.
1041 0 : for (int i = 0; i < particlePtr->sizeChannels(); ++i) {
1042 0 : onMode = particlePtr->channel(i).onMode();
1043 0 : idAbs = abs( particlePtr->channel(i).product(0) );
1044 :
1045 : // Only contributions from three fermion generations, except top.
1046 0 : if ( (onMode == 1 || onMode == 2) && ((idAbs > 0 && idAbs < 6)
1047 0 : || ( idAbs > 10 && idAbs < 17)) ) {
1048 0 : mf = particleDataPtr->m0(idAbs);
1049 :
1050 : // Check that channel above threshold. Phase space.
1051 0 : if (mH > 2. * mf + MASSMARGIN) {
1052 0 : mr = pow2(mf / mH);
1053 0 : betaf = sqrtpos(1. - 4. * mr);
1054 :
1055 : // Combine couplings (including colour) with phase space.
1056 0 : ef = couplingsPtr->ef(idAbs);
1057 0 : vf = couplingsPtr->vf(idAbs);
1058 0 : af = couplingsPtr->af(idAbs);
1059 0 : colf = (idAbs < 6) ? colQ : 1.;
1060 0 : gamTf = colf * ef * ef * betaf;
1061 0 : gamLf = gamTf * 4. * mr;
1062 0 : intTf = colf * ef * vf * betaf;
1063 0 : intLf = intTf * 4. * mr;
1064 0 : intAf = colf * ef * af * betaf;
1065 0 : resTf = colf * (vf * vf * betaf + af * af * pow3(betaf));
1066 0 : resLf = colf * vf * vf * betaf * 4. * mr;
1067 0 : resAf = colf * vf * af * betaf * 4.;
1068 :
1069 : // Store individual coplings and their sums.
1070 0 : idVec.push_back(idAbs);
1071 0 : gamT.push_back(gamTf);
1072 0 : gamL.push_back(gamLf);
1073 0 : intT.push_back(intTf);
1074 0 : intL.push_back(intLf);
1075 0 : intA.push_back(intAf);
1076 0 : resT.push_back(resTf);
1077 0 : resL.push_back(resLf);
1078 0 : resA.push_back(resAf);
1079 0 : gamSumT += gamTf;
1080 0 : gamSumL += gamLf;
1081 0 : intSumT += intTf;
1082 0 : intSumL += intLf;
1083 0 : intSumA += intAf;
1084 0 : resSumT += resTf;
1085 0 : resSumL += resLf;
1086 0 : resSumA += resAf;
1087 :
1088 : // End loop over Z0 decay channels.
1089 0 : }
1090 : }
1091 : }
1092 :
1093 : // Calculate prefactors for gamma/interference/Z0 cross section terms.
1094 0 : gamProp = M_PI * pow2(alpEM) / sH2;
1095 0 : intProp = gamProp * 2. * thetaWRat * sH * (sH - m2Res)
1096 0 : / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
1097 0 : resProp = gamProp * pow2(thetaWRat * sH)
1098 0 : / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
1099 :
1100 : // Optionally only keep gamma* or Z0 term.
1101 0 : if (gmZmode == 1) {intProp = 0.; resProp = 0.;}
1102 0 : if (gmZmode == 2) {gamProp = 0.; intProp = 0.;}
1103 :
1104 : // Scattering angle in subsystem rest frame.
1105 0 : cThe = (tH - uH) / sH;
1106 :
1107 0 : }
1108 :
1109 : //--------------------------------------------------------------------------
1110 :
1111 : // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
1112 :
1113 : double Sigma2ffbar2ffbarsgmZ::sigmaHat() {
1114 :
1115 : // Couplings for current in-flavour.
1116 0 : int id1Abs = abs(id1);
1117 0 : double ei = couplingsPtr->ef(id1Abs);
1118 0 : double vi = couplingsPtr->vf(id1Abs);
1119 0 : double ai = couplingsPtr->af(id1Abs);
1120 :
1121 : // Coefficients of angular expression.
1122 0 : double coefT = ei*ei * gamProp * gamSumT + ei*vi * intProp * intSumT
1123 0 : + (vi*vi + ai*ai) * resProp * resSumT;
1124 0 : double coefL = ei*ei * gamProp * gamSumL + ei*vi * intProp * intSumL
1125 0 : + (vi*vi + ai*ai) * resProp * resSumL;
1126 0 : double coefA = ei*ai * intProp * intSumA + vi*ai * resProp * resSumA;
1127 :
1128 : // Colour factor. Answer.
1129 0 : double sigma = coefT * (1. + pow2(cThe)) + coefL * (1. - pow2(cThe))
1130 0 : + 2. * coefA * cThe;
1131 0 : if (id1Abs < 9) sigma /= 3.;
1132 0 : return sigma;
1133 :
1134 : }
1135 :
1136 : //--------------------------------------------------------------------------
1137 :
1138 : // Select identity, colour and anticolour.
1139 :
1140 : void Sigma2ffbar2ffbarsgmZ::setIdColAcol() {
1141 :
1142 : // Couplings for chosen in-flavour.
1143 0 : int id1Abs = abs(id1);
1144 0 : double ei = couplingsPtr->ef(id1Abs);
1145 0 : double vi = couplingsPtr->vf(id1Abs);
1146 0 : double ai = couplingsPtr->af(id1Abs);
1147 :
1148 : // Contribution from each allowed out-flavour.
1149 0 : sigTLA.resize(0);
1150 0 : for (int i = 0; i < int(idVec.size()); ++i) {
1151 0 : double coefT = ei*ei * gamProp * gamT[i] + ei*vi * intProp * intT[i]
1152 0 : + (vi*vi + ai*ai) * resProp * resT[i];
1153 0 : double coefL = ei*ei * gamProp * gamL[i] + ei*vi * intProp * intL[i]
1154 0 : + (vi*vi + ai*ai) * resProp * resL[i];
1155 0 : double coefA = ei*ai * intProp * intA[i] + vi*ai * resProp * resA[i];
1156 0 : double sigma = coefT * (1. + pow2(cThe)) + coefL * (1. - pow2(cThe))
1157 0 : + 2. * coefA * cThe;
1158 0 : sigTLA.push_back(sigma);
1159 0 : }
1160 :
1161 : // Pick outgoing flavours.
1162 0 : int idNew = idVec[ rndmPtr->pick(sigTLA) ];
1163 0 : id3 = (id1 > 0) ? idNew : -idNew;
1164 0 : setId( id1, id2, id3, -id3);
1165 :
1166 : // Colour flow topologies. Swap when antiquarks.
1167 0 : if (abs(id1) < 9 && idNew < 9) setColAcol( 1, 0, 0, 1, 2, 0, 0, 2);
1168 0 : else if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
1169 0 : else if (idNew < 9) setColAcol( 0, 0, 0, 0, 1, 0, 0, 1);
1170 0 : else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
1171 0 : if (id1 < 0) swapColAcol();
1172 :
1173 0 : }
1174 :
1175 : //==========================================================================
1176 :
1177 : // Sigma2ffbar2ffbarsW class.
1178 : // Cross section f_1 fbar_2 -> W+- -> f_3 fbar_4,
1179 : // i.e. W decay as part of the hard process.
1180 :
1181 : //--------------------------------------------------------------------------
1182 :
1183 : // Initialize process.
1184 :
1185 : void Sigma2ffbar2ffbarsW::initProc() {
1186 :
1187 : // Store W+- mass and width for propagator.
1188 0 : mRes = particleDataPtr->m0(24);
1189 0 : GammaRes = particleDataPtr->mWidth(24);
1190 0 : m2Res = mRes*mRes;
1191 0 : GamMRat = GammaRes / mRes;
1192 0 : thetaWRat = 1. / (12. * couplingsPtr->sin2thetaW());
1193 :
1194 : // Set pointer to particle properties and decay table.
1195 0 : particlePtr = particleDataPtr->particleDataEntryPtr(24);
1196 :
1197 0 : }
1198 :
1199 : //--------------------------------------------------------------------------
1200 :
1201 : // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
1202 :
1203 : void Sigma2ffbar2ffbarsW::sigmaKin() {
1204 :
1205 : // Set up Breit-Wigner. Common sigmaHat cross section for W+ and W-.
1206 0 : double sigBW = 12. * M_PI / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
1207 0 : double preFac = alpEM * thetaWRat * mH;
1208 0 : sigma0 = preFac * sigBW * particlePtr->resWidthOpen(24, mH);
1209 :
1210 : // Convert to d(sigmaHat)/d(tHat). Fixed so integrates to sigmaHat.
1211 0 : sigma0 *= 3. * uH2 / (sH2 * sH);
1212 :
1213 : // Pick a decay channel.
1214 0 : if (!particlePtr->preparePick(24, mH)) {
1215 0 : sigma0 = 0.;
1216 0 : return;
1217 : }
1218 0 : DecayChannel& channel = particlePtr->pickChannel();
1219 0 : id3New = channel.product(0);
1220 0 : id4New = channel.product(1);
1221 :
1222 0 : }
1223 :
1224 : //--------------------------------------------------------------------------
1225 :
1226 : // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
1227 :
1228 : double Sigma2ffbar2ffbarsW::sigmaHat() {
1229 :
1230 : // Secondary width for W+-. CKM and colour factors.
1231 0 : double sigma = sigma0;
1232 0 : if (abs(id1) < 9) sigma *= couplingsPtr->V2CKMid(abs(id1), abs(id2)) / 3.;
1233 :
1234 : // Answer.
1235 0 : return sigma;
1236 :
1237 : }
1238 :
1239 : //--------------------------------------------------------------------------
1240 :
1241 : // Select identity, colour and anticolour.
1242 :
1243 : void Sigma2ffbar2ffbarsW::setIdColAcol() {
1244 :
1245 : // Find sign of W and its decay products. Set outgoing flavours.
1246 0 : int idUp = (abs(id1)%2 == 0) ? id1 : id2;
1247 0 : id3 = (idUp > 0) ? id3New : -id3New;
1248 0 : id4 = (idUp > 0) ? id4New : -id4New;
1249 0 : if (id1 * id3 < 0) swap(id3, id4);
1250 0 : setId( id1, id2, id3, id4);
1251 :
1252 : // Colour flow topologies. Swap when antifermions in 1 and 3.
1253 0 : if (abs(id1) < 9 && abs(id3) < 9) setColAcol( 1, 0, 0, 1, 2, 0, 0, 2);
1254 0 : else if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
1255 0 : else if (abs(id3) < 9) setColAcol( 0, 0, 0, 0, 1, 0, 0, 1);
1256 0 : else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
1257 0 : if (id1 < 0) swapColAcol();
1258 :
1259 0 : }
1260 :
1261 : //==========================================================================
1262 :
1263 : // Sigma2ffbar2FFbarsgmZ class.
1264 : // Cross section f fbar -> gamma*/Z0 -> F Fbar.
1265 :
1266 : //--------------------------------------------------------------------------
1267 :
1268 : // Initialize process.
1269 :
1270 : void Sigma2ffbar2FFbarsgmZ::initProc() {
1271 :
1272 : // Process name.
1273 0 : nameSave = "f fbar -> F Fbar (s-channel gamma*/Z0)";
1274 0 : if (idNew == 4) nameSave = "f fbar -> c cbar (s-channel gamma*/Z0)";
1275 0 : if (idNew == 5) nameSave = "f fbar -> b bbar (s-channel gamma*/Z0)";
1276 0 : if (idNew == 6) nameSave = "f fbar -> t tbar (s-channel gamma*/Z0)";
1277 0 : if (idNew == 7) nameSave = "f fbar -> b' b'bar (s-channel gamma*/Z0)";
1278 0 : if (idNew == 8) nameSave = "f fbar -> t' t'bar (s-channel gamma*/Z0)";
1279 0 : if (idNew == 15) nameSave = "f fbar -> tau+ tau- (s-channel gamma*/Z0)";
1280 0 : if (idNew == 17) nameSave = "f fbar -> tau'+ tau'- (s-channel gamma*/Z0)";
1281 0 : if (idNew == 18)
1282 0 : nameSave = "f fbar -> nu'_tau nu'bar_tau (s-channel gamma*/Z0)";
1283 :
1284 : // Allow to pick only gamma* or Z0 part of full gamma*/Z0 expression.
1285 0 : gmZmode = settingsPtr->mode("WeakZ0:gmZmode");
1286 :
1287 : // Store Z0 mass and width for propagator.
1288 0 : mRes = particleDataPtr->m0(23);
1289 0 : GammaRes = particleDataPtr->mWidth(23);
1290 0 : m2Res = mRes*mRes;
1291 0 : GamMRat = GammaRes / mRes;
1292 0 : thetaWRat = 1. / (16. * couplingsPtr->sin2thetaW()
1293 0 : * couplingsPtr->cos2thetaW());
1294 :
1295 : // Store couplings of F.
1296 0 : ef = couplingsPtr->ef(idNew);
1297 0 : vf = couplingsPtr->vf(idNew);
1298 0 : af = couplingsPtr->af(idNew);
1299 :
1300 : // Secondary open width fraction, relevant for top (or heavier).
1301 0 : openFracPair = particleDataPtr->resOpenFrac(idNew, -idNew);
1302 :
1303 0 : }
1304 :
1305 : //--------------------------------------------------------------------------
1306 :
1307 : // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
1308 :
1309 : void Sigma2ffbar2FFbarsgmZ::sigmaKin() {
1310 :
1311 : // Check that above threshold.
1312 0 : isPhysical = true;
1313 0 : if (mH < m3 + m4 + MASSMARGIN) {
1314 0 : isPhysical = false;
1315 0 : return;
1316 : }
1317 :
1318 : // Define average F, Fbar mass so same beta. Phase space.
1319 0 : double s34Avg = 0.5 * (s3 + s4) - 0.25 * pow2(s3 - s4) / sH;
1320 0 : mr = s34Avg / sH;
1321 0 : betaf = sqrtpos(1. - 4. * mr);
1322 :
1323 : // Final-state colour factor.
1324 0 : double colF = (idNew < 9) ? 3. * (1. + alpS / M_PI) : 1.;
1325 :
1326 : // Reconstruct decay angle so can reuse 2 -> 1 cross section.
1327 0 : cosThe = (tH - uH) / (betaf * sH);
1328 :
1329 : // Calculate prefactors for gamma/interference/Z0 cross section terms.
1330 0 : gamProp = colF * M_PI * pow2(alpEM) / sH2;
1331 0 : intProp = gamProp * 2. * thetaWRat * sH * (sH - m2Res)
1332 0 : / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
1333 0 : resProp = gamProp * pow2(thetaWRat * sH)
1334 0 : / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
1335 :
1336 : // Optionally only keep gamma* or Z0 term.
1337 0 : if (gmZmode == 1) {intProp = 0.; resProp = 0.;}
1338 0 : if (gmZmode == 2) {gamProp = 0.; intProp = 0.;}
1339 :
1340 0 : }
1341 :
1342 : //--------------------------------------------------------------------------
1343 :
1344 : // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
1345 :
1346 : double Sigma2ffbar2FFbarsgmZ::sigmaHat() {
1347 :
1348 : // Fail if below threshold.
1349 0 : if (!isPhysical) return 0.;
1350 :
1351 : // Couplings for in-flavours.
1352 0 : int idAbs = abs(id1);
1353 0 : double ei = couplingsPtr->ef(idAbs);
1354 0 : double vi = couplingsPtr->vf(idAbs);
1355 0 : double ai = couplingsPtr->af(idAbs);
1356 :
1357 : // Coefficients of angular expression.
1358 0 : double coefTran = ei*ei * gamProp * ef*ef + ei * vi * intProp * ef * vf
1359 0 : + (vi*vi + ai*ai) * resProp * (vf*vf + pow2(betaf) * af*af);
1360 0 : double coefLong = 4. * mr * ( ei*ei * gamProp * ef*ef
1361 0 : + ei * vi * intProp * ef * vf + (vi*vi + ai*ai) * resProp * vf*vf );
1362 0 : double coefAsym = betaf * ( ei * ai * intProp * ef * af
1363 0 : + 4. * vi * ai * resProp * vf * af );
1364 :
1365 : // Combine gamma, interference and Z0 parts.
1366 0 : double sigma = coefTran * (1. + pow2(cosThe))
1367 0 : + coefLong * (1. - pow2(cosThe)) + 2. * coefAsym * cosThe;
1368 :
1369 : // Top: corrections for closed decay channels.
1370 0 : sigma *= openFracPair;
1371 :
1372 : // Initial-state colour factor. Answer.
1373 0 : if (idAbs < 9) sigma /= 3.;
1374 : return sigma;
1375 :
1376 0 : }
1377 :
1378 : //--------------------------------------------------------------------------
1379 :
1380 : // Select identity, colour and anticolour.
1381 :
1382 : void Sigma2ffbar2FFbarsgmZ::setIdColAcol() {
1383 :
1384 : // Set outgoing flavours.
1385 0 : id3 = (id1 > 0) ? idNew : -idNew;
1386 0 : setId( id1, id2, id3, -id3);
1387 :
1388 : // Colour flow topologies. Swap when antiquarks.
1389 0 : if (abs(id1) < 9 && idNew < 9) setColAcol( 1, 0, 0, 1, 2, 0, 0, 2);
1390 0 : else if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
1391 0 : else if (idNew < 9) setColAcol( 0, 0, 0, 0, 1, 0, 0, 1);
1392 0 : else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
1393 0 : if (id1 < 0) swapColAcol();
1394 :
1395 0 : }
1396 :
1397 : //--------------------------------------------------------------------------
1398 :
1399 : // Evaluate weight for decay angles of W in top decay.
1400 :
1401 : double Sigma2ffbar2FFbarsgmZ::weightDecay( Event& process, int iResBeg,
1402 : int iResEnd) {
1403 :
1404 : // For top decay hand over to standard routine, else done.
1405 0 : if (idNew == 6 && process[process[iResBeg].mother1()].idAbs() == 6)
1406 0 : return weightTopDecay( process, iResBeg, iResEnd);
1407 0 : else return 1.;
1408 :
1409 0 : }
1410 :
1411 : //==========================================================================
1412 :
1413 : // Sigma2ffbar2FfbarsW class.
1414 : // Cross section f fbar' -> W+- -> F fbar".
1415 :
1416 : //--------------------------------------------------------------------------
1417 :
1418 : // Initialize process.
1419 :
1420 : void Sigma2ffbar2FfbarsW::initProc() {
1421 :
1422 : // Process name.
1423 0 : nameSave = "f fbar -> F fbar (s-channel W+-)";
1424 0 : if (idNew == 4) nameSave = "f fbar -> c qbar (s-channel W+-)";
1425 0 : if (idNew == 5) nameSave = "f fbar -> b qbar (s-channel W+-)";
1426 0 : if (idNew == 6) nameSave = "f fbar -> t qbar (s-channel W+-)";
1427 0 : if (idNew == 7) nameSave = "f fbar -> b' qbar (s-channel W+-)";
1428 0 : if (idNew == 8) nameSave = "f fbar -> t' qbar (s-channel W+-)";
1429 0 : if (idNew == 7 && idNew2 == 6)
1430 0 : nameSave = "f fbar -> b' tbar (s-channel W+-)";
1431 0 : if (idNew == 8 && idNew2 == 7)
1432 0 : nameSave = "f fbar -> t' b'bar (s-channel W+-)";
1433 0 : if (idNew == 15 || idNew == 16)
1434 0 : nameSave = "f fbar -> tau nu_taubar (s-channel W+-)";
1435 0 : if (idNew == 17 || idNew == 18)
1436 0 : nameSave = "f fbar -> tau' nu'_taubar (s-channel W+-)";
1437 :
1438 : // Store W+- mass and width for propagator.
1439 0 : mRes = particleDataPtr->m0(24);
1440 0 : GammaRes = particleDataPtr->mWidth(24);
1441 0 : m2Res = mRes*mRes;
1442 0 : GamMRat = GammaRes / mRes;
1443 0 : thetaWRat = 1. / (12. * couplingsPtr->sin2thetaW());
1444 :
1445 : // For t/t' want to use at least b mass.
1446 0 : idPartner = idNew2;
1447 0 : if ( (idNew == 6 || idNew == 8) && idNew2 == 0 ) idPartner = 5;
1448 :
1449 : // Sum of CKM weights for quarks.
1450 0 : V2New = (idNew < 9) ? couplingsPtr->V2CKMsum(idNew) : 1.;
1451 0 : if (idNew2 != 0) V2New = couplingsPtr->V2CKMid(idNew, idNew2);
1452 :
1453 : // Secondary open width fractions, relevant for top or heavier.
1454 0 : openFracPos = particleDataPtr->resOpenFrac( idNew, -idNew2);
1455 0 : openFracNeg = particleDataPtr->resOpenFrac(-idNew, idNew2);
1456 :
1457 0 : }
1458 :
1459 : //--------------------------------------------------------------------------
1460 :
1461 : // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
1462 :
1463 : void Sigma2ffbar2FfbarsW::sigmaKin() {
1464 :
1465 : // Check that above threshold.
1466 0 : isPhysical = true;
1467 0 : if (mH < m3 + m4 + MASSMARGIN) {
1468 0 : isPhysical = false;
1469 0 : return;
1470 : }
1471 :
1472 : // Phase space factors.
1473 0 : double mr1 = s3 / sH;
1474 0 : double mr2 = s4 / sH;
1475 0 : double betaf = sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2);
1476 :
1477 : // Reconstruct decay angle so can reuse 2 -> 1 cross section.
1478 0 : double cosThe = (tH - uH) / (betaf * sH);
1479 :
1480 : // Set up Breit-Wigner and in- and out-widths.
1481 0 : double sigBW = 9. * M_PI * pow2(alpEM * thetaWRat)
1482 0 : / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
1483 :
1484 : // Initial-state colour factor.
1485 0 : double colF = (idNew < 9) ? 3. * (1. + alpS / M_PI) * V2New : 1.;
1486 :
1487 : // Angular dependence.
1488 0 : double wt = pow2(1. + betaf * cosThe) - pow2(mr1 - mr2);
1489 :
1490 : // Temporary answer.
1491 0 : sigma0 = sigBW * colF * wt;
1492 :
1493 0 : }
1494 :
1495 : //--------------------------------------------------------------------------
1496 :
1497 : // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
1498 :
1499 : double Sigma2ffbar2FfbarsW::sigmaHat() {
1500 :
1501 : // Fail if below threshold.
1502 0 : if (!isPhysical) return 0.;
1503 :
1504 : // CKM and colour factors.
1505 0 : double sigma = sigma0;
1506 0 : if (abs(id1) < 9) sigma *= couplingsPtr->V2CKMid(abs(id1), abs(id2)) / 3.;
1507 :
1508 : // Correction for secondary width in top (or heavier) decay.
1509 0 : int idSame = ((abs(id1) + idNew)%2 == 0) ? id1 : id2;
1510 0 : sigma *= (idSame > 0) ? openFracPos : openFracNeg;
1511 :
1512 : // Answer.
1513 : return sigma;
1514 :
1515 0 : }
1516 :
1517 : //--------------------------------------------------------------------------
1518 :
1519 : // Select identity, colour and anticolour.
1520 :
1521 : void Sigma2ffbar2FfbarsW::setIdColAcol() {
1522 :
1523 : // Set outgoing flavours.
1524 0 : id3 = idNew;
1525 0 : id4 = (idNew2 != 0) ? idNew2 : couplingsPtr->V2CKMpick(idNew);
1526 0 : if (idNew%2 == 0) {
1527 0 : int idInUp = (abs(id1)%2 == 0) ? id1 : id2;
1528 0 : if (idInUp > 0) id4 = -id4;
1529 0 : else id3 = -id3;
1530 0 : } else {
1531 0 : int idInDn = (abs(id1)%2 == 1) ? id1 : id2;
1532 0 : if (idInDn > 0) id4 = -id4;
1533 0 : else id3 = -id3;
1534 : }
1535 0 : setId( id1, id2, id3, id4);
1536 :
1537 : // Swap tHat and uHat for fbar' f -> F f".
1538 0 : if (id1 * id3 < 0) swapTU = true;
1539 :
1540 : // Colour flow topologies. Swap when antiquarks.
1541 0 : if (abs(id1) < 9 && idNew < 9) setColAcol( 1, 0, 0, 1, 2, 0, 0, 2);
1542 0 : else if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
1543 0 : else if (idNew < 9) setColAcol( 0, 0, 0, 0, 1, 0, 0, 1);
1544 0 : else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
1545 0 : if (id1 < 0) swapCol12();
1546 0 : if (id3 < 0) swapCol34();
1547 :
1548 0 : }
1549 :
1550 : //--------------------------------------------------------------------------
1551 :
1552 : // Evaluate weight for decay angles of W in top decay.
1553 :
1554 : double Sigma2ffbar2FfbarsW::weightDecay( Event& process, int iResBeg,
1555 : int iResEnd) {
1556 :
1557 : // For top decay hand over to standard routine, else done.
1558 0 : if (idNew == 6 && process[process[iResBeg].mother1()].idAbs() == 6)
1559 0 : return weightTopDecay( process, iResBeg, iResEnd);
1560 0 : else return 1.;
1561 :
1562 0 : }
1563 :
1564 : //==========================================================================
1565 :
1566 : // Sigma2ffbargmZWgmZW class.
1567 : // Collects common methods for f fbar -> gamma*/Z0/W+- gamma*/Z0/W-+.
1568 :
1569 : //--------------------------------------------------------------------------
1570 :
1571 : // Calculate and store internal products.
1572 :
1573 : void Sigma2ffbargmZWgmZW::setupProd( Event& process, int i1, int i2,
1574 : int i3, int i4, int i5, int i6) {
1575 :
1576 : // Store incoming and outgoing momenta,
1577 0 : pRot[1] = process[i1].p();
1578 0 : pRot[2] = process[i2].p();
1579 0 : pRot[3] = process[i3].p();
1580 0 : pRot[4] = process[i4].p();
1581 0 : pRot[5] = process[i5].p();
1582 0 : pRot[6] = process[i6].p();
1583 :
1584 : // Do random rotation to avoid accidental zeroes in HA expressions.
1585 : bool smallPT = false;
1586 0 : do {
1587 : smallPT = false;
1588 0 : double thetaNow = acos(2. * rndmPtr->flat() - 1.);
1589 0 : double phiNow = 2. * M_PI * rndmPtr->flat();
1590 0 : for (int i = 1; i <= 6; ++i) {
1591 0 : pRot[i].rot( thetaNow, phiNow);
1592 0 : if (pRot[i].pT2() < 1e-4 * pRot[i].pAbs2()) smallPT = true;
1593 : }
1594 0 : } while (smallPT);
1595 :
1596 : // Calculate internal products.
1597 0 : for (int i = 1; i < 6; ++i) {
1598 0 : for (int j = i + 1; j <= 6; ++j) {
1599 0 : hA[i][j] =
1600 0 : sqrt( (pRot[i].e() - pRot[i].pz()) * (pRot[j].e() + pRot[j].pz())
1601 0 : / pRot[i].pT2() ) * complex( pRot[i].px(), pRot[i].py() )
1602 0 : - sqrt( (pRot[i].e() + pRot[i].pz()) * (pRot[j].e() - pRot[j].pz())
1603 0 : / pRot[j].pT2() ) * complex( pRot[j].px(), pRot[j].py() );
1604 0 : hC[i][j] = conj( hA[i][j] );
1605 0 : if (i <= 2) {
1606 0 : hA[i][j] *= complex( 0., 1.);
1607 0 : hC[i][j] *= complex( 0., 1.);
1608 0 : }
1609 0 : hA[j][i] = - hA[i][j];
1610 0 : hC[j][i] = - hC[i][j];
1611 : }
1612 : }
1613 :
1614 0 : }
1615 :
1616 : //--------------------------------------------------------------------------
1617 :
1618 : // Evaluate the F function of Gunion and Kunszt.
1619 :
1620 : complex Sigma2ffbargmZWgmZW::fGK(int j1, int j2, int j3, int j4, int j5,
1621 : int j6) {
1622 :
1623 0 : return 4. * hA[j1][j3] * hC[j2][j6]
1624 0 : * ( hA[j1][j5] * hC[j1][j4] + hA[j3][j5] * hC[j3][j4] );
1625 :
1626 : }
1627 :
1628 : //--------------------------------------------------------------------------
1629 :
1630 : // Evaluate the Xi function of Gunion and Kunszt.
1631 :
1632 : double Sigma2ffbargmZWgmZW::xiGK( double tHnow, double uHnow) {
1633 :
1634 0 : return - 4. * s3 * s4 + tHnow * (3. * tHnow + 4. * uHnow)
1635 0 : + tHnow * tHnow * ( tHnow * uHnow / (s3 * s4)
1636 0 : - 2. * (1. / s3 + 1./s4) * (tHnow + uHnow)
1637 0 : + 2. * (s3 / s4 + s4 / s3) );
1638 :
1639 : }
1640 :
1641 : //--------------------------------------------------------------------------
1642 :
1643 : // Evaluate the Xj function of Gunion and Kunszt.
1644 :
1645 : double Sigma2ffbargmZWgmZW::xjGK( double tHnow, double uHnow) {
1646 :
1647 0 : return 8. * pow2(s3 + s4) - 8. * (s3 + s4) * (tHnow + uHnow)
1648 0 : - 6. * tHnow * uHnow - 2. * tHnow * uHnow * ( tHnow * uHnow
1649 0 : / (s3 * s4) - 2. * (1. / s3 + 1. / s4) * (tHnow + uHnow)
1650 0 : + 2. * (s3 / s4 + s4 / s3) );
1651 :
1652 : }
1653 :
1654 : //==========================================================================
1655 :
1656 : // Sigma2ffbar2gmZgmZ class.
1657 : // Cross section for f fbar -> gamma*/Z0 gamma*/Z0 (f is quark or lepton).
1658 :
1659 : //--------------------------------------------------------------------------
1660 :
1661 : // Initialize process.
1662 :
1663 : void Sigma2ffbar2gmZgmZ::initProc() {
1664 :
1665 : // Allow to pick only gamma* or Z0 part of full gamma*/Z0 expression.
1666 0 : gmZmode = settingsPtr->mode("WeakZ0:gmZmode");
1667 :
1668 : // Store Z0 mass and width for propagator.
1669 0 : mRes = particleDataPtr->m0(23);
1670 0 : GammaRes = particleDataPtr->mWidth(23);
1671 0 : m2Res = mRes*mRes;
1672 0 : GamMRat = GammaRes / mRes;
1673 0 : thetaWRat = 1. / (16. * couplingsPtr->sin2thetaW()
1674 0 : * couplingsPtr->cos2thetaW());
1675 :
1676 : // Set pointer to particle properties and decay table.
1677 0 : particlePtr = particleDataPtr->particleDataEntryPtr(23);
1678 :
1679 0 : }
1680 :
1681 : //--------------------------------------------------------------------------
1682 :
1683 : // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
1684 :
1685 : void Sigma2ffbar2gmZgmZ::sigmaKin() {
1686 :
1687 : // Cross section part common for all incoming flavours.
1688 0 : sigma0 = (M_PI / sH2) * pow2(alpEM) * 0.5
1689 0 : * ( (tH2 + uH2 + 2. * (s3 + s4) * sH) / (tH * uH)
1690 0 : - s3 * s4 * (1./tH2 + 1./uH2) );
1691 :
1692 : // Common coupling factors at the resonance masses
1693 0 : double alpEM3 = couplingsPtr->alphaEM(s3);
1694 0 : double alpS3 = couplingsPtr->alphaS(s3);
1695 0 : double colQ3 = 3. * (1. + alpS3 / M_PI);
1696 0 : double alpEM4 = couplingsPtr->alphaEM(s4);
1697 0 : double alpS4 = couplingsPtr->alphaS(s4);
1698 0 : double colQ4 = 3. * (1. + alpS4 / M_PI);
1699 :
1700 : // Reset quantities to sum. Declare variables in loop.
1701 0 : gamSum3 = 0.;
1702 0 : intSum3 = 0.;
1703 0 : resSum3 = 0.;
1704 0 : gamSum4 = 0.;
1705 0 : intSum4 = 0.;
1706 0 : resSum4 = 0.;
1707 : int onMode;
1708 0 : double mf, mr, psvec, psaxi, betaf, ef2, efvf, vf2af2, colf;
1709 :
1710 : // Loop over all Z0 decay channels.
1711 0 : for (int i = 0; i < particlePtr->sizeChannels(); ++i) {
1712 0 : int idAbs = abs( particlePtr->channel(i).product(0) );
1713 :
1714 : // Only contributions from three fermion generations, except top.
1715 0 : if ( (idAbs > 0 && idAbs < 6) || ( idAbs > 10 && idAbs < 17)) {
1716 0 : mf = particleDataPtr->m0(idAbs);
1717 0 : onMode = particlePtr->channel(i).onMode();
1718 :
1719 : // First Z0: check that above threshold. Phase space.
1720 0 : if (m3 > 2. * mf + MASSMARGIN) {
1721 0 : mr = pow2(mf / m3);
1722 0 : betaf = sqrtpos(1. - 4. * mr);
1723 0 : psvec = betaf * (1. + 2. * mr);
1724 0 : psaxi = pow3(betaf);
1725 :
1726 : // First Z0: combine phase space with couplings.
1727 0 : ef2 = couplingsPtr->ef2(idAbs) * psvec;
1728 0 : efvf = couplingsPtr->efvf(idAbs) * psvec;
1729 0 : vf2af2 = couplingsPtr->vf2(idAbs) * psvec
1730 0 : + couplingsPtr->af2(idAbs) * psaxi;
1731 0 : colf = (idAbs < 6) ? colQ3 : 1.;
1732 :
1733 : // First Z0: store sum of combinations for open outstate channels.
1734 0 : if (onMode == 1 || onMode == 2) {
1735 0 : gamSum3 += colf * ef2;
1736 0 : intSum3 += colf * efvf;
1737 0 : resSum3 += colf * vf2af2;
1738 0 : }
1739 : }
1740 :
1741 : // Second Z0: check that above threshold. Phase space.
1742 0 : if (m4 > 2. * mf + MASSMARGIN) {
1743 0 : mr = pow2(mf / m4);
1744 0 : betaf = sqrtpos(1. - 4. * mr);
1745 0 : psvec = betaf * (1. + 2. * mr);
1746 0 : psaxi = pow3(betaf);
1747 :
1748 : // Second Z0: combine phase space with couplings.
1749 0 : ef2 = couplingsPtr->ef2(idAbs) * psvec;
1750 0 : efvf = couplingsPtr->efvf(idAbs) * psvec;
1751 0 : vf2af2 = couplingsPtr->vf2(idAbs) * psvec
1752 0 : + couplingsPtr->af2(idAbs) * psaxi;
1753 0 : colf = (idAbs < 6) ? colQ4 : 1.;
1754 :
1755 : // Second Z0: store sum of combinations for open outstate channels.
1756 0 : if (onMode == 1 || onMode == 2) {
1757 0 : gamSum4 += colf * ef2;
1758 0 : intSum4 += colf * efvf;
1759 0 : resSum4 += colf * vf2af2;
1760 0 : }
1761 : }
1762 :
1763 : // End loop over fermions.
1764 : }
1765 : }
1766 :
1767 : // First Z0: calculate prefactors for gamma/interference/Z0 terms.
1768 0 : gamProp3 = 4. * alpEM3 / (3. * M_PI * s3);
1769 0 : intProp3 = gamProp3 * 2. * thetaWRat * s3 * (s3 - m2Res)
1770 0 : / ( pow2(s3 - m2Res) + pow2(s3 * GamMRat) );
1771 0 : resProp3 = gamProp3 * pow2(thetaWRat * s3)
1772 0 : / ( pow2(s3 - m2Res) + pow2(s3 * GamMRat) );
1773 :
1774 : // First Z0: optionally only keep gamma* or Z0 term.
1775 0 : if (gmZmode == 1) {intProp3 = 0.; resProp3 = 0.;}
1776 0 : if (gmZmode == 2) {gamProp3 = 0.; intProp3 = 0.;}
1777 :
1778 : // Second Z0: calculate prefactors for gamma/interference/Z0 terms.
1779 0 : gamProp4 = 4. * alpEM4 / (3. * M_PI * s4);
1780 0 : intProp4 = gamProp4 * 2. * thetaWRat * s4 * (s4 - m2Res)
1781 0 : / ( pow2(s4 - m2Res) + pow2(s4 * GamMRat) );
1782 0 : resProp4 = gamProp4 * pow2(thetaWRat * s4)
1783 0 : / ( pow2(s4 - m2Res) + pow2(s4 * GamMRat) );
1784 :
1785 : // Second Z0: optionally only keep gamma* or Z0 term.
1786 0 : if (gmZmode == 1) {intProp4 = 0.; resProp4 = 0.;}
1787 0 : if (gmZmode == 2) {gamProp4 = 0.; intProp4 = 0.;}
1788 :
1789 0 : }
1790 :
1791 : //--------------------------------------------------------------------------
1792 :
1793 : // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
1794 :
1795 : double Sigma2ffbar2gmZgmZ::sigmaHat() {
1796 :
1797 : // Charge/2, left- and righthanded couplings for in-fermion.
1798 0 : int idAbs = abs(id1);
1799 0 : double ei = 0.5 * couplingsPtr->ef(idAbs);
1800 0 : double li = couplingsPtr->lf(idAbs);
1801 0 : double ri = couplingsPtr->rf(idAbs);
1802 :
1803 : // Combine left/right gamma, interference and Z0 parts for each Z0.
1804 0 : double left3 = ei * ei * gamProp3 * gamSum3
1805 0 : + ei * li * intProp3 * intSum3
1806 0 : + li * li * resProp3 * resSum3;
1807 : double right3 = ei * ei * gamProp3 * gamSum3
1808 0 : + ei * ri * intProp3 * intSum3
1809 0 : + ri * ri * resProp3 * resSum3;
1810 0 : double left4 = ei * ei * gamProp4 * gamSum4
1811 0 : + ei * li * intProp4 * intSum4
1812 0 : + li * li * resProp4 * resSum4;
1813 : double right4 = ei * ei * gamProp4 * gamSum4
1814 0 : + ei * ri * intProp4 * intSum4
1815 0 : + ri * ri * resProp4 * resSum4;
1816 :
1817 : // Combine left- and right-handed couplings for the two Z0's.
1818 0 : double sigma = sigma0 * (left3 * left4 + right3 * right4);
1819 :
1820 : // Correct for the running-width Z0 propagators weight in PhaseSpace.
1821 0 : sigma /= (runBW3 * runBW4);
1822 :
1823 : // Initial-state colour factor. Answer.
1824 0 : if (idAbs < 9) sigma /= 3.;
1825 0 : return sigma;
1826 :
1827 : }
1828 :
1829 : //--------------------------------------------------------------------------
1830 :
1831 : // Select identity, colour and anticolour.
1832 :
1833 : void Sigma2ffbar2gmZgmZ::setIdColAcol() {
1834 :
1835 : // Flavours trivial.
1836 0 : setId( id1, id2, 23, 23);
1837 :
1838 : // Colour flow topologies. Swap when antiquarks.
1839 0 : if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
1840 0 : else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
1841 0 : if (id1 < 0) swapColAcol();
1842 :
1843 0 : }
1844 :
1845 : //--------------------------------------------------------------------------
1846 :
1847 : // Evaluate correlated decay flavours of the two gamma*/Z0.
1848 : // Unique complication, caused by gamma*/Z0 mix different left/right.
1849 :
1850 : double Sigma2ffbar2gmZgmZ::weightDecayFlav( Event& process) {
1851 :
1852 : // Order so that fbar(1) f(2) -> f'(3) fbar'(4) f"(5) fbar"(6).
1853 0 : i1 = (process[3].id() < 0) ? 3 : 4;
1854 0 : i2 = 7 - i1;
1855 0 : i3 = (process[7].id() > 0) ? 7 : 8;
1856 0 : i4 = 15 - i3;
1857 0 : i5 = (process[9].id() > 0) ? 9 : 10;
1858 0 : i6 = 19 - i5;
1859 :
1860 : // Charge/2, left- and righthanded couplings for in- and out-fermions.
1861 0 : int idAbs = process[i1].idAbs();
1862 0 : double ei = 0.5 * couplingsPtr->ef(idAbs);
1863 0 : double li = couplingsPtr->lf(idAbs);
1864 0 : double ri = couplingsPtr->rf(idAbs);
1865 0 : idAbs = process[i3].idAbs();
1866 0 : double e3 = 0.5 * couplingsPtr->ef(idAbs);
1867 0 : double l3 = couplingsPtr->lf(idAbs);
1868 0 : double r3 = couplingsPtr->rf(idAbs);
1869 0 : idAbs = process[i5].idAbs();
1870 0 : double e4 = 0.5 * couplingsPtr->ef(idAbs);
1871 0 : double l4 = couplingsPtr->lf(idAbs);
1872 0 : double r4 = couplingsPtr->rf(idAbs);
1873 :
1874 : // Left- and righthanded couplings combined with propagators.
1875 0 : c3LL = ei * ei * gamProp3 * e3 * e3
1876 0 : + ei * li * intProp3 * e3 * l3
1877 0 : + li * li * resProp3 * l3 * l3;
1878 0 : c3LR = ei * ei * gamProp3 * e3 * e3
1879 0 : + ei * li * intProp3 * e3 * r3
1880 0 : + li * li * resProp3 * r3 * r3;
1881 0 : c3RL = ei * ei * gamProp3 * e3 * e3
1882 0 : + ei * ri * intProp3 * e3 * l3
1883 0 : + ri * ri * resProp3 * l3 * l3;
1884 0 : c3RR = ei * ei * gamProp3 * e3 * e3
1885 0 : + ei * ri * intProp3 * e3 * r3
1886 0 : + ri * ri * resProp3 * r3 * r3;
1887 0 : c4LL = ei * ei * gamProp4 * e4 * e4
1888 0 : + ei * li * intProp4 * e4 * l4
1889 0 : + li * li * resProp4 * l4 * l4;
1890 0 : c4LR = ei * ei * gamProp4 * e4 * e4
1891 0 : + ei * li * intProp4 * e4 * r4
1892 0 : + li * li * resProp4 * r4 * r4;
1893 0 : c4RL = ei * ei * gamProp4 * e4 * e4
1894 0 : + ei * ri * intProp4 * e4 * l4
1895 0 : + ri * ri * resProp4 * l4 * l4;
1896 0 : c4RR = ei * ei * gamProp4 * e4 * e4
1897 0 : + ei * ri * intProp4 * e4 * r4
1898 0 : + ri * ri * resProp4 * r4 * r4;
1899 :
1900 : // Flavour weight and maximum.
1901 0 : flavWt = (c3LL + c3LR) * (c4LL + c4LR) + (c3RL + c3RR) * (c4RL + c4RR);
1902 0 : double flavWtMax = (c3LL + c3LR + c3RL + c3RR) * (c4LL + c4LR + c4RL + c4RR);
1903 :
1904 : // Done.
1905 0 : return flavWt / flavWtMax;
1906 :
1907 : }
1908 :
1909 : //--------------------------------------------------------------------------
1910 :
1911 : // Evaluate weight for decay angles of the two gamma*/Z0.
1912 :
1913 : double Sigma2ffbar2gmZgmZ::weightDecay( Event& process, int iResBeg,
1914 : int iResEnd) {
1915 :
1916 : // Two resonance decays, but with common weight.
1917 0 : if (iResBeg != 5 || iResEnd != 6) return 1.;
1918 :
1919 : // Set up four-products and internal products.
1920 0 : setupProd( process, i1, i2, i3, i4, i5, i6);
1921 :
1922 : // Flip tHat and uHat if first incoming is fermion.
1923 0 : double tHres = tH;
1924 0 : double uHres = uH;
1925 0 : if (process[3].id() > 0) swap( tHres, uHres);
1926 :
1927 : // Kinematics factors (norm(x) = |x|^2).
1928 0 : double fGK135 = norm( fGK( 1, 2, 3, 4, 5, 6) / tHres
1929 0 : + fGK( 1, 2, 5, 6, 3, 4) / uHres );
1930 0 : double fGK145 = norm( fGK( 1, 2, 4, 3, 5, 6) / tHres
1931 0 : + fGK( 1, 2, 5, 6, 4, 3) / uHres );
1932 0 : double fGK136 = norm( fGK( 1, 2, 3, 4, 6, 5) / tHres
1933 0 : + fGK( 1, 2, 6, 5, 3, 4) / uHres );
1934 0 : double fGK146 = norm( fGK( 1, 2, 4, 3, 6, 5) / tHres
1935 0 : + fGK( 1, 2, 6, 5, 4, 3) / uHres );
1936 0 : double fGK253 = norm( fGK( 2, 1, 5, 6, 3, 4) / tHres
1937 0 : + fGK( 2, 1, 3, 4, 5, 6) / uHres );
1938 0 : double fGK263 = norm( fGK( 2, 1, 6, 5, 3, 4) / tHres
1939 0 : + fGK( 2, 1, 3, 4, 6, 5) / uHres );
1940 0 : double fGK254 = norm( fGK( 2, 1, 5, 6, 4, 3) / tHres
1941 0 : + fGK( 2, 1, 4, 3, 5, 6) / uHres );
1942 0 : double fGK264 = norm( fGK( 2, 1, 6, 5, 4, 3) / tHres
1943 0 : + fGK( 2, 1, 4, 3, 6, 5) / uHres );
1944 :
1945 : // Weight and maximum.
1946 0 : double wt = c3LL * c4LL * fGK135 + c3LR * c4LL * fGK145
1947 0 : + c3LL * c4LR * fGK136 + c3LR * c4LR * fGK146
1948 0 : + c3RL * c4RL * fGK253 + c3RR * c4RL * fGK263
1949 0 : + c3RL * c4RR * fGK254 + c3RR * c4RR * fGK264;
1950 0 : double wtMax = 16. * s3 * s4 * flavWt
1951 0 : * ( (tHres*tHres + uHres*uHres + 2. * sH * (s3 + s4)) / (tHres * uHres)
1952 0 : - s3 * s4 * (1. / (tHres*tHres) + 1. / (uHres*uHres)) );
1953 :
1954 : // Done.
1955 0 : return wt / wtMax;
1956 :
1957 0 : }
1958 :
1959 : //==========================================================================
1960 :
1961 : // Sigma2ffbar2ZW class.
1962 : // Cross section for f fbar' -> Z0 W+- (f is quark or lepton).
1963 :
1964 : //--------------------------------------------------------------------------
1965 :
1966 : // Initialize process.
1967 :
1968 : void Sigma2ffbar2ZW::initProc() {
1969 :
1970 : // Store W+- mass and width for propagator.
1971 0 : mW = particleDataPtr->m0(24);
1972 0 : widW = particleDataPtr->mWidth(24);
1973 0 : mWS = mW*mW;
1974 0 : mwWS = pow2(mW * widW);
1975 :
1976 : // Left-handed couplings for up/nu- and down/e-type quarks.
1977 0 : lun = (hasLeptonBeams) ? couplingsPtr->lf(12) : couplingsPtr->lf(2);
1978 0 : lde = (hasLeptonBeams) ? couplingsPtr->lf(11) : couplingsPtr->lf(1);
1979 :
1980 : // Common weak coupling factor.
1981 0 : sin2thetaW = couplingsPtr->sin2thetaW();
1982 0 : cos2thetaW = couplingsPtr->cos2thetaW();
1983 0 : thetaWRat = 1. / (4. * cos2thetaW);
1984 0 : cotT = sqrt(cos2thetaW / sin2thetaW);
1985 0 : thetaWpt = (9. - 8. * sin2thetaW) / 4.;
1986 0 : thetaWmm = (8. * sin2thetaW - 6.) / 4.;
1987 :
1988 : // Secondary open width fractions.
1989 0 : openFracPos = particleDataPtr->resOpenFrac(23, 24);
1990 0 : openFracNeg = particleDataPtr->resOpenFrac(23, -24);
1991 :
1992 0 : }
1993 :
1994 : //--------------------------------------------------------------------------
1995 :
1996 : // Evaluate sigmaHat(sHat), part independent of incoming flavour.
1997 :
1998 : void Sigma2ffbar2ZW::sigmaKin() {
1999 :
2000 : // Evaluate cross section, as programmed by Merlin Kole (after tidying),
2001 : // based on Brown, Sahdev, Mikaelian, Phys Rev. D20 (1979) 1069.
2002 : /*
2003 : double resBW = 1. / (pow2(sH - mWS) + mwWS);
2004 : double prefac = 12.0 * M_PI * pow2(alpEM) / (sH2 * 8. * sin2thetaW);
2005 : double temp1 = tH * uH - s3 * s4;
2006 : double temp2 = temp1 / (s3 * s4);
2007 : double temp3 = (s3 + s4) / sH;
2008 : double temp4 = s3 * s4 / sH;
2009 : double partA = temp2 * (0.25 - 0.5 * temp3
2010 : + (pow2(s3 + s4) + 8. * s3 * s4)/(4. * sH2) )
2011 : + (s3 + s4)/(s3 * s4) * (sH/2. - s3 - s4 + pow2(s3 - s4)/(2. * sH));
2012 : double partB1 = lun * (0.25 * temp2 * (1. - temp3 - 4. * temp4 / tH)
2013 : + ((s3 + s4)/(2. * s3 * s4)) * (sH - s3 - s4 + 2. * s3 * s4 / tH) );
2014 : double partB2 = lde * ( 0.25 * temp2 * (1.- temp3 - 4. * temp4 / uH)
2015 : + ((s3 + s4)/(2. * s3 * s4)) * (sH - s3 - s4 + 2. * s3 * s4 / uH) );
2016 : double partE = 0.25 * temp2 + 0.5 *(s3 + s4) / temp4;
2017 : sigma0 = prefac * (pow2(cotT) * sH2 * resBW * partA
2018 : + 2.* sH * cotT * resBW * (sH - mWS) * (partB2 - partB1)
2019 : + pow2(lun - lde) * partE + pow2(lde) * temp1/uH2
2020 : + pow2(lun) * temp1/tH2 + 2. * lun * lde * sH * (s3 + s4) / (uH * tH));
2021 : */
2022 :
2023 : // Evaluate cross section. Expression from EHLQ, with bug fix,
2024 : // but can still give negative cross section so suspect.
2025 0 : double resBW = 1. / (pow2(sH - mWS) + mwWS);
2026 0 : sigma0 = (M_PI / sH2) * 0.5 * pow2(alpEM / sin2thetaW);
2027 0 : sigma0 *= sH * resBW * (thetaWpt * pT2 + thetaWmm * (s3 + s4))
2028 0 : + (sH - mWS) * resBW * sH * (pT2 - s3 - s4) * (lun / tH - lde / uH)
2029 0 : + thetaWRat * sH * pT2 * ( lun*lun / tH2 + lde*lde / uH2 )
2030 0 : + 2. * thetaWRat * sH * (s3 + s4) * lun * lde / (tH * uH);
2031 : // Need to protect against negative cross sections at times.
2032 0 : sigma0 = max(0., sigma0);
2033 :
2034 0 : }
2035 :
2036 : //--------------------------------------------------------------------------
2037 :
2038 : // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
2039 :
2040 : double Sigma2ffbar2ZW::sigmaHat() {
2041 :
2042 : // CKM and colour factors.
2043 0 : double sigma = sigma0;
2044 0 : if (abs(id1) < 9) sigma *= couplingsPtr->V2CKMid(abs(id1), abs(id2)) / 3.;
2045 :
2046 : // Corrections for secondary widths in Z0 and W+- decays.
2047 0 : int idUp = (abs(id1)%2 == 0) ? id1 : id2;
2048 0 : sigma *= (idUp > 0) ? openFracPos : openFracNeg;
2049 :
2050 : // Answer.
2051 0 : return sigma;
2052 :
2053 : }
2054 :
2055 : //--------------------------------------------------------------------------
2056 :
2057 : // Select identity, colour and anticolour.
2058 :
2059 : void Sigma2ffbar2ZW::setIdColAcol() {
2060 :
2061 : // Sign of outgoing W.
2062 0 : int sign = 1 - 2 * (abs(id1)%2);
2063 0 : if (id1 < 0) sign = -sign;
2064 0 : setId( id1, id2, 23, 24 * sign);
2065 :
2066 : // tHat is defined between (f, W-) or (fbar, W+),
2067 : // so OK for u/ubar on side 1, but must swap tHat <-> uHat if d/dbar.
2068 0 : if (abs(id1)%2 == 1) swapTU = true;
2069 :
2070 : // Colour flow topologies. Swap when antiquarks.
2071 0 : if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
2072 0 : else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
2073 0 : if (id1 < 0) swapColAcol();
2074 :
2075 0 : }
2076 :
2077 : //--------------------------------------------------------------------------
2078 :
2079 : // Evaluate weight for Z0 and W+- decay angles.
2080 :
2081 : double Sigma2ffbar2ZW::weightDecay( Event& process, int iResBeg, int iResEnd) {
2082 :
2083 : // Two resonance decays, but with common weight.
2084 0 : if (iResBeg != 5 || iResEnd != 6) return 1.;
2085 :
2086 : // Order so that fbar(1) f(2) -> f'(3) fbar'(4) f"(5) fbar"(6)
2087 : // with f' fbar' from W+- and f" fbar" from Z0 (note flip Z0 <-> W+-).
2088 0 : int i1 = (process[3].id() < 0) ? 3 : 4;
2089 0 : int i2 = 7 - i1;
2090 0 : int i3 = (process[9].id() > 0) ? 9 : 10;
2091 0 : int i4 = 19 - i3;
2092 0 : int i5 = (process[7].id() > 0) ? 7 : 8;
2093 0 : int i6 = 15 - i5;
2094 :
2095 : // Set up four-products and internal products.
2096 0 : setupProd( process, i1, i2, i3, i4, i5, i6);
2097 :
2098 : // Swap tHat and uHat if incoming fermion is downtype.
2099 0 : double tHres = tH;
2100 0 : double uHres = uH;
2101 0 : if (process[i2].id()%2 == 1) swap( tHres, uHres);
2102 :
2103 : // Couplings of incoming (anti)fermions and outgoing from Z0.
2104 0 : int idAbs = process[i1].idAbs();
2105 0 : double ai = couplingsPtr->af(idAbs);
2106 0 : double li1 = couplingsPtr->lf(idAbs);
2107 0 : idAbs = process[i2].idAbs();
2108 0 : double li2 = couplingsPtr->lf(idAbs);
2109 0 : idAbs = process[i5].idAbs();
2110 0 : double l4 = couplingsPtr->lf(idAbs);
2111 0 : double r4 = couplingsPtr->rf(idAbs);
2112 :
2113 : // W propagator/interference factor.
2114 0 : double Wint = cos2thetaW * (sH - mWS) / (pow2(sH - mWS) + mwWS);
2115 :
2116 : // Combinations of couplings and kinematics (norm(x) = |x|^2).
2117 0 : double aWZ = li2 / tHres - 2. * Wint * ai;
2118 0 : double bWZ = li1 / uHres + 2. * Wint * ai;
2119 0 : double fGK135 = norm( aWZ * fGK( 1, 2, 3, 4, 5, 6)
2120 0 : + bWZ * fGK( 1, 2, 5, 6, 3, 4) );
2121 0 : double fGK136 = norm( aWZ * fGK( 1, 2, 3, 4, 6, 5)
2122 0 : + bWZ * fGK( 1, 2, 6, 5, 3, 4) );
2123 0 : double xiT = xiGK( tHres, uHres);
2124 0 : double xiU = xiGK( uHres, tHres);
2125 0 : double xjTU = xjGK( tHres, uHres);
2126 :
2127 : // Weight and maximum weight.
2128 0 : double wt = l4*l4 * fGK135 + r4*r4 * fGK136;
2129 0 : double wtMax = 4. * s3 * s4 * (l4*l4 + r4*r4)
2130 0 : * (aWZ * aWZ * xiT + bWZ * bWZ * xiU + aWZ * bWZ * xjTU);
2131 :
2132 : // Done.
2133 0 : return wt / wtMax;
2134 :
2135 0 : }
2136 :
2137 : //==========================================================================
2138 :
2139 : // Sigma2ffbar2WW class.
2140 : // Cross section for f fbar -> W- W+ (f is quark or lepton).
2141 :
2142 : //--------------------------------------------------------------------------
2143 :
2144 : // Initialize process.
2145 :
2146 : void Sigma2ffbar2WW::initProc() {
2147 :
2148 : // Store Z0 mass and width for propagator. Common coupling factor.
2149 0 : mZ = particleDataPtr->m0(23);
2150 0 : widZ = particleDataPtr->mWidth(23);
2151 0 : mZS = mZ*mZ;
2152 0 : mwZS = pow2(mZ * widZ);
2153 0 : thetaWRat = 1. / (4. * couplingsPtr->sin2thetaW());
2154 :
2155 : // Secondary open width fraction.
2156 0 : openFracPair = particleDataPtr->resOpenFrac(24, -24);
2157 :
2158 0 : }
2159 :
2160 : //--------------------------------------------------------------------------
2161 :
2162 : // Evaluate sigmaHat(sHat), part independent of incoming flavour.
2163 :
2164 : void Sigma2ffbar2WW::sigmaKin() {
2165 :
2166 : // Cross section part common for all incoming flavours.
2167 0 : sigma0 = (M_PI / sH2) * pow2(alpEM);
2168 :
2169 : // Z0 propagator and gamma*/Z0 interference.
2170 0 : double Zprop = sH2 / (pow2(sH - mZS) + mwZS);
2171 0 : double Zint = Zprop * (1. - mZS / sH);
2172 :
2173 : // Common coupling factors (g = gamma*, Z = Z0, f = t-channel fermion).
2174 0 : cgg = 0.5;
2175 0 : cgZ = thetaWRat * Zint;
2176 0 : cZZ = 0.5 * pow2(thetaWRat) * Zprop;
2177 0 : cfg = thetaWRat;
2178 0 : cfZ = pow2(thetaWRat) * Zint;
2179 0 : cff = pow2(thetaWRat);
2180 :
2181 : // Kinematical functions.
2182 0 : double rat34 = sH * (2. * (s3 + s4) + pT2) / (s3 * s4);
2183 0 : double lambdaS = pow2(sH - s3 - s4) - 4. * s3 * s4;
2184 0 : double intA = (sH - s3 - s4) * rat34 / sH;
2185 0 : double intB = 4. * (s3 + s4 - pT2);
2186 0 : gSS = (lambdaS * rat34 + 12. * sH * pT2) / sH2;
2187 0 : gTT = rat34 + 4. * sH * pT2 / tH2;
2188 0 : gST = intA + intB / tH;
2189 0 : gUU = rat34 + 4. * sH * pT2 / uH2;
2190 0 : gSU = intA + intB / uH;
2191 :
2192 0 : }
2193 :
2194 : //--------------------------------------------------------------------------
2195 :
2196 : // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
2197 :
2198 : double Sigma2ffbar2WW::sigmaHat() {
2199 :
2200 : // Flavour-specific couplings.
2201 0 : int idAbs = abs(id1);
2202 0 : double ei = couplingsPtr->ef(idAbs);
2203 0 : double vi = couplingsPtr->vf(idAbs);
2204 0 : double ai = couplingsPtr->af(idAbs);
2205 :
2206 : // Combine, with different cases for up- and down-type in-flavours.
2207 0 : double sigma = sigma0;
2208 0 : sigma *= (idAbs%2 == 1)
2209 0 : ? (cgg * ei*ei + cgZ * ei * vi + cZZ * (vi*vi + ai*ai)) * gSS
2210 0 : + (cfg * ei + cfZ * (vi + ai)) * gST + cff * gTT
2211 : : (cgg * ei*ei + cgZ * ei * vi + cZZ * (vi*vi + ai*ai)) * gSS
2212 0 : - (cfg * ei + cfZ * (vi + ai)) * gSU + cff * gUU;
2213 :
2214 : // Initial-state colour factor. Correction for secondary widths. Answer.
2215 0 : if (idAbs < 9) sigma /= 3.;
2216 0 : sigma *= openFracPair;
2217 0 : return sigma;
2218 :
2219 : }
2220 :
2221 : //--------------------------------------------------------------------------
2222 :
2223 : // Select identity, colour and anticolour.
2224 :
2225 : void Sigma2ffbar2WW::setIdColAcol() {
2226 :
2227 : // Always order W- W+, i.e. W- first.
2228 0 : setId( id1, id2, -24, 24);
2229 :
2230 : // tHat is defined between (f, W-) or (fbar, W+),
2231 0 : if (id1 < 0) swapTU = true;
2232 :
2233 : // Colour flow topologies. Swap when antiquarks.
2234 0 : if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
2235 0 : else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
2236 0 : if (id1 < 0) swapColAcol();
2237 :
2238 0 : }
2239 :
2240 : //--------------------------------------------------------------------------
2241 :
2242 : // Evaluate weight for W+ and W- decay angles.
2243 :
2244 : double Sigma2ffbar2WW::weightDecay( Event& process, int iResBeg, int iResEnd) {
2245 :
2246 : // Two resonance decays, but with common weight.
2247 0 : if (iResBeg != 5 || iResEnd != 6) return 1.;
2248 :
2249 : // Order so that fbar(1) f(2) -> f'(3) fbar'(4) f"(5) fbar"(6).
2250 : // with f' fbar' from W- and f" fbar" from W+.
2251 0 : int i1 = (process[3].id() < 0) ? 3 : 4;
2252 0 : int i2 = 7 - i1;
2253 0 : int i3 = (process[7].id() > 0) ? 7 : 8;
2254 0 : int i4 = 15 - i3;
2255 0 : int i5 = (process[9].id() > 0) ? 9 : 10;
2256 0 : int i6 = 19 - i5;
2257 :
2258 : // Set up four-products and internal products.
2259 0 : setupProd( process, i1, i2, i3, i4, i5, i6);
2260 :
2261 : // tHat and uHat of fbar f -> W- W+ opposite to previous convention.
2262 0 : double tHres = uH;
2263 0 : double uHres = tH;
2264 :
2265 : // Couplings of incoming (anti)fermion.
2266 0 : int idAbs = process[i1].idAbs();
2267 0 : double ai = couplingsPtr->af(idAbs);
2268 0 : double li = couplingsPtr->lf(idAbs);
2269 0 : double ri = couplingsPtr->rf(idAbs);
2270 :
2271 : // gamma*/Z0 propagator/interference factor.
2272 0 : double Zint = mZS * (sH - mZS) / (pow2(sH - mZS) + mwZS);
2273 :
2274 : // Combinations of couplings and kinematics (norm(x) = |x|^2).
2275 0 : double dWW = (li * Zint + ai) / sH;
2276 0 : double aWW = dWW + 0.5 * (ai + 1.) / tHres;
2277 0 : double bWW = dWW + 0.5 * (ai - 1.) / uHres;
2278 0 : double cWW = ri * Zint / sH;
2279 0 : double fGK135 = norm( aWW * fGK( 1, 2, 3, 4, 5, 6)
2280 0 : - bWW * fGK( 1, 2, 5, 6, 3, 4) );
2281 0 : double fGK253 = norm( cWW * ( fGK( 2, 1, 5, 6, 3, 4)
2282 0 : - fGK( 2, 1, 3, 4, 5, 6) ) );
2283 0 : double xiT = xiGK( tHres, uHres);
2284 0 : double xiU = xiGK( uHres, tHres);
2285 0 : double xjTU = xjGK( tHres, uHres);
2286 :
2287 : // Weight and maximum weight.
2288 0 : double wt = fGK135 + fGK253;
2289 0 : double wtMax = 4. * s3 * s4
2290 0 : * ( aWW * aWW * xiT + bWW * bWW * xiU - aWW * bWW * xjTU
2291 0 : + cWW * cWW * (xiT + xiU - xjTU) );
2292 :
2293 : // Done.
2294 0 : return wt / wtMax;
2295 0 : }
2296 :
2297 : //==========================================================================
2298 :
2299 : // Sigma2ffbargmZggm class.
2300 : // Collects common methods for f fbar -> gamma*/Z0 g/gamma and permutations.
2301 :
2302 : //--------------------------------------------------------------------------
2303 :
2304 : // Initialize process.
2305 :
2306 : void Sigma2ffbargmZggm::initProc() {
2307 :
2308 : // Allow to pick only gamma* or Z0 part of full gamma*/Z0 expression.
2309 0 : gmZmode = settingsPtr->mode("WeakZ0:gmZmode");
2310 :
2311 : // Store Z0 mass and width for propagator.
2312 0 : mRes = particleDataPtr->m0(23);
2313 0 : GammaRes = particleDataPtr->mWidth(23);
2314 0 : m2Res = mRes*mRes;
2315 0 : GamMRat = GammaRes / mRes;
2316 0 : thetaWRat = 1. / (16. * couplingsPtr->sin2thetaW()
2317 0 : * couplingsPtr->cos2thetaW());
2318 :
2319 : // Set pointer to particle properties and decay table.
2320 0 : particlePtr = particleDataPtr->particleDataEntryPtr(23);
2321 :
2322 0 : }
2323 :
2324 : //--------------------------------------------------------------------------
2325 :
2326 : // Evaluate sum of flavour couplings times phase space.
2327 :
2328 : void Sigma2ffbargmZggm::flavSum() {
2329 :
2330 : // Coupling factors for Z0 subsystem.
2331 0 : double alpSZ = couplingsPtr->alphaS(s3);
2332 0 : double colQZ = 3. * (1. + alpSZ / M_PI);
2333 :
2334 : // Reset quantities to sum. Declare variables in loop.
2335 0 : gamSum = 0.;
2336 0 : intSum = 0.;
2337 0 : resSum = 0.;
2338 : int onMode;
2339 0 : double mf, mr, psvec, psaxi, betaf, ef2, efvf, vf2af2, colf;
2340 :
2341 : // Loop over all Z0 decay channels.
2342 0 : for (int i = 0; i < particlePtr->sizeChannels(); ++i) {
2343 0 : int idAbs = abs( particlePtr->channel(i).product(0) );
2344 :
2345 : // Only contributions from three fermion generations, except top.
2346 0 : if ( (idAbs > 0 && idAbs < 6) || ( idAbs > 10 && idAbs < 17)) {
2347 0 : mf = particleDataPtr->m0(idAbs);
2348 :
2349 : // Check that above threshold. Phase space.
2350 0 : if (m3 > 2. * mf + MASSMARGIN) {
2351 0 : mr = pow2(mf / m3);
2352 0 : betaf = sqrtpos(1. - 4. * mr);
2353 0 : psvec = betaf * (1. + 2. * mr);
2354 0 : psaxi = pow3(betaf);
2355 :
2356 : // Combine phase space with couplings.
2357 0 : ef2 = couplingsPtr->ef2(idAbs) * psvec;
2358 0 : efvf = couplingsPtr->efvf(idAbs) * psvec;
2359 0 : vf2af2 = couplingsPtr->vf2(idAbs) * psvec
2360 0 : + couplingsPtr->af2(idAbs) * psaxi;
2361 0 : colf = (idAbs < 6) ? colQZ : 1.;
2362 :
2363 : // Store sum of combinations. For outstate only open channels.
2364 0 : onMode = particlePtr->channel(i).onMode();
2365 0 : if (onMode == 1 || onMode == 2) {
2366 0 : gamSum += colf * ef2;
2367 0 : intSum += colf * efvf;
2368 0 : resSum += colf * vf2af2;
2369 0 : }
2370 :
2371 : // End loop over fermions.
2372 : }
2373 : }
2374 : }
2375 :
2376 : // Done. Return values in gamSum, intSum and resSum.
2377 :
2378 0 : }
2379 :
2380 : //--------------------------------------------------------------------------
2381 :
2382 : // Calculate common parts of gamma/interference/Z0 propagator terms.
2383 :
2384 : void Sigma2ffbargmZggm::propTerm() {
2385 :
2386 : // Calculate prefactors for gamma/interference/Z0 cross section terms.
2387 0 : gamProp = 4. * alpEM / (3. * M_PI * s3);
2388 0 : intProp = gamProp * 2. * thetaWRat * s3 * (s3 - m2Res)
2389 0 : / ( pow2(s3 - m2Res) + pow2(s3 * GamMRat) );
2390 0 : resProp = gamProp * pow2(thetaWRat * s3)
2391 0 : / ( pow2(s3 - m2Res) + pow2(s3 * GamMRat) );
2392 :
2393 : // Optionally only keep gamma* or Z0 term.
2394 0 : if (gmZmode == 1) {intProp = 0.; resProp = 0.;}
2395 0 : if (gmZmode == 2) {gamProp = 0.; intProp = 0.;}
2396 :
2397 0 : }
2398 :
2399 : //--------------------------------------------------------------------------
2400 :
2401 : // Evaluate weight for gamma*/Z0 decay angle.
2402 :
2403 : double Sigma2ffbargmZggm::weightDecay( Event& process, int iResBeg,
2404 : int iResEnd) {
2405 :
2406 : // Z should sit in entry 5 and one more parton in entry 6.
2407 0 : if (iResBeg != 5 || iResEnd != 6) return 1.;
2408 :
2409 : // In an outgoing sense fermions are labelled f(1) fbar(2) f'(3) fbar'(4)
2410 : // where f' fbar' come from gamma*/Z0 decay.
2411 : int i1, i2;
2412 0 : int i3 = (process[7].id() > 0) ? 7 : 8;
2413 0 : int i4 = 15 - i3;
2414 :
2415 : // Order so that fbar(1) f(2) -> gamma*/Z0 g/gamma.
2416 0 : if (process[3].idAbs() < 20 && process[4].idAbs() < 20) {
2417 0 : i1 = (process[3].id() < 0) ? 3 : 4;
2418 0 : i2 = 7 - i1;
2419 :
2420 : // Order so that f(2)/fbar(1) g/gamma -> f(1)/fbar(2) f'(3) gamma*/Z0.
2421 0 : } else if (process[3].idAbs() < 20) {
2422 0 : i1 = (process[3].id() < 0) ? 3 : 6;
2423 0 : i2 = 9 - i1;
2424 0 : } else {
2425 0 : i1 = (process[4].id() < 0) ? 4 : 6;
2426 0 : i2 = 10 - i1;
2427 : }
2428 :
2429 : // Charge/2, left- and righthanded couplings for in- and out-fermion.
2430 0 : int id1Abs = process[i1].idAbs();
2431 0 : double ei = 0.5 * couplingsPtr->ef(id1Abs);
2432 0 : double li = couplingsPtr->lf(id1Abs);
2433 0 : double ri = couplingsPtr->rf(id1Abs);
2434 0 : int id3Abs = process[i3].idAbs();
2435 0 : double ef = 0.5 * couplingsPtr->ef(id3Abs);
2436 0 : double lf = couplingsPtr->lf(id3Abs);
2437 0 : double rf = couplingsPtr->rf(id3Abs);
2438 :
2439 : // Combinations of left/right for in/out, gamma*/interference/Z0.
2440 0 : double clilf = ei*ei * gamProp * ef*ef + ei*li * intProp * ef*lf
2441 0 : + li*li * resProp * lf*lf;
2442 0 : double clirf = ei*ei * gamProp * ef*ef + ei*li * intProp * ef*rf
2443 0 : + li*li * resProp * rf*rf;
2444 0 : double crilf = ei*ei * gamProp * ef*ef + ei*ri * intProp * ef*lf
2445 0 : + ri*ri * resProp * lf*lf;
2446 0 : double crirf = ei*ei * gamProp * ef*ef + ei*ri * intProp * ef*rf
2447 0 : + ri*ri * resProp * rf*rf;
2448 :
2449 : // Evaluate four-vector products.
2450 0 : double p13 = process[i1].p() * process[i3].p();
2451 0 : double p14 = process[i1].p() * process[i4].p();
2452 0 : double p23 = process[i2].p() * process[i3].p();
2453 0 : double p24 = process[i2].p() * process[i4].p();
2454 :
2455 : // Calculate weight and its maximum.
2456 0 : double wt = (clilf + crirf) * (p13*p13 + p24*p24)
2457 0 : + (clirf + crilf) * (p14*p14 + p23*p23) ;
2458 0 : double wtMax = (clilf + clirf + crilf + crirf)
2459 0 : * (pow2(p13 + p14) + pow2(p23 + p24));
2460 :
2461 : // Done.
2462 0 : return (wt / wtMax);
2463 :
2464 0 : }
2465 :
2466 : //==========================================================================
2467 :
2468 : // Sigma2qqbar2gmZg class.
2469 : // Cross section for q qbar -> gamma*/Z0 g.
2470 :
2471 : //--------------------------------------------------------------------------
2472 :
2473 : // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
2474 :
2475 : void Sigma2qqbar2gmZg::sigmaKin() {
2476 :
2477 : // Cross section part common for all incoming flavours.
2478 0 : sigma0 = (M_PI / sH2) * (alpEM * alpS)
2479 0 : * (2./9.) * (tH2 + uH2 + 2. * sH * s3) / (tH * uH);
2480 :
2481 : // Calculate flavour sums for final state.
2482 0 : flavSum();
2483 :
2484 : // Calculate prefactors for gamma/interference/Z0 cross section terms.
2485 0 : propTerm();
2486 :
2487 0 : }
2488 :
2489 : //--------------------------------------------------------------------------
2490 :
2491 : // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
2492 :
2493 : double Sigma2qqbar2gmZg::sigmaHat() {
2494 :
2495 : // Combine gamma, interference and Z0 parts.
2496 0 : int idAbs = abs(id1);
2497 0 : double sigma = sigma0
2498 0 : * ( couplingsPtr->ef2(idAbs) * gamProp * gamSum
2499 0 : + couplingsPtr->efvf(idAbs) * intProp * intSum
2500 0 : + couplingsPtr->vf2af2(idAbs) * resProp * resSum);
2501 :
2502 : // Correct for the running-width Z0 propagater weight in PhaseSpace.
2503 0 : sigma /= runBW3;
2504 :
2505 : // Answer.
2506 0 : return sigma;
2507 :
2508 : }
2509 :
2510 : //--------------------------------------------------------------------------
2511 :
2512 : // Select identity, colour and anticolour.
2513 :
2514 : void Sigma2qqbar2gmZg::setIdColAcol() {
2515 :
2516 : // Flavours trivial.
2517 0 : setId( id1, id2, 23, 21);
2518 :
2519 : // Colour flow topologies. Swap when antiquarks.
2520 0 : setColAcol( 1, 0, 0, 2, 0, 0, 1, 2);
2521 0 : if (id1 < 0) swapColAcol();
2522 :
2523 0 : }
2524 :
2525 : //==========================================================================
2526 :
2527 : // Sigma2qg2gmZq class.
2528 : // Cross section for q g -> gamma*/Z0 q.
2529 :
2530 : //--------------------------------------------------------------------------
2531 :
2532 : // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
2533 :
2534 : void Sigma2qg2gmZq::sigmaKin() {
2535 :
2536 : // Cross section part common for all incoming flavours.
2537 0 : sigma0 = (M_PI / sH2) * (alpEM * alpS)
2538 0 : * (1./12.) * (sH2 + uH2 + 2. * tH * s3) / (-sH * uH);
2539 :
2540 : // Calculate flavour sums for final state.
2541 0 : flavSum();
2542 :
2543 : // Calculate prefactors for gamma/interference/Z0 cross section terms.
2544 0 : propTerm();
2545 :
2546 0 : }
2547 :
2548 : //--------------------------------------------------------------------------
2549 :
2550 : // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
2551 :
2552 : double Sigma2qg2gmZq::sigmaHat() {
2553 :
2554 : // Combine gamma, interference and Z0 parts.
2555 0 : int idAbs = (id2 == 21) ? abs(id1) : abs(id2);
2556 0 : double sigma = sigma0
2557 0 : * ( couplingsPtr->ef2(idAbs) * gamProp * gamSum
2558 0 : + couplingsPtr->efvf(idAbs) * intProp * intSum
2559 0 : + couplingsPtr->vf2af2(idAbs) * resProp * resSum);
2560 :
2561 : // Correct for the running-width Z0 propagater weight in PhaseSpace.
2562 0 : sigma /= runBW3;
2563 :
2564 : // Answer.
2565 0 : return sigma;
2566 :
2567 : }
2568 :
2569 : //--------------------------------------------------------------------------
2570 :
2571 : // Select identity, colour and anticolour.
2572 :
2573 : void Sigma2qg2gmZq::setIdColAcol() {
2574 :
2575 : // Flavour set up for q g -> gamma*/Z0 q.
2576 0 : int idq = (id2 == 21) ? id1 : id2;
2577 0 : setId( id1, id2, 23, idq);
2578 :
2579 : // tH defined between f and f': must swap tHat <-> uHat if q g in.
2580 0 : swapTU = (id2 == 21);
2581 :
2582 : // Colour flow topologies. Swap when antiquarks.
2583 0 : if (id2 == 21) setColAcol( 1, 0, 2, 1, 0, 0, 2, 0);
2584 0 : else setColAcol( 2, 1, 1, 0, 0, 0, 2, 0);
2585 0 : if (idq < 0) swapColAcol();
2586 :
2587 0 : }
2588 :
2589 : //==========================================================================
2590 :
2591 : // Sigma2ffbar2gmZgm class.
2592 : // Cross section for f fbar -> gamma*/Z0 gamma.
2593 :
2594 : //--------------------------------------------------------------------------
2595 :
2596 : // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
2597 :
2598 : void Sigma2ffbar2gmZgm::sigmaKin() {
2599 :
2600 : // Cross section part common for all incoming flavours.
2601 0 : sigma0 = (M_PI / sH2) * (alpEM*alpEM)
2602 0 : * 0.5 * (tH2 + uH2 + 2. * sH * s3) / (tH * uH);
2603 :
2604 : // Calculate flavour sums for final state.
2605 0 : flavSum();
2606 :
2607 : // Calculate prefactors for gamma/interference/Z0 cross section terms.
2608 0 : propTerm();
2609 :
2610 :
2611 0 : }
2612 :
2613 : //--------------------------------------------------------------------------
2614 :
2615 : // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
2616 :
2617 : double Sigma2ffbar2gmZgm::sigmaHat() {
2618 :
2619 : // Combine gamma, interference and Z0 parts.
2620 0 : int idAbs = abs(id1);
2621 0 : double sigma = sigma0 * couplingsPtr->ef2(idAbs)
2622 0 : * ( couplingsPtr->ef2(idAbs) * gamProp * gamSum
2623 0 : + couplingsPtr->efvf(idAbs) * intProp * intSum
2624 0 : + couplingsPtr->vf2af2(idAbs) * resProp * resSum);
2625 :
2626 : // Correct for the running-width Z0 propagater weight in PhaseSpace.
2627 0 : sigma /= runBW3;
2628 :
2629 : // Colour factor. Answer.
2630 0 : if (idAbs < 9) sigma /= 3.;
2631 0 : return sigma;
2632 :
2633 : }
2634 :
2635 : //--------------------------------------------------------------------------
2636 :
2637 : // Select identity, colour and anticolour.
2638 :
2639 : void Sigma2ffbar2gmZgm::setIdColAcol() {
2640 :
2641 : // Flavours trivial.
2642 0 : setId( id1, id2, 23, 22);
2643 :
2644 : // Colour flow topologies. Swap when antiquarks.
2645 0 : if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
2646 0 : else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
2647 0 : if (id1 < 0) swapColAcol();
2648 :
2649 0 : }
2650 :
2651 : //==========================================================================
2652 :
2653 : // Sigma2fgm2gmZf class.
2654 : // Cross section for f gamma -> gamma*/Z0 f'.
2655 :
2656 : //--------------------------------------------------------------------------
2657 :
2658 : // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
2659 :
2660 : void Sigma2fgm2gmZf::sigmaKin() {
2661 :
2662 : // Cross section part common for all incoming flavours.
2663 0 : sigma0 = (M_PI / sH2) * (alpEM*alpEM)
2664 0 : * 0.5 * (sH2 + uH2 + 2. * tH * s3) / (- sH * uH);
2665 :
2666 : // Calculate flavour sums for final state.
2667 0 : flavSum();
2668 :
2669 : // Calculate prefactors for gamma/interference/Z0 cross section terms.
2670 0 : propTerm();
2671 :
2672 0 : }
2673 :
2674 : //--------------------------------------------------------------------------
2675 :
2676 : // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
2677 :
2678 : double Sigma2fgm2gmZf::sigmaHat() {
2679 :
2680 : // Combine gamma, interference and Z0 parts.
2681 0 : int idAbs = (id2 == 22) ? abs(id1) : abs(id2);
2682 0 : double sigma = sigma0 * couplingsPtr->ef2(idAbs)
2683 0 : * ( couplingsPtr->ef2(idAbs) * gamProp * gamSum
2684 0 : + couplingsPtr->efvf(idAbs) * intProp * intSum
2685 0 : + couplingsPtr->vf2af2(idAbs) * resProp * resSum);
2686 :
2687 : // Correct for the running-width Z0 propagater weight in PhaseSpace.
2688 0 : sigma /= runBW3;
2689 :
2690 : // Answer.
2691 0 : return sigma;
2692 :
2693 : }
2694 :
2695 : //--------------------------------------------------------------------------
2696 :
2697 : // Select identity, colour and anticolour.
2698 :
2699 : void Sigma2fgm2gmZf::setIdColAcol() {
2700 :
2701 : // Flavour set up for q gamma -> gamma*/Z0 q.
2702 0 : int idq = (id2 == 22) ? id1 : id2;
2703 0 : setId( id1, id2, 23, idq);
2704 :
2705 : // tH defined between f and f': must swap tHat <-> uHat if q gamma in.
2706 0 : swapTU = (id2 == 22);
2707 :
2708 : // Colour flow topologies. Swap when antiquarks.
2709 0 : if (abs(id1) < 9) setColAcol( 1, 0, 0, 0, 0, 0, 1, 0);
2710 0 : else if (abs(id2) < 9) setColAcol( 0, 0, 1, 0, 0, 0, 1, 0);
2711 0 : else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
2712 0 : if (idq < 0) swapColAcol();
2713 :
2714 0 : }
2715 :
2716 : //==========================================================================
2717 :
2718 : // Sigma2ffbarWggm class.
2719 : // Collects common methods for f fbar -> W+- g/gamma and permutations.
2720 :
2721 : //--------------------------------------------------------------------------
2722 :
2723 : // Evaluate weight for W+- decay angle.
2724 :
2725 : double Sigma2ffbarWggm::weightDecay( Event& process, int iResBeg,
2726 : int iResEnd) {
2727 :
2728 : // W should sit in entry 5 and one more parton in entry 6.
2729 0 : if (iResBeg != 5 || iResEnd != 6) return 1.;
2730 :
2731 : // In an outgoing sense fermions are labelled f(1) fbar(2) f'(3) fbar'(4)
2732 : // where f' fbar' come from W+- decay.
2733 : int i1, i2;
2734 0 : int i3 = (process[7].id() > 0) ? 7 : 8;
2735 0 : int i4 = 15 - i3;
2736 :
2737 : // Order so that fbar(1) f(2) -> W+- g/gamma.
2738 0 : if (process[3].idAbs() < 20 && process[4].idAbs() < 20) {
2739 0 : i1 = (process[3].id() < 0) ? 3 : 4;
2740 0 : i2 = 7 - i1;
2741 :
2742 : // Order so that f(2)/fbar(1) g/gamma -> f(1)/fbar(2) f'(3) W+-.
2743 0 : } else if (process[3].idAbs() < 20) {
2744 0 : i1 = (process[3].id() < 0) ? 3 : 6;
2745 0 : i2 = 9 - i1;
2746 0 : } else {
2747 0 : i1 = (process[4].id() < 0) ? 4 : 6;
2748 0 : i2 = 10 - i1;
2749 : }
2750 :
2751 : // Evaluate four-vector products.
2752 0 : double p13 = process[i1].p() * process[i3].p();
2753 0 : double p14 = process[i1].p() * process[i4].p();
2754 0 : double p23 = process[i2].p() * process[i3].p();
2755 0 : double p24 = process[i2].p() * process[i4].p();
2756 :
2757 : // Calculate weight and its maximum.
2758 0 : double wt = pow2(p13) + pow2(p24);
2759 0 : double wtMax = pow2(p13 + p14) + pow2(p23 + p24);
2760 :
2761 : // Done.
2762 0 : return (wt / wtMax);
2763 :
2764 0 : }
2765 :
2766 : //==========================================================================
2767 :
2768 : // Sigma2qqbar2Wg class.
2769 : // Cross section for q qbar' -> W+- g.
2770 :
2771 : //--------------------------------------------------------------------------
2772 :
2773 : // Initialize process.
2774 :
2775 : void Sigma2qqbar2Wg::initProc() {
2776 :
2777 : // Secondary open width fractions, relevant for top (or heavier).
2778 0 : openFracPos = particleDataPtr->resOpenFrac(24);
2779 0 : openFracNeg = particleDataPtr->resOpenFrac(-24);
2780 :
2781 0 : }
2782 :
2783 : //--------------------------------------------------------------------------
2784 :
2785 : // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
2786 :
2787 : void Sigma2qqbar2Wg::sigmaKin() {
2788 :
2789 : // Cross section part common for all incoming flavours.
2790 0 : sigma0 = (M_PI / sH2) * (alpEM * alpS / couplingsPtr->sin2thetaW())
2791 0 : * (2./9.) * (tH2 + uH2 + 2. * sH * s3) / (tH * uH);
2792 :
2793 0 : }
2794 :
2795 : //--------------------------------------------------------------------------
2796 :
2797 : // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
2798 :
2799 : double Sigma2qqbar2Wg::sigmaHat() {
2800 :
2801 : // CKM factor. Secondary width for W+ or W-.
2802 0 : double sigma = sigma0 * couplingsPtr->V2CKMid(abs(id1), abs(id2));
2803 0 : int idUp = (abs(id1)%2 == 0) ? id1 : id2;
2804 0 : sigma *= (idUp > 0) ? openFracPos : openFracNeg;
2805 :
2806 : // Answer.
2807 0 : return sigma;
2808 :
2809 : }
2810 :
2811 : //--------------------------------------------------------------------------
2812 :
2813 : // Select identity, colour and anticolour.
2814 :
2815 : void Sigma2qqbar2Wg::setIdColAcol() {
2816 :
2817 : // Sign of outgoing W.
2818 0 : int sign = 1 - 2 * (abs(id1)%2);
2819 0 : if (id1 < 0) sign = -sign;
2820 0 : setId( id1, id2, 24 * sign, 21);
2821 :
2822 : // Colour flow topologies. Swap when antiquarks.
2823 0 : setColAcol( 1, 0, 0, 2, 0, 0, 1, 2);
2824 0 : if (id1 < 0) swapColAcol();
2825 :
2826 0 : }
2827 :
2828 : //==========================================================================
2829 :
2830 : // Sigma2qg2Wq class.
2831 : // Cross section for q g -> W+- q'.
2832 :
2833 : //--------------------------------------------------------------------------
2834 :
2835 : // Initialize process.
2836 :
2837 : void Sigma2qg2Wq::initProc() {
2838 :
2839 : // Secondary open width fractions, relevant for top (or heavier).
2840 0 : openFracPos = particleDataPtr->resOpenFrac(24);
2841 0 : openFracNeg = particleDataPtr->resOpenFrac(-24);
2842 :
2843 0 : }
2844 :
2845 : //--------------------------------------------------------------------------
2846 :
2847 : // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
2848 :
2849 : void Sigma2qg2Wq::sigmaKin() {
2850 :
2851 : // Cross section part common for all incoming flavours.
2852 0 : sigma0 = (M_PI / sH2) * (alpEM * alpS / couplingsPtr->sin2thetaW())
2853 0 : * (1./12.) * (sH2 + uH2 + 2. * tH * s3) / (-sH * uH);
2854 :
2855 0 : }
2856 :
2857 : //--------------------------------------------------------------------------
2858 :
2859 : // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
2860 :
2861 : double Sigma2qg2Wq::sigmaHat() {
2862 :
2863 : // CKM factor. Secondary width for W+ or W-.
2864 0 : int idAbs = (id2 == 21) ? abs(id1) : abs(id2);
2865 0 : double sigma = sigma0 * couplingsPtr->V2CKMsum(idAbs);
2866 0 : int idUp = (id2 == 21) ? id1 : id2;
2867 0 : if (idAbs%2 == 1) idUp = -idUp;
2868 0 : sigma *= (idUp > 0) ? openFracPos : openFracNeg;
2869 :
2870 : // Answer.
2871 0 : return sigma;
2872 :
2873 : }
2874 :
2875 : //--------------------------------------------------------------------------
2876 :
2877 : // Select identity, colour and anticolour.
2878 :
2879 : void Sigma2qg2Wq::setIdColAcol() {
2880 :
2881 : // Sign of outgoing W. Flavour of outgoing quark.
2882 0 : int idq = (id2 == 21) ? id1 : id2;
2883 0 : int sign = 1 - 2 * (abs(idq)%2);
2884 0 : if (idq < 0) sign = -sign;
2885 0 : id4 = couplingsPtr->V2CKMpick(idq);
2886 :
2887 : // Flavour set up for q g -> W q.
2888 0 : setId( id1, id2, 24 * sign, id4);
2889 :
2890 : // tH defined between f and f': must swap tHat <-> uHat if q g in.
2891 0 : swapTU = (id2 == 21);
2892 :
2893 : // Colour flow topologies. Swap when antiquarks.
2894 0 : if (id2 == 21) setColAcol( 1, 0, 2, 1, 0, 0, 2, 0);
2895 0 : else setColAcol( 2, 1, 1, 0, 0, 0, 2, 0);
2896 0 : if (idq < 0) swapColAcol();
2897 :
2898 0 : }
2899 :
2900 : //==========================================================================
2901 :
2902 : // Sigma2ffbar2Wgm class.
2903 : // Cross section for f fbar' -> W+- gamma.
2904 :
2905 : //--------------------------------------------------------------------------
2906 :
2907 : // Initialize process.
2908 :
2909 : void Sigma2ffbar2Wgm::initProc() {
2910 :
2911 : // Secondary open width fractions, relevant for top (or heavier).
2912 0 : openFracPos = particleDataPtr->resOpenFrac(24);
2913 0 : openFracNeg = particleDataPtr->resOpenFrac(-24);
2914 :
2915 0 : }
2916 :
2917 : //--------------------------------------------------------------------------
2918 :
2919 : // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
2920 :
2921 : void Sigma2ffbar2Wgm::sigmaKin() {
2922 :
2923 : // Cross section part common for all incoming flavours.
2924 0 : sigma0 = (M_PI / sH2) * (alpEM*alpEM / couplingsPtr->sin2thetaW())
2925 0 : * 0.5 * (tH2 + uH2 + 2. * sH * s3) / (tH * uH);
2926 0 : }
2927 :
2928 : //--------------------------------------------------------------------------
2929 :
2930 : // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
2931 :
2932 : double Sigma2ffbar2Wgm::sigmaHat() {
2933 :
2934 : // Extrafactor different for e nu and q qbar' instate.
2935 0 : int id1Abs = abs(id1);
2936 0 : int id2Abs = abs(id2);
2937 0 : double chgUp = (id1Abs > 10) ? 0. : 2./3.;
2938 0 : double sigma = sigma0 * pow2( chgUp - tH / (tH + uH) );
2939 :
2940 : // CKM and colour factors. Secondary width for W+ or W-.
2941 0 : if (id1Abs < 9) sigma *= couplingsPtr->V2CKMid(id1Abs, id2Abs) / 3.;
2942 0 : int idUp = (abs(id1)%2 == 0) ? id1 : id2;
2943 0 : sigma *= (idUp > 0) ? openFracPos : openFracNeg;
2944 :
2945 : // Answer.
2946 0 : return sigma;
2947 :
2948 : }
2949 :
2950 : //--------------------------------------------------------------------------
2951 :
2952 : // Select identity, colour and anticolour.
2953 :
2954 : void Sigma2ffbar2Wgm::setIdColAcol() {
2955 :
2956 : // Sign of outgoing W.
2957 0 : int sign = 1 - 2 * (abs(id1)%2);
2958 0 : if (id1 < 0) sign = -sign;
2959 0 : setId( id1, id2, 24 * sign, 22);
2960 :
2961 : // tH defined between (f,W-) or (fbar',W+).
2962 0 : swapTU = (sign * id1 > 0);
2963 :
2964 : // Colour flow topologies. Swap when antiquarks.
2965 0 : if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
2966 0 : else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
2967 0 : if (id1 < 0) swapColAcol();
2968 :
2969 0 : }
2970 :
2971 : //==========================================================================
2972 :
2973 : // Sigma2fgm2Wf class.
2974 : // Cross section for f gamma -> W+- f'.
2975 :
2976 : //--------------------------------------------------------------------------
2977 :
2978 : // Initialize process.
2979 :
2980 : void Sigma2fgm2Wf::initProc() {
2981 :
2982 : // Secondary open width fractions, relevant for top (or heavier).
2983 0 : openFracPos = particleDataPtr->resOpenFrac(24);
2984 0 : openFracNeg = particleDataPtr->resOpenFrac(-24);
2985 :
2986 0 : }
2987 :
2988 : //--------------------------------------------------------------------------
2989 :
2990 : // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
2991 :
2992 : void Sigma2fgm2Wf::sigmaKin() {
2993 :
2994 : // Cross section part common for all incoming flavours.
2995 0 : sigma0 = (M_PI / sH2) * (alpEM*alpEM / couplingsPtr->sin2thetaW())
2996 0 : * 0.5 * (sH2 + uH2 + 2. * tH * s3) / (pT2 * s3 - sH * uH);
2997 :
2998 0 : }
2999 :
3000 : //--------------------------------------------------------------------------
3001 :
3002 : // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
3003 :
3004 : double Sigma2fgm2Wf::sigmaHat() {
3005 :
3006 : // Extrafactor dependent on charge of incoming fermion.
3007 0 : int idAbs = (id2 == 22) ? abs(id1) : abs(id2);
3008 0 : double charge = (idAbs > 10) ? 1. : ( (idAbs%2 == 1) ? 1./3. : 2./3. );
3009 0 : double sigma = sigma0 * pow2( charge - sH / (sH + uH) );
3010 :
3011 : // CKM factor. Secondary width for W+ or W-.
3012 0 : sigma *= couplingsPtr->V2CKMsum(idAbs);
3013 0 : int idUp = (id2 == 22) ? id1 : id2;
3014 0 : if (idAbs%2 == 1) idUp = -idUp;
3015 0 : sigma *= (idUp > 0) ? openFracPos : openFracNeg;
3016 :
3017 : // Answer.
3018 0 : return sigma;
3019 :
3020 : }
3021 :
3022 : //--------------------------------------------------------------------------
3023 :
3024 : // Select identity, colour and anticolour.
3025 :
3026 : void Sigma2fgm2Wf::setIdColAcol() {
3027 :
3028 : // Sign of outgoing W. Flavour of outgoing fermion.
3029 0 : int idq = (id2 == 22) ? id1 : id2;
3030 0 : int sign = 1 - 2 * (abs(idq)%2);
3031 0 : if (idq < 0) sign = -sign;
3032 0 : id4 = couplingsPtr->V2CKMpick(idq);
3033 :
3034 : // Flavour set up for q gamma -> W q.
3035 0 : setId( id1, id2, 24 * sign, id4);
3036 :
3037 : // tH defined between f and f': must swap tHat <-> uHat if q gamma in.
3038 0 : swapTU = (id2 == 22);
3039 :
3040 : // Colour flow topologies. Swap when antiquarks.
3041 0 : if (abs(id1) < 9) setColAcol( 1, 0, 0, 0, 0, 0, 1, 0);
3042 0 : else if (abs(id2) < 9) setColAcol( 0, 0, 1, 0, 0, 0, 1, 0);
3043 0 : else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
3044 0 : if (idq < 0) swapColAcol();
3045 :
3046 0 : }
3047 :
3048 : //==========================================================================
3049 :
3050 : // Sigma2gmgm2ffbar class.
3051 : // Cross section for gamma gamma -> l lbar.
3052 :
3053 : //--------------------------------------------------------------------------
3054 :
3055 : // Initialize process wrt flavour.
3056 :
3057 : void Sigma2gmgm2ffbar::initProc() {
3058 :
3059 : // Process name.
3060 0 : nameSave = "gamma gamma -> f fbar";
3061 0 : if (idNew == 1) nameSave = "gamma gamma -> q qbar (uds)";
3062 0 : if (idNew == 4) nameSave = "gamma gamma -> c cbar";
3063 0 : if (idNew == 5) nameSave = "gamma gamma -> b bbar";
3064 0 : if (idNew == 6) nameSave = "gamma gamma -> t tbar";
3065 0 : if (idNew == 11) nameSave = "gamma gamma -> e+ e-";
3066 0 : if (idNew == 13) nameSave = "gamma gamma -> mu+ mu-";
3067 0 : if (idNew == 15) nameSave = "gamma gamma -> tau+ tau-";
3068 :
3069 : // Generate massive phase space, except for u+d+s.
3070 0 : idMass = 0;
3071 0 : if (idNew > 3) idMass = idNew;
3072 :
3073 : // Charge and colour factor.
3074 0 : ef4 = 1.;
3075 0 : if (idNew == 1) ef4 = 3. * (pow4(2./3.) + 2. * pow4(1./3.));
3076 0 : if (idNew == 4 || idNew == 6) ef4 = 3. * pow4(2./3.);
3077 0 : if (idNew == 5) ef4 = 3. * pow4(1./3.);
3078 :
3079 : // Secondary open width fraction.
3080 0 : openFracPair = particleDataPtr->resOpenFrac(idNew, -idNew);
3081 :
3082 0 : }
3083 :
3084 : //--------------------------------------------------------------------------
3085 :
3086 : // Evaluate d(sigmaHat)/d(tHat) - no incoming flavour dependence.
3087 :
3088 : void Sigma2gmgm2ffbar::sigmaKin() {
3089 :
3090 : // Pick current flavour for u+d+s mix by e_q^4 weights.
3091 0 : if (idNew == 1) {
3092 0 : double rId = 18. * rndmPtr->flat();
3093 0 : idNow = 1;
3094 0 : if (rId > 1.) idNow = 2;
3095 0 : if (rId > 17.) idNow = 3;
3096 0 : s34Avg = pow2(particleDataPtr->m0(idNow));
3097 0 : } else {
3098 0 : idNow = idNew;
3099 0 : s34Avg = 0.5 * (s3 + s4) - 0.25 * pow2(s3 - s4) / sH;
3100 : }
3101 :
3102 : // Modified Mandelstam variables for massive kinematics with m3 = m4.
3103 0 : double tHQ = -0.5 * (sH - tH + uH);
3104 0 : double uHQ = -0.5 * (sH + tH - uH);
3105 0 : double tHQ2 = tHQ * tHQ;
3106 0 : double uHQ2 = uHQ * uHQ;
3107 :
3108 : // Calculate kinematics dependence.
3109 0 : if (sH < 4. * s34Avg) sigTU = 0.;
3110 0 : else sigTU = 2. * (tHQ * uHQ - s34Avg * sH)
3111 0 : * (tHQ2 + uHQ2 + 2. * s34Avg * sH) / (tHQ2 * uHQ2);
3112 :
3113 : // Answer.
3114 0 : sigma = (M_PI / sH2) * pow2(alpEM) * ef4 * sigTU * openFracPair;
3115 :
3116 0 : }
3117 :
3118 : //--------------------------------------------------------------------------
3119 :
3120 : // Select identity, colour and anticolour.
3121 :
3122 : void Sigma2gmgm2ffbar::setIdColAcol() {
3123 :
3124 : // Flavours are trivial.
3125 0 : setId( id1, id2, idNow, -idNow);
3126 :
3127 : // Colour flow in singlet state.
3128 0 : if (idNow < 10) setColAcol( 0, 0, 0, 0, 1, 0, 0, 1);
3129 0 : else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
3130 :
3131 0 : }
3132 :
3133 : //==========================================================================
3134 :
3135 : } // end namespace Pythia8
|