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