StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StandardModel.cc
1 // StandardModel.cc is a part of the PYTHIA event generator.
2 // Copyright (C) 2014 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 AlphaStrong class.
7 
8 #include "Pythia8/StandardModel.h"
9 
10 namespace Pythia8 {
11 
12 //==========================================================================
13 
14 // The AlphaStrong class.
15 
16 //--------------------------------------------------------------------------
17 
18 // Constants: could be changed here if desired, but normally should not.
19 // These are of technical nature, as described for each.
20 
21 // Number of iterations to determine Lambda from given alpha_s.
22 const int AlphaStrong::NITER = 10;
23 
24 // Masses: m_c, m_b, m_t, m_Z.
25 // Used for flavour thresholds and normalization scale.
26 const double AlphaStrong::MC = 1.5;
27 const double AlphaStrong::MB = 4.8;
28 const double AlphaStrong::MT = 171.0;
29 const double AlphaStrong::MZ = 91.188;
30 
31 // Always evaluate running alpha_s above Lambda3 to avoid disaster.
32 // Safety margin picked to freeze roughly for alpha_s = 10.
33 const double AlphaStrong::SAFETYMARGIN1 = 1.07;
34 const double AlphaStrong::SAFETYMARGIN2 = 1.33;
35 
36 // CMW factor for 3, 4, 5, and 6 flavours.
37 const double AlphaStrong::FACCMW3 = 1.661;
38 const double AlphaStrong::FACCMW4 = 1.618;
39 const double AlphaStrong::FACCMW5 = 1.569;
40 const double AlphaStrong::FACCMW6 = 1.513;
41 
42 //--------------------------------------------------------------------------
43 
44 // Initialize alpha_strong calculation by finding Lambda values etc.
45 
46 void AlphaStrong::init( double valueIn, int orderIn, int nfmaxIn,
47  bool useCMWIn) {
48 
49  // Order of alpha_s evaluation.Default values.
50  valueRef = valueIn;
51  order = max( 0, min( 2, orderIn ) );
52  nfmax = max(5,min(6,nfmaxIn));
53  useCMW = useCMWIn;
54  lastCallToFull = false;
55  Lambda3Save = Lambda4Save = Lambda5Save = Lambda6Save = scale2Min = 0.;
56 
57  // Fix alpha_s.
58  if (order == 0) {
59 
60  // First order alpha_s: match at flavour thresholds.
61  } else if (order == 1) {
62  Lambda5Save = MZ * exp( -6. * M_PI / (23. * valueRef) );
63  Lambda6Save = Lambda5Save * pow(Lambda5Save/MT, 2./21.);
64  Lambda4Save = Lambda5Save * pow(MB/Lambda5Save, 2./25.);
65  Lambda3Save = Lambda4Save * pow(MC/Lambda4Save, 2./27.);
66 
67  // Second order alpha_s: iterative match at flavour thresholds.
68  } else {
69  // The one-loop coefficients: b1 / b0^2
70  double b16 = 234. / 441.;
71  double b15 = 348. / 529.;
72  double b14 = 462. / 625.;
73  double b13 = 576. / 729.;
74  // The two-loop coefficients: b2 * b0 / b1^2
75  double b26 = -36855. / 109512.;
76  double b25 = 224687. / 242208.;
77  double b24 = 548575. / 426888.;
78  double b23 = 938709. / 663552.;
79 
80  double logScale, loglogScale, correction, valueIter;
81  // Find Lambda_5 at m_Z.
82  Lambda5Save = MZ * exp( -6. * M_PI / (23. * valueRef) );
83  for (int iter = 0; iter < NITER; ++iter) {
84  logScale = 2. * log(MZ/Lambda5Save);
85  loglogScale = log(logScale);
86  correction = 1. - b15 * loglogScale / logScale
87  + pow2(b15 / logScale) * (pow2(loglogScale - 0.5) + b25 - 1.25);
88  valueIter = valueRef / correction;
89  Lambda5Save = MZ * exp( -6. * M_PI / (23. * valueIter) );
90  }
91 
92  // Find Lambda_6 at m_t.
93  double logScaleT = 2. * log(MT/Lambda5Save);
94  double loglogScaleT = log(logScaleT);
95  double valueT = 12. * M_PI / (21. * logScaleT)
96  * (1. - b16 * loglogScaleT / logScaleT
97  + pow2(b16 / logScaleT) * (pow2(loglogScaleT - 0.5) + b26 - 1.25) );
98  Lambda6Save = Lambda5Save;
99  for (int iter = 0; iter < NITER; ++iter) {
100  logScale = 2. * log(MT/Lambda6Save);
101  loglogScale = log(logScale);
102  correction = 1. - b15 * loglogScale / logScale
103  + pow2(b15 / logScale) * (pow2(loglogScale - 0.5) + b25 - 1.25);
104  valueIter = valueT / correction;
105  Lambda6Save = MT * exp( -6. * M_PI / (21. * valueIter) );
106  }
107 
108  // Find Lambda_4 at m_b.
109  double logScaleB = 2. * log(MB/Lambda5Save);
110  double loglogScaleB = log(logScaleB);
111  double valueB = 12. * M_PI / (23. * logScaleB)
112  * (1. - b15 * loglogScaleB / logScaleB
113  + pow2(b15 / logScaleB) * (pow2(loglogScaleB - 0.5) + b25- 1.25) );
114  Lambda4Save = Lambda5Save;
115  for (int iter = 0; iter < NITER; ++iter) {
116  logScale = 2. * log(MB/Lambda4Save);
117  loglogScale = log(logScale);
118  correction = 1. - b14 * loglogScale / logScale
119  + pow2(b14 / logScale) * (pow2(loglogScale - 0.5) + b24 - 1.25);
120  valueIter = valueB / correction;
121  Lambda4Save = MB * exp( -6. * M_PI / (25. * valueIter) );
122  }
123  // Find Lambda_3 at m_c.
124  double logScaleC = 2. * log(MC/Lambda4Save);
125  double loglogScaleC = log(logScaleC);
126  double valueC = 12. * M_PI / (25. * logScaleC)
127  * (1. - b14 * loglogScaleC / logScaleC
128  + pow2(b14 / logScaleC) * (pow2(loglogScaleC - 0.5) + b24 - 1.25) );
129  Lambda3Save = Lambda4Save;
130  for (int iter = 0; iter < NITER; ++iter) {
131  logScale = 2. * log(MC/Lambda3Save);
132  loglogScale = log(logScale);
133  correction = 1. - b13 * loglogScale / logScale
134  + pow2(b13 / logScale) * (pow2(loglogScale - 0.5) + b23 - 1.25);
135  valueIter = valueC / correction;
136  Lambda3Save = MC * exp( -6. * M_PI / (27. * valueIter) );
137  }
138  }
139 
140  // Optionally rescale Lambda values by CMW factor.
141  if (useCMW) {
142  Lambda3Save *= FACCMW3;
143  Lambda4Save *= FACCMW4;
144  Lambda5Save *= FACCMW5;
145  Lambda6Save *= FACCMW6;
146  }
147 
148  // Impose SAFETYMARGINs to prevent getting too close to LambdaQCD.
149  if (order == 1) scale2Min = pow2(SAFETYMARGIN1 * Lambda3Save);
150  else if (order == 2) scale2Min = pow2(SAFETYMARGIN2 * Lambda3Save);
151 
152  // Save squares of mass and Lambda values as well.
153  Lambda3Save2 = pow2(Lambda3Save);
154  Lambda4Save2 = pow2(Lambda4Save);
155  Lambda5Save2 = pow2(Lambda5Save);
156  Lambda6Save2 = pow2(Lambda6Save);
157  mc2 = pow2(MC);
158  mb2 = pow2(MB);
159  mt2 = pow2(MT);
160  valueNow = valueIn;
161  scale2Now = MZ * MZ;
162  isInit = true;
163 
164 }
165 
166 //--------------------------------------------------------------------------
167 
168 // Calculate alpha_s value.
169 
170 double AlphaStrong::alphaS( double scale2) {
171 
172  // Check for initialization and ensure minimal scale2 value.
173  if (!isInit) return 0.;
174  if (scale2 < scale2Min) scale2 = scale2Min;
175 
176  // If equal to old scale then same answer.
177  if (scale2 == scale2Now && (order < 2 || lastCallToFull)) return valueNow;
178  scale2Now = scale2;
179  lastCallToFull = true;
180 
181  // Fix alpha_s.
182  if (order == 0) {
183  valueNow = valueRef;
184 
185  // First order alpha_s: differs by mass region.
186  } else if (order == 1) {
187  if (scale2 > mt2 && nfmax >= 6)
188  valueNow = 12. * M_PI / (21. * log(scale2/Lambda6Save2));
189  else if (scale2 > mb2)
190  valueNow = 12. * M_PI / (23. * log(scale2/Lambda5Save2));
191  else if (scale2 > mc2)
192  valueNow = 12. * M_PI / (25. * log(scale2/Lambda4Save2));
193  else valueNow = 12. * M_PI / (27. * log(scale2/Lambda3Save2));
194 
195  // Second order alpha_s: differs by mass region.
196  } else {
197  double Lambda2, b0, b1, b2;
198  if (scale2 > mt2 && nfmax >= 6) {
199  Lambda2 = Lambda6Save2;
200  b0 = 21.;
201  b1 = 234. / 441.;
202  b2 = -36855. / 109512.;
203  } else if (scale2 > mb2) {
204  Lambda2 = Lambda5Save2;
205  b0 = 23.;
206  b1 = 348. / 529.;
207  b2 = 224687. / 242208.;
208  } else if (scale2 > mc2) {
209  Lambda2 = Lambda4Save2;
210  b0 = 25.;
211  b1 = 462. / 625.;
212  b2 = 548575. / 426888.;
213  } else {
214  Lambda2 = Lambda3Save2;
215  b0 = 27.;
216  b1 = 64. / 81.;
217  b2 = 938709. / 663552.;
218  }
219  double logScale = log(scale2/Lambda2);
220  double loglogScale = log(logScale);
221  valueNow = 12. * M_PI / (b0 * logScale)
222  * ( 1. - b1 * loglogScale / logScale
223  + pow2(b1 / logScale) * (pow2(loglogScale - 0.5) + b2 - 1.25) );
224  }
225 
226  // Done.
227  return valueNow;
228 
229 }
230 
231 //--------------------------------------------------------------------------
232 
233 // Calculate alpha_s value, but only use up to first-order piece.
234 // (To be combined with alphaS2OrdCorr.)
235 
236 double AlphaStrong::alphaS1Ord( double scale2) {
237 
238  // Check for initialization and ensure minimal scale2 value.
239  if (!isInit) return 0.;
240  if (scale2 < scale2Min) scale2 = scale2Min;
241 
242  // If equal to old scale then same answer.
243  if (scale2 == scale2Now && (order < 2 || !lastCallToFull)) return valueNow;
244  scale2Now = scale2;
245  lastCallToFull = false;
246 
247  // Fix alpha_S.
248  if (order == 0) {
249  valueNow = valueRef;
250 
251  // First/second order alpha_s: differs by mass region.
252  } else {
253  if (scale2 > mt2 && nfmax >= 6)
254  valueNow = 12. * M_PI / (21. * log(scale2/Lambda6Save2));
255  else if (scale2 > mb2)
256  valueNow = 12. * M_PI / (23. * log(scale2/Lambda5Save2));
257  else if (scale2 > mc2)
258  valueNow = 12. * M_PI / (25. * log(scale2/Lambda4Save2));
259  else valueNow = 12. * M_PI / (27. * log(scale2/Lambda3Save2));
260  }
261 
262  // Done.
263  return valueNow;
264 }
265 
266 //--------------------------------------------------------------------------
267 
268 // Calculates the second-order extra factor in alpha_s.
269 // (To be combined with alphaS1Ord.)
270 
271 double AlphaStrong::alphaS2OrdCorr( double scale2) {
272 
273  // Check for initialization and ensure minimal scale2 value.
274  if (!isInit) return 1.;
275  if (scale2 < scale2Min) scale2 = scale2Min;
276 
277  // Only meaningful for second-order calculations.
278  if (order < 2) return 1.;
279 
280  // Second order correction term: differs by mass region.
281  double Lambda2, b1, b2;
282  if (scale2 > mt2 && nfmax >= 6) {
283  Lambda2 = Lambda6Save2;
284  b1 = 234. / 441.;
285  b2 = -36855. / 109512.;
286  } else if (scale2 > mb2) {
287  Lambda2 = Lambda5Save2;
288  b1 = 348. / 529.;
289  b2 = 224687. / 242208.;
290  } else if (scale2 > mc2) {
291  Lambda2 = Lambda4Save2;
292  b1 = 462. / 625.;
293  b2 = 548575. / 426888.;
294  } else {
295  Lambda2 = Lambda3Save2;
296  b1 = 64. / 81.;
297  b2 = 938709. / 663552.;
298  }
299  double logScale = log(scale2/Lambda2);
300  double loglogScale = log(logScale);
301  return ( 1. - b1 * loglogScale / logScale
302  + pow2(b1 / logScale) * (pow2(loglogScale - 0.5) + b2 - 1.25) );
303 
304 }
305 
306 //--------------------------------------------------------------------------
307 
308 // muThres(2): tell what values of flavour thresholds are being used.
309 
310 double AlphaStrong::muThres( int idQ) {
311  int idAbs = abs(idQ);
312  // Return the scale of each flavour threshold included in running.
313  if (idAbs == 4) return MC;
314  else if (idAbs == 5) return MB;
315  else if (idAbs == 6 && nfmax >= 6) return MT;
316  // Else return -1 (indicates no such threshold is included in running).
317  return -1.;
318 }
319 
320 double AlphaStrong::muThres2( int idQ) {
321  int idAbs = abs(idQ);
322  // Return the scale of each flavour threshold included in running.
323  if (idAbs == 4) return mc2;
324  else if (idAbs == 5) return mb2;
325  else if (idAbs == 6 && nfmax >=6) return mt2;
326  // Else return -1 (indicates no such threshold is included in running).
327  return -1.;
328 }
329 
330 //--------------------------------------------------------------------------
331 
332 // facCMW: tells what values of the CMW factors are being used (if any).
333 
334 double AlphaStrong::facCMW( int NFIn) {
335  // Return unity if we are not doing CMW rescaling..
336  if (!isInit || !useCMW) return 1.0;
337  // Else return the NF-dependent value of the CMW rescaling factor.
338  else if (NFIn <= 3) return FACCMW3;
339  else if (NFIn == 4) return FACCMW4;
340  else if (NFIn == 5) return FACCMW5;
341  else return FACCMW6;
342 }
343 
344 //==========================================================================
345 
346 // The AlphaEM class.
347 
348 //--------------------------------------------------------------------------
349 
350 // Definitions of static variables.
351 
352 // Z0 mass. Used for normalization scale.
353 const double AlphaEM::MZ = 91.188;
354 
355 // Effective thresholds for electron, muon, light quarks, tau+c, b.
356 const double AlphaEM::Q2STEP[5] = {0.26e-6, 0.011, 0.25, 3.5, 90.};
357 
358 // Running coefficients are sum charge2 / 3 pi in pure QED, here slightly
359 // enhanced for quarks to approximately account for QCD corrections.
360 const double AlphaEM::BRUNDEF[5] = {0.1061, 0.2122, 0.460, 0.700, 0.725};
361 
362 //--------------------------------------------------------------------------
363 
364 // Initialize alpha_EM calculation.
365 
366 void AlphaEM::init(int orderIn, Settings* settingsPtr) {
367 
368  // Order. Read in alpha_EM value at 0 and m_Z, and mass of Z.
369  order = orderIn;
370  alpEM0 = settingsPtr->parm("StandardModel:alphaEM0");
371  alpEMmZ = settingsPtr->parm("StandardModel:alphaEMmZ");
372  mZ2 = MZ * MZ;
373 
374  // AlphaEM values at matching scales and matching b value.
375  if (order <= 0) return;
376  for (int i = 0; i < 5; ++i) bRun[i] = BRUNDEF[i];
377 
378  // Step down from mZ to tau/charm threshold.
379  alpEMstep[4] = alpEMmZ / ( 1. + alpEMmZ * bRun[4]
380  * log(mZ2 / Q2STEP[4]) );
381  alpEMstep[3] = alpEMstep[4] / ( 1. - alpEMstep[4] * bRun[3]
382  * log(Q2STEP[3] / Q2STEP[4]) );
383 
384  // Step up from me to light-quark threshold.
385  alpEMstep[0] = alpEM0;
386  alpEMstep[1] = alpEMstep[0] / ( 1. - alpEMstep[0] * bRun[0]
387  * log(Q2STEP[1] / Q2STEP[0]) );
388  alpEMstep[2] = alpEMstep[1] / ( 1. - alpEMstep[1] * bRun[1]
389  * log(Q2STEP[2] / Q2STEP[1]) );
390 
391  // Fit b in range between light-quark and tau/charm to join smoothly.
392  bRun[2] = (1./alpEMstep[3] - 1./alpEMstep[2])
393  / log(Q2STEP[2] / Q2STEP[3]);
394 
395 }
396 
397 //--------------------------------------------------------------------------
398 
399 // Calculate alpha_EM value
400 
401 double AlphaEM::alphaEM( double scale2) {
402 
403  // Fix alphaEM; for order = -1 fixed at m_Z.
404  if (order == 0) return alpEM0;
405  if (order < 0) return alpEMmZ;
406 
407  // Running alphaEM.
408  for (int i = 4; i >= 0; --i) if (scale2 > Q2STEP[i])
409  return alpEMstep[i] / (1. - bRun[i] * alpEMstep[i]
410  * log(scale2 / Q2STEP[i]) );
411  return alpEM0;
412 
413 }
414 
415 //==========================================================================
416 
417 // The CoupSM class.
418 
419 //--------------------------------------------------------------------------
420 
421 // Definitions of static variables: charges and axial couplings.
422 const double CoupSM::efSave[20] = { 0., -1./3., 2./3., -1./3., 2./3., -1./3.,
423  2./3., -1./3., 2./3., 0., 0., -1., 0., -1., 0., -1., 0., -1., 0., 0.};
424 const double CoupSM::afSave[20] = { 0., -1., 1., -1., 1., -1., 1., -1., 1.,
425  0., 0., -1., 1., -1., 1., -1., 1., -1., 1., 0.};
426 
427 //--------------------------------------------------------------------------
428 
429 // Initialize electroweak mixing angle and couplings, and CKM matrix elements.
430 
431 void CoupSM::init(Settings& settings, Rndm* rndmPtrIn) {
432 
433  // Store input pointer;
434  rndmPtr = rndmPtrIn;
435 
436  // Initialize the local AlphaStrong instance.
437  double alphaSvalue = settings.parm("SigmaProcess:alphaSvalue");
438  int alphaSorder = settings.mode("SigmaProcess:alphaSorder");
439  int alphaSnfmax = settings.mode("StandardModel:alphaSnfmax");
440  alphaSlocal.init( alphaSvalue, alphaSorder, alphaSnfmax, false);
441 
442  // Initialize the local AlphaEM instance.
443  int order = settings.mode("SigmaProcess:alphaEMorder");
444  alphaEMlocal.init( order, &settings);
445 
446  // Read in electroweak mixing angle and the Fermi constant.
447  s2tW = settings.parm("StandardModel:sin2thetaW");
448  c2tW = 1. - s2tW;
449  s2tWbar = settings.parm("StandardModel:sin2thetaWbar");
450  GFermi = settings.parm("StandardModel:GF");
451 
452  // Initialize electroweak couplings.
453  for (int i = 0; i < 20; ++i) {
454  vfSave[i] = afSave[i] - 4. * s2tWbar * efSave[i];
455  lfSave[i] = afSave[i] - 2. * s2tWbar * efSave[i];
456  rfSave[i] = - 2. * s2tWbar * efSave[i];
457  ef2Save[i] = pow2(efSave[i]);
458  vf2Save[i] = pow2(vfSave[i]);
459  af2Save[i] = pow2(afSave[i]);
460  efvfSave[i] = efSave[i] * vfSave[i];
461  vf2af2Save[i] = vf2Save[i] + af2Save[i];
462  }
463 
464  // Read in CKM matrix element values and store them.
465  VCKMsave[1][1] = settings.parm("StandardModel:Vud");
466  VCKMsave[1][2] = settings.parm("StandardModel:Vus");
467  VCKMsave[1][3] = settings.parm("StandardModel:Vub");
468  VCKMsave[2][1] = settings.parm("StandardModel:Vcd");
469  VCKMsave[2][2] = settings.parm("StandardModel:Vcs");
470  VCKMsave[2][3] = settings.parm("StandardModel:Vcb");
471  VCKMsave[3][1] = settings.parm("StandardModel:Vtd");
472  VCKMsave[3][2] = settings.parm("StandardModel:Vts");
473  VCKMsave[3][3] = settings.parm("StandardModel:Vtb");
474 
475  // Also allow for the potential existence of a fourth generation.
476  VCKMsave[1][4] = settings.parm("FourthGeneration:VubPrime");
477  VCKMsave[2][4] = settings.parm("FourthGeneration:VcbPrime");
478  VCKMsave[3][4] = settings.parm("FourthGeneration:VtbPrime");
479  VCKMsave[4][1] = settings.parm("FourthGeneration:VtPrimed");
480  VCKMsave[4][2] = settings.parm("FourthGeneration:VtPrimes");
481  VCKMsave[4][3] = settings.parm("FourthGeneration:VtPrimeb");
482  VCKMsave[4][4] = settings.parm("FourthGeneration:VtPrimebPrime");
483 
484  // Calculate squares of matrix elements.
485  for(int i = 1; i < 5; ++i) for(int j = 1; j < 5; ++j)
486  V2CKMsave[i][j] = pow2(VCKMsave[i][j]);
487 
488  // Sum VCKM^2_out sum for given incoming flavour, excluding top as partner.
489  V2CKMout[1] = V2CKMsave[1][1] + V2CKMsave[2][1];
490  V2CKMout[2] = V2CKMsave[1][1] + V2CKMsave[1][2] + V2CKMsave[1][3];
491  V2CKMout[3] = V2CKMsave[1][2] + V2CKMsave[2][2];
492  V2CKMout[4] = V2CKMsave[2][1] + V2CKMsave[2][2] + V2CKMsave[2][3];
493  V2CKMout[5] = V2CKMsave[1][3] + V2CKMsave[2][3];
494  V2CKMout[6] = V2CKMsave[3][1] + V2CKMsave[3][2] + V2CKMsave[3][3];
495  V2CKMout[7] = V2CKMsave[1][4] + V2CKMsave[2][4];
496  V2CKMout[8] = V2CKMsave[4][1] + V2CKMsave[4][2] + V2CKMsave[4][3];
497  for (int i = 11; i <= 18; ++i) V2CKMout[i] = 1.;
498 
499 }
500 
501 //--------------------------------------------------------------------------
502 
503 // Return CKM value for incoming flavours (sign irrelevant).
504 
505 double CoupSM::VCKMid(int id1, int id2) {
506 
507  // Use absolute sign (want to cover both f -> f' W and f fbar' -> W).
508  int id1Abs = abs(id1);
509  int id2Abs = abs(id2);
510  if (id1Abs == 0 || id2Abs == 0 || (id1Abs + id2Abs)%2 != 1) return 0.;
511 
512  // Ensure proper order before reading out from VCKMsave or lepton match.
513  if (id1Abs%2 == 1) swap(id1Abs, id2Abs);
514  if (id1Abs <= 8 && id2Abs <= 8) return VCKMsave[id1Abs/2][(id2Abs + 1)/2];
515  if ( (id1Abs == 12 || id1Abs == 14 || id1Abs == 16 || id1Abs == 18)
516  && id2Abs == id1Abs - 1 ) return 1.;
517 
518  // No more valid cases.
519  return 0.;
520 
521 }
522 
523 //--------------------------------------------------------------------------
524 
525 // Return squared CKM value for incoming flavours (sign irrelevant).
526 
527 double CoupSM::V2CKMid(int id1, int id2) {
528 
529  // Use absolute sign (want to cover both f -> f' W and f fbar' -> W).
530  int id1Abs = abs(id1);
531  int id2Abs = abs(id2);
532  if (id1Abs == 0 || id2Abs == 0 || (id1Abs + id2Abs)%2 != 1) return 0.;
533 
534  // Ensure proper order before reading out from V2CKMsave or lepton match.
535  if (id1Abs%2 == 1) swap(id1Abs, id2Abs);
536  if (id1Abs <= 8 && id2Abs <= 8) return V2CKMsave[id1Abs/2][(id2Abs + 1)/2];
537  if ( (id1Abs == 12 || id1Abs == 14 || id1Abs == 16 || id1Abs == 18)
538  && id2Abs == id1Abs - 1 ) return 1.;
539 
540  // No more valid cases.
541  return 0.;
542 
543 }
544 
545 //--------------------------------------------------------------------------
546 
547 // Pick an outgoing flavour for given incoming one, given CKM mixing.
548 
549 int CoupSM::V2CKMpick(int id) {
550 
551  // Initial values.
552  int idIn = abs(id);
553  int idOut = 0;
554 
555  // Quarks: need to make random choice.
556  if (idIn >= 1 && idIn <= 8) {
557  double V2CKMrndm = rndmPtr->flat() * V2CKMout[idIn];
558  if (idIn == 1) idOut = (V2CKMrndm < V2CKMsave[1][1]) ? 2 : 4;
559  else if (idIn == 2) idOut = (V2CKMrndm < V2CKMsave[1][1]) ? 1
560  : ( (V2CKMrndm < V2CKMsave[1][1] + V2CKMsave[1][2]) ? 3 : 5 );
561  else if (idIn == 3) idOut = (V2CKMrndm < V2CKMsave[1][2]) ? 2 : 4;
562  else if (idIn == 4) idOut = (V2CKMrndm < V2CKMsave[2][1]) ? 1
563  : ( (V2CKMrndm < V2CKMsave[2][1] + V2CKMsave[2][2]) ? 3 : 5 );
564  else if (idIn == 5) idOut = (V2CKMrndm < V2CKMsave[1][3]) ? 2 : 4;
565  else if (idIn == 6) idOut = (V2CKMrndm < V2CKMsave[3][1]) ? 1
566  : ( (V2CKMrndm < V2CKMsave[3][1] + V2CKMsave[3][2]) ? 3 : 5 );
567  else if (idIn == 7) idOut = (V2CKMrndm < V2CKMsave[1][4]) ? 2 : 4;
568  else if (idIn == 8) idOut = (V2CKMrndm < V2CKMsave[4][1]) ? 1
569  : ( (V2CKMrndm < V2CKMsave[4][1] + V2CKMsave[4][2]) ? 3 : 5 );
570 
571  // Leptons: unambiguous.
572  } else if (idIn >= 11 && idIn <= 18) {
573  if (idIn%2 == 1) idOut = idIn + 1;
574  else idOut = idIn - 1;
575  }
576 
577  // Done. Return with sign.
578  return ( (id > 0) ? idOut : -idOut );
579 
580 }
581 
582 //==========================================================================
583 
584 } // end namespace Pythia8