~ubuntu-branches/ubuntu/trusty/pythia8/trusty-proposed

« back to all changes in this revision

Viewing changes to src/SigmaEW.cc

  • Committer: Package Import Robot
  • Author(s): Lifeng Sun
  • Date: 2012-05-22 11:43:00 UTC
  • Revision ID: package-import@ubuntu.com-20120522114300-0jvsv2vl4o2bo435
Tags: upstream-8.1.65
ImportĀ upstreamĀ versionĀ 8.1.65

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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