1 // SigmaEW.cc is a part of the PYTHIA event generator.
2 // Copyright (C) 2010 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.
6 // Function definitions (not found in the header) for the
7 // electroweak simulation classes (including photon processes).
13 //==========================================================================
15 // Sigma2qg2qgamma class.
16 // Cross section for q g -> q gamma.
18 //--------------------------------------------------------------------------
20 // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
22 void Sigma2qg2qgamma::sigmaKin() {
24 // Calculate kinematics dependence.
25 sigUS = (1./3.) * (sH2 + uH2) / (-sH * uH);
28 sigma0 = (M_PI/sH2) * alpS * alpEM * sigUS;
32 //--------------------------------------------------------------------------
34 // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
36 double Sigma2qg2qgamma::sigmaHat() {
38 // Incoming flavour gives charge factor.
39 int idNow = (id2 == 21) ? id1 : id2;
40 double eNow = couplingsPtr->ef( abs(idNow) );
41 return sigma0 * pow2(eNow);
45 //--------------------------------------------------------------------------
47 // Select identity, colour and anticolour.
49 void Sigma2qg2qgamma::setIdColAcol() {
51 // Construct outgoing flavours.
52 id3 = (id1 == 21) ? 22 : id1;
53 id4 = (id2 == 21) ? 22 : id2;
54 setId( id1, id2, id3, id4);
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();
63 //==========================================================================
65 // Sigma2qqbar2ggamma class.
66 // Cross section for q qbar -> g gamma.
68 //--------------------------------------------------------------------------
70 // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
72 void Sigma2qqbar2ggamma::sigmaKin() {
74 // Calculate kinematics dependence.
75 double sigTU = (8./9.) * (tH2 + uH2) / (tH * uH);
78 sigma0 = (M_PI/sH2) * alpS * alpEM * sigTU;
82 //--------------------------------------------------------------------------
84 // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
86 double Sigma2qqbar2ggamma::sigmaHat() {
88 // Incoming flavour gives charge factor.
89 double eNow = couplingsPtr->ef( abs(id1) );
90 return sigma0 * pow2(eNow);
94 //--------------------------------------------------------------------------
96 // Select identity, colour and anticolour.
98 void Sigma2qqbar2ggamma::setIdColAcol() {
100 // Outgoing flavours trivial.
101 setId( id1, id2, 21, 22);
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();
109 //==========================================================================
111 // Sigma2gg2ggamma class.
112 // Cross section for g g -> g gamma.
113 // Proceeds through a quark box, by default using 5 massless quarks.
115 //--------------------------------------------------------------------------
117 // Initialize process, especially parton-flux object.
119 void Sigma2gg2ggamma::initProc() {
121 // Maximum quark flavour in loop.
122 int nQuarkLoop = settingsPtr->mode("PromptPhoton:nQuarkLoop");
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.;
132 //--------------------------------------------------------------------------
134 // Evaluate d(sigmaHat)/d(tHat).
136 void Sigma2gg2ggamma::sigmaKin() {
138 // Logarithms of Mandelstam variable ratios.
139 double logST = log( -sH / tH );
140 double logSU = log( -sH / uH );
141 double logTU = log( tH / uH );
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));
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.;
155 double b2stuRe = -1.;
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);
164 sigma = (5. / (192. * M_PI * sH2)) * pow2(chargeSum)
165 * pow3(alpS) * alpEM * sigBox;
169 //--------------------------------------------------------------------------
171 // Select identity, colour and anticolour.
173 void Sigma2gg2ggamma::setIdColAcol() {
175 // Flavours and colours are trivial.
176 setId( id1, id2, 21, 22);
177 setColAcol( 1, 2, 2, 3, 1, 3, 0, 0);
178 if (rndmPtr->flat() > 0.5) swapColAcol();
182 //==========================================================================
184 // Sigma2ffbar2gammagamma class.
185 // Cross section for q qbar -> gamma gamma.
187 //--------------------------------------------------------------------------
189 // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
191 void Sigma2ffbar2gammagamma::sigmaKin() {
193 // Calculate kinematics dependence.
194 sigTU = 2. * (tH2 + uH2) / (tH * uH);
196 // Answer contains factor 1/2 from identical photons.
197 sigma0 = (M_PI/sH2) * pow2(alpEM) * 0.5 * sigTU;
201 //--------------------------------------------------------------------------
203 // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
205 double Sigma2ffbar2gammagamma::sigmaHat() {
207 // Incoming flavour gives charge and colour factors.
208 double eNow = couplingsPtr->ef( abs(id1) );
209 double colFac = (abs(id1) < 9) ? 1. / 3. : 1.;
210 return sigma0 * pow4(eNow) * colFac;
214 //--------------------------------------------------------------------------
216 // Select identity, colour and anticolour.
218 void Sigma2ffbar2gammagamma::setIdColAcol() {
220 // Outgoing flavours trivial.
221 setId( id1, id2, 22, 22);
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();
230 //==========================================================================
232 // Sigma2gg2gammagamma class.
233 // Cross section for g g -> gamma gamma.
234 // Proceeds through a quark box, by default using 5 massless quarks.
236 //--------------------------------------------------------------------------
238 // Initialize process.
240 void Sigma2gg2gammagamma::initProc() {
242 // Maximum quark flavour in loop.
243 int nQuarkLoop = settingsPtr->mode("PromptPhoton:nQuarkLoop");
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.;
253 //--------------------------------------------------------------------------
255 // Evaluate d(sigmaHat)/d(tHat).
257 void Sigma2gg2gammagamma::sigmaKin() {
259 // Logarithms of Mandelstam variable ratios.
260 double logST = log( -sH / tH );
261 double logSU = log( -sH / uH );
262 double logTU = log( tH / uH );
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));
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.;
276 double b2stuRe = -1.;
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);
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;
290 //--------------------------------------------------------------------------
292 // Select identity, colour and anticolour.
294 void Sigma2gg2gammagamma::setIdColAcol() {
296 // Flavours and colours are trivial.
297 setId( id1, id2, 22, 22);
298 setColAcol( 1, 2, 2, 1, 0, 0, 0, 0);
302 //==========================================================================
304 // Sigma2ff2fftgmZ class.
305 // Cross section for f f' -> f f' via t-channel gamma*/Z0 exchange
306 // (f is quark or lepton).
308 //--------------------------------------------------------------------------
310 // Initialize process.
312 void Sigma2ff2fftgmZ::initProc() {
314 // Store Z0 mass for propagator. Common coupling factor.
315 gmZmode = settingsPtr->mode("WeakZ0:gmZmode");
316 mZ = particleDataPtr->m0(23);
318 thetaWRat = 1. / (16. * couplingsPtr->sin2thetaW() * couplingsPtr->cos2thetaW());
322 //--------------------------------------------------------------------------
324 // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
326 void Sigma2ff2fftgmZ::sigmaKin() {
328 // Cross section part common for all incoming flavours.
329 double sigma0 = (M_PI / sH2) * pow2(alpEM);
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.;}
340 //--------------------------------------------------------------------------
342 // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
344 double Sigma2ff2fftgmZ::sigmaHat() {
346 // Couplings for current flavour combination.
347 int id1Abs = abs(id1);
348 double e1 = couplingsPtr->ef(id1Abs);
349 double v1 = couplingsPtr->vf(id1Abs);
350 double a1 = couplingsPtr->af(id1Abs);
351 int id2Abs = abs(id2);
352 double e2 = couplingsPtr->ef(id2Abs);
353 double v2 = couplingsPtr->vf(id2Abs);
354 double a2 = couplingsPtr->af(id2Abs);
356 // Distinguish same-sign and opposite-sign fermions.
357 double epsi = (id1 * id2 > 0) ? 1. : -1.;
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));
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.;
375 //--------------------------------------------------------------------------
377 // Select identity, colour and anticolour.
379 void Sigma2ff2fftgmZ::setIdColAcol() {
381 // Trivial flavours: out = in.
382 setId( id1, id2, id1, id2);
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) )
397 //==========================================================================
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).
403 //--------------------------------------------------------------------------
405 // Initialize process.
407 void Sigma2ff2fftW::initProc() {
409 // Store W+- mass for propagator. Common coupling factor.
410 mW = particleDataPtr->m0(24);
412 thetaWRat = 1. / (4. * couplingsPtr->sin2thetaW());
416 //--------------------------------------------------------------------------
418 // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
420 void Sigma2ff2fftW::sigmaKin() {
422 // Cross section part common for all incoming flavours.
423 sigma0 = (M_PI / sH2) * pow2(alpEM * thetaWRat)
424 * 4. * sH2 / pow2(tH - mWS);
428 //--------------------------------------------------------------------------
430 // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
432 double Sigma2ff2fftW::sigmaHat() {
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.;
440 // Basic cross section.
441 double sigma = sigma0;
442 if (id1 * id2 < 0) sigma *= uH2 / sH2;
444 // CKM factors for final states.
445 sigma *= couplingsPtr->V2CKMsum(id1Abs) * couplingsPtr->V2CKMsum(id2Abs);
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.;
456 //--------------------------------------------------------------------------
458 // Select identity, colour and anticolour.
460 void Sigma2ff2fftW::setIdColAcol() {
462 // Pick out-flavours by relative CKM weights.
463 id3 = couplingsPtr->V2CKMpick(id1);
464 id4 = couplingsPtr->V2CKMpick(id2);
465 setId( id1, id2, id3, id4);
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) )
481 //==========================================================================
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.
487 //--------------------------------------------------------------------------
489 // Initialize process.
491 void Sigma2qq2QqtW::initProc() {
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+-)";
501 // Store W+- mass for propagator. Common coupling factor.
502 mW = particleDataPtr->m0(24);
504 thetaWRat = 1. / (4. * couplingsPtr->sin2thetaW());
506 // Secondary open width fractions, relevant for top (or heavier).
507 openFracPos = particleDataPtr->resOpenFrac(idNew);
508 openFracNeg = particleDataPtr->resOpenFrac(-idNew);
512 //--------------------------------------------------------------------------
514 // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
516 void Sigma2qq2QqtW::sigmaKin() {
518 // Cross section part common for all incoming flavours.
519 sigma0 = (M_PI / sH2) * pow2(alpEM * thetaWRat) * 4. / pow2(tH - mWS);
523 //--------------------------------------------------------------------------
525 // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
527 double Sigma2qq2QqtW::sigmaHat() {
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.;
536 // Basic cross section.
537 double sigma = sigma0;
538 sigma *= (id1 * id2 > 0) ? sH * (sH - s3) : uH * (uH - s3);
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;
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 *= ( couplingsPtr->V2CKMid(id1Abs, idNew) * openFrac1
549 * couplingsPtr->V2CKMsum(id2Abs) + couplingsPtr->V2CKMsum(id1Abs)
550 * couplingsPtr->V2CKMid(id2Abs, idNew) * openFrac2 );
552 sigma *= couplingsPtr->V2CKMid(id1Abs, idNew) * openFrac1
553 * couplingsPtr->V2CKMsum(id2Abs);
555 sigma *= couplingsPtr->V2CKMsum(id1Abs)
556 * couplingsPtr->V2CKMid(id2Abs, idNew) * openFrac2;
559 // Spin-state extra factor 2 per incoming neutrino.
560 if (id1Abs == 12 || id1Abs == 14 || id1Abs == 16) sigma *= 2.;
561 if (id2Abs == 12 || id2Abs == 14 || id2Abs == 16) sigma *= 2.;
568 //--------------------------------------------------------------------------
570 // Select identity, colour and anticolour.
572 void Sigma2qq2QqtW::setIdColAcol() {
574 // For topologies like d dbar -> (t/c/u) (t/c/u)bar pick side.
575 int id1Abs = abs(id1);
576 int id2Abs = abs(id2);
578 if ( (id1Abs + idNew)%2 == 1 && (id2Abs + idNew)%2 == 1 ) {
579 double prob1 = couplingsPtr->V2CKMid(id1Abs, idNew)
580 * couplingsPtr->V2CKMsum(id2Abs);
581 prob1 *= (id1 > 0) ? openFracPos : openFracNeg;
582 double prob2 = couplingsPtr->V2CKMid(id2Abs, idNew)
583 * couplingsPtr->V2CKMsum(id1Abs);
584 prob2 *= (id2 > 0) ? openFracPos : openFracNeg;
585 if (prob2 > rndmPtr->flat() * (prob1 + prob2)) side = 2;
587 else if ((id2Abs + idNew)%2 == 1) side = 2;
589 // Pick out-flavours by relative CKM weights.
591 // q q' -> t q" : correct order from start.
592 id3 = (id1 > 0) ? idNew : -idNew;
593 id4 = couplingsPtr->V2CKMpick(id2);
594 setId( id1, id2, id3, id4);
596 // q q' -> q" t : stored as t q" so swap tHat <-> uHat.
598 id3 = couplingsPtr->V2CKMpick(id1);
599 id4 = (id2 > 0) ? idNew : -idNew;
600 setId( id1, id2, id4, id3);
603 // Colour flow topologies. Swap when antiquarks on side 1.
604 if (side == 1 && id1 * id2 > 0) setColAcol( 1, 0, 2, 0, 1, 0, 2, 0);
605 else if (id1 * id2 > 0) setColAcol( 1, 0, 2, 0, 2, 0, 1, 0);
606 else if (side == 1) setColAcol( 1, 0, 0, 2, 1, 0, 0, 2);
607 else setColAcol( 1, 0, 0, 2, 0, 2, 1, 0);
608 if (id1 < 0) swapColAcol();
612 //--------------------------------------------------------------------------
614 // Evaluate weight for decay angles of W in top decay.
616 double Sigma2qq2QqtW::weightDecay( Event& process, int iResBeg,
619 // For top decay hand over to standard routine, else done.
620 if (idNew == 6 && process[process[iResBeg].mother1()].idAbs() == 6)
621 return weightTopDecay( process, iResBeg, iResEnd);
626 //==========================================================================
628 // Sigma1ffbar2gmZ class.
629 // Cross section for f fbar -> gamma*/Z0 (f is quark or lepton).
631 //--------------------------------------------------------------------------
633 // Initialize process.
635 void Sigma1ffbar2gmZ::initProc() {
637 // Allow to pick only gamma* or Z0 part of full gamma*/Z0 expression.
638 gmZmode = settingsPtr->mode("WeakZ0:gmZmode");
640 // Store Z0 mass and width for propagator.
641 mRes = particleDataPtr->m0(23);
642 GammaRes = particleDataPtr->mWidth(23);
644 GamMRat = GammaRes / mRes;
645 thetaWRat = 1. / (16. * couplingsPtr->sin2thetaW() * couplingsPtr->cos2thetaW());
647 // Set pointer to particle properties and decay table.
648 particlePtr = particleDataPtr->particleDataEntryPtr(23);
652 //--------------------------------------------------------------------------
654 // Evaluate sigmaHat(sHat), part independent of incoming flavour.
656 void Sigma1ffbar2gmZ::sigmaKin() {
658 // Common coupling factors.
659 double colQ = 3. * (1. + alpS / M_PI);
661 // Reset quantities to sum. Declare variables in loop.
666 double mf, mr, psvec, psaxi, betaf, ef2, efvf, vf2af2, colf;
668 // Loop over all Z0 decay channels.
669 for (int i = 0; i < particlePtr->sizeChannels(); ++i) {
670 idAbs = abs( particlePtr->channel(i).product(0) );
672 // Only contributions from three fermion generations, except top.
673 if ( (idAbs > 0 && idAbs < 6) || ( idAbs > 10 && idAbs < 17)) {
674 mf = particleDataPtr->m0(idAbs);
676 // Check that above threshold. Phase space.
677 if (mH > 2. * mf + MASSMARGIN) {
679 betaf = sqrtpos(1. - 4. * mr);
680 psvec = betaf * (1. + 2. * mr);
683 // Combine phase space with couplings.
684 ef2 = couplingsPtr->ef2(idAbs) * psvec;
685 efvf = couplingsPtr->efvf(idAbs) * psvec;
686 vf2af2 = couplingsPtr->vf2(idAbs) * psvec
687 + couplingsPtr->af2(idAbs) * psaxi;
688 colf = (idAbs < 6) ? colQ : 1.;
690 // Store sum of combinations. For outstate only open channels.
691 onMode = particlePtr->channel(i).onMode();
692 if (onMode == 1 || onMode == 2) {
693 gamSum += colf * ef2;
694 intSum += colf * efvf;
695 resSum += colf * vf2af2;
698 // End loop over fermions.
703 // Calculate prefactors for gamma/interference/Z0 cross section terms.
704 gamProp = 4. * M_PI * pow2(alpEM) / (3. * sH);
705 intProp = gamProp * 2. * thetaWRat * sH * (sH - m2Res)
706 / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
707 resProp = gamProp * pow2(thetaWRat * sH)
708 / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
710 // Optionally only keep gamma* or Z0 term.
711 if (gmZmode == 1) {intProp = 0.; resProp = 0.;}
712 if (gmZmode == 2) {gamProp = 0.; intProp = 0.;}
716 //--------------------------------------------------------------------------
718 // Evaluate sigmaHat(sHat), including incoming flavour dependence.
720 double Sigma1ffbar2gmZ::sigmaHat() {
722 // Combine gamma, interference and Z0 parts.
723 int idAbs = abs(id1);
724 double sigma = couplingsPtr->ef2(idAbs) * gamProp * gamSum
725 + couplingsPtr->efvf(idAbs) * intProp * intSum
726 + couplingsPtr->vf2af2(idAbs) * resProp * resSum;
728 // Colour factor. Answer.
729 if (idAbs < 9) sigma /= 3.;
734 //--------------------------------------------------------------------------
736 // Select identity, colour and anticolour.
738 void Sigma1ffbar2gmZ::setIdColAcol() {
741 setId( id1, id2, 23);
743 // Colour flow topologies. Swap when antiquarks.
744 if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0);
745 else setColAcol( 0, 0, 0, 0, 0, 0);
746 if (id1 < 0) swapColAcol();
750 //--------------------------------------------------------------------------
752 // Evaluate weight for gamma*/Z0 decay angle.
754 double Sigma1ffbar2gmZ::weightDecay( Event& process, int iResBeg,
757 // Z should sit in entry 5.
758 if (iResBeg != 5 || iResEnd != 5) return 1.;
760 // Couplings for in- and out-flavours.
761 int idInAbs = process[3].idAbs();
762 double ei = couplingsPtr->ef(idInAbs);
763 double vi = couplingsPtr->vf(idInAbs);
764 double ai = couplingsPtr->af(idInAbs);
765 int idOutAbs = process[6].idAbs();
766 double ef = couplingsPtr->ef(idOutAbs);
767 double vf = couplingsPtr->vf(idOutAbs);
768 double af = couplingsPtr->af(idOutAbs);
770 // Phase space factors. (One power of beta left out in formulae.)
771 double mf = process[6].m();
772 double mr = mf*mf / sH;
773 double betaf = sqrtpos(1. - 4. * mr);
775 // Coefficients of angular expression.
776 double coefTran = ei*ei * gamProp * ef*ef + ei * vi * intProp * ef * vf
777 + (vi*vi + ai*ai) * resProp * (vf*vf + pow2(betaf) * af*af);
778 double coefLong = 4. * mr * ( ei*ei * gamProp * ef*ef
779 + ei * vi * intProp * ef * vf + (vi*vi + ai*ai) * resProp * vf*vf );
780 double coefAsym = betaf * ( ei * ai * intProp * ef * af
781 + 4. * vi * ai * resProp * vf * af );
783 // Flip asymmetry for in-fermion + out-antifermion.
784 if (process[3].id() * process[6].id() < 0) coefAsym = -coefAsym;
786 // Reconstruct decay angle and weight for it.
787 double cosThe = (process[3].p() - process[4].p())
788 * (process[7].p() - process[6].p()) / (sH * betaf);
789 double wtMax = 2. * (coefTran + abs(coefAsym));
790 double wt = coefTran * (1. + pow2(cosThe))
791 + coefLong * (1. - pow2(cosThe)) + 2. * coefAsym * cosThe;
798 //==========================================================================
800 // Sigma1ffbar2W class.
801 // Cross section for f fbar' -> W+- (f is quark or lepton).
803 //--------------------------------------------------------------------------
805 // Initialize process.
807 void Sigma1ffbar2W::initProc() {
809 // Store W+- mass and width for propagator.
810 mRes = particleDataPtr->m0(24);
811 GammaRes = particleDataPtr->mWidth(24);
813 GamMRat = GammaRes / mRes;
814 thetaWRat = 1. / (12. * couplingsPtr->sin2thetaW());
816 // Set pointer to particle properties and decay table.
817 particlePtr = particleDataPtr->particleDataEntryPtr(24);
821 //--------------------------------------------------------------------------
823 // Evaluate sigmaHat(sHat), part independent of incoming flavour.
825 void Sigma1ffbar2W::sigmaKin() {
827 // Set up Breit-Wigner. Cross section for W+ and W- separately.
828 double sigBW = 12. * M_PI / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
829 double preFac = alpEM * thetaWRat * mH;
830 sigma0Pos = preFac * sigBW * particlePtr->resWidthOpen(24, mH);
831 sigma0Neg = preFac * sigBW * particlePtr->resWidthOpen(-24, mH);
835 //--------------------------------------------------------------------------
837 // Evaluate sigmaHat(sHat), including incoming flavour dependence.
839 double Sigma1ffbar2W::sigmaHat() {
841 // Secondary width for W+ or W-. CKM and colour factors.
842 int idUp = (abs(id1)%2 == 0) ? id1 : id2;
843 double sigma = (idUp > 0) ? sigma0Pos : sigma0Neg;
844 if (abs(id1) < 9) sigma *= couplingsPtr->V2CKMid(abs(id1), abs(id2)) / 3.;
851 //--------------------------------------------------------------------------
853 // Select identity, colour and anticolour.
855 void Sigma1ffbar2W::setIdColAcol() {
857 // Sign of outgoing W.
858 int sign = 1 - 2 * (abs(id1)%2);
859 if (id1 < 0) sign = -sign;
860 setId( id1, id2, 24 * sign);
862 // Colour flow topologies. Swap when antiquarks.
863 if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0);
864 else setColAcol( 0, 0, 0, 0, 0, 0);
865 if (id1 < 0) swapColAcol();
869 //--------------------------------------------------------------------------
871 // Evaluate weight for W decay angle.
873 double Sigma1ffbar2W::weightDecay( Event& process, int iResBeg,
876 // W should sit in entry 5.
877 if (iResBeg != 5 || iResEnd != 5) return 1.;
879 // Phase space factors.
880 double mr1 = pow2(process[6].m()) / sH;
881 double mr2 = pow2(process[7].m()) / sH;
882 double betaf = sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2);
884 // Sign of asymmetry.
885 double eps = (process[3].id() * process[6].id() > 0) ? 1. : -1.;
887 // Reconstruct decay angle and weight for it.
888 double cosThe = (process[3].p() - process[4].p())
889 * (process[7].p() - process[6].p()) / (sH * betaf);
891 double wt = pow2(1. + betaf * eps * cosThe) - pow2(mr1 - mr2);
898 //==========================================================================
900 // Sigma2ffbar2ffbarsgm class.
901 // Cross section f fbar -> gamma* -> f' fbar', for multiple interactions.
904 //--------------------------------------------------------------------------
906 // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
908 void Sigma2ffbar2ffbarsgm::sigmaKin() {
910 // Pick new flavour. Allow three leptons and five quarks.
911 double colQ = 1. + (alpS / M_PI);
912 double flavWt = 3. + colQ * 11. / 3.;
913 double flavRndm = rndmPtr->flat() * flavWt;
915 if (flavRndm < 1.) idNew = 11;
916 else if (flavRndm < 2.) idNew = 13;
919 flavRndm = 3. * (flavWt - 3.) / colQ;
920 if (flavRndm < 4.) idNew = 2;
921 else if (flavRndm < 8.) idNew = 4;
922 else if (flavRndm < 9.) idNew = 1;
923 else if (flavRndm < 10.) idNew = 3;
926 double mNew = particleDataPtr->m0(idNew);
927 double m2New = mNew*mNew;
929 // Calculate kinematics dependence. Give correct mass factors for
930 // tHat, uHat defined as if massless kinematics, d(sigma)/d(Omega)
931 // = beta (1 + cos^2(theta) + (1 - beta^2) sin^2(theta)).
932 // Special case related to phase space form in multiple interactions.
934 if (sH > 4. * m2New) {
935 double beta = sqrt(1. - 4. * m2New / sH);
936 sigS = beta * (2.* (tH2 + uH2) + 4. * (1. - beta * beta) * tH * uH)
940 // Answer is proportional to number of outgoing flavours.
941 sigma0 = (M_PI/sH2) * pow2(alpEM) * sigS * flavWt;
945 //--------------------------------------------------------------------------
947 // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
949 double Sigma2ffbar2ffbarsgm::sigmaHat() {
951 // Charge and colour factors.
952 double eNow = couplingsPtr->ef( abs(id1) );
953 double sigma = sigma0 * pow2(eNow);
954 if (abs(id1) < 9) sigma /= 3.;
961 //--------------------------------------------------------------------------
963 // Select identity, colour and anticolour.
965 void Sigma2ffbar2ffbarsgm::setIdColAcol() {
967 // Set outgoing flavours.
968 id3 = (id1 > 0) ? idNew : -idNew;
969 setId( id1, id2, id3, -id3);
971 // Colour flow topologies. Swap when antiquarks.
972 if (abs(id1) < 9 && idNew < 9) setColAcol( 1, 0, 0, 1, 2, 0, 0, 2);
973 else if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
974 else if (idNew < 9) setColAcol( 0, 0, 0, 0, 1, 0, 0, 1);
975 else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
976 if (id1 < 0) swapColAcol();
980 //==========================================================================
982 // Sigma2ffbar2FFbarsgmZ class.
983 // Cross section f fbar -> gamma*/Z0 -> F Fbar.
985 //--------------------------------------------------------------------------
987 // Initialize process.
989 void Sigma2ffbar2FFbarsgmZ::initProc() {
992 nameSave = "f fbar -> F Fbar (s-channel gamma*/Z0)";
993 if (idNew == 4) nameSave = "f fbar -> c cbar (s-channel gamma*/Z0)";
994 if (idNew == 5) nameSave = "f fbar -> b bbar (s-channel gamma*/Z0)";
995 if (idNew == 6) nameSave = "f fbar -> t tbar (s-channel gamma*/Z0)";
996 if (idNew == 7) nameSave = "f fbar -> b' b'bar (s-channel gamma*/Z0)";
997 if (idNew == 8) nameSave = "f fbar -> t' t'bar (s-channel gamma*/Z0)";
998 if (idNew == 15) nameSave = "f fbar -> tau+ tau- (s-channel gamma*/Z0)";
999 if (idNew == 17) nameSave = "f fbar -> tau'+ tau'- (s-channel gamma*/Z0)";
1001 nameSave = "f fbar -> nu'_tau nu'bar_tau (s-channel gamma*/Z0)";
1003 // Allow to pick only gamma* or Z0 part of full gamma*/Z0 expression.
1004 gmZmode = settingsPtr->mode("WeakZ0:gmZmode");
1006 // Store Z0 mass and width for propagator.
1007 mRes = particleDataPtr->m0(23);
1008 GammaRes = particleDataPtr->mWidth(23);
1010 GamMRat = GammaRes / mRes;
1011 thetaWRat = 1. / (16. * couplingsPtr->sin2thetaW()
1012 * couplingsPtr->cos2thetaW());
1014 // Store couplings of F.
1015 ef = couplingsPtr->ef(idNew);
1016 vf = couplingsPtr->vf(idNew);
1017 af = couplingsPtr->af(idNew);
1019 // Secondary open width fraction, relevant for top (or heavier).
1020 openFracPair = particleDataPtr->resOpenFrac(idNew, -idNew);
1024 //--------------------------------------------------------------------------
1026 // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
1028 void Sigma2ffbar2FFbarsgmZ::sigmaKin() {
1030 // Check that above threshold.
1032 if (mH < m3 + m4 + MASSMARGIN) {
1037 // Define average F, Fbar mass so same beta. Phase space.
1038 double s34Avg = 0.5 * (s3 + s4) - 0.25 * pow2(s3 - s4) / sH;
1040 betaf = sqrtpos(1. - 4. * mr);
1042 // Final-state colour factor.
1043 double colF = (idNew < 9) ? 3. * (1. + alpS / M_PI) : 1.;
1045 // Reconstruct decay angle so can reuse 2 -> 1 cross section.
1046 cosThe = (tH - uH) / (betaf * sH);
1048 // Calculate prefactors for gamma/interference/Z0 cross section terms.
1049 gamProp = colF * M_PI * pow2(alpEM) / sH2;
1050 intProp = gamProp * 2. * thetaWRat * sH * (sH - m2Res)
1051 / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
1052 resProp = gamProp * pow2(thetaWRat * sH)
1053 / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
1055 // Optionally only keep gamma* or Z0 term.
1056 if (gmZmode == 1) {intProp = 0.; resProp = 0.;}
1057 if (gmZmode == 2) {gamProp = 0.; intProp = 0.;}
1061 //--------------------------------------------------------------------------
1063 // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
1065 double Sigma2ffbar2FFbarsgmZ::sigmaHat() {
1067 // Fail if below threshold.
1068 if (!isPhysical) return 0.;
1070 // Couplings for in-flavours.
1071 int idAbs = abs(id1);
1072 double ei = couplingsPtr->ef(idAbs);
1073 double vi = couplingsPtr->vf(idAbs);
1074 double ai = couplingsPtr->af(idAbs);
1076 // Coefficients of angular expression.
1077 double coefTran = ei*ei * gamProp * ef*ef + ei * vi * intProp * ef * vf
1078 + (vi*vi + ai*ai) * resProp * (vf*vf + pow2(betaf) * af*af);
1079 double coefLong = 4. * mr * ( ei*ei * gamProp * ef*ef
1080 + ei * vi * intProp * ef * vf + (vi*vi + ai*ai) * resProp * vf*vf );
1081 double coefAsym = betaf * ( ei * ai * intProp * ef * af
1082 + 4. * vi * ai * resProp * vf * af );
1084 // Combine gamma, interference and Z0 parts.
1085 double sigma = coefTran * (1. + pow2(cosThe))
1086 + coefLong * (1. - pow2(cosThe)) + 2. * coefAsym * cosThe;
1088 // Top: corrections for closed decay channels.
1089 sigma *= openFracPair;
1091 // Initial-state colour factor. Answer.
1092 if (idAbs < 9) sigma /= 3.;
1097 //--------------------------------------------------------------------------
1099 // Select identity, colour and anticolour.
1101 void Sigma2ffbar2FFbarsgmZ::setIdColAcol() {
1103 // Set outgoing flavours.
1104 id3 = (id1 > 0) ? idNew : -idNew;
1105 setId( id1, id2, id3, -id3);
1107 // Colour flow topologies. Swap when antiquarks.
1108 if (abs(id1) < 9 && idNew < 9) setColAcol( 1, 0, 0, 1, 2, 0, 0, 2);
1109 else if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
1110 else if (idNew < 9) setColAcol( 0, 0, 0, 0, 1, 0, 0, 1);
1111 else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
1112 if (id1 < 0) swapColAcol();
1116 //--------------------------------------------------------------------------
1118 // Evaluate weight for decay angles of W in top decay.
1120 double Sigma2ffbar2FFbarsgmZ::weightDecay( Event& process, int iResBeg,
1123 // For top decay hand over to standard routine, else done.
1124 if (idNew == 6 && process[process[iResBeg].mother1()].idAbs() == 6)
1125 return weightTopDecay( process, iResBeg, iResEnd);
1130 //==========================================================================
1132 // Sigma2ffbar2FfbarsW class.
1133 // Cross section f fbar' -> W+- -> F fbar".
1135 //--------------------------------------------------------------------------
1137 // Initialize process.
1139 void Sigma2ffbar2FfbarsW::initProc() {
1142 nameSave = "f fbar -> F fbar (s-channel W+-)";
1143 if (idNew == 4) nameSave = "f fbar -> c qbar (s-channel W+-)";
1144 if (idNew == 5) nameSave = "f fbar -> b qbar (s-channel W+-)";
1145 if (idNew == 6) nameSave = "f fbar -> t qbar (s-channel W+-)";
1146 if (idNew == 7) nameSave = "f fbar -> b' qbar (s-channel W+-)";
1147 if (idNew == 8) nameSave = "f fbar -> t' qbar (s-channel W+-)";
1148 if (idNew == 7 && idNew2 == 6)
1149 nameSave = "f fbar -> b' tbar (s-channel W+-)";
1150 if (idNew == 8 && idNew2 == 7)
1151 nameSave = "f fbar -> t' b'bar (s-channel W+-)";
1152 if (idNew == 15 || idNew == 16)
1153 nameSave = "f fbar -> tau nu_taubar (s-channel W+-)";
1154 if (idNew == 17 || idNew == 18)
1155 nameSave = "f fbar -> tau' nu'_taubar (s-channel W+-)";
1157 // Store W+- mass and width for propagator.
1158 mRes = particleDataPtr->m0(24);
1159 GammaRes = particleDataPtr->mWidth(24);
1161 GamMRat = GammaRes / mRes;
1162 thetaWRat = 1. / (12. * couplingsPtr->sin2thetaW());
1164 // For t/t' want to use at least b mass.
1166 if ( (idNew == 6 || idNew == 8) && idNew2 == 0 ) idPartner = 5;
1168 // Sum of CKM weights for quarks.
1169 V2New = (idNew < 9) ? couplingsPtr->V2CKMsum(idNew) : 1.;
1170 if (idNew2 != 0) V2New = couplingsPtr->V2CKMid(idNew, idNew2);
1172 // Secondary open width fractions, relevant for top or heavier.
1173 openFracPos = particleDataPtr->resOpenFrac( idNew, -idNew2);
1174 openFracNeg = particleDataPtr->resOpenFrac(-idNew, idNew2);
1178 //--------------------------------------------------------------------------
1180 // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
1182 void Sigma2ffbar2FfbarsW::sigmaKin() {
1184 // Check that above threshold.
1186 if (mH < m3 + m4 + MASSMARGIN) {
1191 // Phase space factors.
1192 double mr1 = s3 / sH;
1193 double mr2 = s4 / sH;
1194 double betaf = sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2);
1196 // Reconstruct decay angle so can reuse 2 -> 1 cross section.
1197 double cosThe = (tH - uH) / (betaf * sH);
1199 // Set up Breit-Wigner and in- and out-widths.
1200 double sigBW = 9. * M_PI * pow2(alpEM * thetaWRat)
1201 / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
1203 // Initial-state colour factor.
1204 double colF = (idNew < 9) ? 3. * (1. + alpS / M_PI) * V2New : 1.;
1206 // Angular dependence.
1207 double wt = pow2(1. + betaf * cosThe) - pow2(mr1 - mr2);
1209 // Temporary answer.
1210 sigma0 = sigBW * colF * wt;
1214 //--------------------------------------------------------------------------
1216 // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
1218 double Sigma2ffbar2FfbarsW::sigmaHat() {
1220 // Fail if below threshold.
1221 if (!isPhysical) return 0.;
1223 // CKM and colour factors.
1224 double sigma = sigma0;
1225 if (abs(id1) < 9) sigma *= couplingsPtr->V2CKMid(abs(id1), abs(id2)) / 3.;
1227 // Correction for secondary width in top (or heavier) decay.
1228 int idSame = ((abs(id1) + idNew)%2 == 0) ? id1 : id2;
1229 sigma *= (idSame > 0) ? openFracPos : openFracNeg;
1236 //--------------------------------------------------------------------------
1238 // Select identity, colour and anticolour.
1240 void Sigma2ffbar2FfbarsW::setIdColAcol() {
1242 // Set outgoing flavours.
1244 id4 = (idNew2 != 0) ? idNew2 : couplingsPtr->V2CKMpick(idNew);
1246 int idInUp = (abs(id1)%2 == 0) ? id1 : id2;
1247 if (idInUp > 0) id4 = -id4;
1250 int idInDn = (abs(id1)%2 == 1) ? id1 : id2;
1251 if (idInDn > 0) id4 = -id4;
1254 setId( id1, id2, id3, id4);
1256 // Swap tHat and uHat for fbar' f -> F f".
1257 if (id1 * id3 < 0) swapTU = true;
1259 // Colour flow topologies. Swap when antiquarks.
1260 if (abs(id1) < 9 && idNew < 9) setColAcol( 1, 0, 0, 1, 2, 0, 0, 2);
1261 else if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
1262 else if (idNew < 9) setColAcol( 0, 0, 0, 0, 1, 0, 0, 1);
1263 else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
1264 if (id1 < 0) swapCol12();
1265 if (id3 < 0) swapCol34();
1269 //--------------------------------------------------------------------------
1271 // Evaluate weight for decay angles of W in top decay.
1273 double Sigma2ffbar2FfbarsW::weightDecay( Event& process, int iResBeg,
1276 // For top decay hand over to standard routine, else done.
1277 if (idNew == 6 && process[process[iResBeg].mother1()].idAbs() == 6)
1278 return weightTopDecay( process, iResBeg, iResEnd);
1283 //==========================================================================
1285 // Sigma2ffbargmZWgmZW class.
1286 // Collects common methods for f fbar -> gamma*/Z0/W+- gamma*/Z0/W-+.
1288 //--------------------------------------------------------------------------
1290 // Calculate and store internal products.
1292 void Sigma2ffbargmZWgmZW::setupProd( Event& process, int i1, int i2,
1293 int i3, int i4, int i5, int i6) {
1295 // Store incoming and outgoing momenta,
1296 pRot[1] = process[i1].p();
1297 pRot[2] = process[i2].p();
1298 pRot[3] = process[i3].p();
1299 pRot[4] = process[i4].p();
1300 pRot[5] = process[i5].p();
1301 pRot[6] = process[i6].p();
1303 // Do random rotation to avoid accidental zeroes in HA expressions.
1304 bool smallPT = false;
1307 double thetaNow = acos(2. * rndmPtr->flat() - 1.);
1308 double phiNow = 2. * M_PI * rndmPtr->flat();
1309 for (int i = 1; i <= 6; ++i) {
1310 pRot[i].rot( thetaNow, phiNow);
1311 if (pRot[i].pT2() < 1e-4 * pRot[i].pAbs2()) smallPT = true;
1315 // Calculate internal products.
1316 for (int i = 1; i < 6; ++i) {
1317 for (int j = i + 1; j <= 6; ++j) {
1319 sqrt( (pRot[i].e() - pRot[i].pz()) * (pRot[j].e() + pRot[j].pz())
1320 / pRot[i].pT2() ) * complex( pRot[i].px(), pRot[i].py() )
1321 - sqrt( (pRot[i].e() + pRot[i].pz()) * (pRot[j].e() - pRot[j].pz())
1322 / pRot[j].pT2() ) * complex( pRot[j].px(), pRot[j].py() );
1323 hC[i][j] = conj( hA[i][j] );
1325 hA[i][j] *= complex( 0., 1.);
1326 hC[i][j] *= complex( 0., 1.);
1328 hA[j][i] = - hA[i][j];
1329 hC[j][i] = - hC[i][j];
1335 //--------------------------------------------------------------------------
1337 // Evaluate the F function of Gunion and Kunszt.
1339 complex Sigma2ffbargmZWgmZW::fGK(int j1, int j2, int j3, int j4, int j5,
1342 return 4. * hA[j1][j3] * hC[j2][j6]
1343 * ( hA[j1][j5] * hC[j1][j4] + hA[j3][j5] * hC[j3][j4] );
1347 //--------------------------------------------------------------------------
1349 // Evaluate the Xi function of Gunion and Kunszt.
1351 double Sigma2ffbargmZWgmZW::xiGK( double tHnow, double uHnow) {
1353 return - 4. * s3 * s4 + tHnow * (3. * tHnow + 4. * uHnow)
1354 + tHnow * tHnow * ( tHnow * uHnow / (s3 * s4)
1355 - 2. * (1. / s3 + 1./s4) * (tHnow + uHnow)
1356 + 2. * (s3 / s4 + s4 / s3) );
1360 //--------------------------------------------------------------------------
1362 // Evaluate the Xj function of Gunion and Kunszt.
1364 double Sigma2ffbargmZWgmZW::xjGK( double tHnow, double uHnow) {
1366 return 8. * pow2(s3 + s4) - 8. * (s3 + s4) * (tHnow + uHnow)
1367 - 6. * tHnow * uHnow - 2. * tHnow * uHnow * ( tHnow * uHnow
1368 / (s3 * s4) - 2. * (1. / s3 + 1. / s4) * (tHnow + uHnow)
1369 + 2. * (s3 / s4 + s4 / s3) );
1373 //==========================================================================
1375 // Sigma2ffbar2gmZgmZ class.
1376 // Cross section for f fbar -> gamma*/Z0 gamma*/Z0 (f is quark or lepton).
1378 //--------------------------------------------------------------------------
1380 // Initialize process.
1382 void Sigma2ffbar2gmZgmZ::initProc() {
1384 // Allow to pick only gamma* or Z0 part of full gamma*/Z0 expression.
1385 gmZmode = settingsPtr->mode("WeakZ0:gmZmode");
1387 // Store Z0 mass and width for propagator.
1388 mRes = particleDataPtr->m0(23);
1389 GammaRes = particleDataPtr->mWidth(23);
1391 GamMRat = GammaRes / mRes;
1392 thetaWRat = 1. / (16. * couplingsPtr->sin2thetaW()
1393 * couplingsPtr->cos2thetaW());
1395 // Set pointer to particle properties and decay table.
1396 particlePtr = particleDataPtr->particleDataEntryPtr(23);
1400 //--------------------------------------------------------------------------
1402 // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
1404 void Sigma2ffbar2gmZgmZ::sigmaKin() {
1406 // Cross section part common for all incoming flavours.
1407 sigma0 = (M_PI / sH2) * pow2(alpEM) * 0.5
1408 * ( (tH2 + uH2 + 2. * (s3 + s4) * sH) / (tH * uH)
1409 - s3 * s4 * (1./tH2 + 1./uH2) );
1411 // Common coupling factors at the resonance masses
1412 double alpEM3 = couplingsPtr->alphaEM(s3);
1413 double alpS3 = couplingsPtr->alphaS(s3);
1414 double colQ3 = 3. * (1. + alpS3 / M_PI);
1415 double alpEM4 = couplingsPtr->alphaEM(s4);
1416 double alpS4 = couplingsPtr->alphaS(s4);
1417 double colQ4 = 3. * (1. + alpS4 / M_PI);
1419 // Reset quantities to sum. Declare variables in loop.
1427 double mf, mr, psvec, psaxi, betaf, ef2, efvf, vf2af2, colf;
1429 // Loop over all Z0 decay channels.
1430 for (int i = 0; i < particlePtr->sizeChannels(); ++i) {
1431 int idAbs = abs( particlePtr->channel(i).product(0) );
1433 // Only contributions from three fermion generations, except top.
1434 if ( (idAbs > 0 && idAbs < 6) || ( idAbs > 10 && idAbs < 17)) {
1435 mf = particleDataPtr->m0(idAbs);
1436 onMode = particlePtr->channel(i).onMode();
1438 // First Z0: check that above threshold. Phase space.
1439 if (m3 > 2. * mf + MASSMARGIN) {
1441 betaf = sqrtpos(1. - 4. * mr);
1442 psvec = betaf * (1. + 2. * mr);
1443 psaxi = pow3(betaf);
1445 // First Z0: combine phase space with couplings.
1446 ef2 = couplingsPtr->ef2(idAbs) * psvec;
1447 efvf = couplingsPtr->efvf(idAbs) * psvec;
1448 vf2af2 = couplingsPtr->vf2(idAbs) * psvec
1449 + couplingsPtr->af2(idAbs) * psaxi;
1450 colf = (idAbs < 6) ? colQ3 : 1.;
1452 // First Z0: store sum of combinations for open outstate channels.
1453 if (onMode == 1 || onMode == 2) {
1454 gamSum3 += colf * ef2;
1455 intSum3 += colf * efvf;
1456 resSum3 += colf * vf2af2;
1460 // Second Z0: check that above threshold. Phase space.
1461 if (m4 > 2. * mf + MASSMARGIN) {
1463 betaf = sqrtpos(1. - 4. * mr);
1464 psvec = betaf * (1. + 2. * mr);
1465 psaxi = pow3(betaf);
1467 // Second Z0: combine phase space with couplings.
1468 ef2 = couplingsPtr->ef2(idAbs) * psvec;
1469 efvf = couplingsPtr->efvf(idAbs) * psvec;
1470 vf2af2 = couplingsPtr->vf2(idAbs) * psvec
1471 + couplingsPtr->af2(idAbs) * psaxi;
1472 colf = (idAbs < 6) ? colQ4 : 1.;
1474 // Second Z0: store sum of combinations for open outstate channels.
1475 if (onMode == 1 || onMode == 2) {
1476 gamSum4 += colf * ef2;
1477 intSum4 += colf * efvf;
1478 resSum4 += colf * vf2af2;
1482 // End loop over fermions.
1486 // First Z0: calculate prefactors for gamma/interference/Z0 terms.
1487 gamProp3 = 4. * alpEM3 / (3. * M_PI * s3);
1488 intProp3 = gamProp3 * 2. * thetaWRat * s3 * (s3 - m2Res)
1489 / ( pow2(s3 - m2Res) + pow2(s3 * GamMRat) );
1490 resProp3 = gamProp3 * pow2(thetaWRat * s3)
1491 / ( pow2(s3 - m2Res) + pow2(s3 * GamMRat) );
1493 // First Z0: optionally only keep gamma* or Z0 term.
1494 if (gmZmode == 1) {intProp3 = 0.; resProp3 = 0.;}
1495 if (gmZmode == 2) {gamProp3 = 0.; intProp3 = 0.;}
1497 // Second Z0: calculate prefactors for gamma/interference/Z0 terms.
1498 gamProp4 = 4. * alpEM4 / (3. * M_PI * s4);
1499 intProp4 = gamProp4 * 2. * thetaWRat * s4 * (s4 - m2Res)
1500 / ( pow2(s4 - m2Res) + pow2(s4 * GamMRat) );
1501 resProp4 = gamProp4 * pow2(thetaWRat * s4)
1502 / ( pow2(s4 - m2Res) + pow2(s4 * GamMRat) );
1504 // Second Z0: optionally only keep gamma* or Z0 term.
1505 if (gmZmode == 1) {intProp4 = 0.; resProp4 = 0.;}
1506 if (gmZmode == 2) {gamProp4 = 0.; intProp4 = 0.;}
1510 //--------------------------------------------------------------------------
1512 // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
1514 double Sigma2ffbar2gmZgmZ::sigmaHat() {
1516 // Charge/2, left- and righthanded couplings for in-fermion.
1517 int idAbs = abs(id1);
1518 double ei = 0.5 * couplingsPtr->ef(idAbs);
1519 double li = couplingsPtr->lf(idAbs);
1520 double ri = couplingsPtr->rf(idAbs);
1522 // Combine left/right gamma, interference and Z0 parts for each Z0.
1523 double left3 = ei * ei * gamProp3 * gamSum3
1524 + ei * li * intProp3 * intSum3
1525 + li * li * resProp3 * resSum3;
1526 double right3 = ei * ei * gamProp3 * gamSum3
1527 + ei * ri * intProp3 * intSum3
1528 + ri * ri * resProp3 * resSum3;
1529 double left4 = ei * ei * gamProp4 * gamSum4
1530 + ei * li * intProp4 * intSum4
1531 + li * li * resProp4 * resSum4;
1532 double right4 = ei * ei * gamProp4 * gamSum4
1533 + ei * ri * intProp4 * intSum4
1534 + ri * ri * resProp4 * resSum4;
1536 // Combine left- and right-handed couplings for the two Z0's.
1537 double sigma = sigma0 * (left3 * left4 + right3 * right4);
1539 // Correct for the running-width Z0 propagators weight in PhaseSpace.
1540 sigma /= (runBW3 * runBW4);
1542 // Initial-state colour factor. Answer.
1543 if (idAbs < 9) sigma /= 3.;
1548 //--------------------------------------------------------------------------
1550 // Select identity, colour and anticolour.
1552 void Sigma2ffbar2gmZgmZ::setIdColAcol() {
1554 // Flavours trivial.
1555 setId( id1, id2, 23, 23);
1557 // Colour flow topologies. Swap when antiquarks.
1558 if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
1559 else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
1560 if (id1 < 0) swapColAcol();
1564 //--------------------------------------------------------------------------
1566 // Evaluate correlated decay flavours of the two gamma*/Z0.
1567 // Unique complication, caused by gamma*/Z0 mix different left/right.
1569 double Sigma2ffbar2gmZgmZ::weightDecayFlav( Event& process) {
1571 // Order so that fbar(1) f(2) -> f'(3) fbar'(4) f"(5) fbar"(6).
1572 i1 = (process[3].id() < 0) ? 3 : 4;
1574 i3 = (process[7].id() > 0) ? 7 : 8;
1576 i5 = (process[9].id() > 0) ? 9 : 10;
1579 // Charge/2, left- and righthanded couplings for in- and out-fermions.
1580 int idAbs = process[i1].idAbs();
1581 double ei = 0.5 * couplingsPtr->ef(idAbs);
1582 double li = couplingsPtr->lf(idAbs);
1583 double ri = couplingsPtr->rf(idAbs);
1584 idAbs = process[i3].idAbs();
1585 double e3 = 0.5 * couplingsPtr->ef(idAbs);
1586 double l3 = couplingsPtr->lf(idAbs);
1587 double r3 = couplingsPtr->rf(idAbs);
1588 idAbs = process[i5].idAbs();
1589 double e4 = 0.5 * couplingsPtr->ef(idAbs);
1590 double l4 = couplingsPtr->lf(idAbs);
1591 double r4 = couplingsPtr->rf(idAbs);
1593 // Left- and righthanded couplings combined with propagators.
1594 c3LL = ei * ei * gamProp3 * e3 * e3
1595 + ei * li * intProp3 * e3 * l3
1596 + li * li * resProp3 * l3 * l3;
1597 c3LR = ei * ei * gamProp3 * e3 * e3
1598 + ei * li * intProp3 * e3 * r3
1599 + li * li * resProp3 * r3 * r3;
1600 c3RL = ei * ei * gamProp3 * e3 * e3
1601 + ei * ri * intProp3 * e3 * l3
1602 + ri * ri * resProp3 * l3 * l3;
1603 c3RR = ei * ei * gamProp3 * e3 * e3
1604 + ei * ri * intProp3 * e3 * r3
1605 + ri * ri * resProp3 * r3 * r3;
1606 c4LL = ei * ei * gamProp4 * e4 * e4
1607 + ei * li * intProp4 * e4 * l4
1608 + li * li * resProp4 * l4 * l4;
1609 c4LR = ei * ei * gamProp4 * e4 * e4
1610 + ei * li * intProp4 * e4 * r4
1611 + li * li * resProp4 * r4 * r4;
1612 c4RL = ei * ei * gamProp4 * e4 * e4
1613 + ei * ri * intProp4 * e4 * l4
1614 + ri * ri * resProp4 * l4 * l4;
1615 c4RR = ei * ei * gamProp4 * e4 * e4
1616 + ei * ri * intProp4 * e4 * r4
1617 + ri * ri * resProp4 * r4 * r4;
1619 // Flavour weight and maximum.
1620 flavWt = (c3LL + c3LR) * (c4LL + c4LR) + (c3RL + c3RR) * (c4RL + c4RR);
1621 double flavWtMax = (c3LL + c3LR + c3RL + c3RR) * (c4LL + c4LR + c4RL + c4RR);
1624 return flavWt / flavWtMax;
1628 //--------------------------------------------------------------------------
1630 // Evaluate weight for decay angles of the two gamma*/Z0.
1632 double Sigma2ffbar2gmZgmZ::weightDecay( Event& process, int iResBeg,
1635 // Two resonance decays, but with common weight.
1636 if (iResBeg != 5 || iResEnd != 6) return 1.;
1638 // Set up four-products and internal products.
1639 setupProd( process, i1, i2, i3, i4, i5, i6);
1641 // Flip tHat and uHat if first incoming is fermion.
1644 if (process[3].id() > 0) swap( tHres, uHres);
1646 // Kinematics factors (norm(x) = |x|^2).
1647 double fGK135 = norm( fGK( 1, 2, 3, 4, 5, 6) / tHres
1648 + fGK( 1, 2, 5, 6, 3, 4) / uHres );
1649 double fGK145 = norm( fGK( 1, 2, 4, 3, 5, 6) / tHres
1650 + fGK( 1, 2, 5, 6, 4, 3) / uHres );
1651 double fGK136 = norm( fGK( 1, 2, 3, 4, 6, 5) / tHres
1652 + fGK( 1, 2, 6, 5, 3, 4) / uHres );
1653 double fGK146 = norm( fGK( 1, 2, 4, 3, 6, 5) / tHres
1654 + fGK( 1, 2, 6, 5, 4, 3) / uHres );
1655 double fGK253 = norm( fGK( 2, 1, 5, 6, 3, 4) / tHres
1656 + fGK( 2, 1, 3, 4, 5, 6) / uHres );
1657 double fGK263 = norm( fGK( 2, 1, 6, 5, 3, 4) / tHres
1658 + fGK( 2, 1, 3, 4, 6, 5) / uHres );
1659 double fGK254 = norm( fGK( 2, 1, 5, 6, 4, 3) / tHres
1660 + fGK( 2, 1, 4, 3, 5, 6) / uHres );
1661 double fGK264 = norm( fGK( 2, 1, 6, 5, 4, 3) / tHres
1662 + fGK( 2, 1, 4, 3, 6, 5) / uHres );
1664 // Weight and maximum.
1665 double wt = c3LL * c4LL * fGK135 + c3LR * c4LL * fGK145
1666 + c3LL * c4LR * fGK136 + c3LR * c4LR * fGK146
1667 + c3RL * c4RL * fGK253 + c3RR * c4RL * fGK263
1668 + c3RL * c4RR * fGK254 + c3RR * c4RR * fGK264;
1669 double wtMax = 16. * s3 * s4 * flavWt
1670 * ( (tHres*tHres + uHres*uHres + 2. * sH * (s3 + s4)) / (tHres * uHres)
1671 - s3 * s4 * (1. / (tHres*tHres) + 1. / (uHres*uHres)) );
1678 //==========================================================================
1680 // Sigma2ffbar2ZW class.
1681 // Cross section for f fbar' -> Z0 W+- (f is quark or lepton).
1683 //--------------------------------------------------------------------------
1685 // Initialize process.
1687 void Sigma2ffbar2ZW::initProc() {
1689 // Store W+- mass and width for propagator.
1690 mW = particleDataPtr->m0(24);
1691 widW = particleDataPtr->mWidth(24);
1693 mwWS = pow2(mW * widW);
1695 // Left-handed couplings for up/nu- and down/e-type quarks.
1696 lun = (hasLeptonBeams) ? couplingsPtr->lf(12) : couplingsPtr->lf(2);
1697 lde = (hasLeptonBeams) ? couplingsPtr->lf(11) : couplingsPtr->lf(1);
1699 // Common weak coupling factor.
1700 sin2thetaW = couplingsPtr->sin2thetaW();
1701 cos2thetaW = couplingsPtr->cos2thetaW();
1702 thetaWRat = 1. / (4. * cos2thetaW);
1703 cotT = sqrt(cos2thetaW / sin2thetaW);
1704 thetaWpt = (9. - 8. * sin2thetaW) / 4.;
1705 thetaWmm = (8. * sin2thetaW - 6.) / 4.;
1707 // Secondary open width fractions.
1708 openFracPos = particleDataPtr->resOpenFrac(23, 24);
1709 openFracNeg = particleDataPtr->resOpenFrac(23, -24);
1713 //--------------------------------------------------------------------------
1715 // Evaluate sigmaHat(sHat), part independent of incoming flavour.
1717 void Sigma2ffbar2ZW::sigmaKin() {
1719 // Evaluate cross section, as programmed by Merlin Kole (after tidying),
1720 // based on Brown, Sahdev, Mikaelian, Phys Rev. D20 (1979) 1069.
1722 double resBW = 1. / (pow2(sH - mWS) + mwWS);
1723 double prefac = 12.0 * M_PI * pow2(alpEM) / (sH2 * 8. * sin2thetaW);
1724 double temp1 = tH * uH - s3 * s4;
1725 double temp2 = temp1 / (s3 * s4);
1726 double temp3 = (s3 + s4) / sH;
1727 double temp4 = s3 * s4 / sH;
1728 double partA = temp2 * (0.25 - 0.5 * temp3
1729 + (pow2(s3 + s4) + 8. * s3 * s4)/(4. * sH2) )
1730 + (s3 + s4)/(s3 * s4) * (sH/2. - s3 - s4 + pow2(s3 - s4)/(2. * sH));
1731 double partB1 = lun * (0.25 * temp2 * (1. - temp3 - 4. * temp4 / tH)
1732 + ((s3 + s4)/(2. * s3 * s4)) * (sH - s3 - s4 + 2. * s3 * s4 / tH) );
1733 double partB2 = lde * ( 0.25 * temp2 * (1.- temp3 - 4. * temp4 / uH)
1734 + ((s3 + s4)/(2. * s3 * s4)) * (sH - s3 - s4 + 2. * s3 * s4 / uH) );
1735 double partE = 0.25 * temp2 + 0.5 *(s3 + s4) / temp4;
1736 sigma0 = prefac * (pow2(cotT) * sH2 * resBW * partA
1737 + 2.* sH * cotT * resBW * (sH - mWS) * (partB2 - partB1)
1738 + pow2(lun - lde) * partE + pow2(lde) * temp1/uH2
1739 + pow2(lun) * temp1/tH2 + 2. * lun * lde * sH * (s3 + s4) / (uH * tH));
1742 // Evaluate cross section. Expression from EHLQ, with bug fix,
1743 // but can still give negative cross section so suspect.
1744 double resBW = 1. / (pow2(sH - mWS) + mwWS);
1745 sigma0 = (M_PI / sH2) * 0.5 * pow2(alpEM / sin2thetaW);
1746 sigma0 *= sH * resBW * (thetaWpt * pT2 + thetaWmm * (s3 + s4))
1747 + (sH - mWS) * resBW * sH * (pT2 - s3 - s4) * (lun / tH - lde / uH)
1748 + thetaWRat * sH * pT2 * ( lun*lun / tH2 + lde*lde / uH2 )
1749 + 2. * thetaWRat * sH * (s3 + s4) * lun * lde / (tH * uH);
1750 // Need to protect against negative cross sections at times.
1751 sigma0 = max(0., sigma0);
1755 //--------------------------------------------------------------------------
1757 // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
1759 double Sigma2ffbar2ZW::sigmaHat() {
1761 // CKM and colour factors.
1762 double sigma = sigma0;
1763 if (abs(id1) < 9) sigma *= couplingsPtr->V2CKMid(abs(id1), abs(id2)) / 3.;
1765 // Corrections for secondary widths in Z0 and W+- decays.
1766 int idUp = (abs(id1)%2 == 0) ? id1 : id2;
1767 sigma *= (idUp > 0) ? openFracPos : openFracNeg;
1774 //--------------------------------------------------------------------------
1776 // Select identity, colour and anticolour.
1778 void Sigma2ffbar2ZW::setIdColAcol() {
1780 // Sign of outgoing W.
1781 int sign = 1 - 2 * (abs(id1)%2);
1782 if (id1 < 0) sign = -sign;
1783 setId( id1, id2, 23, 24 * sign);
1785 // tHat is defined between (f, W-) or (fbar, W+),
1786 // so OK for u/ubar on side 1, but must swap tHat <-> uHat if d/dbar.
1787 if (abs(id1)%2 == 1) swapTU = true;
1789 // Colour flow topologies. Swap when antiquarks.
1790 if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
1791 else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
1792 if (id1 < 0) swapColAcol();
1796 //--------------------------------------------------------------------------
1798 // Evaluate weight for Z0 and W+- decay angles.
1800 double Sigma2ffbar2ZW::weightDecay( Event& process, int iResBeg, int iResEnd) {
1802 // Two resonance decays, but with common weight.
1803 if (iResBeg != 5 || iResEnd != 6) return 1.;
1805 // Order so that fbar(1) f(2) -> f'(3) fbar'(4) f"(5) fbar"(6)
1806 // with f' fbar' from W+- and f" fbar" from Z0 (note flip Z0 <-> W+-).
1807 int i1 = (process[3].id() < 0) ? 3 : 4;
1809 int i3 = (process[9].id() > 0) ? 9 : 10;
1811 int i5 = (process[7].id() > 0) ? 7 : 8;
1814 // Set up four-products and internal products.
1815 setupProd( process, i1, i2, i3, i4, i5, i6);
1817 // Swap tHat and uHat if incoming fermion is downtype.
1820 if (process[i2].id()%2 == 1) swap( tHres, uHres);
1822 // Couplings of incoming (anti)fermions and outgoing from Z0.
1823 int idAbs = process[i1].idAbs();
1824 double ai = couplingsPtr->af(idAbs);
1825 double li1 = couplingsPtr->lf(idAbs);
1826 idAbs = process[i2].idAbs();
1827 double li2 = couplingsPtr->lf(idAbs);
1828 idAbs = process[i5].idAbs();
1829 double l4 = couplingsPtr->lf(idAbs);
1830 double r4 = couplingsPtr->rf(idAbs);
1832 // W propagator/interference factor.
1833 double Wint = cos2thetaW * (sH - mWS) / (pow2(sH - mWS) + mwWS);
1835 // Combinations of couplings and kinematics (norm(x) = |x|^2).
1836 double aWZ = li2 / tHres - 2. * Wint * ai;
1837 double bWZ = li1 / uHres + 2. * Wint * ai;
1838 double fGK135 = norm( aWZ * fGK( 1, 2, 3, 4, 5, 6)
1839 + bWZ * fGK( 1, 2, 5, 6, 3, 4) );
1840 double fGK136 = norm( aWZ * fGK( 1, 2, 3, 4, 6, 5)
1841 + bWZ * fGK( 1, 2, 6, 5, 3, 4) );
1842 double xiT = xiGK( tHres, uHres);
1843 double xiU = xiGK( uHres, tHres);
1844 double xjTU = xjGK( tHres, uHres);
1846 // Weight and maximum weight.
1847 double wt = l4*l4 * fGK135 + r4*r4 * fGK136;
1848 double wtMax = 4. * s3 * s4 * (l4*l4 + r4*r4)
1849 * (aWZ * aWZ * xiT + bWZ * bWZ * xiU + aWZ * bWZ * xjTU);
1856 //==========================================================================
1858 // Sigma2ffbar2WW class.
1859 // Cross section for f fbar -> W- W+ (f is quark or lepton).
1861 //--------------------------------------------------------------------------
1863 // Initialize process.
1865 void Sigma2ffbar2WW::initProc() {
1867 // Store Z0 mass and width for propagator. Common coupling factor.
1868 mZ = particleDataPtr->m0(23);
1869 widZ = particleDataPtr->mWidth(23);
1871 mwZS = pow2(mZ * widZ);
1872 thetaWRat = 1. / (4. * couplingsPtr->sin2thetaW());
1874 // Secondary open width fraction.
1875 openFracPair = particleDataPtr->resOpenFrac(24, -24);
1879 //--------------------------------------------------------------------------
1881 // Evaluate sigmaHat(sHat), part independent of incoming flavour.
1883 void Sigma2ffbar2WW::sigmaKin() {
1885 // Cross section part common for all incoming flavours.
1886 sigma0 = (M_PI / sH2) * pow2(alpEM);
1888 // Z0 propagator and gamma*/Z0 interference.
1889 double Zprop = sH2 / (pow2(sH - mZS) + mwZS);
1890 double Zint = Zprop * (1. - mZS / sH);
1892 // Common coupling factors (g = gamma*, Z = Z0, f = t-channel fermion).
1894 cgZ = thetaWRat * Zint;
1895 cZZ = 0.5 * pow2(thetaWRat) * Zprop;
1897 cfZ = pow2(thetaWRat) * Zint;
1898 cff = pow2(thetaWRat);
1900 // Kinematical functions.
1901 double rat34 = sH * (2. * (s3 + s4) + pT2) / (s3 * s4);
1902 double lambdaS = pow2(sH - s3 - s4) - 4. * s3 * s4;
1903 double intA = (sH - s3 - s4) * rat34 / sH;
1904 double intB = 4. * (s3 + s4 - pT2);
1905 gSS = (lambdaS * rat34 + 12. * sH * pT2) / sH2;
1906 gTT = rat34 + 4. * sH * pT2 / tH2;
1907 gST = intA + intB / tH;
1908 gUU = rat34 + 4. * sH * pT2 / uH2;
1909 gSU = intA + intB / uH;
1913 //--------------------------------------------------------------------------
1915 // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
1917 double Sigma2ffbar2WW::sigmaHat() {
1919 // Flavour-specific couplings.
1920 int idAbs = abs(id1);
1921 double ei = couplingsPtr->ef(idAbs);
1922 double vi = couplingsPtr->vf(idAbs);
1923 double ai = couplingsPtr->af(idAbs);
1925 // Combine, with different cases for up- and down-type in-flavours.
1926 double sigma = sigma0;
1927 sigma *= (idAbs%2 == 1)
1928 ? (cgg * ei*ei + cgZ * ei * vi + cZZ * (vi*vi + ai*ai)) * gSS
1929 + (cfg * ei + cfZ * (vi + ai)) * gST + cff * gTT
1930 : (cgg * ei*ei + cgZ * ei * vi + cZZ * (vi*vi + ai*ai)) * gSS
1931 - (cfg * ei + cfZ * (vi + ai)) * gSU + cff * gUU;
1933 // Initial-state colour factor. Correction for secondary widths. Answer.
1934 if (idAbs < 9) sigma /= 3.;
1935 sigma *= openFracPair;
1940 //--------------------------------------------------------------------------
1942 // Select identity, colour and anticolour.
1944 void Sigma2ffbar2WW::setIdColAcol() {
1946 // Always order W- W+, i.e. W- first.
1947 setId( id1, id2, -24, 24);
1949 // tHat is defined between (f, W-) or (fbar, W+),
1950 if (id1 < 0) swapTU = true;
1952 // Colour flow topologies. Swap when antiquarks.
1953 if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
1954 else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
1955 if (id1 < 0) swapColAcol();
1959 //--------------------------------------------------------------------------
1961 // Evaluate weight for W+ and W- decay angles.
1963 double Sigma2ffbar2WW::weightDecay( Event& process, int iResBeg, int iResEnd) {
1965 // Two resonance decays, but with common weight.
1966 if (iResBeg != 5 || iResEnd != 6) return 1.;
1968 // Order so that fbar(1) f(2) -> f'(3) fbar'(4) f"(5) fbar"(6).
1969 // with f' fbar' from W- and f" fbar" from W+.
1970 int i1 = (process[3].id() < 0) ? 3 : 4;
1972 int i3 = (process[7].id() > 0) ? 7 : 8;
1974 int i5 = (process[9].id() > 0) ? 9 : 10;
1977 // Set up four-products and internal products.
1978 setupProd( process, i1, i2, i3, i4, i5, i6);
1980 // tHat and uHat of fbar f -> W- W+ opposite to previous convention.
1984 // Couplings of incoming (anti)fermion.
1985 int idAbs = process[i1].idAbs();
1986 double ai = couplingsPtr->af(idAbs);
1987 double li = couplingsPtr->lf(idAbs);
1988 double ri = couplingsPtr->rf(idAbs);
1990 // gamma*/Z0 propagator/interference factor.
1991 double Zint = mZS * (sH - mZS) / (pow2(sH - mZS) + mwZS);
1993 // Combinations of couplings and kinematics (norm(x) = |x|^2).
1994 double dWW = (li * Zint + ai) / sH;
1995 double aWW = dWW + 0.5 * (ai + 1.) / tHres;
1996 double bWW = dWW + 0.5 * (ai - 1.) / uHres;
1997 double cWW = ri * Zint / sH;
1998 double fGK135 = norm( aWW * fGK( 1, 2, 3, 4, 5, 6)
1999 - bWW * fGK( 1, 2, 5, 6, 3, 4) );
2000 double fGK253 = norm( cWW * ( fGK( 2, 1, 5, 6, 3, 4)
2001 - fGK( 2, 1, 3, 4, 5, 6) ) );
2002 double xiT = xiGK( tHres, uHres);
2003 double xiU = xiGK( uHres, tHres);
2004 double xjTU = xjGK( tHres, uHres);
2006 // Weight and maximum weight.
2007 double wt = fGK135 + fGK253;
2008 double wtMax = 4. * s3 * s4
2009 * ( aWW * aWW * xiT + bWW * bWW * xiU - aWW * bWW * xjTU
2010 + cWW * cWW * (xiT + xiU - xjTU) );
2016 //==========================================================================
2018 // Sigma2ffbargmZggm class.
2019 // Collects common methods for f fbar -> gamma*/Z0 g/gamma and permutations.
2021 //--------------------------------------------------------------------------
2023 // Initialize process.
2025 void Sigma2ffbargmZggm::initProc() {
2027 // Allow to pick only gamma* or Z0 part of full gamma*/Z0 expression.
2028 gmZmode = settingsPtr->mode("WeakZ0:gmZmode");
2030 // Store Z0 mass and width for propagator.
2031 mRes = particleDataPtr->m0(23);
2032 GammaRes = particleDataPtr->mWidth(23);
2034 GamMRat = GammaRes / mRes;
2035 thetaWRat = 1. / (16. * couplingsPtr->sin2thetaW()
2036 * couplingsPtr->cos2thetaW());
2038 // Set pointer to particle properties and decay table.
2039 particlePtr = particleDataPtr->particleDataEntryPtr(23);
2043 //--------------------------------------------------------------------------
2045 // Evaluate sum of flavour couplings times phase space.
2047 void Sigma2ffbargmZggm::flavSum() {
2049 // Coupling factors for Z0 subsystem.
2050 double alpSZ = couplingsPtr->alphaS(s3);
2051 double colQZ = 3. * (1. + alpSZ / M_PI);
2053 // Reset quantities to sum. Declare variables in loop.
2058 double mf, mr, psvec, psaxi, betaf, ef2, efvf, vf2af2, colf;
2060 // Loop over all Z0 decay channels.
2061 for (int i = 0; i < particlePtr->sizeChannels(); ++i) {
2062 int idAbs = abs( particlePtr->channel(i).product(0) );
2064 // Only contributions from three fermion generations, except top.
2065 if ( (idAbs > 0 && idAbs < 6) || ( idAbs > 10 && idAbs < 17)) {
2066 mf = particleDataPtr->m0(idAbs);
2068 // Check that above threshold. Phase space.
2069 if (m3 > 2. * mf + MASSMARGIN) {
2071 betaf = sqrtpos(1. - 4. * mr);
2072 psvec = betaf * (1. + 2. * mr);
2073 psaxi = pow3(betaf);
2075 // Combine phase space with couplings.
2076 ef2 = couplingsPtr->ef2(idAbs) * psvec;
2077 efvf = couplingsPtr->efvf(idAbs) * psvec;
2078 vf2af2 = couplingsPtr->vf2(idAbs) * psvec
2079 + couplingsPtr->af2(idAbs) * psaxi;
2080 colf = (idAbs < 6) ? colQZ : 1.;
2082 // Store sum of combinations. For outstate only open channels.
2083 onMode = particlePtr->channel(i).onMode();
2084 if (onMode == 1 || onMode == 2) {
2085 gamSum += colf * ef2;
2086 intSum += colf * efvf;
2087 resSum += colf * vf2af2;
2090 // End loop over fermions.
2095 // Done. Return values in gamSum, intSum and resSum.
2099 //--------------------------------------------------------------------------
2101 // Calculate common parts of gamma/interference/Z0 propagator terms.
2103 void Sigma2ffbargmZggm::propTerm() {
2105 // Calculate prefactors for gamma/interference/Z0 cross section terms.
2106 gamProp = 4. * alpEM / (3. * M_PI * s3);
2107 intProp = gamProp * 2. * thetaWRat * s3 * (s3 - m2Res)
2108 / ( pow2(s3 - m2Res) + pow2(s3 * GamMRat) );
2109 resProp = gamProp * pow2(thetaWRat * s3)
2110 / ( pow2(s3 - m2Res) + pow2(s3 * GamMRat) );
2112 // Optionally only keep gamma* or Z0 term.
2113 if (gmZmode == 1) {intProp = 0.; resProp = 0.;}
2114 if (gmZmode == 2) {gamProp = 0.; intProp = 0.;}
2118 //--------------------------------------------------------------------------
2120 // Evaluate weight for gamma*/Z0 decay angle.
2122 double Sigma2ffbargmZggm::weightDecay( Event& process, int iResBeg,
2125 // Z should sit in entry 5 and one more parton in entry 6.
2126 if (iResBeg != 5 || iResEnd != 6) return 1.;
2128 // In an outgoing sense fermions are labelled f(1) fbar(2) f'(3) fbar'(4)
2129 // where f' fbar' come from gamma*/Z0 decay.
2131 int i3 = (process[7].id() > 0) ? 7 : 8;
2134 // Order so that fbar(1) f(2) -> gamma*/Z0 g/gamma.
2135 if (process[3].idAbs() < 20 && process[4].idAbs() < 20) {
2136 i1 = (process[3].id() < 0) ? 3 : 4;
2139 // Order so that f(2)/fbar(1) g/gamma -> f(1)/fbar(2) f'(3) gamma*/Z0.
2140 } else if (process[3].idAbs() < 20) {
2141 i1 = (process[3].id() < 0) ? 3 : 6;
2144 i1 = (process[4].id() < 0) ? 4 : 6;
2148 // Charge/2, left- and righthanded couplings for in- and out-fermion.
2149 int id1Abs = process[i1].idAbs();
2150 double ei = 0.5 * couplingsPtr->ef(id1Abs);
2151 double li = couplingsPtr->lf(id1Abs);
2152 double ri = couplingsPtr->rf(id1Abs);
2153 int id3Abs = process[i3].idAbs();
2154 double ef = 0.5 * couplingsPtr->ef(id3Abs);
2155 double lf = couplingsPtr->lf(id3Abs);
2156 double rf = couplingsPtr->rf(id3Abs);
2158 // Combinations of left/right for in/out, gamma*/interference/Z0.
2159 double clilf = ei*ei * gamProp * ef*ef + ei*li * intProp * ef*lf
2160 + li*li * resProp * lf*lf;
2161 double clirf = ei*ei * gamProp * ef*ef + ei*li * intProp * ef*rf
2162 + li*li * resProp * rf*rf;
2163 double crilf = ei*ei * gamProp * ef*ef + ei*ri * intProp * ef*lf
2164 + ri*ri * resProp * lf*lf;
2165 double crirf = ei*ei * gamProp * ef*ef + ei*ri * intProp * ef*rf
2166 + ri*ri * resProp * rf*rf;
2168 // Evaluate four-vector products.
2169 double p13 = process[i1].p() * process[i3].p();
2170 double p14 = process[i1].p() * process[i4].p();
2171 double p23 = process[i2].p() * process[i3].p();
2172 double p24 = process[i2].p() * process[i4].p();
2174 // Calculate weight and its maximum.
2175 double wt = (clilf + crirf) * (p13*p13 + p24*p24)
2176 + (clirf + crilf) * (p14*p14 + p23*p23) ;
2177 double wtMax = (clilf + clirf + crilf + crirf)
2178 * (pow2(p13 + p14) + pow2(p23 + p24));
2181 return (wt / wtMax);
2185 //==========================================================================
2187 // Sigma2qqbar2gmZg class.
2188 // Cross section for q qbar -> gamma*/Z0 g.
2190 //--------------------------------------------------------------------------
2192 // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
2194 void Sigma2qqbar2gmZg::sigmaKin() {
2196 // Cross section part common for all incoming flavours.
2197 sigma0 = (M_PI / sH2) * (alpEM * alpS)
2198 * (2./9.) * (tH2 + uH2 + 2. * sH * s3) / (tH * uH);
2200 // Calculate flavour sums for final state.
2203 // Calculate prefactors for gamma/interference/Z0 cross section terms.
2208 //--------------------------------------------------------------------------
2210 // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
2212 double Sigma2qqbar2gmZg::sigmaHat() {
2214 // Combine gamma, interference and Z0 parts.
2215 int idAbs = abs(id1);
2216 double sigma = sigma0
2217 * ( couplingsPtr->ef2(idAbs) * gamProp * gamSum
2218 + couplingsPtr->efvf(idAbs) * intProp * intSum
2219 + couplingsPtr->vf2af2(idAbs) * resProp * resSum);
2221 // Correct for the running-width Z0 propagater weight in PhaseSpace.
2229 //--------------------------------------------------------------------------
2231 // Select identity, colour and anticolour.
2233 void Sigma2qqbar2gmZg::setIdColAcol() {
2235 // Flavours trivial.
2236 setId( id1, id2, 23, 21);
2238 // Colour flow topologies. Swap when antiquarks.
2239 setColAcol( 1, 0, 0, 2, 0, 0, 1, 2);
2240 if (id1 < 0) swapColAcol();
2244 //==========================================================================
2246 // Sigma2qg2gmZq class.
2247 // Cross section for q g -> gamma*/Z0 q.
2249 //--------------------------------------------------------------------------
2251 // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
2253 void Sigma2qg2gmZq::sigmaKin() {
2255 // Cross section part common for all incoming flavours.
2256 sigma0 = (M_PI / sH2) * (alpEM * alpS)
2257 * (1./12.) * (sH2 + uH2 + 2. * tH * s3) / (-sH * uH);
2259 // Calculate flavour sums for final state.
2262 // Calculate prefactors for gamma/interference/Z0 cross section terms.
2267 //--------------------------------------------------------------------------
2269 // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
2271 double Sigma2qg2gmZq::sigmaHat() {
2273 // Combine gamma, interference and Z0 parts.
2274 int idAbs = (id2 == 21) ? abs(id1) : abs(id2);
2275 double sigma = sigma0
2276 * ( couplingsPtr->ef2(idAbs) * gamProp * gamSum
2277 + couplingsPtr->efvf(idAbs) * intProp * intSum
2278 + couplingsPtr->vf2af2(idAbs) * resProp * resSum);
2280 // Correct for the running-width Z0 propagater weight in PhaseSpace.
2288 //--------------------------------------------------------------------------
2290 // Select identity, colour and anticolour.
2292 void Sigma2qg2gmZq::setIdColAcol() {
2294 // Flavour set up for q g -> gamma*/Z0 q.
2295 int idq = (id2 == 21) ? id1 : id2;
2296 setId( id1, id2, 23, idq);
2298 // tH defined between f and f': must swap tHat <-> uHat if q g in.
2299 swapTU = (id2 == 21);
2301 // Colour flow topologies. Swap when antiquarks.
2302 if (id2 == 21) setColAcol( 1, 0, 2, 1, 0, 0, 2, 0);
2303 else setColAcol( 2, 1, 1, 0, 0, 0, 2, 0);
2304 if (idq < 0) swapColAcol();
2308 //==========================================================================
2310 // Sigma2ffbar2gmZgm class.
2311 // Cross section for f fbar -> gamma*/Z0 gamma.
2313 //--------------------------------------------------------------------------
2315 // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
2317 void Sigma2ffbar2gmZgm::sigmaKin() {
2319 // Cross section part common for all incoming flavours.
2320 sigma0 = (M_PI / sH2) * (alpEM*alpEM)
2321 * 0.5 * (tH2 + uH2 + 2. * sH * s3) / (tH * uH);
2323 // Calculate flavour sums for final state.
2326 // Calculate prefactors for gamma/interference/Z0 cross section terms.
2332 //--------------------------------------------------------------------------
2334 // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
2336 double Sigma2ffbar2gmZgm::sigmaHat() {
2338 // Combine gamma, interference and Z0 parts.
2339 int idAbs = abs(id1);
2340 double sigma = sigma0 * couplingsPtr->ef2(idAbs)
2341 * ( couplingsPtr->ef2(idAbs) * gamProp * gamSum
2342 + couplingsPtr->efvf(idAbs) * intProp * intSum
2343 + couplingsPtr->vf2af2(idAbs) * resProp * resSum);
2345 // Correct for the running-width Z0 propagater weight in PhaseSpace.
2348 // Colour factor. Answer.
2349 if (idAbs < 9) sigma /= 3.;
2354 //--------------------------------------------------------------------------
2356 // Select identity, colour and anticolour.
2358 void Sigma2ffbar2gmZgm::setIdColAcol() {
2360 // Flavours trivial.
2361 setId( id1, id2, 23, 22);
2363 // Colour flow topologies. Swap when antiquarks.
2364 if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
2365 else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
2366 if (id1 < 0) swapColAcol();
2370 //==========================================================================
2372 // Sigma2fgm2gmZf class.
2373 // Cross section for f gamma -> gamma*/Z0 f'.
2375 //--------------------------------------------------------------------------
2377 // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
2379 void Sigma2fgm2gmZf::sigmaKin() {
2381 // Cross section part common for all incoming flavours.
2382 sigma0 = (M_PI / sH2) * (alpEM*alpEM)
2383 * 0.5 * (sH2 + uH2 + 2. * tH * s3) / (- sH * uH);
2385 // Calculate flavour sums for final state.
2388 // Calculate prefactors for gamma/interference/Z0 cross section terms.
2393 //--------------------------------------------------------------------------
2395 // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
2397 double Sigma2fgm2gmZf::sigmaHat() {
2399 // Combine gamma, interference and Z0 parts.
2400 int idAbs = (id2 == 22) ? abs(id1) : abs(id2);
2401 double sigma = sigma0 * couplingsPtr->ef2(idAbs)
2402 * ( couplingsPtr->ef2(idAbs) * gamProp * gamSum
2403 + couplingsPtr->efvf(idAbs) * intProp * intSum
2404 + couplingsPtr->vf2af2(idAbs) * resProp * resSum);
2406 // Correct for the running-width Z0 propagater weight in PhaseSpace.
2414 //--------------------------------------------------------------------------
2416 // Select identity, colour and anticolour.
2418 void Sigma2fgm2gmZf::setIdColAcol() {
2420 // Flavour set up for q gamma -> gamma*/Z0 q.
2421 int idq = (id2 == 22) ? id1 : id2;
2422 setId( id1, id2, 23, idq);
2424 // tH defined between f and f': must swap tHat <-> uHat if q gamma in.
2425 swapTU = (id2 == 22);
2427 // Colour flow topologies. Swap when antiquarks.
2428 if (abs(id1) < 9) setColAcol( 1, 0, 0, 0, 0, 0, 1, 0);
2429 else if (abs(id2) < 9) setColAcol( 0, 0, 1, 0, 0, 0, 1, 0);
2430 else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
2431 if (idq < 0) swapColAcol();
2435 //==========================================================================
2437 // Sigma2ffbarWggm class.
2438 // Collects common methods for f fbar -> W+- g/gamma and permutations.
2440 //--------------------------------------------------------------------------
2442 // Evaluate weight for W+- decay angle.
2444 double Sigma2ffbarWggm::weightDecay( Event& process, int iResBeg,
2447 // W should sit in entry 5 and one more parton in entry 6.
2448 if (iResBeg != 5 || iResEnd != 6) return 1.;
2450 // In an outgoing sense fermions are labelled f(1) fbar(2) f'(3) fbar'(4)
2451 // where f' fbar' come from W+- decay.
2453 int i3 = (process[7].id() > 0) ? 7 : 8;
2456 // Order so that fbar(1) f(2) -> W+- g/gamma.
2457 if (process[3].idAbs() < 20 && process[4].idAbs() < 20) {
2458 i1 = (process[3].id() < 0) ? 3 : 4;
2461 // Order so that f(2)/fbar(1) g/gamma -> f(1)/fbar(2) f'(3) W+-.
2462 } else if (process[3].idAbs() < 20) {
2463 i1 = (process[3].id() < 0) ? 3 : 6;
2466 i1 = (process[4].id() < 0) ? 4 : 6;
2470 // Evaluate four-vector products.
2471 double p13 = process[i1].p() * process[i3].p();
2472 double p14 = process[i1].p() * process[i4].p();
2473 double p23 = process[i2].p() * process[i3].p();
2474 double p24 = process[i2].p() * process[i4].p();
2476 // Calculate weight and its maximum.
2477 double wt = pow2(p13) + pow2(p24);
2478 double wtMax = pow2(p13 + p14) + pow2(p23 + p24);
2481 return (wt / wtMax);
2485 //==========================================================================
2487 // Sigma2qqbar2Wg class.
2488 // Cross section for q qbar' -> W+- g.
2490 //--------------------------------------------------------------------------
2492 // Initialize process.
2494 void Sigma2qqbar2Wg::initProc() {
2496 // Secondary open width fractions, relevant for top (or heavier).
2497 openFracPos = particleDataPtr->resOpenFrac(24);
2498 openFracNeg = particleDataPtr->resOpenFrac(-24);
2502 //--------------------------------------------------------------------------
2504 // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
2506 void Sigma2qqbar2Wg::sigmaKin() {
2508 // Cross section part common for all incoming flavours.
2509 sigma0 = (M_PI / sH2) * (alpEM * alpS / couplingsPtr->sin2thetaW())
2510 * (2./9.) * (tH2 + uH2 + 2. * sH * s3) / (tH * uH);
2514 //--------------------------------------------------------------------------
2516 // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
2518 double Sigma2qqbar2Wg::sigmaHat() {
2520 // CKM factor. Secondary width for W+ or W-.
2521 double sigma = sigma0 * couplingsPtr->V2CKMid(abs(id1), abs(id2));
2522 int idUp = (abs(id1)%2 == 0) ? id1 : id2;
2523 sigma *= (idUp > 0) ? openFracPos : openFracNeg;
2530 //--------------------------------------------------------------------------
2532 // Select identity, colour and anticolour.
2534 void Sigma2qqbar2Wg::setIdColAcol() {
2536 // Sign of outgoing W.
2537 int sign = 1 - 2 * (abs(id1)%2);
2538 if (id1 < 0) sign = -sign;
2539 setId( id1, id2, 24 * sign, 21);
2541 // Colour flow topologies. Swap when antiquarks.
2542 setColAcol( 1, 0, 0, 2, 0, 0, 1, 2);
2543 if (id1 < 0) swapColAcol();
2547 //==========================================================================
2549 // Sigma2qg2Wq class.
2550 // Cross section for q g -> W+- q'.
2552 //--------------------------------------------------------------------------
2554 // Initialize process.
2556 void Sigma2qg2Wq::initProc() {
2558 // Secondary open width fractions, relevant for top (or heavier).
2559 openFracPos = particleDataPtr->resOpenFrac(24);
2560 openFracNeg = particleDataPtr->resOpenFrac(-24);
2564 //--------------------------------------------------------------------------
2566 // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
2568 void Sigma2qg2Wq::sigmaKin() {
2570 // Cross section part common for all incoming flavours.
2571 sigma0 = (M_PI / sH2) * (alpEM * alpS / couplingsPtr->sin2thetaW())
2572 * (1./12.) * (sH2 + uH2 + 2. * tH * s3) / (-sH * uH);
2576 //--------------------------------------------------------------------------
2578 // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
2580 double Sigma2qg2Wq::sigmaHat() {
2582 // CKM factor. Secondary width for W+ or W-.
2583 int idAbs = (id2 == 21) ? abs(id1) : abs(id2);
2584 double sigma = sigma0 * couplingsPtr->V2CKMsum(idAbs);
2585 int idUp = (id2 == 21) ? id1 : id2;
2586 if (idAbs%2 == 1) idUp = -idUp;
2587 sigma *= (idUp > 0) ? openFracPos : openFracNeg;
2594 //--------------------------------------------------------------------------
2596 // Select identity, colour and anticolour.
2598 void Sigma2qg2Wq::setIdColAcol() {
2600 // Sign of outgoing W. Flavour of outgoing quark.
2601 int idq = (id2 == 21) ? id1 : id2;
2602 int sign = 1 - 2 * (abs(idq)%2);
2603 if (idq < 0) sign = -sign;
2604 id4 = couplingsPtr->V2CKMpick(idq);
2606 // Flavour set up for q g -> W q.
2607 setId( id1, id2, 24 * sign, id4);
2609 // tH defined between f and f': must swap tHat <-> uHat if q g in.
2610 swapTU = (id2 == 21);
2612 // Colour flow topologies. Swap when antiquarks.
2613 if (id2 == 21) setColAcol( 1, 0, 2, 1, 0, 0, 2, 0);
2614 else setColAcol( 2, 1, 1, 0, 0, 0, 2, 0);
2615 if (idq < 0) swapColAcol();
2619 //==========================================================================
2621 // Sigma2ffbar2Wgm class.
2622 // Cross section for f fbar' -> W+- gamma.
2624 //--------------------------------------------------------------------------
2626 // Initialize process.
2628 void Sigma2ffbar2Wgm::initProc() {
2630 // Secondary open width fractions, relevant for top (or heavier).
2631 openFracPos = particleDataPtr->resOpenFrac(24);
2632 openFracNeg = particleDataPtr->resOpenFrac(-24);
2636 //--------------------------------------------------------------------------
2638 // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
2640 void Sigma2ffbar2Wgm::sigmaKin() {
2642 // Cross section part common for all incoming flavours.
2643 sigma0 = (M_PI / sH2) * (alpEM*alpEM / couplingsPtr->sin2thetaW())
2644 * 0.5 * (tH2 + uH2 + 2. * sH * s3) / (tH * uH);
2647 //--------------------------------------------------------------------------
2649 // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
2651 double Sigma2ffbar2Wgm::sigmaHat() {
2653 // Extrafactor different for e nu and q qbar' instate.
2654 int id1Abs = abs(id1);
2655 int id2Abs = abs(id2);
2656 double chgUp = (id1Abs > 10) ? 0. : 2./3.;
2657 double sigma = sigma0 * pow2( chgUp - tH / (tH + uH) );
2659 // CKM and colour factors. Secondary width for W+ or W-.
2660 if (id1Abs < 9) sigma *= couplingsPtr->V2CKMid(id1Abs, id2Abs) / 3.;
2661 int idUp = (abs(id1)%2 == 0) ? id1 : id2;
2662 sigma *= (idUp > 0) ? openFracPos : openFracNeg;
2669 //--------------------------------------------------------------------------
2671 // Select identity, colour and anticolour.
2673 void Sigma2ffbar2Wgm::setIdColAcol() {
2675 // Sign of outgoing W.
2676 int sign = 1 - 2 * (abs(id1)%2);
2677 if (id1 < 0) sign = -sign;
2678 setId( id1, id2, 24 * sign, 22);
2680 // tH defined between (f,W-) or (fbar',W+).
2681 swapTU = (sign * id1 > 0);
2683 // Colour flow topologies. Swap when antiquarks.
2684 if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
2685 else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
2686 if (id1 < 0) swapColAcol();
2690 //==========================================================================
2692 // Sigma2fgm2Wf class.
2693 // Cross section for f gamma -> W+- f'.
2695 //--------------------------------------------------------------------------
2697 // Initialize process.
2699 void Sigma2fgm2Wf::initProc() {
2701 // Secondary open width fractions, relevant for top (or heavier).
2702 openFracPos = particleDataPtr->resOpenFrac(24);
2703 openFracNeg = particleDataPtr->resOpenFrac(-24);
2707 //--------------------------------------------------------------------------
2709 // Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
2711 void Sigma2fgm2Wf::sigmaKin() {
2713 // Cross section part common for all incoming flavours.
2714 sigma0 = (M_PI / sH2) * (alpEM*alpEM / couplingsPtr->sin2thetaW())
2715 * 0.5 * (sH2 + uH2 + 2. * tH * s3) / (pT2 * s3 - sH * uH);
2719 //--------------------------------------------------------------------------
2721 // Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
2723 double Sigma2fgm2Wf::sigmaHat() {
2725 // Extrafactor dependent on charge of incoming fermion.
2726 int idAbs = (id2 == 22) ? abs(id1) : abs(id2);
2727 double charge = (idAbs > 10) ? 1. : ( (idAbs%2 == 1) ? 1./3. : 2./3. );
2728 double sigma = sigma0 * pow2( charge - sH / (sH + uH) );
2730 // CKM factor. Secondary width for W+ or W-.
2731 sigma *= couplingsPtr->V2CKMsum(idAbs);
2732 int idUp = (id2 == 22) ? id1 : id2;
2733 if (idAbs%2 == 1) idUp = -idUp;
2734 sigma *= (idUp > 0) ? openFracPos : openFracNeg;
2741 //--------------------------------------------------------------------------
2743 // Select identity, colour and anticolour.
2745 void Sigma2fgm2Wf::setIdColAcol() {
2747 // Sign of outgoing W. Flavour of outgoing fermion.
2748 int idq = (id2 == 22) ? id1 : id2;
2749 int sign = 1 - 2 * (abs(idq)%2);
2750 if (idq < 0) sign = -sign;
2751 id4 = couplingsPtr->V2CKMpick(idq);
2753 // Flavour set up for q gamma -> W q.
2754 setId( id1, id2, 24 * sign, id4);
2756 // tH defined between f and f': must swap tHat <-> uHat if q gamma in.
2757 swapTU = (id2 == 22);
2759 // Colour flow topologies. Swap when antiquarks.
2760 if (abs(id1) < 9) setColAcol( 1, 0, 0, 0, 0, 0, 1, 0);
2761 else if (abs(id2) < 9) setColAcol( 0, 0, 1, 0, 0, 0, 1, 0);
2762 else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
2763 if (idq < 0) swapColAcol();
2767 //==========================================================================
2769 // Sigma2gmgm2ffbar class.
2770 // Cross section for gamma gamma -> l lbar.
2772 //--------------------------------------------------------------------------
2774 // Initialize process wrt flavour.
2776 void Sigma2gmgm2ffbar::initProc() {
2779 nameSave = "gamma gamma -> f fbar";
2780 if (idNew == 1) nameSave = "gamma gamma -> q qbar (uds)";
2781 if (idNew == 4) nameSave = "gamma gamma -> c cbar";
2782 if (idNew == 5) nameSave = "gamma gamma -> b bbar";
2783 if (idNew == 6) nameSave = "gamma gamma -> t tbar";
2784 if (idNew == 11) nameSave = "gamma gamma -> e+ e-";
2785 if (idNew == 13) nameSave = "gamma gamma -> mu+ mu-";
2786 if (idNew == 15) nameSave = "gamma gamma -> tau+ tau-";
2788 // Generate massive phase space, except for u+d+s.
2790 if (idNew > 3) idMass = idNew;
2792 // Charge and colour factor.
2794 if (idNew == 1) ef4 = 3. * (pow4(2./3.) + 2. * pow4(1./3.));
2795 if (idNew == 4 || idNew == 6) ef4 = 3. * pow4(2./3.);
2796 if (idNew == 5) ef4 = 3. * pow4(1./3.);
2798 // Secondary open width fraction.
2799 openFracPair = particleDataPtr->resOpenFrac(idNew, -idNew);
2803 //--------------------------------------------------------------------------
2805 // Evaluate d(sigmaHat)/d(tHat) - no incoming flavour dependence.
2807 void Sigma2gmgm2ffbar::sigmaKin() {
2809 // Pick current flavour for u+d+s mix by e_q^4 weights.
2811 double rId = 18. * rndmPtr->flat();
2813 if (rId > 1.) idNow = 2;
2814 if (rId > 17.) idNow = 3;
2815 s34Avg = pow2(particleDataPtr->m0(idNow));
2818 s34Avg = 0.5 * (s3 + s4) - 0.25 * pow2(s3 - s4) / sH;
2821 // Modified Mandelstam variables for massive kinematics with m3 = m4.
2822 double tHQ = -0.5 * (sH - tH + uH);
2823 double uHQ = -0.5 * (sH + tH - uH);
2824 double tHQ2 = tHQ * tHQ;
2825 double uHQ2 = uHQ * uHQ;
2827 // Calculate kinematics dependence.
2828 if (sH < 4. * s34Avg) sigTU = 0.;
2829 else sigTU = 2. * (tHQ * uHQ - s34Avg * sH)
2830 * (tHQ2 + uHQ2 + 2. * s34Avg * sH) / (tHQ2 * uHQ2);
2833 sigma = (M_PI / sH2) * pow2(alpEM) * ef4 * sigTU * openFracPair;
2837 //--------------------------------------------------------------------------
2839 // Select identity, colour and anticolour.
2841 void Sigma2gmgm2ffbar::setIdColAcol() {
2843 // Flavours are trivial.
2844 setId( id1, id2, idNow, -idNow);
2846 // Colour flow in singlet state.
2847 if (idNow < 10) setColAcol( 0, 0, 0, 0, 1, 0, 0, 1);
2848 else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
2852 //==========================================================================
2854 } // end namespace Pythia8