1 // StandardModel.cc is a part of the PYTHIA event generator.
2 // Copyright (C) 2013 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 AlphaStrong class.
8 #include "StandardModel.h"
12 //==========================================================================
14 // The AlphaStrong class.
16 //--------------------------------------------------------------------------
18 // Constants: could be changed here if desired, but normally should not.
19 // These are of technical nature, as described for each.
21 // Number of iterations to determine Lambda from given alpha_s.
22 const int AlphaStrong::NITER = 10;
24 // Masses: m_c, m_b, m_Z. Used for flavour thresholds and normalization scale.
25 const double AlphaStrong::MC = 1.5;
26 const double AlphaStrong::MB = 4.8;
27 const double AlphaStrong::MZ = 91.188;
29 // Always evaluate running alpha_s above Lambda3 to avoid disaster.
30 // Safety margin picked to freeze roughly for alpha_s = 10.
31 const double AlphaStrong::SAFETYMARGIN1 = 1.07;
32 const double AlphaStrong::SAFETYMARGIN2 = 1.33;
34 //--------------------------------------------------------------------------
36 // Initialize alpha_strong calculation by finding Lambda values etc.
38 void AlphaStrong::init( double valueIn, int orderIn) {
40 // Order of alpha_s evaluation.Default values.
42 order = max( 0, min( 2, orderIn ) );
43 lastCallToFull = false;
44 Lambda3Save = Lambda4Save = Lambda5Save = scale2Min = 0.;
49 // First order alpha_s: match at flavour thresholds.
50 } else if (order == 1) {
51 Lambda5Save = MZ * exp( -6. * M_PI / (23. * valueRef) );
52 Lambda4Save = Lambda5Save * pow(MB/Lambda5Save, 2./25.);
53 Lambda3Save = Lambda4Save * pow(MC/Lambda4Save, 2./27.);
54 scale2Min = pow2(SAFETYMARGIN1 * Lambda3Save);
56 // Second order alpha_s: iterative match at flavour thresholds.
58 double b15 = 348. / 529.;
59 double b14 = 462. / 625.;
60 double b13 = 64. / 81.;
61 double b25 = 224687. / 242208.;
62 double b24 = 548575. / 426888.;
63 double b23 = 938709. / 663552.;
64 double logScale, loglogScale, correction, valueIter;
66 // Find Lambda_5 at m_Z.
67 Lambda5Save = MZ * exp( -6. * M_PI / (23. * valueRef) );
68 for (int iter = 0; iter < NITER; ++iter) {
69 logScale = 2. * log(MZ/Lambda5Save);
70 loglogScale = log(logScale);
71 correction = 1. - b15 * loglogScale / logScale
72 + pow2(b15 / logScale) * (pow2(loglogScale - 0.5) + b25 - 1.25);
73 valueIter = valueRef / correction;
74 Lambda5Save = MZ * exp( -6. * M_PI / (23. * valueIter) );
77 // Find Lambda_4 at m_b.
78 double logScaleB = 2. * log(MB/Lambda5Save);
79 double loglogScaleB = log(logScaleB);
80 double valueB = 12. * M_PI / (23. * logScaleB)
81 * (1. - b15 * loglogScaleB / logScaleB
82 + pow2(b15 / logScaleB) * (pow2(loglogScaleB - 0.5) + b25- 1.25) );
83 Lambda4Save = Lambda5Save;
84 for (int iter = 0; iter < NITER; ++iter) {
85 logScale = 2. * log(MB/Lambda4Save);
86 loglogScale = log(logScale);
87 correction = 1. - b14 * loglogScale / logScale
88 + pow2(b14 / logScale) * (pow2(loglogScale - 0.5) + b24 - 1.25);
89 valueIter = valueB / correction;
90 Lambda4Save = MB * exp( -6. * M_PI / (25. * valueIter) );
93 // Find Lambda_3 at m_c.
94 double logScaleC = 2. * log(MC/Lambda4Save);
95 double loglogScaleC = log(logScaleC);
96 double valueC = 12. * M_PI / (25. * logScaleC)
97 * (1. - b14 * loglogScaleC / logScaleC
98 + pow2(b14 / logScaleC) * (pow2(loglogScaleC - 0.5) + b24 - 1.25) );
99 Lambda3Save = Lambda4Save;
100 for (int iter = 0; iter < NITER; ++iter) {
101 logScale = 2. * log(MC/Lambda3Save);
102 loglogScale = log(logScale);
103 correction = 1. - b13 * loglogScale / logScale
104 + pow2(b13 / logScale) * (pow2(loglogScale - 0.5) + b23 - 1.25);
105 valueIter = valueC / correction;
106 Lambda3Save = MC * exp( -6. * M_PI / (27. * valueIter) );
108 scale2Min = pow2(SAFETYMARGIN2 * Lambda3Save);
111 // Save squares of mass and Lambda values as well.
112 Lambda3Save2 = pow2(Lambda3Save);
113 Lambda4Save2 = pow2(Lambda4Save);
114 Lambda5Save2 = pow2(Lambda5Save);
123 //--------------------------------------------------------------------------
125 // Calculate alpha_s value
127 double AlphaStrong::alphaS( double scale2) {
129 // Check for initialization and ensure minimal scale2 value.
130 if (!isInit) return 0.;
131 if (scale2 < scale2Min) scale2 = scale2Min;
133 // If equal to old scale then same answer.
134 if (scale2 == scale2Now && (order < 2 || lastCallToFull)) return valueNow;
136 lastCallToFull = true;
142 // First order alpha_s: differs by mass region.
143 } else if (order == 1) {
145 valueNow = 12. * M_PI / (23. * log(scale2/Lambda5Save2));
146 else if (scale2 > mc2)
147 valueNow = 12. * M_PI / (25. * log(scale2/Lambda4Save2));
148 else valueNow = 12. * M_PI / (27. * log(scale2/Lambda3Save2));
150 // Second order alpha_s: differs by mass region.
152 double Lambda2, b0, b1, b2;
154 Lambda2 = Lambda5Save2;
157 b2 = 224687. / 242208.;
158 } else if (scale2 > mc2) {
159 Lambda2 = Lambda4Save2;
162 b2 = 548575. / 426888.;
164 Lambda2 = Lambda3Save2;
167 b2 = 938709. / 663552.;
169 double logScale = log(scale2/Lambda2);
170 double loglogScale = log(logScale);
171 valueNow = 12. * M_PI / (b0 * logScale)
172 * ( 1. - b1 * loglogScale / logScale
173 + pow2(b1 / logScale) * (pow2(loglogScale - 0.5) + b2 - 1.25) );
181 //--------------------------------------------------------------------------
183 // Calculate alpha_s value, but only use up to first-order piece.
184 // (To be combined with alphaS2OrdCorr.)
186 double AlphaStrong::alphaS1Ord( double scale2) {
188 // Check for initialization and ensure minimal scale2 value.
189 if (!isInit) return 0.;
190 if (scale2 < scale2Min) scale2 = scale2Min;
192 // If equal to old scale then same answer.
193 if (scale2 == scale2Now && (order < 2 || !lastCallToFull)) return valueNow;
195 lastCallToFull = false;
201 // First/second order alpha_s: differs by mass region.
204 valueNow = 12. * M_PI / (23. * log(scale2/Lambda5Save2));
205 else if (scale2 > mc2)
206 valueNow = 12. * M_PI / (25. * log(scale2/Lambda4Save2));
207 else valueNow = 12. * M_PI / (27. * log(scale2/Lambda3Save2));
214 //--------------------------------------------------------------------------
216 // Calculates the second-order extra factor in alpha_s.
217 // (To be combined with alphaS1Ord.)
219 double AlphaStrong::alphaS2OrdCorr( double scale2) {
221 // Check for initialization and ensure minimal scale2 value.
222 if (!isInit) return 1.;
223 if (scale2 < scale2Min) scale2 = scale2Min;
225 // Only meaningful for second order calculations.
226 if (order < 2) return 1.;
228 // Second order correction term: differs by mass region.
229 double Lambda2, b1, b2;
231 Lambda2 = Lambda5Save2;
233 b2 = 224687. / 242208.;
234 } else if (scale2 > mc2) {
235 Lambda2 = Lambda4Save2;
237 b2 = 548575. / 426888.;
239 Lambda2 = Lambda3Save2;
241 b2 = 938709. / 663552.;
243 double logScale = log(scale2/Lambda2);
244 double loglogScale = log(logScale);
245 return ( 1. - b1 * loglogScale / logScale
246 + pow2(b1 / logScale) * (pow2(loglogScale - 0.5) + b2 - 1.25) );
250 //==========================================================================
252 // The AlphaEM class.
254 //--------------------------------------------------------------------------
256 // Definitions of static variables.
258 // Z0 mass. Used for normalization scale.
259 const double AlphaEM::MZ = 91.188;
261 // Effective thresholds for electron, muon, light quarks, tau+c, b.
262 const double AlphaEM::Q2STEP[5] = {0.26e-6, 0.011, 0.25, 3.5, 90.};
264 // Running coefficients are sum charge2 / 3 pi in pure QED, here slightly
265 // enhanced for quarks to approximately account for QCD corrections.
266 const double AlphaEM::BRUNDEF[5] = {0.1061, 0.2122, 0.460, 0.700, 0.725};
268 //--------------------------------------------------------------------------
270 // Initialize alpha_EM calculation.
272 void AlphaEM::init(int orderIn, Settings* settingsPtr) {
274 // Order. Read in alpha_EM value at 0 and m_Z, and mass of Z.
276 alpEM0 = settingsPtr->parm("StandardModel:alphaEM0");
277 alpEMmZ = settingsPtr->parm("StandardModel:alphaEMmZ");
280 // AlphaEM values at matching scales and matching b value.
281 if (order <= 0) return;
282 for (int i = 0; i < 5; ++i) bRun[i] = BRUNDEF[i];
284 // Step down from mZ to tau/charm threshold.
285 alpEMstep[4] = alpEMmZ / ( 1. + alpEMmZ * bRun[4]
286 * log(mZ2 / Q2STEP[4]) );
287 alpEMstep[3] = alpEMstep[4] / ( 1. - alpEMstep[4] * bRun[3]
288 * log(Q2STEP[3] / Q2STEP[4]) );
290 // Step up from me to light-quark threshold.
291 alpEMstep[0] = alpEM0;
292 alpEMstep[1] = alpEMstep[0] / ( 1. - alpEMstep[0] * bRun[0]
293 * log(Q2STEP[1] / Q2STEP[0]) );
294 alpEMstep[2] = alpEMstep[1] / ( 1. - alpEMstep[1] * bRun[1]
295 * log(Q2STEP[2] / Q2STEP[1]) );
297 // Fit b in range between light-quark and tau/charm to join smoothly.
298 bRun[2] = (1./alpEMstep[3] - 1./alpEMstep[2])
299 / log(Q2STEP[2] / Q2STEP[3]);
303 //--------------------------------------------------------------------------
305 // Calculate alpha_EM value
307 double AlphaEM::alphaEM( double scale2) {
309 // Fix alphaEM; for order = -1 fixed at m_Z.
310 if (order == 0) return alpEM0;
311 if (order < 0) return alpEMmZ;
314 for (int i = 4; i >= 0; --i) if (scale2 > Q2STEP[i])
315 return alpEMstep[i] / (1. - bRun[i] * alpEMstep[i]
316 * log(scale2 / Q2STEP[i]) );
321 //==========================================================================
325 //--------------------------------------------------------------------------
327 // Definitions of static variables: charges and axial couplings.
328 const double CoupSM::efSave[20] = { 0., -1./3., 2./3., -1./3., 2./3., -1./3.,
329 2./3., -1./3., 2./3., 0., 0., -1., 0., -1., 0., -1., 0., -1., 0., 0.};
330 const double CoupSM::afSave[20] = { 0., -1., 1., -1., 1., -1., 1., -1., 1.,
331 0., 0., -1., 1., -1., 1., -1., 1., -1., 1., 0.};
333 //--------------------------------------------------------------------------
335 // Initialize electroweak mixing angle and couplings, and CKM matrix elements.
337 void CoupSM::init(Settings& settings, Rndm* rndmPtrIn) {
339 // Store input pointer;
342 // Initialize the local AlphaStrong instance.
343 double alphaSvalue = settings.parm("SigmaProcess:alphaSvalue");
344 int alphaSorder = settings.mode("SigmaProcess:alphaSorder");
345 alphaSlocal.init( alphaSvalue, alphaSorder);
347 // Initialize the local AlphaEM instance.
348 int order = settings.mode("SigmaProcess:alphaEMorder");
349 alphaEMlocal.init( order, &settings);
351 // Read in electroweak mixing angle and the Fermi constant.
352 s2tW = settings.parm("StandardModel:sin2thetaW");
354 s2tWbar = settings.parm("StandardModel:sin2thetaWbar");
355 GFermi = settings.parm("StandardModel:GF");
357 // Initialize electroweak couplings.
358 for (int i = 0; i < 20; ++i) {
359 vfSave[i] = afSave[i] - 4. * s2tWbar * efSave[i];
360 lfSave[i] = afSave[i] - 2. * s2tWbar * efSave[i];
361 rfSave[i] = - 2. * s2tWbar * efSave[i];
362 ef2Save[i] = pow2(efSave[i]);
363 vf2Save[i] = pow2(vfSave[i]);
364 af2Save[i] = pow2(afSave[i]);
365 efvfSave[i] = efSave[i] * vfSave[i];
366 vf2af2Save[i] = vf2Save[i] + af2Save[i];
369 // Read in CKM matrix element values and store them.
370 VCKMsave[1][1] = settings.parm("StandardModel:Vud");
371 VCKMsave[1][2] = settings.parm("StandardModel:Vus");
372 VCKMsave[1][3] = settings.parm("StandardModel:Vub");
373 VCKMsave[2][1] = settings.parm("StandardModel:Vcd");
374 VCKMsave[2][2] = settings.parm("StandardModel:Vcs");
375 VCKMsave[2][3] = settings.parm("StandardModel:Vcb");
376 VCKMsave[3][1] = settings.parm("StandardModel:Vtd");
377 VCKMsave[3][2] = settings.parm("StandardModel:Vts");
378 VCKMsave[3][3] = settings.parm("StandardModel:Vtb");
380 // Also allow for the potential existence of a fourth generation.
381 VCKMsave[1][4] = settings.parm("FourthGeneration:VubPrime");
382 VCKMsave[2][4] = settings.parm("FourthGeneration:VcbPrime");
383 VCKMsave[3][4] = settings.parm("FourthGeneration:VtbPrime");
384 VCKMsave[4][1] = settings.parm("FourthGeneration:VtPrimed");
385 VCKMsave[4][2] = settings.parm("FourthGeneration:VtPrimes");
386 VCKMsave[4][3] = settings.parm("FourthGeneration:VtPrimeb");
387 VCKMsave[4][4] = settings.parm("FourthGeneration:VtPrimebPrime");
389 // Calculate squares of matrix elements.
390 for(int i = 1; i < 5; ++i) for(int j = 1; j < 5; ++j)
391 V2CKMsave[i][j] = pow2(VCKMsave[i][j]);
393 // Sum VCKM^2_out sum for given incoming flavour, excluding top as partner.
394 V2CKMout[1] = V2CKMsave[1][1] + V2CKMsave[2][1];
395 V2CKMout[2] = V2CKMsave[1][1] + V2CKMsave[1][2] + V2CKMsave[1][3];
396 V2CKMout[3] = V2CKMsave[1][2] + V2CKMsave[2][2];
397 V2CKMout[4] = V2CKMsave[2][1] + V2CKMsave[2][2] + V2CKMsave[2][3];
398 V2CKMout[5] = V2CKMsave[1][3] + V2CKMsave[2][3];
399 V2CKMout[6] = V2CKMsave[3][1] + V2CKMsave[3][2] + V2CKMsave[3][3];
400 V2CKMout[7] = V2CKMsave[1][4] + V2CKMsave[2][4];
401 V2CKMout[8] = V2CKMsave[4][1] + V2CKMsave[4][2] + V2CKMsave[4][3];
402 for (int i = 11; i <= 18; ++i) V2CKMout[i] = 1.;
406 //--------------------------------------------------------------------------
408 // Return CKM value for incoming flavours (sign irrelevant).
410 double CoupSM::VCKMid(int id1, int id2) {
412 // Use absolute sign (want to cover both f -> f' W and f fbar' -> W).
413 int id1Abs = abs(id1);
414 int id2Abs = abs(id2);
415 if (id1Abs == 0 || id2Abs == 0 || (id1Abs + id2Abs)%2 != 1) return 0.;
417 // Ensure proper order before reading out from VCKMsave or lepton match.
418 if (id1Abs%2 == 1) swap(id1Abs, id2Abs);
419 if (id1Abs <= 8 && id2Abs <= 8) return VCKMsave[id1Abs/2][(id2Abs + 1)/2];
420 if ( (id1Abs == 12 || id1Abs == 14 || id1Abs == 16 || id1Abs == 18)
421 && id2Abs == id1Abs - 1 ) return 1.;
423 // No more valid cases.
428 //--------------------------------------------------------------------------
430 // Return squared CKM value for incoming flavours (sign irrelevant).
432 double CoupSM::V2CKMid(int id1, int id2) {
434 // Use absolute sign (want to cover both f -> f' W and f fbar' -> W).
435 int id1Abs = abs(id1);
436 int id2Abs = abs(id2);
437 if (id1Abs == 0 || id2Abs == 0 || (id1Abs + id2Abs)%2 != 1) return 0.;
439 // Ensure proper order before reading out from V2CKMsave or lepton match.
440 if (id1Abs%2 == 1) swap(id1Abs, id2Abs);
441 if (id1Abs <= 8 && id2Abs <= 8) return V2CKMsave[id1Abs/2][(id2Abs + 1)/2];
442 if ( (id1Abs == 12 || id1Abs == 14 || id1Abs == 16 || id1Abs == 18)
443 && id2Abs == id1Abs - 1 ) return 1.;
445 // No more valid cases.
450 //--------------------------------------------------------------------------
452 // Pick an outgoing flavour for given incoming one, given CKM mixing.
454 int CoupSM::V2CKMpick(int id) {
460 // Quarks: need to make random choice.
461 if (idIn >= 1 && idIn <= 8) {
462 double V2CKMrndm = rndmPtr->flat() * V2CKMout[idIn];
463 if (idIn == 1) idOut = (V2CKMrndm < V2CKMsave[1][1]) ? 2 : 4;
464 else if (idIn == 2) idOut = (V2CKMrndm < V2CKMsave[1][1]) ? 1
465 : ( (V2CKMrndm < V2CKMsave[1][1] + V2CKMsave[1][2]) ? 3 : 5 );
466 else if (idIn == 3) idOut = (V2CKMrndm < V2CKMsave[1][2]) ? 2 : 4;
467 else if (idIn == 4) idOut = (V2CKMrndm < V2CKMsave[2][1]) ? 1
468 : ( (V2CKMrndm < V2CKMsave[2][1] + V2CKMsave[2][2]) ? 3 : 5 );
469 else if (idIn == 5) idOut = (V2CKMrndm < V2CKMsave[1][3]) ? 2 : 4;
470 else if (idIn == 6) idOut = (V2CKMrndm < V2CKMsave[3][1]) ? 1
471 : ( (V2CKMrndm < V2CKMsave[3][1] + V2CKMsave[3][2]) ? 3 : 5 );
472 else if (idIn == 7) idOut = (V2CKMrndm < V2CKMsave[1][4]) ? 2 : 4;
473 else if (idIn == 8) idOut = (V2CKMrndm < V2CKMsave[4][1]) ? 1
474 : ( (V2CKMrndm < V2CKMsave[4][1] + V2CKMsave[4][2]) ? 3 : 5 );
476 // Leptons: unambiguous.
477 } else if (idIn >= 11 && idIn <= 18) {
478 if (idIn%2 == 1) idOut = idIn + 1;
479 else idOut = idIn - 1;
482 // Done. Return with sign.
483 return ( (id > 0) ? idOut : -idOut );
487 //==========================================================================
489 } // end namespace Pythia8