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