StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
PartonDistributions.cc
1 // PartonDistributions.cc is a part of the PYTHIA event generator.
2 // Copyright (C) 2018 Torbjorn Sjostrand.
3 // PYTHIA is licenced under the GNU GPL v2 or later, 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 PDF, LHAPDF,
7 // GRV94L, CTEQ5L, MSTWpdf, CTEQ6pdf, GRVpiL, PomFix, PomH1FitAB,
8 // PomH1Jets, Lepton, NNPDF and CJKL classes.
9 
10 #include "Pythia8/PartonDistributions.h"
11 
12 namespace Pythia8 {
13 
14 //==========================================================================
15 
16 // Base class for parton distribution functions.
17 
18 //--------------------------------------------------------------------------
19 
20 // Resolve valence content for assumed meson. Possibly modified later.
21 
22 void PDF::setValenceContent() {
23 
24  // Subdivide meson by flavour content.
25  if (idBeamAbs < 100 || idBeamAbs > 1000) return;
26  int idTmp1 = idBeamAbs/100;
27  int idTmp2 = (idBeamAbs/10)%10;
28 
29  // Find which is quark and which antiquark.
30  if (idTmp1%2 == 0) {
31  idVal1 = idTmp1;
32  idVal2 = -idTmp2;
33  } else {
34  idVal1 = idTmp2;
35  idVal2 = -idTmp1;
36  }
37  if (idBeam < 0) {
38  idVal1 = -idVal1;
39  idVal2 = -idVal2;
40  }
41 
42  // Special case for Pomeron, to start off.
43  if (idBeamAbs == 990) {
44  idVal1 = 1;
45  idVal2 = -1;
46  }
47 
48  // Photon not fixed until at Process-/PartonLevel.
49  if (idBeamAbs == 22) {
50  idVal1 = 10;
51  idVal2 = -10;
52  }
53 
54 }
55 
56 //--------------------------------------------------------------------------
57 
58 // Standard parton densities.
59 
60 double PDF::xf(int id, double x, double Q2) {
61 
62  // Need to update if flavour, x or Q2 changed.
63  // Use idSav = 9 to indicate that ALL flavours are up-to-date.
64  // Assume that flavour and antiflavour always updated simultaneously.
65  if ( (abs(idSav) != abs(id) && idSav != 9) || x != xSav || Q2 != Q2Sav)
66  {idSav = id; xfUpdate(id, x, Q2); xSav = x; Q2Sav = Q2;}
67 
68  // Baryon beams: only p and pbar for now.
69  if (idBeamAbs == 2212) {
70  int idNow = (idBeam > 0) ? id : -id;
71  int idAbs = abs(id);
72  if (idNow == 0 || idAbs == 21) return max(0., xg);
73  if (idNow == 1) return max(0., xd);
74  if (idNow == -1) return max(0., xdbar);
75  if (idNow == 2) return max(0., xu);
76  if (idNow == -2) return max(0., xubar);
77  if (idNow == 3) return max(0., xs);
78  if (idNow == -3) return max(0., xsbar);
79  if (idAbs == 4) return max(0., xc);
80  if (idAbs == 5) return max(0., xb);
81  if (idAbs == 22) return max(0., xgamma);
82  return 0.;
83 
84  // Baryon beams: n and nbar by isospin conjugation of p and pbar.
85  } else if (idBeamAbs == 2112) {
86  int idNow = (idBeam > 0) ? id : -id;
87  int idAbs = abs(id);
88  if (idNow == 0 || idAbs == 21) return max(0., xg);
89  if (idNow == 1) return max(0., xu);
90  if (idNow == -1) return max(0., xubar);
91  if (idNow == 2) return max(0., xd);
92  if (idNow == -2) return max(0., xdbar);
93  if (idNow == 3) return max(0., xs);
94  if (idNow == -3) return max(0., xsbar);
95  if (idAbs == 4) return max(0., xc);
96  if (idAbs == 5) return max(0., xb);
97  if (idAbs == 22) return max(0., xgamma);
98  return 0.;
99 
100  // Nondiagonal meson beams: only pi+ and pi- for now.
101  // Some LHAPDF sets are stored with u d as valence, so use dbar = u.
102  } else if (idBeamAbs == 211) {
103  int idNow = (idBeam > 0) ? id : -id;
104  int idAbs = abs(id);
105  if (idNow == 0 || idAbs == 21) return max(0., xg);
106  if (idNow == 1) return max(0., xubar );
107  if (idNow == -1) return max(0., xu );
108  if (idNow == 2) return max(0., xu);
109  if (idNow == -2) return max(0., xubar);
110  if (idNow == 3) return max(0., xs);
111  if (idNow == -3) return max(0., xsbar);
112  if (idAbs == 4) return max(0., xc);
113  if (idAbs == 5) return max(0., xb);
114  if (idAbs == 22) return max(0., xgamma);
115  return 0.;
116 
117  // Diagonal meson beams: only pi0, Pomeron for now.
118  } else if (idBeam == 111 || idBeam == 990) {
119  int idAbs = abs(id);
120  if (id == 0 || idAbs == 21) return max(0., xg);
121  if (id == idVal1 || id == idVal2) return max(0., xu);
122  if (idAbs <= 2) return max(0., xubar);
123  if (idAbs == 3) return max(0., xs);
124  if (idAbs == 4) return max(0., xc);
125  if (idAbs == 5) return max(0., xb);
126  if (idAbs == 22) return max(0., xgamma);
127  return 0.;
128 
129  // Photon beam.
130  } else if (idBeam == 22) {
131  int idAbs = abs(id);
132  if (id == 0 || idAbs == 21) return max(0., xg);
133  if (id == 1) return max(0., xd);
134  if (id == -1) return max(0., xdbar);
135  if (id == 2) return max(0., xu);
136  if (id == -2) return max(0., xubar);
137  if (id == 3) return max(0., xs);
138  if (id == -3) return max(0., xsbar);
139  if (idAbs == 4) return max(0., xc);
140  if (idAbs == 5) return max(0., xb);
141  if (idAbs == 22) return max(0., xgamma);
142  return 0.;
143 
144  // Photon beam inside lepton beam.
145  } else if ( ( idBeamAbs == 11 || idBeamAbs == 13 || idBeamAbs == 15 )
146  && hasGammaInLepton ) {
147  int idAbs = abs(id);
148  if (idAbs == 0 || idAbs == 21) return max(0., xg);
149  if (idAbs == 1) return max(0., xd);
150  if (idAbs == 2) return max(0., xu);
151  if (idAbs == 3) return max(0., xs);
152  if (idAbs == 4) return max(0., xc);
153  if (idAbs == 5) return max(0., xb);
154  if (idAbs == 22) return max(0., xgamma);
155  return 0.;
156 
157  // Nuclear PDFs
158  } else if ( idBeamAbs > 100000000 ) {
159  int idAbs = abs(id);
160  if (idAbs == 0 || idAbs == 21) return max(0., xg);
161  if (id == 1) return max(0., xd);
162  if (id == -1) return max(0., xdbar);
163  if (id == 2) return max(0., xu);
164  if (id == -2) return max(0., xubar);
165  if (id == 3) return max(0., xs);
166  if (id == -3) return max(0., xsbar);
167  if (idAbs == 4) return max(0., xc);
168  if (idAbs == 5) return max(0., xb);
169  if (idAbs == 22) return max(0., xgamma);
170  return 0;
171 
172  // Lepton beam.
173  } else {
174  if (id == idBeam ) return max(0., xlepton);
175  if (abs(id) == 22) return max(0., xgamma);
176  return 0.;
177  }
178 
179 }
180 
181 //--------------------------------------------------------------------------
182 
183 // Only valence part of parton densities.
184 
185 double PDF::xfVal(int id, double x, double Q2) {
186 
187  // Need to update if flavour, x or Q2 changed.
188  // Use idSav = 9 to indicate that ALL flavours are up-to-date.
189  // Assume that flavour and antiflavour always updated simultaneously.
190  if ( (abs(idSav) != abs(id) && idSav != 9) || x != xSav || Q2 != Q2Sav)
191  {idSav = id; xfUpdate(id, x, Q2); xSav = x; Q2Sav = Q2;}
192 
193  // Baryon and nondiagonal meson beams: only p, pbar, n, nbar, pi+, pi-.
194  if (idBeamAbs == 2212) {
195  int idNow = (idBeam > 0) ? id : -id;
196  if (idNow == 1) return max(0., xdVal);
197  if (idNow == 2) return max(0., xuVal);
198  return 0.;
199  } else if (idBeamAbs == 2112) {
200  int idNow = (idBeam > 0) ? id : -id;
201  if (idNow == 1) return max(0., xuVal);
202  if (idNow == 2) return max(0., xdVal);
203  return 0.;
204  } else if (idBeamAbs == 211) {
205  int idNow = (idBeam > 0) ? id : -id;
206  if (idNow == 2 || idNow == -1) return max(0., xuVal);
207  return 0.;
208 
209  // Diagonal meson beams: only pi0, Pomeron for now.
210  } else if (idBeam == 111 || idBeam == 990) {
211  if (id == idVal1 || id == idVal2) return max(0., xuVal);
212  return 0.;
213 
214  // Photon beam.
215  } else if (idBeam == 22) {
216  int idAbs = abs(id);
217  if (id == idVal1 || id == idVal2) {
218  if (idAbs == 1) return max(0., xdVal);
219  if (idAbs == 2) return max(0., xuVal);
220  if (idAbs == 3) return max(0., xsVal);
221  if (idAbs == 4) return max(0., xcVal);
222  if (idAbs == 5) return max(0., xbVal);
223  }
224  return 0.;
225 
226  // Lepton beam.
227  } else {
228  if (id == idBeam) return max(0., xlepton);
229  return 0.;
230  }
231 
232 }
233 
234 //--------------------------------------------------------------------------
235 
236 // Only sea part of parton densities.
237 
238 double PDF::xfSea(int id, double x, double Q2) {
239 
240  // Need to update if flavour, x or Q2 changed.
241  // Use idSav = 9 to indicate that ALL flavours are up-to-date.
242  // Assume that flavour and antiflavour always updated simultaneously.
243  if ( (abs(idSav) != abs(id) && idSav != 9) || x != xSav || Q2 != Q2Sav)
244  {idSav = id; xfUpdate(id, x, Q2); xSav = x; Q2Sav = Q2;}
245 
246  // Hadron beams.
247  if (idBeamAbs > 100) {
248  int idNow = (idBeam > 0) ? id : -id;
249  int idAbs = abs(id);
250  if (idNow == 0 || idAbs == 21) return max(0., xg);
251  if (idBeamAbs == 2212) {
252  if (idNow == 1) return max(0., xdSea);
253  if (idNow == -1) return max(0., xdbar);
254  if (idNow == 2) return max(0., xuSea);
255  if (idNow == -2) return max(0., xubar);
256  } else if (idBeamAbs == 2112) {
257  if (idNow == 1) return max(0., xuSea);
258  if (idNow == -1) return max(0., xubar);
259  if (idNow == 2) return max(0., xdSea);
260  if (idNow == -2) return max(0., xdbar);
261  } else {
262  if (idAbs <= 2) return max(0., xuSea);
263  }
264  if (idNow == 3) return max(0., xs);
265  if (idNow == -3) return max(0., xsbar);
266  if (idAbs == 4) return max(0., xc);
267  if (idAbs == 5) return max(0., xb);
268  if (idAbs == 22) return max(0., xgamma);
269  return 0.;
270 
271  // Photon beam.
272  } else if (idBeamAbs == 22) {
273  int idAbs = abs(id);
274  if ( id == 0 || idAbs == 21 ) return max(0., xg);
275  if ( idAbs == 22 ) return max(0., xgamma);
276 
277  // If a valence parton return only the sea part.
278  // Otherwise return the total PDF.
279  if ( id == idVal1 || id == idVal2 ) {
280  if (idAbs == 1) return max(0., xdSea);
281  if (idAbs == 2) return max(0., xuSea);
282  if (idAbs == 3) return max(0., xsSea);
283  if (idAbs == 4) return max(0., xcSea);
284  if (idAbs == 5) return max(0., xbSea);
285  } else {
286  if (idAbs == 1) return max(0., xd);
287  if (idAbs == 2) return max(0., xu);
288  if (idAbs == 3) return max(0., xs);
289  if (idAbs == 4) return max(0., xc);
290  if (idAbs == 5) return max(0., xb);
291  }
292  return 0.;
293 
294  // Lepton beam.
295  } else {
296  if (abs(id) == 22) return max(0., xgamma);
297  return 0.;
298  }
299 
300 }
301 
302 //==========================================================================
303 
304 // Gives the GRV 94 L (leading order) parton distribution function set
305 // in parametrized form. Authors: M. Glueck, E. Reya and A. Vogt.
306 // Ref: M. Glueck, E. Reya and A. Vogt, Z.Phys. C67 (1995) 433.
307 
308 void GRV94L::xfUpdate(int , double x, double Q2) {
309 
310  // Common expressions. Constrain Q2 for which parametrization is valid.
311  double mu2 = 0.23;
312  double lam2 = 0.2322 * 0.2322;
313  double s = (Q2 > mu2) ? log( log(Q2/lam2) / log(mu2/lam2) ) : 0.;
314  double ds = sqrt(s);
315  double s2 = s * s;
316  double s3 = s2 * s;
317 
318  // uv :
319  double nu = 2.284 + 0.802 * s + 0.055 * s2;
320  double aku = 0.590 - 0.024 * s;
321  double bku = 0.131 + 0.063 * s;
322  double au = -0.449 - 0.138 * s - 0.076 * s2;
323  double bu = 0.213 + 2.669 * s - 0.728 * s2;
324  double cu = 8.854 - 9.135 * s + 1.979 * s2;
325  double du = 2.997 + 0.753 * s - 0.076 * s2;
326  double uv = grvv (x, nu, aku, bku, au, bu, cu, du);
327 
328  // dv :
329  double nd = 0.371 + 0.083 * s + 0.039 * s2;
330  double akd = 0.376;
331  double bkd = 0.486 + 0.062 * s;
332  double ad = -0.509 + 3.310 * s - 1.248 * s2;
333  double bd = 12.41 - 10.52 * s + 2.267 * s2;
334  double cd = 6.373 - 6.208 * s + 1.418 * s2;
335  double dd = 3.691 + 0.799 * s - 0.071 * s2;
336  double dv = grvv (x, nd, akd, bkd, ad, bd, cd, dd);
337 
338  // udb :
339  double alx = 1.451;
340  double bex = 0.271;
341  double akx = 0.410 - 0.232 * s;
342  double bkx = 0.534 - 0.457 * s;
343  double agx = 0.890 - 0.140 * s;
344  double bgx = -0.981;
345  double cx = 0.320 + 0.683 * s;
346  double dx = 4.752 + 1.164 * s + 0.286 * s2;
347  double ex = 4.119 + 1.713 * s;
348  double esx = 0.682 + 2.978 * s;
349  double udb = grvw (x, s, alx, bex, akx, bkx, agx, bgx, cx,
350  dx, ex, esx);
351 
352  // del :
353  double ne = 0.082 + 0.014 * s + 0.008 * s2;
354  double ake = 0.409 - 0.005 * s;
355  double bke = 0.799 + 0.071 * s;
356  double ae = -38.07 + 36.13 * s - 0.656 * s2;
357  double be = 90.31 - 74.15 * s + 7.645 * s2;
358  double ce = 0.;
359  double de = 7.486 + 1.217 * s - 0.159 * s2;
360  double del = grvv (x, ne, ake, bke, ae, be, ce, de);
361 
362  // sb :
363  double sts = 0.;
364  double als = 0.914;
365  double bes = 0.577;
366  double aks = 1.798 - 0.596 * s;
367  double as = -5.548 + 3.669 * ds - 0.616 * s;
368  double bs = 18.92 - 16.73 * ds + 5.168 * s;
369  double dst = 6.379 - 0.350 * s + 0.142 * s2;
370  double est = 3.981 + 1.638 * s;
371  double ess = 6.402;
372  double sb = grvs (x, s, sts, als, bes, aks, as, bs, dst, est, ess);
373 
374  // cb :
375  double stc = 0.888;
376  double alc = 1.01;
377  double bec = 0.37;
378  double akc = 0.;
379  double ac = 0.;
380  double bc = 4.24 - 0.804 * s;
381  double dct = 3.46 - 1.076 * s;
382  double ect = 4.61 + 1.49 * s;
383  double esc = 2.555 + 1.961 * s;
384  double chm = grvs (x, s, stc, alc, bec, akc, ac, bc, dct, ect, esc);
385 
386  // bb :
387  double stb = 1.351;
388  double alb = 1.00;
389  double beb = 0.51;
390  double akb = 0.;
391  double ab = 0.;
392  double bb = 1.848;
393  double dbt = 2.929 + 1.396 * s;
394  double ebt = 4.71 + 1.514 * s;
395  double esb = 4.02 + 1.239 * s;
396  double bot = grvs (x, s, stb, alb, beb, akb, ab, bb, dbt, ebt, esb);
397 
398  // gl :
399  double alg = 0.524;
400  double beg = 1.088;
401  double akg = 1.742 - 0.930 * s;
402  double bkg = - 0.399 * s2;
403  double ag = 7.486 - 2.185 * s;
404  double bg = 16.69 - 22.74 * s + 5.779 * s2;
405  double cg = -25.59 + 29.71 * s - 7.296 * s2;
406  double dg = 2.792 + 2.215 * s + 0.422 * s2 - 0.104 * s3;
407  double eg = 0.807 + 2.005 * s;
408  double esg = 3.841 + 0.316 * s;
409  double gl = grvw (x, s, alg, beg, akg, bkg, ag, bg, cg,
410  dg, eg, esg);
411 
412  // Update values
413  xg = gl;
414  xu = uv + 0.5*(udb - del);
415  xd = dv + 0.5*(udb + del);
416  xubar = 0.5*(udb - del);
417  xdbar = 0.5*(udb + del);
418  xs = sb;
419  xsbar = sb;
420  xc = chm;
421  xb = bot;
422 
423  // Subdivision of valence and sea.
424  xuVal = uv;
425  xuSea = xubar;
426  xdVal = dv;
427  xdSea = xdbar;
428 
429  // idSav = 9 to indicate that all flavours reset.
430  idSav = 9;
431 
432 }
433 
434 //--------------------------------------------------------------------------
435 
436 double GRV94L::grvv (double x, double n, double ak, double bk, double a,
437  double b, double c, double d) {
438 
439  double dx = sqrt(x);
440  return n * pow(x, ak) * (1. + a * pow(x, bk) + x * (b + c * dx)) *
441  pow(1. - x, d);
442 
443 }
444 
445 //--------------------------------------------------------------------------
446 
447 double GRV94L::grvw (double x, double s, double al, double be, double ak,
448  double bk, double a, double b, double c, double d, double e, double es) {
449 
450  double lx = log(1./x);
451  return (pow(x, ak) * (a + x * (b + x * c)) * pow(lx, bk) + pow(s, al)
452  * exp(-e + sqrt(es * pow(s, be) * lx))) * pow(1. - x, d);
453 
454 }
455 
456 //--------------------------------------------------------------------------
457 
458 double GRV94L::grvs (double x, double s, double sth, double al, double be,
459  double ak, double ag, double b, double d, double e, double es) {
460 
461  if(s <= sth) {
462  return 0.;
463  } else {
464  double dx = sqrt(x);
465  double lx = log(1./x);
466  return pow(s - sth, al) / pow(lx, ak) * (1. + ag * dx + b * x) *
467  pow(1. - x, d) * exp(-e + sqrt(es * pow(s, be) * lx));
468  }
469 
470 }
471 
472 //==========================================================================
473 
474 // Gives the CTEQ 5 L (leading order) parton distribution function set
475 // in parametrized form. Parametrization by J. Pumplin.
476 // Ref: CTEQ Collaboration, H.L. Lai et al., Eur.Phys.J. C12 (2000) 375.
477 
478 // The range of (x, Q) covered by this parametrization of the QCD
479 // evolved parton distributions is 1E-6 < x < 1, 1.1 GeV < Q < 10 TeV.
480 // In the current implementation, densities are frozen at borders.
481 
482 void CTEQ5L::xfUpdate(int , double x, double Q2) {
483 
484  // Constrain x and Q2 to range for which parametrization is valid.
485  double Q = sqrt( max( 1., min( 1e8, Q2) ) );
486  x = max( 1e-6, min( 1.-1e-10, x) );
487 
488  // Derived kinematical quantities.
489  double y = - log(x);
490  double u = log( x / 0.00001);
491  double x1 = 1. - x;
492  double x1L = log(1. - x);
493  double sumUbarDbar = 0.;
494 
495  // Parameters of parametrizations.
496  const double Qmin[8] = { 0., 0., 0., 0., 0., 0., 1.3, 4.5};
497  const double alpha[8] = { 0.2987216, 0.3407552, 0.4491863, 0.2457668,
498  0.5293999, 0.3713141, 0.03712017, 0.004952010 };
499  const double ut1[8] = { 4.971265, 2.612618, -0.4656819, 3.862583,
500  0.1895615, 3.753257, 4.400772, 5.562568 };
501  const double ut2[8] = { -1.105128, -1.258304e5, -274.2390, -1.265969,
502  -3.069097, -1.113085, -1.356116, -1.801317 };
503  const double am[8][9][3] = {
504  // d.
505  { { 0.5292616E+01, -0.2751910E+01, -0.2488990E+01 },
506  { 0.9714424E+00, 0.1011827E-01, -0.1023660E-01 },
507  { -0.1651006E+02, 0.7959721E+01, 0.8810563E+01 },
508  { -0.1643394E+02, 0.5892854E+01, 0.9348874E+01 },
509  { 0.3067422E+02, 0.4235796E+01, -0.5112136E+00 },
510  { 0.2352526E+02, -0.5305168E+01, -0.1169174E+02 },
511  { -0.1095451E+02, 0.3006577E+01, 0.5638136E+01 },
512  { -0.1172251E+02, -0.2183624E+01, 0.4955794E+01 },
513  { 0.1662533E-01, 0.7622870E-02, -0.4895887E-03 } },
514  // u.
515  { { 0.9905300E+00, -0.4502235E+00, 0.1624441E+00 },
516  { 0.8867534E+00, 0.1630829E-01, -0.4049085E-01 },
517  { 0.8547974E+00, 0.3336301E+00, 0.1371388E+00 },
518  { 0.2941113E+00, -0.1527905E+01, 0.2331879E+00 },
519  { 0.3384235E+02, 0.3715315E+01, 0.8276930E+00 },
520  { 0.6230115E+01, 0.3134639E+01, -0.1729099E+01 },
521  { -0.1186928E+01, -0.3282460E+00, 0.1052020E+00 },
522  { -0.8545702E+01, -0.6247947E+01, 0.3692561E+01 },
523  { 0.1724598E-01, 0.7120465E-02, 0.4003646E-04 } },
524  // g.
525  { { 0.1193572E+03, -0.3886845E+01, -0.1133965E+01 },
526  { -0.9421449E+02, 0.3995885E+01, 0.1607363E+01 },
527  { 0.4206383E+01, 0.2485954E+00, 0.2497468E+00 },
528  { 0.1210557E+03, -0.3015765E+01, -0.1423651E+01 },
529  { -0.1013897E+03, -0.7113478E+00, 0.2621865E+00 },
530  { -0.1312404E+01, -0.9297691E+00, -0.1562531E+00 },
531  { 0.1627137E+01, 0.4954111E+00, -0.6387009E+00 },
532  { 0.1537698E+00, -0.2487878E+00, 0.8305947E+00 },
533  { 0.2496448E-01, 0.2457823E-02, 0.8234276E-03 } },
534  // ubar + dbar.
535  { { 0.2647441E+02, 0.1059277E+02, -0.9176654E+00 },
536  { 0.1990636E+01, 0.8558918E-01, 0.4248667E-01 },
537  { -0.1476095E+02, -0.3276255E+02, 0.1558110E+01 },
538  { -0.2966889E+01, -0.3649037E+02, 0.1195914E+01 },
539  { -0.1000519E+03, -0.2464635E+01, 0.1964849E+00 },
540  { 0.3718331E+02, 0.4700389E+02, -0.2772142E+01 },
541  { -0.1872722E+02, -0.2291189E+02, 0.1089052E+01 },
542  { -0.1628146E+02, -0.1823993E+02, 0.2537369E+01 },
543  { -0.1156300E+01, -0.1280495E+00, 0.5153245E-01 } },
544  // dbar/ubar.
545  { { -0.6556775E+00, 0.2490190E+00, 0.3966485E-01 },
546  { 0.1305102E+01, -0.1188925E+00, -0.4600870E-02 },
547  { -0.2371436E+01, 0.3566814E+00, -0.2834683E+00 },
548  { -0.6152826E+01, 0.8339877E+00, -0.7233230E+00 },
549  { -0.8346558E+01, 0.2892168E+01, 0.2137099E+00 },
550  { 0.1279530E+02, 0.1021114E+00, 0.5787439E+00 },
551  { 0.5858816E+00, -0.1940375E+01, -0.4029269E+00 },
552  { -0.2795725E+02, -0.5263392E+00, 0.1290229E+01 },
553  { 0.0000000E+00, 0.0000000E+00, 0.0000000E+00 } },
554  // sbar.
555  { { 0.1580931E+01, -0.2273826E+01, -0.1822245E+01 },
556  { 0.2702644E+01, 0.6763243E+00, 0.7231586E-02 },
557  { -0.1857924E+02, 0.3907500E+01, 0.5850109E+01 },
558  { -0.3044793E+02, 0.2639332E+01, 0.5566644E+01 },
559  { -0.4258011E+01, -0.5429244E+01, 0.4418946E+00 },
560  { 0.3465259E+02, -0.5532604E+01, -0.4904153E+01 },
561  { -0.1658858E+02, 0.2923275E+01, 0.2266286E+01 },
562  { -0.1149263E+02, 0.2877475E+01, -0.7999105E+00 },
563  { 0.0000000E+00, 0.0000000E+00, 0.0000000E+00 } },
564  // cbar.
565  { { -0.8293661E+00, -0.3982375E+01, -0.6494283E-01 },
566  { 0.2754618E+01, 0.8338636E+00, -0.6885160E-01 },
567  { -0.1657987E+02, 0.1439143E+02, -0.6887240E+00 },
568  { -0.2800703E+02, 0.1535966E+02, -0.7377693E+00 },
569  { -0.6460216E+01, -0.4783019E+01, 0.4913297E+00 },
570  { 0.3141830E+02, -0.3178031E+02, 0.7136013E+01 },
571  { -0.1802509E+02, 0.1862163E+02, -0.4632843E+01 },
572  { -0.1240412E+02, 0.2565386E+02, -0.1066570E+02 },
573  { 0.0000000E+00, 0.0000000E+00, 0.0000000E+00 } },
574  // bbar.
575  { { -0.6031237E+01, 0.1992727E+01, -0.1076331E+01 },
576  { 0.2933912E+01, 0.5839674E+00, 0.7509435E-01 },
577  { -0.8284919E+01, 0.1488593E+01, -0.8251678E+00 },
578  { -0.1925986E+02, 0.2805753E+01, -0.3015446E+01 },
579  { -0.9480483E+01, -0.9767837E+00, -0.1165544E+01 },
580  { 0.2193195E+02, -0.1788518E+02, 0.9460908E+01 },
581  { -0.1327377E+02, 0.1201754E+02, -0.6277844E+01 },
582  { 0.0000000E+00, 0.0000000E+00, 0.0000000E+00 },
583  { 0.0000000E+00, 0.0000000E+00, 0.0000000E+00 } } };
584 
585  // Loop over 8 different parametrizations. Check if inside allowed region.
586  for (int i = 0; i < 8; ++i) {
587  double answer = 0.;
588  if (Q > max(Qmin[i], alpha[i])) {
589 
590  // Evaluate answer.
591  double tmp = log(Q / alpha[i]);
592  double sb = log(tmp);
593  double sb1 = sb - 1.2;
594  double sb2 = sb1*sb1;
595  double af[9];
596  for (int j = 0; j < 9; ++j)
597  af[j] = am[i][j][0] + sb1 * am[i][j][1] + sb2 * am[i][j][2];
598  double part1 = af[1] * pow( y, 1. + 0.01 * af[4]) * (1. + af[8] * u);
599  double part2 = af[0] * x1 + af[3] * x;
600  double part3 = x * x1 * (af[5] + af[6] * x1 + af[7] * x * x1);
601  double part4 = (ut2[i] < -100.) ? ut1[i] * x1L + af[2] * x1L
602  : ut1[i] * x1L + af[2] * log(x1 + exp(ut2[i]));
603  answer = x * exp( part1 + part2 + part3 + part4);
604  answer *= 1. - Qmin[i] / Q;
605  }
606 
607  // Store results.
608  if (i == 0) xd = x * answer;
609  else if (i == 1) xu = x * answer;
610  else if (i == 2) xg = x * answer;
611  else if (i == 3) sumUbarDbar = x * answer;
612  else if (i == 4) { xubar = sumUbarDbar / (1. + answer);
613  xdbar = sumUbarDbar * answer / (1. + answer); }
614  else if (i == 5) {xs = x * answer; xsbar = xs;}
615  else if (i == 6) xc = x * answer;
616  else if (i == 7) xb = x * answer;
617  }
618 
619  // Subdivision of valence and sea.
620  xuVal = xu - xubar;
621  xuSea = xubar;
622  xdVal = xd - xdbar;
623  xdSea = xdbar;
624 
625  // idSav = 9 to indicate that all flavours reset.
626  idSav = 9;
627 
628 }
629 
630 //==========================================================================
631 
632 // The MSTWpdf class.
633 // MSTW 2008 PDF's, specifically the LO one.
634 // Original C++ version by Jeppe Andersen.
635 // Modified by Graeme Watt <watt(at)hep.ucl.ac.uk>.
636 
637 //--------------------------------------------------------------------------
638 
639 // Constants: could be changed here if desired, but normally should not.
640 // These are of technical nature, as described for each.
641 
642 // Number of parton flavours, x and Q2 grid points,
643 // bins below c and b thresholds.
644 const int MSTWpdf::np = 12;
645 const int MSTWpdf::nx = 64;
646 const int MSTWpdf::nq = 48;
647 const int MSTWpdf::nqc0 = 4;
648 const int MSTWpdf::nqb0 = 14;
649 
650 // Range of (x, Q2) grid.
651 const double MSTWpdf::xmin = 1e-6;
652 const double MSTWpdf::xmax = 1.0;
653 const double MSTWpdf::qsqmin = 1.0;
654 const double MSTWpdf::qsqmax = 1e9;
655 
656 // Array of x values.
657 const double MSTWpdf::xxInit[65] = {0., 1e-6, 2e-6, 4e-6, 6e-6, 8e-6,
658  1e-5, 2e-5, 4e-5, 6e-5, 8e-5, 1e-4, 2e-4, 4e-4, 6e-4, 8e-4,
659  1e-3, 2e-3, 4e-3, 6e-3, 8e-3, 1e-2, 1.4e-2, 2e-2, 3e-2, 4e-2, 6e-2,
660  8e-2, 0.10, 0.125, 0.15, 0.175, 0.20, 0.225, 0.25, 0.275, 0.30,
661  0.325, 0.35, 0.375, 0.40, 0.425, 0.45, 0.475, 0.50, 0.525, 0.55,
662  0.575, 0.60, 0.625, 0.65, 0.675, 0.70, 0.725, 0.75, 0.775, 0.80,
663  0.825, 0.85, 0.875, 0.90, 0.925, 0.95, 0.975, 1.0 };
664 
665 // Array of Q values.
666 const double MSTWpdf::qqInit[49] = {0., 1.0, 1.25, 1.5, 0., 0., 2.5, 3.2,
667  4.0, 5.0, 6.4, 8.0, 10., 12., 0., 0., 26.0, 40.0, 64.0, 1e2, 1.6e2,
668  2.4e2, 4e2, 6.4e2, 1e3, 1.8e3, 3.2e3, 5.6e3, 1e4, 1.8e4, 3.2e4, 5.6e4,
669  1e5, 1.8e5, 3.2e5, 5.6e5, 1e6, 1.8e6, 3.2e6, 5.6e6, 1e7, 1.8e7, 3.2e7,
670  5.6e7, 1e8, 1.8e8, 3.2e8, 5.6e8, 1e9 };
671 
672 //--------------------------------------------------------------------------
673 
674 // Initialize PDF: select data file and open stream.
675 
676 void MSTWpdf::init(int iFitIn, string xmlPath, Info* infoPtr) {
677 
678  // Choice of fit among possibilities.
679  iFit = iFitIn;
680 
681  // Select which data file to read for current fit.
682  if (xmlPath[ xmlPath.length() - 1 ] != '/') xmlPath += "/";
683  string fileName = " ";
684  if (iFit == 1) fileName = "mrstlostar.00.dat";
685  if (iFit == 2) fileName = "mrstlostarstar.00.dat";
686  if (iFit == 3) fileName = "mstw2008lo.00.dat";
687  if (iFit == 4) fileName = "mstw2008nlo.00.dat";
688 
689  // Open data file.
690  ifstream data_file( (xmlPath + fileName).c_str() );
691  if (!data_file.good()) {
692  printErr("Error in MSTWpdf::init: did not find data file ", infoPtr);
693  isSet = false;
694  return;
695  }
696 
697  // Initialization with a stream.
698  init(data_file, infoPtr);
699  data_file.close();
700 
701 }
702 
703 //--------------------------------------------------------------------------
704 
705 // Initialize PDF: read in data grid from stream and set up interpolation.
706 
707 void MSTWpdf::init(istream& data_file, Info* infoPtr) {
708 
709  // Check that data stream is available.
710  if (!data_file.good()) {
711  printErr("Error in MSTWpdf::init: cannot read from stream", infoPtr);
712  isSet = false;
713  return;
714  }
715 
716  // Counters and temporary variables.
717  int i,n,m,k,l,j;
718  double dtemp;
719 
720  // Variables used for initialising c_ij array:
721  double f[np+1][nx+1][nq+1];
722  double f1[np+1][nx+1][nq+1]; // derivative w.r.t. x
723  double f2[np+1][nx+1][nq+1]; // derivative w.r.t. q
724  double f12[np+1][nx+1][nq+1];// cross derivative
725  double f21[np+1][nx+1][nq+1];// cross derivative
726  int wt[16][16]={{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
727  {0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0},
728  {-3,0,0,3,0,0,0,0,-2,0,0,-1,0,0,0,0},
729  {2,0,0,-2,0,0,0,0,1,0,0,1,0,0,0,0},
730  {0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0},
731  {0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0},
732  {0,0,0,0,-3,0,0,3,0,0,0,0,-2,0,0,-1},
733  {0,0,0,0,2,0,0,-2,0,0,0,0,1,0,0,1},
734  {-3,3,0,0,-2,-1,0,0,0,0,0,0,0,0,0,0},
735  {0,0,0,0,0,0,0,0,-3,3,0,0,-2,-1,0,0},
736  {9,-9,9,-9,6,3,-3,-6,6,-6,-3,3,4,2,1,2},
737  {-6,6,-6,6,-4,-2,2,4,-3,3,3,-3,-2,-1,-1,-2},
738  {2,-2,0,0,1,1,0,0,0,0,0,0,0,0,0,0},
739  {0,0,0,0,0,0,0,0,2,-2,0,0,1,1,0,0},
740  {-6,6,-6,6,-3,-3,3,3,-4,4,2,-2,-2,-2,-1,-1},
741  {4,-4,4,-4,2,2,-2,-2,2,-2,-2,2,1,1,1,1}};
742  double xxd,d1d2,cl[16],x[16],d1,d2,y[5],y1[5],y2[5],y12[5];
743  double mc2,mb2,eps=1e-6; // q^2 grid points at mc2+eps, mb2+eps
744 
745  // Read distance, tolerance, heavy quark masses
746  // and alphaS values from file.
747  char comma;
748  int nExtraFlavours;
749  data_file.ignore(256,'\n');
750  data_file.ignore(256,'\n');
751  data_file.ignore(256,'='); data_file >> distance >> tolerance;
752  data_file.ignore(256,'='); data_file >> mCharm;
753  data_file.ignore(256,'='); data_file >> mBottom;
754  data_file.ignore(256,'='); data_file >> alphaSQ0;
755  data_file.ignore(256,'='); data_file >> alphaSMZ;
756  data_file.ignore(256,'='); data_file >> alphaSorder >> comma >> alphaSnfmax;
757  data_file.ignore(256,'='); data_file >> nExtraFlavours;
758  data_file.ignore(256,'\n');
759  data_file.ignore(256,'\n');
760  data_file.ignore(256,'\n');
761 
762  // Use c and b quark masses for outlay of qq array.
763  for (int iqq = 0; iqq < 49; ++iqq) qq[iqq] = qqInit[iqq];
764  mc2=mCharm*mCharm;
765  mb2=mBottom*mBottom;
766  qq[4]=mc2;
767  qq[5]=mc2+eps;
768  qq[14]=mb2;
769  qq[15]=mb2+eps;
770 
771  // Check that the heavy quark masses are sensible.
772  if (mc2 < qq[3] || mc2 > qq[6]) {
773  printErr("Error in MSTWpdf::init: invalid mCharm", infoPtr);
774  isSet = false;
775  return;
776  }
777  if (mb2 < qq[13] || mb2 > qq[16]) {
778  printErr("Error in MSTWpdf::init: invalid mBottom", infoPtr);
779  isSet = false;
780  return;
781  }
782 
783  // The nExtraFlavours variable is provided to aid compatibility
784  // with future grids where, for example, a photon distribution
785  // might be provided (cf. the MRST2004QED PDFs).
786  if (nExtraFlavours < 0 || nExtraFlavours > 1) {
787  printErr("Error in MSTWpdf::init: invalid nExtraFlavours", infoPtr);
788  isSet = false;
789  return;
790  }
791 
792  // Now read in the grids from the grid file.
793  for (n=1;n<=nx-1;n++)
794  for (m=1;m<=nq;m++) {
795  for (i=1;i<=9;i++)
796  data_file >> f[i][n][m];
797  if (alphaSorder==2) { // only at NNLO
798  data_file >> f[10][n][m]; // = chm-cbar
799  data_file >> f[11][n][m]; // = bot-bbar
800  }
801  else {
802  f[10][n][m] = 0.; // = chm-cbar
803  f[11][n][m] = 0.; // = bot-bbar
804  }
805  if (nExtraFlavours>0)
806  data_file >> f[12][n][m]; // = photon
807  else
808  f[12][n][m] = 0.; // photon
809  if (data_file.eof()) {
810  printErr("Error in MSTWpdf::init: could not read data stream",
811  infoPtr);
812  isSet = false;
813  return;
814  }
815  }
816 
817  // Check that ALL the file contents have been read in.
818  data_file >> dtemp;
819  if (!data_file.eof()) {
820  printErr("Error in MSTWpdf::init: could not read data stream", infoPtr);
821  isSet = false;
822  return;
823  }
824 
825  // PDFs are identically zero at x = 1.
826  for (i=1;i<=np;i++)
827  for (m=1;m<=nq;m++)
828  f[i][nx][m]=0.0;
829 
830  // Set up the new array in log10(x) and log10(qsq).
831  for (i=1;i<=nx;i++)
832  xx[i]=log10(xxInit[i]);
833  for (m=1;m<=nq;m++)
834  qq[m]=log10(qq[m]);
835 
836  // Now calculate the derivatives used for bicubic interpolation.
837  for (i=1;i<=np;i++) {
838 
839  // Start by calculating the first x derivatives
840  // along the first x value:
841  for (m=1;m<=nq;m++) {
842  f1[i][1][m]=polderivative1(xx[1],xx[2],xx[3],f[i][1][m],f[i][2][m],
843  f[i][3][m]);
844  // Then along the rest (up to the last):
845  for (k=2;k<nx;k++)
846  f1[i][k][m]=polderivative2(xx[k-1],xx[k],xx[k+1],f[i][k-1][m],
847  f[i][k][m],f[i][k+1][m]);
848  // Then for the last column:
849  f1[i][nx][m]=polderivative3(xx[nx-2],xx[nx-1],xx[nx],f[i][nx-2][m],
850  f[i][nx-1][m],f[i][nx][m]);
851  }
852 
853  // Then calculate the qq derivatives. At NNLO there are
854  // discontinuities in the PDFs at mc2 and mb2, so calculate
855  // the derivatives at q^2 = mc2, mc2+eps, mb2, mb2+eps in
856  // the same way as at the endpoints qsqmin and qsqmax.
857  for (m=1;m<=nq;m++) {
858  if (m==1 || m==nqc0+1 || m==nqb0+1) {
859  for (k=1;k<=nx;k++)
860  f2[i][k][m]=polderivative1(qq[m],qq[m+1],qq[m+2],
861  f[i][k][m],f[i][k][m+1],f[i][k][m+2]);
862  }
863  else if (m==nq || m==nqc0 || m==nqb0) {
864  for (k=1;k<=nx;k++)
865  f2[i][k][m]=polderivative3(qq[m-2],qq[m-1],qq[m],
866  f[i][k][m-2],f[i][k][m-1],f[i][k][m]);
867  }
868  else {
869  // The rest:
870  for (k=1;k<=nx;k++)
871  f2[i][k][m]=polderivative2(qq[m-1],qq[m],qq[m+1],
872  f[i][k][m-1],f[i][k][m],f[i][k][m+1]);
873  }
874  }
875 
876  // Now, calculate the cross derivatives.
877  // Calculate these as the average between (d/dx)(d/dy) and (d/dy)(d/dx).
878 
879  // First calculate (d/dx)(d/dy).
880  // Start by calculating the first x derivatives
881  // along the first x value:
882  for (m=1;m<=nq;m++)
883  f12[i][1][m]=polderivative1(xx[1],xx[2],xx[3],f2[i][1][m],
884  f2[i][2][m],f2[i][3][m]);
885  // Then along the rest (up to the last):
886  for (k=2;k<nx;k++) {
887  for (m=1;m<=nq;m++)
888  f12[i][k][m]=polderivative2(xx[k-1],xx[k],xx[k+1],f2[i][k-1][m],
889  f2[i][k][m],f2[i][k+1][m]);
890  }
891  // Then for the last column:
892  for (m=1;m<=nq;m++)
893  f12[i][nx][m]=polderivative3(xx[nx-2],xx[nx-1],xx[nx],
894  f2[i][nx-2][m],f2[i][nx-1][m],f2[i][nx][m]);
895 
896  // Now calculate (d/dy)(d/dx).
897  for (m=1;m<=nq;m++) {
898  if (m==1 || m==nqc0+1 || m==nqb0+1) {
899  for (k=1;k<=nx;k++)
900  f21[i][k][m]=polderivative1(qq[m],qq[m+1],qq[m+2],
901  f1[i][k][m],f1[i][k][m+1],f1[i][k][m+2]);
902  }
903  else if (m==nq || m==nqc0 || m==nqb0) {
904  for (k=1;k<=nx;k++)
905  f21[i][k][m]=polderivative3(qq[m-2],qq[m-1],qq[m],
906  f1[i][k][m-2],f1[i][k][m-1],f1[i][k][m]);
907  }
908  else {
909  // The rest:
910  for (k=1;k<=nx;k++)
911  f21[i][k][m]=polderivative2(qq[m-1],qq[m],qq[m+1],
912  f1[i][k][m-1],f1[i][k][m],f1[i][k][m+1]);
913  }
914  }
915 
916  // Now take the average of (d/dx)(d/dy) and (d/dy)(d/dx).
917  for (k=1;k<=nx;k++) {
918  for (m=1;m<=nq;m++) {
919  f12[i][k][m] = 0.5*(f12[i][k][m]+f21[i][k][m]);
920  }
921  }
922 
923  // Now calculate the coefficients c_ij.
924  for (n=1;n<=nx-1;n++) {
925  for (m=1;m<=nq-1;m++) {
926  d1=xx[n+1]-xx[n];
927  d2=qq[m+1]-qq[m];
928  d1d2=d1*d2;
929 
930  y[1]=f[i][n][m];
931  y[2]=f[i][n+1][m];
932  y[3]=f[i][n+1][m+1];
933  y[4]=f[i][n][m+1];
934 
935  y1[1]=f1[i][n][m];
936  y1[2]=f1[i][n+1][m];
937  y1[3]=f1[i][n+1][m+1];
938  y1[4]=f1[i][n][m+1];
939 
940  y2[1]=f2[i][n][m];
941  y2[2]=f2[i][n+1][m];
942  y2[3]=f2[i][n+1][m+1];
943  y2[4]=f2[i][n][m+1];
944 
945  y12[1]=f12[i][n][m];
946  y12[2]=f12[i][n+1][m];
947  y12[3]=f12[i][n+1][m+1];
948  y12[4]=f12[i][n][m+1];
949 
950  for (k=1;k<=4;k++) {
951  x[k-1]=y[k];
952  x[k+3]=y1[k]*d1;
953  x[k+7]=y2[k]*d2;
954  x[k+11]=y12[k]*d1d2;
955  }
956 
957  for (l=0;l<=15;l++) {
958  xxd=0.0;
959  for (k=0;k<=15;k++) xxd+= wt[l][k]*x[k];
960  cl[l]=xxd;
961  }
962 
963  l=0;
964  for (k=1;k<=4;k++)
965  for (j=1;j<=4;j++) c[i][n][m][k][j]=cl[l++];
966  } //m
967  } //n
968  } // i
969 
970 }
971 
972 //--------------------------------------------------------------------------
973 
974 // Update PDF values.
975 
976 void MSTWpdf::xfUpdate(int , double x, double Q2) {
977 
978  // Update using MSTW routine.
979  double q = sqrtpos(Q2);
980  // Quarks:
981  double dn = parton(1,x,q);
982  double up = parton(2,x,q);
983  double str = parton(3,x,q);
984  double chm = parton(4,x,q);
985  double bot = parton(5,x,q);
986  // Valence quarks:
987  double dnv = parton(7,x,q);
988  double upv = parton(8,x,q);
989  double sv = parton(9,x,q);
990  double cv = parton(10,x,q);
991  double bv = parton(11,x,q);
992  // Antiquarks = quarks - valence quarks:
993  double dsea = dn - dnv;
994  double usea = up - upv;
995  double sbar = str - sv;
996  double cbar = chm - cv;
997  double bbar = bot - bv;
998  // Gluon:
999  double glu = parton(0,x,q);
1000  // Photon (= zero unless considering QED contributions):
1001  double phot = parton(13,x,q);
1002 
1003  // Transfer to Pythia notation.
1004  xg = glu;
1005  xu = up;
1006  xd = dn;
1007  xubar = usea;
1008  xdbar = dsea;
1009  xs = str;
1010  xsbar = sbar;
1011  xc = 0.5 * (chm + cbar);
1012  xb = 0.5 * (bot + bbar);
1013  xgamma = phot;
1014 
1015  // Subdivision of valence and sea.
1016  xuVal = upv;
1017  xuSea = xubar;
1018  xdVal = dnv;
1019  xdSea = xdbar;
1020 
1021  // idSav = 9 to indicate that all flavours reset.
1022  idSav = 9;
1023 
1024 }
1025 
1026 //--------------------------------------------------------------------------
1027 
1028 // Returns the PDF value for parton of flavour 'f' at x,q.
1029 
1030 double MSTWpdf::parton(int f,double x,double q) {
1031 
1032  double qsq;
1033  int ip;
1034  int interpolate(1);
1035  double parton_pdf=0,parton_pdf1=0,anom;
1036  double xxx,qqq;
1037 
1038  qsq=q*q;
1039 
1040  // If mc2 < qsq < mc2+eps, then qsq = mc2+eps.
1041  if (qsq>pow(10.,qq[nqc0]) && qsq<pow(10.,qq[nqc0+1])) {
1042  qsq = pow(10.,qq[nqc0+1]);
1043  }
1044 
1045  // If mb2 < qsq < mb2+eps, then qsq = mb2+eps.
1046  if (qsq>pow(10.,qq[nqb0]) && qsq<pow(10.,qq[nqb0+1])) {
1047  qsq = pow(10.,qq[nqb0+1]);
1048  }
1049 
1050  if (x<xmin) {
1051  interpolate=0;
1052  if (x<=0.) return 0.;
1053  }
1054  else if (x>xmax) return 0.;
1055 
1056  if (qsq<qsqmin) {
1057  interpolate=-1;
1058  if (q<=0.) return 0.;
1059  }
1060  else if (qsq>qsqmax) {
1061  interpolate=0;
1062  }
1063 
1064  if (f==0) ip=1;
1065  else if (f>=1 && f<=5) ip=f+1;
1066  else if (f<=-1 && f>=-5) ip=-f+1;
1067  else if (f>=7 && f<=11) ip=f;
1068  else if (f==13) ip=12;
1069  else if (abs(f)==6 || f==12) return 0.;
1070  else return 0.;
1071 
1072  // Interpolation in log10(x), log10(qsq):
1073  xxx=log10(x);
1074  qqq=log10(qsq);
1075 
1076  if (interpolate==1) { // do usual interpolation
1077  parton_pdf=parton_interpolate(ip,xxx,qqq);
1078  if (f<=-1 && f>=-5) // antiquark = quark - valence
1079  parton_pdf -= parton_interpolate(ip+5,xxx,qqq);
1080  }
1081  else if (interpolate==-1) { // extrapolate to low Q^2
1082 
1083  if (x<xmin) { // extrapolate to low x
1084  parton_pdf = parton_extrapolate(ip,xxx,log10(qsqmin));
1085  parton_pdf1 = parton_extrapolate(ip,xxx,log10(1.01*qsqmin));
1086  if (f<=-1 && f>=-5) { // antiquark = quark - valence
1087  parton_pdf -= parton_extrapolate(ip+5,xxx,log10(qsqmin));
1088  parton_pdf1 -= parton_extrapolate(ip+5,xxx,log10(1.01*qsqmin));
1089  }
1090  }
1091  else { // do usual interpolation
1092  parton_pdf = parton_interpolate(ip,xxx,log10(qsqmin));
1093  parton_pdf1 = parton_interpolate(ip,xxx,log10(1.01*qsqmin));
1094  if (f<=-1 && f>=-5) { // antiquark = quark - valence
1095  parton_pdf -= parton_interpolate(ip+5,xxx,log10(qsqmin));
1096  parton_pdf1 -= parton_interpolate(ip+5,xxx,log10(1.01*qsqmin));
1097  }
1098  }
1099  // Calculate the anomalous dimension, dlog(xf)/dlog(qsq),
1100  // evaluated at qsqmin. Then extrapolate the PDFs to low
1101  // qsq < qsqmin by interpolating the anomalous dimenion between
1102  // the value at qsqmin and a value of 1 for qsq << qsqmin.
1103  // If value of PDF at qsqmin is very small, just set
1104  // anomalous dimension to 1 to prevent rounding errors.
1105  if (fabs(parton_pdf) >= 1.e-5)
1106  anom = max(-2.5, (parton_pdf1-parton_pdf)/parton_pdf/0.01);
1107  else anom = 1.;
1108  parton_pdf = parton_pdf*pow(qsq/qsqmin,anom*qsq/qsqmin+1.-qsq/qsqmin);
1109 
1110  }
1111  else { // extrapolate outside PDF grid to low x or high Q^2
1112  parton_pdf = parton_extrapolate(ip,xxx,qqq);
1113  if (f<=-1 && f>=-5) // antiquark = quark - valence
1114  parton_pdf -= parton_extrapolate(ip+5,xxx,qqq);
1115  }
1116 
1117  return parton_pdf;
1118 }
1119 
1120 //--------------------------------------------------------------------------
1121 
1122 // Interpolate PDF value inside data grid.
1123 
1124 double MSTWpdf::parton_interpolate(int ip, double xxx, double qqq) {
1125 
1126  double g, t, u;
1127  int n, m, l;
1128 
1129  n=locate(xx,nx,xxx); // 0: below xmin, nx: above xmax
1130  m=locate(qq,nq,qqq); // 0: below qsqmin, nq: above qsqmax
1131 
1132  t=(xxx-xx[n])/(xx[n+1]-xx[n]);
1133  u=(qqq-qq[m])/(qq[m+1]-qq[m]);
1134 
1135  // Assume PDF proportional to (1-x)^p as x -> 1.
1136  if (n==nx-1) {
1137  double g0=((c[ip][n][m][1][4]*u+c[ip][n][m][1][3])*u
1138  +c[ip][n][m][1][2])*u+c[ip][n][m][1][1]; // value at xx[n]
1139  double g1=((c[ip][n-1][m][1][4]*u+c[ip][n-1][m][1][3])*u
1140  +c[ip][n-1][m][1][2])*u+c[ip][n-1][m][1][1]; // value at xx[n-1]
1141  double p = 1.0;
1142  if (g0>0.0&&g1>0.0) p = log(g1/g0)/log((xx[n+1]-xx[n-1])/(xx[n+1]-xx[n]));
1143  if (p<=1.0) p=1.0;
1144  g=g0*pow((xx[n+1]-xxx)/(xx[n+1]-xx[n]),p);
1145  }
1146 
1147  // Usual interpolation.
1148  else {
1149  g=0.0;
1150  for (l=4;l>=1;l--) {
1151  g=t*g+((c[ip][n][m][l][4]*u+c[ip][n][m][l][3])*u
1152  +c[ip][n][m][l][2])*u+c[ip][n][m][l][1];
1153  }
1154  }
1155 
1156  return g;
1157 }
1158 
1159 //--------------------------------------------------------------------------
1160 
1161 // Extrapolate PDF value outside data grid.
1162 
1163 
1164 double MSTWpdf::parton_extrapolate(int ip, double xxx, double qqq) {
1165 
1166  double parton_pdf=0.;
1167  int n,m;
1168 
1169  n=locate(xx,nx,xxx); // 0: below xmin, nx: above xmax
1170  m=locate(qq,nq,qqq); // 0: below qsqmin, nq: above qsqmax
1171 
1172  if (n==0&&(m>0&&m<nq)) { // if extrapolation in small x only
1173 
1174  double f0,f1;
1175  f0=parton_interpolate(ip,xx[1],qqq);
1176  f1=parton_interpolate(ip,xx[2],qqq);
1177  if ( f0>1e-3 && f1>1e-3 ) { // if values are positive, keep them so
1178  f0=log(f0);
1179  f1=log(f1);
1180  parton_pdf=exp(f0+(f1-f0)/(xx[2]-xx[1])*(xxx-xx[1]));
1181  } else // otherwise just extrapolate in the value
1182  parton_pdf=f0+(f1-f0)/(xx[2]-xx[1])*(xxx-xx[1]);
1183 
1184  } if (n>0&&m==nq) { // if extrapolation into large q only
1185 
1186  double f0,f1;
1187  f0=parton_interpolate(ip,xxx,qq[nq]);
1188  f1=parton_interpolate(ip,xxx,qq[nq-1]);
1189  if ( f0>1e-3 && f1>1e-3 ) { // if values are positive, keep them so
1190  f0=log(f0);
1191  f1=log(f1);
1192  parton_pdf=exp(f0+(f0-f1)/(qq[nq]-qq[nq-1])*(qqq-qq[nq]));
1193  } else // otherwise just extrapolate in the value
1194  parton_pdf=f0+(f0-f1)/(qq[nq]-qq[nq-1])*(qqq-qq[nq]);
1195 
1196  } if (n==0&&m==nq) { // if extrapolation into large q AND small x
1197 
1198  double f0,f1;
1199  f0=parton_extrapolate(ip,xx[1],qqq);
1200  f1=parton_extrapolate(ip,xx[2],qqq);
1201  if ( f0>1e-3 && f1>1e-3 ) { // if values are positive, keep them so
1202  f0=log(f0);
1203  f1=log(f1);
1204  parton_pdf=exp(f0+(f1-f0)/(xx[2]-xx[1])*(xxx-xx[1]));
1205  } else // otherwise just extrapolate in the value
1206  parton_pdf=f0+(f1-f0)/(xx[2]-xx[1])*(xxx-xx[1]);
1207 
1208  }
1209 
1210  return parton_pdf;
1211 }
1212 
1213 //--------------------------------------------------------------------------
1214 
1215 // Returns an integer j such that x lies inbetween xloc[j] and xloc[j+1].
1216 // unit offset of increasing ordered array xloc assumed.
1217 // n is the length of the array (xloc[n] highest element).
1218 
1219 int MSTWpdf::locate(double xloc[],int n,double x) {
1220  int ju,jm,jl(0),j;
1221  ju=n+1;
1222 
1223  while (ju-jl>1) {
1224  jm=(ju+jl)/2; // compute a mid point.
1225  if ( x>= xloc[jm])
1226  jl=jm;
1227  else ju=jm;
1228  }
1229  if (x==xloc[1]) j=1;
1230  else if (x==xloc[n]) j=n-1;
1231  else j=jl;
1232 
1233  return j;
1234 }
1235 
1236 //--------------------------------------------------------------------------
1237 
1238 // Returns the estimate of the derivative at x1 obtained by a polynomial
1239 // interpolation using the three points (x_i,y_i).
1240 
1241 double MSTWpdf::polderivative1(double x1, double x2, double x3, double y1,
1242  double y2, double y3) {
1243 
1244  return (x3*x3*(y1-y2)+2.0*x1*(x3*(-y1+y2)+x2*(y1-y3))+x2*x2*(-y1+y3)
1245  +x1*x1*(-y2+y3))/((x1-x2)*(x1-x3)*(x2-x3));
1246 
1247 }
1248 
1249 //--------------------------------------------------------------------------
1250 
1251 // Returns the estimate of the derivative at x2 obtained by a polynomial
1252 // interpolation using the three points (x_i,y_i).
1253 
1254 double MSTWpdf::polderivative2(double x1, double x2, double x3, double y1,
1255  double y2, double y3) {
1256 
1257  return (x3*x3*(y1-y2)-2.0*x2*(x3*(y1-y2)+x1*(y2-y3))+x2*x2*(y1-y3)
1258  +x1*x1*(y2-y3))/((x1-x2)*(x1-x3)*(x2-x3));
1259 
1260 }
1261 
1262 //--------------------------------------------------------------------------
1263 
1264 // Returns the estimate of the derivative at x3 obtained by a polynomial
1265 // interpolation using the three points (x_i,y_i).
1266 
1267 double MSTWpdf::polderivative3(double x1, double x2, double x3, double y1,
1268  double y2, double y3) {
1269 
1270  return (x3*x3*(-y1+y2)+2.0*x2*x3*(y1-y3)+x1*x1*(y2-y3)+x2*x2*(-y1+y3)
1271  +2.0*x1*x3*(-y2+y3))/((x1-x2)*(x1-x3)*(x2-x3));
1272 
1273 }
1274 
1275 //==========================================================================
1276 
1277 // The CTEQ6pdf class.
1278 // Code for handling CTEQ6L, CTEQ6L1, CTEQ66.00, CT09MC1, CT09MC2, CT09MCS.
1279 // Also handles ACTW Pomeron sets B, D and SG (alpha = 1.14) and D (= 1.19).
1280 
1281 // Constants: could be changed here if desired, but normally should not.
1282 // These are of technical nature, as described for each.
1283 
1284 // Stay away from xMin, xMax, Qmin, Qmax limits.
1285 const double CTEQ6pdf::EPSILON = 1e-6;
1286 
1287 // Assumed approximate power of small-x behaviour for interpolation.
1288 const double CTEQ6pdf::XPOWER = 0.3;
1289 
1290 //--------------------------------------------------------------------------
1291 
1292 // Initialize PDF: select data file and open stream.
1293 
1294 void CTEQ6pdf::init(int iFitIn, string xmlPath, Info* infoPtr) {
1295 
1296  // Choice of fit among possibilities.
1297  iFit = iFitIn;
1298 
1299  // Select which data file to read for current fit.
1300  if (xmlPath[ xmlPath.length() - 1 ] != '/') xmlPath += "/";
1301  string fileName = " ";
1302  if (iFit == 1) fileName = "cteq6l.tbl";
1303  if (iFit == 2) fileName = "cteq6l1.tbl";
1304  if (iFit == 3) fileName = "ctq66.00.pds";
1305  if (iFit == 4) fileName = "ct09mc1.pds";
1306  if (iFit == 5) fileName = "ct09mc2.pds";
1307  if (iFit == 6) fileName = "ct09mcs.pds";
1308  // Ditto for current Pomeron fit.
1309  if (iFit == 11) fileName = "pomactwb14.pds";
1310  if (iFit == 12) fileName = "pomactwd14.pds";
1311  if (iFit == 13) fileName = "pomactwsg14.pds";
1312  if (iFit == 14) fileName = "pomactwd19.pds";
1313  bool isPdsGrid = (iFit > 2);
1314 
1315  // Open data file.
1316  ifstream pdfgrid( (xmlPath + fileName).c_str() );
1317  if (!pdfgrid.good()) {
1318  printErr("Error in CTEQ6pdf::init: did not find data file", infoPtr);
1319  isSet = false;
1320  return;
1321  }
1322 
1323  // Initialization with a stream.
1324  init( pdfgrid, isPdsGrid, infoPtr);
1325  pdfgrid.close();
1326 
1327 }
1328 
1329 //--------------------------------------------------------------------------
1330 
1331 // Initialize PDF: read in data grid from stream and set up interpolation.
1332 
1333 void CTEQ6pdf::init(istream& pdfgrid, bool isPdsGrid, Info* infoPtr) {
1334 
1335  // Check that data stream is available.
1336  if (!pdfgrid.good()) {
1337  printErr("Error in CTEQ6pdf::init: cannot read from stream", infoPtr);
1338  isSet = false;
1339  return;
1340  }
1341 
1342  // Read in common information.
1343  int iDum;
1344  double orderTmp, nQTmp, qTmp, rDum;
1345  string line;
1346  getline( pdfgrid, line);
1347  getline( pdfgrid, line);
1348  getline( pdfgrid, line);
1349  istringstream is1(line);
1350  is1 >> orderTmp >> nQTmp >> lambda >> mQ[1] >> mQ[2] >> mQ[3]
1351  >> mQ[4] >> mQ[5] >> mQ[6];
1352  order = int(orderTmp + 0.5);
1353  nQuark = int(nQTmp + 0.5);
1354  getline( pdfgrid, line);
1355 
1356  // Read in information for the .pds grid format.
1357  if (isPdsGrid) {
1358  getline( pdfgrid, line);
1359  istringstream is2(line);
1360  is2 >> iDum >> iDum >> iDum >> nfMx >> mxVal >> iDum;
1361  if (mxVal > 4) mxVal = 3;
1362  getline( pdfgrid, line);
1363  getline( pdfgrid, line);
1364  istringstream is3(line);
1365  is3 >> nX >> nT >> iDum >> nG >> iDum;
1366  for (int i = 0; i < nG + 2; ++i) getline( pdfgrid, line);
1367  getline( pdfgrid, line);
1368  istringstream is4(line);
1369  is4 >> qIni >> qMax;
1370  for (int iT = 0; iT <= nT; ++iT) {
1371  getline( pdfgrid, line);
1372  istringstream is5(line);
1373  is5 >> qTmp;
1374  tv[iT] = log( log( qTmp/lambda));
1375  }
1376  getline( pdfgrid, line);
1377  getline( pdfgrid, line);
1378  istringstream is6(line);
1379  is6 >> xMin >> rDum;
1380  int nPackX = 6;
1381  xv[0] = 0.;
1382  for (int iXrng = 0; iXrng < int( (nX + nPackX - 1) / nPackX); ++iXrng) {
1383  getline( pdfgrid, line);
1384  istringstream is7(line);
1385  for (int iX = nPackX * iXrng + 1; iX <= nPackX * (iXrng + 1); ++iX)
1386  if (iX <= nX) is7 >> xv[iX];
1387  }
1388  }
1389 
1390  // Read in information for the .tbl grid format.
1391  else {
1392  mxVal = 2;
1393  getline( pdfgrid, line);
1394  istringstream is2(line);
1395  is2 >> nX >> nT >> nfMx;
1396  getline( pdfgrid, line);
1397  getline( pdfgrid, line);
1398  istringstream is3(line);
1399  is3 >> qIni >> qMax;
1400  int nPackT = 6;
1401  for (int iTrng = 0; iTrng < int( (nT + nPackT) / nPackT); ++iTrng) {
1402  getline( pdfgrid, line);
1403  istringstream is4(line);
1404  for (int iT = nPackT * iTrng; iT < nPackT * (iTrng + 1); ++iT)
1405  if (iT <= nT) {
1406  is4 >> qTmp;
1407  tv[iT] = log( log( qTmp / lambda) );
1408  }
1409  }
1410  getline( pdfgrid, line);
1411  getline( pdfgrid, line);
1412  istringstream is5(line);
1413  is5 >> xMin;
1414  int nPackX = 6;
1415  for (int iXrng = 0; iXrng < int( (nX + nPackX) / nPackX); ++iXrng) {
1416  getline( pdfgrid, line);
1417  istringstream is6(line);
1418  for (int iX = nPackX * iXrng; iX < nPackX * (iXrng + 1); ++iX)
1419  if (iX <= nX) is6 >> xv[iX];
1420  }
1421  }
1422 
1423  // Read in the grid proper.
1424  getline( pdfgrid, line);
1425  int nBlk = (nX + 1) * (nT + 1);
1426  int nPts = nBlk * (nfMx + 1 + mxVal);
1427  int nPack = (isPdsGrid) ? 6 : 5;
1428  for (int iRng = 0; iRng < int( (nPts + nPack - 1) / nPack); ++iRng) {
1429  getline( pdfgrid, line);
1430  istringstream is8(line);
1431  for (int i = nPack * iRng + 1; i <= nPack * (iRng + 1); ++i)
1432  if (i <= nPts) is8 >> upd[i];
1433  }
1434 
1435  // Initialize x grid mapped to x^0.3.
1436  xvpow[0] = 0.;
1437  for (int iX = 1; iX <= nX; ++iX) xvpow[iX] = pow(xv[iX], XPOWER);
1438 
1439  // Set x and Q borders with some margin.
1440  xMinEps = xMin * (1. + EPSILON);
1441  xMaxEps = 1. - EPSILON;
1442  qMinEps = qIni * (1. + EPSILON);
1443  qMaxEps = qMax * (1. - EPSILON);
1444 
1445  // Initialize (x, Q) values of previous call.
1446  xLast = 0.;
1447  qLast = 0.;
1448 
1449 }
1450 
1451 //--------------------------------------------------------------------------
1452 
1453 // Update PDF values.
1454 
1455 void CTEQ6pdf::xfUpdate(int , double x, double Q2) {
1456 
1457  // Update using CTEQ6 routine, within allowed (x, q) range.
1458  double xEps = doExtraPol ? x : max( xMinEps, x);
1459  double qEps = max( qMinEps, min( qMaxEps, sqrtpos(Q2) ) );
1460 
1461  // Gluon:
1462  double glu = xEps * parton6( 0, xEps, qEps);
1463  // Sea quarks (note wrong order u, d). ACTW has no s, c, b.
1464  double bot = (iFit > 10) ? 0. : xEps * parton6( 5, xEps, qEps);
1465  double chm = (iFit > 10) ? 0. : xEps * parton6( 4, xEps, qEps);
1466  double str = xEps * parton6( 3, xEps, qEps);
1467  double usea = xEps * parton6(-1, xEps, qEps);
1468  double dsea = xEps * parton6(-2, xEps, qEps);
1469  // Valence quarks:
1470  double upv = xEps * parton6( 1, xEps, qEps) - usea;
1471  double dnv = xEps * parton6( 2, xEps, qEps) - dsea;
1472 
1473  // Check that rescaling *only* occurs for ACTW Pomeron PDF sets.
1474  if (iFit < 10) rescale = 1.;
1475 
1476  // Transfer to Pythia notation.
1477  xg = rescale * glu;
1478  xu = rescale * (upv + usea);
1479  xd = rescale * (dnv + dsea);
1480  xubar = rescale * usea;
1481  xdbar = rescale * dsea;
1482  xs = rescale * str;
1483  xsbar = rescale * str;
1484  xc = rescale * chm;
1485  xb = rescale * bot;
1486  xgamma = 0.;
1487 
1488  // Subdivision of valence and sea.
1489  xuVal = rescale * upv;
1490  xuSea = rescale * usea;
1491  xdVal = rescale * dnv;
1492  xdSea = rescale * dsea;
1493 
1494  // idSav = 9 to indicate that all flavours reset.
1495  idSav = 9;
1496 
1497 }
1498 
1499 //--------------------------------------------------------------------------
1500 
1501 // Returns the PDF value for parton of flavour iParton at x, q.
1502 
1503 double CTEQ6pdf::parton6(int iParton, double x, double q) {
1504 
1505  // Put zero for large x. Parton table and interpolation variables.
1506  if (x > xMaxEps) return 0.;
1507  int iP = (iParton > mxVal) ? -iParton : iParton;
1508  double ss = pow( x, XPOWER);
1509  double tt = log( log(q / lambda) );
1510 
1511  // Find location in grid.Skip if same as in latest call.
1512  if (x != xLast || q != qLast) {
1513 
1514  // Binary search in x grid.
1515  iGridX = 0;
1516  iGridLX = -1;
1517  int ju = nX + 1;
1518  int jm = 0;
1519  while (ju - iGridLX > 1 && jm >= 0) {
1520  jm = (ju + iGridLX) / 2;
1521  if (x >= xv[jm]) iGridLX = jm;
1522  else ju = jm;
1523  }
1524 
1525  // Separate acceptable from unacceptable grid points.
1526  if (iGridLX <= -1) return 0.;
1527  else if (iGridLX == 0) iGridX = 0;
1528  else if (iGridLX <= nX - 2) iGridX = iGridLX - 1;
1529  else if (iGridLX == nX - 1) iGridX = iGridLX - 2;
1530  else return 0.;
1531 
1532  // Expressions for interpolation in x Grid.
1533  if (iGridLX > 1 && iGridLX < nX - 1) {
1534  double svec1 = xvpow[iGridX];
1535  double svec2 = xvpow[iGridX+1];
1536  double svec3 = xvpow[iGridX+2];
1537  double svec4 = xvpow[iGridX+3];
1538  double s12 = svec1 - svec2;
1539  double s13 = svec1 - svec3;
1540  xConst[8] = svec2 - svec3;
1541  double s24 = svec2 - svec4;
1542  double s34 = svec3 - svec4;
1543  xConst[6] = ss - svec2;
1544  xConst[7] = ss - svec3;
1545  xConst[0] = s13 / xConst[8];
1546  xConst[1] = s12 / xConst[8];
1547  xConst[2] = s34 / xConst[8];
1548  xConst[3] = s24 / xConst[8];
1549  double s1213 = s12 + s13;
1550  double s2434 = s24 + s34;
1551  double sdet = s12 * s34 - s1213 * s2434;
1552  double tmp = xConst[6] * xConst[7] / sdet;
1553  xConst[4] = (s34 * xConst[6] - s2434 * xConst[7]) * tmp / s12;
1554  xConst[5] = (s1213 * xConst[6] - s12 * xConst[7]) * tmp / s34;
1555  }
1556 
1557  // Expression for extrapolation in x Grid.
1558  dlx = (iGridLX == 0 && doExtraPol)
1559  ? log(x / xv[1]) / log(xv[2] / xv[1]) : 1.;
1560 
1561  // Binary search in Q grid.
1562  iGridQ = 0;
1563  iGridLQ = -1;
1564  ju = nT + 1;
1565  jm = 0;
1566  while (ju - iGridLQ > 1 && jm >= 0) {
1567  jm = (ju + iGridLQ) / 2;
1568  if (tt >= tv[jm]) iGridLQ = jm;
1569  else ju = jm;
1570  }
1571  if (iGridLQ == 0) iGridQ = 0;
1572  else if (iGridLQ <= nT - 2) iGridQ = iGridLQ - 1;
1573  else iGridQ = nT - 3;
1574 
1575  // Expressions for interpolation in Q Grid.
1576  if (iGridLQ > 0 && iGridLQ < nT - 1) {
1577  double tvec1 = tv[iGridQ];
1578  double tvec2 = tv[iGridQ+1];
1579  double tvec3 = tv[iGridQ+2];
1580  double tvec4 = tv[iGridQ+3];
1581  double t12 = tvec1 - tvec2;
1582  double t13 = tvec1 - tvec3;
1583  tConst[8] = tvec2 - tvec3;
1584  double t24 = tvec2 - tvec4;
1585  double t34 = tvec3 - tvec4;
1586  tConst[6] = tt - tvec2;
1587  tConst[7] = tt - tvec3;
1588  double tmp1 = t12 + t13;
1589  double tmp2 = t24 + t34;
1590  double tdet = t12 * t34 - tmp1 * tmp2;
1591  tConst[0] = t13 / tConst[8];
1592  tConst[1] = t12 / tConst[8];
1593  tConst[2] = t34 / tConst[8];
1594  tConst[3] = t24 / tConst[8];
1595  tConst[4] = (t34 * tConst[6] - tmp2 * tConst[7]) / t12
1596  * tConst[6] * tConst[7] / tdet;
1597  tConst[5] = (tmp1 * tConst[6] - t12 * tConst[7]) / t34
1598  * tConst[6] * tConst[7] / tdet;
1599  }
1600 
1601  // Save x and q values so do not have to redo same again.
1602  xLast = x;
1603  qLast = q;
1604  }
1605 
1606  // Jump to here if x and q are the same as for the last call.
1607  int jtmp = ( (iP + nfMx) * (nT + 1) + (iGridQ - 1) ) * (nX + 1) + iGridX + 1;
1608 
1609  // Interpolate in x space for four different q values.
1610  // Also option for extrapolation to small x values.
1611  for(int it = 1; it <= 4; ++it) {
1612  int j1 = jtmp + it * (nX + 1);
1613  if (iGridLX == 0 && doExtraPol) {
1614  fVec[it] = upd[j1+1] * pow( upd[j1+2] / upd[j1+1], dlx );
1615  } else if (iGridX == 0) {
1616  double fij[5];
1617  fij[1] = 0.;
1618  fij[2] = upd[j1+1] * pow2(xv[1]);
1619  fij[3] = upd[j1+2] * pow2(xv[2]);
1620  fij[4] = upd[j1+3] * pow2(xv[3]);
1621  double fX = polint4F( &xvpow[0], &fij[1], ss);
1622  fVec[it] = (x > 0.) ? fX / pow2(x) : 0.;
1623  } else if (iGridLX==nX-1) {
1624  fVec[it] = polint4F( &xvpow[nX-3], &upd[j1], ss);
1625  } else {
1626  double sf2 = upd[j1+1];
1627  double sf3 = upd[j1+2];
1628  double g1 = sf2 * xConst[0] - sf3 * xConst[1];
1629  double g4 = -sf2 * xConst[2] + sf3 * xConst[3];
1630  fVec[it] = (xConst[4] * (upd[j1] - g1) + xConst[5] * (upd[j1+3] - g4)
1631  + sf2 * xConst[7] - sf3 * xConst[6]) / xConst[8];
1632  }
1633  }
1634 
1635  // Interpolate in q space for x-interpolated values found above.
1636  double ff;
1637  if( iGridLQ <= 0 ) {
1638  ff = polint4F( &tv[0], &fVec[1], tt);
1639  } else if (iGridLQ >= nT - 1) {
1640  ff=polint4F( &tv[nT-3], &fVec[1], tt);
1641  } else {
1642  double tf2 = fVec[2];
1643  double tf3 = fVec[3];
1644  double g1 = tf2 * tConst[0] - tf3 * tConst[1];
1645  double g4 = -tf2 * tConst[2] + tf3 * tConst[3];
1646  ff = (tConst[4] * (fVec[1] - g1) + tConst[5] * (fVec[4] - g4)
1647  + tf2 * tConst[7] - tf3 * tConst[6]) / tConst[8];
1648  }
1649 
1650  // Done.
1651  return ff;
1652 }
1653 
1654 //--------------------------------------------------------------------------
1655 
1656 // The POLINT4 routine is based on the POLINT routine from "Numerical Recipes",
1657 // but assuming N=4, and ignoring the error estimation.
1658 // Suggested by Z. Sullivan.
1659 
1660 double CTEQ6pdf::polint4F(double xa[],double ya[],double x) {
1661 
1662  double y, h1, h2, h3, h4, w, den, d1, c1, d2, c2, d3, c3, cd1, cc1,
1663  cd2, cc2, dd1, dc1;
1664 
1665  h1 = xa[0] - x;
1666  h2 = xa[1] - x;
1667  h3 = xa[2] - x;
1668  h4 = xa[3] - x;
1669 
1670  w = ya[1] - ya[0];
1671  den = w / (h1 - h2);
1672  d1 = h2 * den;
1673  c1 = h1 * den;
1674 
1675  w = ya[2] - ya[1];
1676  den = w / (h2 - h3);
1677  d2 = h3 * den;
1678  c2 = h2 * den;
1679 
1680  w = ya[3] - ya[2];
1681  den = w / (h3 - h4);
1682  d3 = h4 * den;
1683  c3 = h3 * den;
1684 
1685  w = c2 - d1;
1686  den = w / (h1 - h3);
1687  cd1 = h3 * den;
1688  cc1 = h1 * den;
1689 
1690  w = c3 - d2;
1691  den = w / (h2 - h4);
1692  cd2 = h4 * den;
1693  cc2 = h2 * den;
1694 
1695  w = cc2 - cd1;
1696  den = w / (h1 - h4);
1697  dd1 = h4 * den;
1698  dc1 = h1 * den;
1699 
1700  if (h3 + h4 < 0.) y = ya[3] + d3 + cd2 + dd1;
1701  else if (h2 + h3 < 0.) y = ya[2] + d2 + cd1 + dc1;
1702  else if (h1 + h2 < 0.) y = ya[1] + c2 + cd1 + dc1;
1703  else y = ya[0] + c1 + cc1 + dc1;
1704 
1705  return y;
1706 
1707 }
1708 
1709 //==========================================================================
1710 
1711 // SA Unresolved proton: equivalent photon spectrum from
1712 // V.M. Budnev, I.F. Ginzburg, G.V. Meledin and V.G. Serbo,
1713 // Phys. Rept. 15 (1974/1975) 181.
1714 
1715 // Constants:
1716 const double ProtonPoint::ALPHAEM = 0.00729735;
1717 const double ProtonPoint::Q2MAX = 2.0;
1718 const double ProtonPoint::Q20 = 0.71;
1719 const double ProtonPoint::A = 7.16;
1720 const double ProtonPoint::B = -3.96;
1721 const double ProtonPoint::C = 0.028;
1722 
1723 //--------------------------------------------------------------------------
1724 
1725 // Gives a generic Q2-independent equivalent photon spectrum.
1726 
1727 void ProtonPoint::xfUpdate(int , double x, double /*Q2*/ ) {
1728 
1729  // Photon spectrum
1730  double tmpQ2Min = 0.88 * pow2(x);
1731  double phiMax = phiFunc(x, Q2MAX / Q20);
1732  double phiMin = phiFunc(x, tmpQ2Min / Q20);
1733 
1734  double fgm = 0.;
1735  if (phiMax < phiMin) {
1736  printErr("Error in ProtonPoint::xfUpdate: phiMax - phiMin < 0!", infoPtr);
1737  } else {
1738  // Corresponds to: x*f(x)
1739  fgm = (ALPHAEM / M_PI) * (1 - x) * (phiMax - phiMin);
1740  }
1741 
1742  // Update values
1743  xg = 0.;
1744  xu = 0.;
1745  xd = 0.;
1746  xubar = 0.;
1747  xdbar = 0.;
1748  xs = 0.;
1749  xsbar = 0.;
1750  xc = 0.;
1751  xb = 0.;
1752  xgamma = fgm;
1753 
1754  // Subdivision of valence and sea.
1755  xuVal = 0.;
1756  xuSea = 0;
1757  xdVal = 0.;
1758  xdSea = 0;
1759 
1760  // idSav = 9 to indicate that all flavours reset.
1761  idSav = 9;
1762 
1763 }
1764 
1765 //--------------------------------------------------------------------------
1766 
1767 // Function related to Q2 integration.
1768 
1769 double ProtonPoint::phiFunc(double x, double Q) {
1770 
1771  double tmpV = 1. + Q;
1772  double tmpSum1 = 0;
1773  double tmpSum2 = 0;
1774  for (int k=1; k<4; ++k) {
1775  tmpSum1 += 1. / (k * pow(tmpV, k));
1776  tmpSum2 += pow(B, k) / (k * pow(tmpV, k));
1777  }
1778 
1779  double tmpY = pow2(x) / (1 - x);
1780  double funVal = (1 + A * tmpY) * (-1.*log(tmpV / Q) + tmpSum1)
1781  + (1 - B) * tmpY / (4 * Q * pow(tmpV, 3))
1782  + C * (1 + tmpY/4.)* (log((tmpV - B)/tmpV) + tmpSum2);
1783 
1784  return funVal;
1785 
1786 }
1787 
1788 //==========================================================================
1789 
1790 // Gives the GRV 1992 pi+ (leading order) parton distribution function set
1791 // in parametrized form. Authors: Glueck, Reya and Vogt.
1792 // Ref: M. Glueck, E. Reya and A. Vogt, Z. Phys. C53 (1992) 651.
1793 // Allowed variable range: 0.25 GeV^2 < Q^2 < 10^8 GeV^2 and 10^-5 < x < 1.
1794 
1795 void GRVpiL::xfUpdate(int , double x, double Q2) {
1796 
1797  // Common expressions. Constrain Q2 for which parametrization is valid.
1798  double mu2 = 0.25;
1799  double lam2 = 0.232 * 0.232;
1800  double s = (Q2 > mu2) ? log( log(Q2/lam2) / log(mu2/lam2) ) : 0.;
1801  double s2 = s * s;
1802  double x1 = 1. - x;
1803  double xL = -log(x);
1804  double xS = sqrt(x);
1805 
1806  // uv, dbarv.
1807  double uv = (0.519 + 0.180 * s - 0.011 * s2) * pow(x, 0.499 - 0.027 * s)
1808  * (1. + (0.381 - 0.419 * s) * xS) * pow(x1, 0.367 + 0.563 * s);
1809 
1810  // g.
1811  double gl = ( pow(x, 0.482 + 0.341 * sqrt(s))
1812  * ( (0.678 + 0.877 * s - 0.175 * s2) + (0.338 - 1.597 * s) * xS
1813  + (-0.233 * s + 0.406 * s2) * x) + pow(s, 0.599)
1814  * exp(-(0.618 + 2.070 * s) + sqrt(3.676 * pow(s, 1.263) * xL) ) )
1815  * pow(x1, 0.390 + 1.053 * s);
1816 
1817  // sea: u, d, s.
1818  double ub = pow(s, 0.55) * (1. - 0.748 * xS + (0.313 + 0.935 * s) * x)
1819  * pow(x1, 3.359) * exp(-(4.433 + 1.301 * s) + sqrt((9.30 - 0.887 * s)
1820  * pow(s, 0.56) * xL) ) / pow(xL, 2.538 - 0.763 * s);
1821 
1822  // c.
1823  double chm = (s < 0.888) ? 0. : pow(s - 0.888, 1.02) * (1. + 1.008 * x)
1824  * pow(x1, 1.208 + 0.771 * s) * exp(-(4.40 + 1.493 * s)
1825  + sqrt( (2.032 + 1.901 * s) * pow(s, 0.39) * xL) );
1826 
1827  // b.
1828  double bot = (s < 1.351) ? 0. : pow(s - 1.351, 1.03)
1829  * pow(x1, 0.697 + 0.855 * s) * exp(-(4.51 + 1.490 * s)
1830  + sqrt( (3.056 + 1.694 * s) * pow(s, 0.39) * xL) );
1831 
1832  // Update values.
1833  xg = rescale * gl;
1834  xu = rescale * (uv + ub);
1835  xd = rescale * ub;
1836  xubar = rescale * ub;
1837  xdbar = rescale * (uv + ub);
1838  xs = rescale * ub;
1839  xsbar = rescale * ub;
1840  xc = rescale * chm;
1841  xb = rescale * bot;
1842 
1843  // Subdivision of valence and sea.
1844  xuVal = rescale * uv;
1845  xuSea = rescale * ub;
1846  xdVal = rescale * uv;
1847  xdSea = rescale * ub;
1848 
1849  // idSav = 9 to indicate that all flavours reset.
1850  idSav = 9;
1851 
1852 }
1853 
1854 //==========================================================================
1855 
1856 // Pomeron PDF: simple Q2-independent parametrizations N x^a (1 - x)^b.
1857 
1858 //--------------------------------------------------------------------------
1859 
1860 // Calculate normalization factors once and for all.
1861 
1862 void PomFix::init() {
1863 
1864  normGluon = GammaReal(PomGluonA + PomGluonB + 2.)
1865  / (GammaReal(PomGluonA + 1.) * GammaReal(PomGluonB + 1.));
1866  normQuark = GammaReal(PomQuarkA + PomQuarkB + 2.)
1867  / (GammaReal(PomQuarkA + 1.) * GammaReal(PomQuarkB + 1.));
1868 
1869 }
1870 
1871 //--------------------------------------------------------------------------
1872 
1873 // Gives a generic Q2-independent Pomeron PDF.
1874 
1875 void PomFix::xfUpdate(int , double x, double) {
1876 
1877  // Gluon and quark distributions.
1878  double gl = normGluon * pow(x, PomGluonA) * pow( (1. - x), PomGluonB);
1879  double qu = normQuark * pow(x, PomQuarkA) * pow( (1. - x), PomQuarkB);
1880 
1881  // Update values
1882  xg = (1. - PomQuarkFrac) * gl;
1883  xu = (PomQuarkFrac / (4. + 2. * PomStrangeSupp) ) * qu;
1884  xd = xu;
1885  xubar = xu;
1886  xdbar = xu;
1887  xs = PomStrangeSupp * xu;
1888  xsbar = xs;
1889  xc = 0.;
1890  xb = 0.;
1891 
1892  // Subdivision of valence and sea.
1893  xuVal = 0.;
1894  xuSea = xu;
1895  xdVal = 0.;
1896  xdSea = xd;
1897 
1898  // idSav = 9 to indicate that all flavours reset.
1899  idSav = 9;
1900 
1901 }
1902 
1903 //==========================================================================
1904 
1905 // Pomeron PDF: the H1 2006 Fit A and Fit B Q2-dependent parametrizations.
1906 
1907 //--------------------------------------------------------------------------
1908 
1909 // Initialize PDF: select data file and open stream.
1910 
1911 void PomH1FitAB::init( int iFit, string xmlPath, Info* infoPtr) {
1912 
1913  // Open files from which grids should be read in.
1914  if (xmlPath[ xmlPath.length() - 1 ] != '/') xmlPath += "/";
1915  string dataFile = "pomH1FitBlo.data";
1916  if (iFit == 1) dataFile = "pomH1FitA.data";
1917  if (iFit == 2) dataFile = "pomH1FitB.data";
1918  ifstream is( (xmlPath + dataFile).c_str() );
1919  if (!is.good()) {
1920  printErr("Error in PomH1FitAB::init: did not find data file", infoPtr);
1921  isSet = false;
1922  return;
1923  }
1924 
1925  // Initialization with a stream.
1926  init( is, infoPtr );
1927  is.close();
1928 
1929 }
1930 
1931 //--------------------------------------------------------------------------
1932 
1933 // Initialize PDF: read in data grid from stream and set up interpolation.
1934 
1935 void PomH1FitAB::init( istream& is, Info* infoPtr) {
1936 
1937  // Check that data stream is available.
1938  if (!is.good()) {
1939  printErr("Error in PomH1FitAB::init: cannot read from stream", infoPtr);
1940  isSet = false;
1941  return;
1942  }
1943 
1944  // Lower and upper bounds. Bin widths for logarithmic spacing.
1945  nx = 100;
1946  xlow = 0.001;
1947  xupp = 0.99;
1948  dx = log(xupp / xlow) / (nx - 1.);
1949  nQ2 = 30;
1950  Q2low = 1.0;
1951  Q2upp = 30000.;
1952  dQ2 = log(Q2upp / Q2low) / (nQ2 - 1.);
1953 
1954  // Read in quark data grid.
1955  for (int i = 0; i < nx; ++i)
1956  for (int j = 0; j < nQ2; ++j)
1957  is >> quarkGrid[i][j];
1958 
1959  // Read in gluon data grid.
1960  for (int i = 0; i < nx; ++i)
1961  for (int j = 0; j < nQ2; ++j)
1962  is >> gluonGrid[i][j];
1963 
1964  // Check for errors during read-in of file.
1965  if (!is) {
1966  printErr("Error in PomH1FitAB::init: could not read data stream", infoPtr);
1967  isSet = false;
1968  return;
1969  }
1970 
1971  // Done.
1972  isSet = true;
1973  return;
1974 
1975 }
1976 
1977 //--------------------------------------------------------------------------
1978 
1979 void PomH1FitAB::xfUpdate(int , double x, double Q2) {
1980 
1981  // Retrict input to validity range.
1982  double xt = min( xupp, max( xlow, x) );
1983  double Q2t = min( Q2upp, max( Q2low, Q2) );
1984 
1985  // Lower grid point and distance above it.
1986  double dlx = log( xt / xlow) / dx;
1987  int i = min( nx - 2, int(dlx) );
1988  dlx -= i;
1989  double dlQ2 = log( Q2t / Q2low) / dQ2;
1990  int j = min( nQ2 - 2, int(dlQ2) );
1991  dlQ2 -= j;
1992 
1993  // Extrapolate to small x values for quark and gluon PDF.
1994  double qu, gl;
1995  if (x < xlow && doExtraPol) {
1996  dlx = log( x / xlow) / dx;
1997  qu = (1. - dlQ2) * quarkGrid[0][j]
1998  * pow( quarkGrid[1][j] / quarkGrid[0][j], dlx)
1999  + dlQ2 * quarkGrid[0][j + 1]
2000  * pow( quarkGrid[1][j + 1] / quarkGrid[0][j + 1], dlx);
2001  gl = (1. - dlQ2) * gluonGrid[0][j]
2002  * pow( gluonGrid[1][j] / gluonGrid[0][j], dlx)
2003  + dlQ2 * gluonGrid[0][j + 1]
2004  * pow( gluonGrid[1][j + 1] / gluonGrid[0][j + 1], dlx);
2005 
2006  } else {
2007  // Interpolate to derive quark PDF.
2008  qu = (1. - dlx) * (1. - dlQ2) * quarkGrid[i][j]
2009  + dlx * (1. - dlQ2) * quarkGrid[i + 1][j]
2010  + (1. - dlx) * dlQ2 * quarkGrid[i][j + 1]
2011  + dlx * dlQ2 * quarkGrid[i + 1][j + 1];
2012 
2013  // Interpolate to derive gluon PDF.
2014  gl = (1. - dlx) * (1. - dlQ2) * gluonGrid[i][j]
2015  + dlx * (1. - dlQ2) * gluonGrid[i + 1][j]
2016  + (1. - dlx) * dlQ2 * gluonGrid[i][j + 1]
2017  + dlx * dlQ2 * gluonGrid[i + 1][j + 1];
2018  }
2019 
2020  // Update values.
2021  xg = rescale * gl;
2022  xu = rescale * qu;
2023  xd = xu;
2024  xubar = xu;
2025  xdbar = xu;
2026  xs = xu;
2027  xsbar = xu;
2028  xc = 0.;
2029  xb = 0.;
2030 
2031  // Subdivision of valence and sea.
2032  xuVal = 0.;
2033  xuSea = xu;
2034  xdVal = 0.;
2035  xdSea = xu;
2036 
2037  // idSav = 9 to indicate that all flavours reset.
2038  idSav = 9;
2039 
2040 }
2041 
2042 //==========================================================================
2043 
2044 // Pomeron PDF: the H1 2007 Jets Q2-dependent parametrization.
2045 
2046 //--------------------------------------------------------------------------
2047 
2048 // Initialize PDF: select data file and open stream.
2049 
2050 void PomH1Jets::init( int , string xmlPath, Info* infoPtr) {
2051 
2052  // Open files from which grids should be read in.
2053  if (xmlPath[ xmlPath.length() - 1 ] != '/') xmlPath += "/";
2054  ifstream is( (xmlPath + "pomH1Jets.data").c_str() );
2055  if (!is.good()) {
2056  printErr("Error in PomH1Jets::init: did not find data file", infoPtr);
2057  isSet = false;
2058  return;
2059  }
2060 
2061  // Initialization with a stream.
2062  init( is, infoPtr);
2063  is.close();
2064 
2065 }
2066 
2067 //--------------------------------------------------------------------------
2068 
2069 // Initialize PDF: read in data grid from stream and set up interpolation.
2070 
2071 void PomH1Jets::init( istream& is, Info* infoPtr) {
2072 
2073  // Check that data stream is available.
2074  if (!is.good()) {
2075  printErr("Error in PomH1Jets::init: cannot read from stream", infoPtr);
2076  isSet = false;
2077  return;
2078  }
2079 
2080  // Read in x and Q grids. Do interpolation logarithmically in Q2.
2081  for (int i = 0; i < 100; ++i) {
2082  is >> setw(13) >> xGrid[i];
2083  }
2084  for (int j = 0; j < 88; ++j) {
2085  is >> setw(13) >> Q2Grid[j];
2086  Q2Grid[j] = log( Q2Grid[j] );
2087  }
2088 
2089  // Read in gluon data grid.
2090  for (int j = 0; j < 88; ++j) {
2091  for (int i = 0; i < 100; ++i) {
2092  is >> setw(13) >> gluonGrid[i][j];
2093  }
2094  }
2095 
2096  // Read in singlet data grid.
2097  for (int j = 0; j < 88; ++j) {
2098  for (int i = 0; i < 100; ++i) {
2099  is >> setw(13) >> singletGrid[i][j];
2100  }
2101  }
2102 
2103  // Read in charm data grid.
2104  for (int j = 0; j < 88; ++j) {
2105  for (int i = 0; i < 100; ++i) {
2106  is >> setw(13) >> charmGrid[i][j];
2107  }
2108  }
2109 
2110  // Check for errors during read-in of files.
2111  if (!is) {
2112  printErr("Error in PomH1Jets::init: could not read data file", infoPtr);
2113  isSet = false;
2114  return;
2115  }
2116 
2117  // Done.
2118  isSet = true;
2119 
2120 }
2121 
2122 //--------------------------------------------------------------------------
2123 
2124 void PomH1Jets::xfUpdate(int , double x, double Q2) {
2125 
2126  // Find position in x array.
2127  double xLog = log(x);
2128  int i = 0;
2129  double dx = 0.;
2130  if (xLog <= xGrid[0]);
2131  else if (xLog >= xGrid[99]) {
2132  i = 98;
2133  dx = 1.;
2134  } else {
2135  while (xLog > xGrid[i]) ++i;
2136  --i;
2137  dx = (xLog - xGrid[i]) / (xGrid[i + 1] - xGrid[i]);
2138  }
2139 
2140  // Find position in y array.
2141  double Q2Log = log(Q2);
2142  int j = 0;
2143  double dQ2 = 0.;
2144  if (Q2Log <= Q2Grid[0]);
2145  else if (Q2Log >= Q2Grid[87]) {
2146  j = 86;
2147  dQ2 = 1.;
2148  } else {
2149  while (Q2Log > Q2Grid[j]) ++j;
2150  --j;
2151  dQ2 = (Q2Log - Q2Grid[j]) / (Q2Grid[j + 1] - Q2Grid[j]);
2152  }
2153 
2154  // Extrapolate to small x values for gluon, singlet and charm PDF.
2155  double gl, sn, ch;
2156  if (xLog < xGrid[0] && doExtraPol) {
2157  double dlx = (xLog - xGrid[0]) / (xGrid[1] - xGrid[0]) ;
2158  gl = (1. - dQ2) * gluonGrid[0][j]
2159  * pow( gluonGrid[1][j] / gluonGrid[0][j], dlx)
2160  + dQ2 * gluonGrid[0][j + 1]
2161  * pow( gluonGrid[1][j + 1] / gluonGrid[0][j + 1], dlx);
2162  sn = (1. - dQ2) * singletGrid[0][j]
2163  * pow( singletGrid[1][j] / singletGrid[0][j], dlx)
2164  + dQ2 * singletGrid[0][j + 1]
2165  * pow( singletGrid[1][j + 1] / singletGrid[0][j + 1], dlx);
2166  ch = (1. - dQ2) * charmGrid[0][j]
2167  * pow( charmGrid[1][j] / charmGrid[0][j], dlx)
2168  + dQ2 * charmGrid[0][j + 1]
2169  * pow( charmGrid[1][j + 1] / charmGrid[0][j + 1], dlx);
2170 
2171  } else {
2172  // Interpolate to derive gluon PDF.
2173  gl = (1. - dx) * (1. - dQ2) * gluonGrid[i][j]
2174  + dx * (1. - dQ2) * gluonGrid[i + 1][j]
2175  + (1. - dx) * dQ2 * gluonGrid[i][j + 1]
2176  + dx * dQ2 * gluonGrid[i + 1][j + 1];
2177 
2178  // Interpolate to derive singlet PDF. (Sum of u, d, s, ubar, dbar, sbar.)
2179  sn = (1. - dx) * (1. - dQ2) * singletGrid[i][j]
2180  + dx * (1. - dQ2) * singletGrid[i + 1][j]
2181  + (1. - dx) * dQ2 * singletGrid[i][j + 1]
2182  + dx * dQ2 * singletGrid[i + 1][j + 1];
2183 
2184  // Interpolate to derive charm PDF. (Charge-square times c and cbar.)
2185  ch = (1. - dx) * (1. - dQ2) * charmGrid[i][j]
2186  + dx * (1. - dQ2) * charmGrid[i + 1][j]
2187  + (1. - dx) * dQ2 * charmGrid[i][j + 1]
2188  + dx * dQ2 * charmGrid[i + 1][j + 1];
2189  }
2190 
2191  // Update values.
2192  xg = rescale * gl;
2193  xu = rescale * sn / 6.;
2194  xd = xu;
2195  xubar = xu;
2196  xdbar = xu;
2197  xs = xu;
2198  xsbar = xu;
2199  xc = rescale * ch * 9./8.;
2200  xb = 0.;
2201 
2202  // Subdivision of valence and sea.
2203  xuVal = 0.;
2204  xuSea = xu;
2205  xdVal = 0.;
2206  xdSea = xd;
2207 
2208  // idSav = 9 to indicate that all flavours reset.
2209  idSav = 9;
2210 
2211 }
2212 
2213 //==========================================================================
2214 
2215 void PomHISASD::xfUpdate(int, double x, double Q2) {
2216 
2217  // Check that pomeron momentum fraction is available.
2218  if ( xPomNow < 0.0 || xPomNow > 1.0 || !pPDFPtr )
2219  printErr("Error in PomHISASD::xfUpdate: no xPom available.", infoPtr);
2220 
2221  double xx = xPomNow * x;
2222  double fac = newfac * pow(1.0 - x, hixpow) / log(1.0 / xx);
2223  if ( fac == 0.0 ) fac = 1.0;
2224 
2225  xd = xdbar = fac * pPDFPtr->xfSea(1, xx, Q2);
2226  xu = xubar = fac * pPDFPtr->xfSea(2, xx, Q2);
2227  xs = xsbar = fac * pPDFPtr->xfSea(3, xx, Q2);
2228  xc = fac * pPDFPtr->xfSea(4, xx, Q2);
2229  xb = fac * pPDFPtr->xfSea(5, xx, Q2);
2230  xg = fac * pPDFPtr->xfSea(21, xx, Q2);
2231  xlepton = xgamma = 0.0;
2232 
2233  // Subdivision of valence and sea.
2234  xuVal = 0.;
2235  xuSea = xu;
2236  xdVal = 0.;
2237  xdSea = xd;
2238 
2239  // idSav = 9 to indicate that all flavours reset.
2240  idSav = 9;
2241 
2242 }
2243 
2244 //==========================================================================
2245 
2246 // Gives electron (or muon, or tau) parton distribution.
2247 
2248 // Constants: alphaEM(0), m_e, m_mu, m_tau.
2249 const double Lepton::ALPHAEM = 0.00729735;
2250 const double Lepton::ME = 0.0005109989;
2251 const double Lepton::MMU = 0.10566;
2252 const double Lepton::MTAU = 1.77699;
2253 
2254 void Lepton::xfUpdate(int id, double x, double Q2) {
2255 
2256  // Squared mass of lepton species: electron, muon, tau.
2257  if (!isInit) {
2258  double mLep = ME;
2259  if (abs(id) == 13) mLep = MMU;
2260  if (abs(id) == 15) mLep = MTAU;
2261  m2Lep = pow2( mLep );
2262  isInit = true;
2263  }
2264 
2265  // Electron inside electron, see R. Kleiss et al., in Z physics at
2266  // LEP 1, CERN 89-08, p. 34
2267  double xLog = log(max(1e-10,x));
2268  double xMinusLog = log( max(1e-10, 1. - x) );
2269  double Q2Log = log( max(3., Q2/m2Lep) );
2270  double beta = (ALPHAEM / M_PI) * (Q2Log - 1.);
2271  double delta = 1. + (ALPHAEM / M_PI) * (1.5 * Q2Log + 1.289868)
2272  + pow2(ALPHAEM / M_PI) * (-2.164868 * Q2Log*Q2Log
2273  + 9.840808 * Q2Log - 10.130464);
2274  double fPrel = beta * pow(1. - x, beta - 1.) * sqrtpos( delta )
2275  - 0.5 * beta * (1. + x) + 0.125 * beta*beta * ( (1. + x)
2276  * (-4. * xMinusLog + 3. * xLog) - 4. * xLog / (1. - x) - 5. - x);
2277 
2278  // Zero distribution for very large x and rescale it for intermediate.
2279  if (x > 1. - 1e-10) fPrel = 0.;
2280  else if (x > 1. - 1e-7) fPrel *= pow(1000.,beta) / (pow(1000.,beta) - 1.);
2281  xlepton = x * fPrel;
2282 
2283  // Photons with restricted virtuality.
2284  double sCM = infoPtr->s();
2285  double m2s = 4 * m2Lep / sCM;
2286  double Q2minGamma = 2. * m2Lep * pow2(x)
2287  / ( 1. - x - m2s + sqrt(1. - m2s) * sqrt( pow2(1. - x) - m2s ) );
2288  xgamma = (0.5 * ALPHAEM / M_PI) * (1. + pow2(1. - x))
2289  * log( Q2maxGamma / Q2minGamma );
2290 
2291  // idSav = 9 to indicate that all flavours reset.
2292  idSav = 9;
2293 
2294 }
2295 
2296 //==========================================================================
2297 
2298 // The NNPDF class.
2299 // Code for handling NNPDF2.3 QCD+QED LO
2300 // Code provided by Juan Rojo and Stefano Carrazza.
2301 
2302 //--------------------------------------------------------------------------
2303 
2304 // Freeze PDFs below XMINGRID
2305 const double NNPDF::fXMINGRID = 1e-9;
2306 
2307 //--------------------------------------------------------------------------
2308 
2309 // Initialize PDF: select data file and open stream.
2310 
2311 void NNPDF::init(int iFitIn, string xmlPath, Info* infoPtr) {
2312 
2313  // Choice of fit among possibilities.
2314  iFit = iFitIn;
2315 
2316  // Select which data file to read for current fit.
2317  if (xmlPath[ xmlPath.length() - 1 ] != '/') xmlPath += "/";
2318  string fileName = " ";
2319  // NNPDF2.3 LO QCD+QED, for two values of alphas
2320  if (iFit == 1) fileName = "NNPDF23_lo_as_0130_qed_mem0.grid";
2321  if (iFit == 2) fileName = "NNPDF23_lo_as_0119_qed_mem0.grid";
2322  // NNPDF2.3 NLO QCD+QED
2323  if (iFit == 3) fileName = "NNPDF23_nlo_as_0119_qed_mc_mem0.grid";
2324  // NNPDF2.4 NLO QCD+QED
2325  if (iFit == 4) fileName = "NNPDF23_nnlo_as_0119_qed_mc_mem0.grid";
2326 
2327  // Open data file.
2328  fstream f;
2329  f.open( (xmlPath + fileName).c_str(),ios::in);
2330  if (f.fail()) {
2331  printErr("Error in NNPDF::init: did not find data file ", infoPtr);
2332  isSet = false;
2333  return;
2334  }
2335 
2336  // Initialization with a stream.
2337  init(f, infoPtr);
2338  f.close();
2339 
2340 }
2341 
2342 //--------------------------------------------------------------------------
2343 
2344 // Initialize PDF: read in data grid from stream and set up interpolation.
2345 
2346 void NNPDF::init(istream& f, Info* infoPtr) {
2347 
2348  // Check that data stream is available.
2349  if (!f.good()) {
2350  printErr("Error in NNPDF::init: cannot read from stream", infoPtr);
2351  isSet = false;
2352  return;
2353  }
2354 
2355  // Reading grid: removing header.
2356  string tmp;
2357  for (;;) {
2358  getline(f,tmp);
2359  if (tmp.find("NNPDF20intqed") != string::npos) {
2360  getline(f,tmp);
2361  break;
2362  }
2363  }
2364 
2365  // Get nx and x grid.
2366  f >> fNX;
2367  fXGrid = new double[fNX];
2368  for (int ix = 0; ix < fNX; ix++) f >> fXGrid[ix];
2369  fLogXGrid = new double[fNX];
2370  for (int ix = 0; ix < fNX; ix++) fLogXGrid[ix] = log(fXGrid[ix]);
2371 
2372  // Get nQ2 and Q2 grid (ignorming first value).
2373  f >> fNQ2;
2374  f >> tmp;
2375  fQ2Grid = new double[fNQ2];
2376  for (int iq = 0; iq < fNQ2; iq++) f >> fQ2Grid[iq];
2377  fLogQ2Grid = new double[fNQ2];
2378  for (int iq = 0; iq < fNQ2; iq++) fLogQ2Grid[iq] = log(fQ2Grid[iq]);
2379 
2380  // Prepare grid array.
2381  fPDFGrid = new double**[fNFL];
2382  for (int i = 0; i < fNFL; i++) {
2383  fPDFGrid[i] = new double*[fNX];
2384  for (int j = 0; j < fNX; j++) {
2385  fPDFGrid[i][j] = new double[fNQ2];
2386  for (int z = 0; z < fNQ2; z++) fPDFGrid[i][j][z] = 0.0;
2387  }
2388  }
2389 
2390  // Check values of number of grid entries.
2391  if (fNX<= 0 || fNX>100 || fNQ2<=0 || fNQ2>50) {
2392  cout << "Error in NNPDF::init, Invalid grid values" << endl
2393  << "fNX = " << fNX << endl << "fNQ2 = " << fNQ2 << endl
2394  << "fNFL = " <<fNFL << endl;
2395  isSet = false;
2396  return;
2397  }
2398 
2399  // Ignore replica number. Read PDF grid points.
2400  f >> tmp;
2401  for (int ix = 0; ix < fNX; ix++)
2402  for (int iq = 0; iq < fNQ2; iq++)
2403  for (int fl = 0; fl < fNFL; fl++)
2404  f >> fPDFGrid[fl][ix][iq];
2405 
2406  // Other vectors.
2407  fRes = new double[fNFL];
2408 
2409 }
2410 
2411 //--------------------------------------------------------------------------
2412 
2413 void NNPDF::xfUpdate(int , double x, double Q2) {
2414 
2415  // Update using NNPDF routine, within allowed (x, q) range.
2416  xfxevolve(x,Q2);
2417 
2418  // Then transfer to Pythia8 notation.
2419  xg = fRes[6];
2420  xu = fRes[8];
2421  xd = fRes[7];
2422  xubar = fRes[4];
2423  xdbar = fRes[5];
2424  xs = fRes[9];
2425  xsbar = fRes[3];
2426  xc = fRes[10];
2427  xb = fRes[11];
2428  xgamma = fRes[13];
2429 
2430  // Subdivision of valence and sea.
2431  xuVal = xu - xubar;
2432  xuSea = xubar;
2433  xdVal = xd - xdbar;
2434  xdSea = xdbar;
2435 
2436  // idSav = 9 to indicate that all flavours reset.
2437  idSav = 9;
2438 
2439 }
2440 
2441 //--------------------------------------------------------------------------
2442 
2443 void NNPDF::xfxevolve(double x, double Q2) {
2444 
2445  // Freeze outside x-Q2 grid.
2446  if (x < fXMINGRID || x > fXGrid[fNX-1]) {
2447  if (x < fXMINGRID) x = fXMINGRID;
2448  if (x > fXGrid[fNX-1]) x = fXGrid[fNX-1];
2449  }
2450  if (Q2 < fQ2Grid[0] || Q2 > fQ2Grid[fNQ2-1]) {
2451  if (Q2 < fQ2Grid[0]) Q2 = fQ2Grid[0];
2452  if (Q2 > fQ2Grid[fNQ2-1]) Q2 = fQ2Grid[fNQ2-1];
2453  }
2454 
2455  // Find nearest points in the x-Q2 grid.
2456  int minx = 0;
2457  int maxx = fNX;
2458  while (maxx-minx > 1) {
2459  int midx = (minx+maxx)/2;
2460  if (x < fXGrid[midx]) maxx = midx;
2461  else minx = midx;
2462  }
2463  int ix = minx;
2464  int minq = 0;
2465  int maxq = fNQ2;
2466  while (maxq-minq > 1) {
2467  int midq = (minq+maxq)/2;
2468  if (Q2 < fQ2Grid[midq]) maxq = midq;
2469  else minq = midq;
2470  }
2471  int iq2 = minq;
2472 
2473  // Assign grid for interpolation. M,N -> order of polyN interpolation.
2474  int ix1a[fM], ix2a[fN];
2475  double x1a[fM], x2a[fN];
2476  double ya[fM][fN];
2477 
2478  for (int i = 0; i < fM; i++) {
2479  if (ix+1 >= fM/2 && ix+1 <= (fNX-fM/2)) ix1a[i] = ix+1 - fM/2 + i;
2480  if (ix+1 < fM/2) ix1a[i] = i;
2481  if (ix+1 > (fNX-fM/2)) ix1a[i] = (fNX-fM) + i;
2482  // Check grids.
2483  if (ix1a[i] < 0 || ix1a[i] >= fNX) {
2484  cout << "Error in grids! i, ixia[i] = " << i << "\t" << ix1a[i] << endl;
2485  return;
2486  }
2487  }
2488 
2489  for (int j = 0; j < fN; j++) {
2490  if (iq2+1 >= fN/2 && iq2+1 <= (fNQ2-fN/2)) ix2a[j] = iq2+1 - fN/2 + j;
2491  if (iq2+1 < fN/2) ix2a[j] = j;
2492  if (iq2+1 > (fNQ2-fN/2)) ix2a[j] = (fNQ2-fN) + j;
2493  // Check grids.
2494  if (ix2a[j] < 0 || ix2a[j] >= fNQ2) {
2495  cout << "Error in grids! j, ix2a[j] = " << j << "\t" << ix2a[j] << endl;
2496  return;
2497  }
2498  }
2499 
2500  const double xch = 1e-1;
2501  double x1;
2502  if (x < xch) x1 = log(x);
2503  else x1 = x;
2504  double x2 = log(Q2);
2505 
2506  for (int ipdf = 0; ipdf < fNFL; ipdf++) {
2507  fRes[ipdf] = 0.0;
2508  for (int i = 0; i < fM; i++) {
2509  if (x < xch) x1a[i] = fLogXGrid[ix1a[i]];
2510  else x1a[i] = fXGrid[ix1a[i]];
2511 
2512  for (int j = 0; j < fN; j++) {
2513  x2a[j] = fLogQ2Grid[ix2a[j]];
2514  ya[i][j] = fPDFGrid[ipdf][ix1a[i]][ix2a[j]];
2515  }
2516  }
2517 
2518  // 2D polynomial interpolation.
2519  double y = 0, dy = 0;
2520  polin2(x1a,x2a,ya,x1,x2,y,dy);
2521  fRes[ipdf] = y;
2522  }
2523 
2524 }
2525 
2526 //--------------------------------------------------------------------------
2527 
2528 // 1D polynomial interpolation.
2529 
2530 void NNPDF::polint(double xa[], double yal[], int n, double x,
2531  double& y, double& dy) {
2532 
2533  int ns = 0;
2534  double dif = abs(x-xa[0]);
2535  double c[fM > fN ? fM : fN];
2536  double d[fM > fN ? fM : fN];
2537 
2538  for (int i = 0; i < n; i++) {
2539  double dift = abs(x-xa[i]);
2540  if (dift < dif) {
2541  ns = i;
2542  dif = dift;
2543  }
2544  c[i] = yal[i];
2545  d[i] = yal[i];
2546  }
2547  y = yal[ns];
2548  ns--;
2549  for (int m = 1; m < n; m++) {
2550  for (int i = 0; i < n-m; i++) {
2551  double ho = xa[i]-x;
2552  double hp = xa[i+m]-x;
2553  double w = c[i+1]-d[i];
2554  double den = ho-hp;
2555  if (den == 0) {
2556  cout << "NNPDF::polint, failure" << endl;
2557  return;
2558  }
2559  den = w/den;
2560  d[i] = hp*den;
2561  c[i] = ho*den;
2562  }
2563  if (2*(ns+1) < n-m) dy = c[ns+1];
2564  else {
2565  dy = d[ns];
2566  ns--;
2567  }
2568  y+=dy;
2569  }
2570 }
2571 
2572 //--------------------------------------------------------------------------
2573 
2574 // 2D polynomial interpolation.
2575 
2576 void NNPDF::polin2(double x1al[], double x2al[], double yal[][fN],
2577  double x1, double x2, double& y, double& dy) {
2578 
2579  double yntmp[fN];
2580  double ymtmp[fM];
2581 
2582  for (int j = 0; j < fM; j++) {
2583  for (int k = 0; k < fN; k++) yntmp[k] = yal[j][k];
2584  polint(x2al,yntmp,fN,x2,ymtmp[j],dy);
2585  }
2586  polint(x1al,ymtmp,fM,x1,y,dy);
2587 
2588 }
2589 
2590 //==========================================================================
2591 
2592 // LHAPDF plugin interface.
2593 
2594 //--------------------------------------------------------------------------
2595 
2596 // Constructor.
2597 
2598 LHAPDF::LHAPDF(int idIn, string pSet, Info* infoPtrIn) :
2599  pdfPtr(0), infoPtr(infoPtrIn), lib(0) {
2600  isSet = false;
2601  if (!infoPtr) return;
2602 
2603  // Determine the plugin library name.
2604  if (pSet.size() < 8) {
2605  printErr("Error in LHAPDF::LHAPDF: invalid pSet " + pSet, infoPtr);
2606  return;
2607  }
2608  libName = pSet.substr(0, 7);
2609  if (libName != "LHAPDF5" && libName != "LHAPDF6") {
2610  printErr("Error in LHAPDF::LHAPDF: invalid pSet " + pSet, infoPtr);
2611  return;
2612  }
2613  libName = "libpythia8lhapdf" + libName.substr(6) + ".so";
2614 
2615  // Load the plugin library.
2616  const char* error(0);
2617  map<string, pair<void*, int> >::iterator plugin =
2618  infoPtr->plugins.find(libName);
2619  if (plugin == infoPtr->plugins.end()) {
2620  lib = dlopen(libName.c_str(), RTLD_LAZY);
2621  error = dlerror();
2622  }
2623  if (error) {
2624  printErr("Error in LHAPDF::init: " + string(error), infoPtr);
2625  return;
2626  }
2627  if (plugin == infoPtr->plugins.end())
2628  infoPtr->plugins[libName] = pair<void*, int>(lib, 1);
2629  else {
2630  lib = plugin->second.first;
2631  ++plugin->second.second;
2632  }
2633  dlerror();
2634 
2635  // Determine the PDF set and member.
2636  string set = pSet.substr(8);
2637  int mem = 0;
2638  size_t pos = set.find_last_of("/");
2639  if (pos != string::npos) {
2640  istringstream memStream(set.substr(pos + 1));
2641  memStream >> mem;
2642  }
2643  set = set.substr(0, pos);
2644 
2645  // Load the PDF.
2646  NewLHAPDF* newLHAPDF = (NewLHAPDF*)symbol("newLHAPDF");
2647  if (!newLHAPDF) return;
2648  pdfPtr = newLHAPDF(idIn, set, mem, infoPtr);
2649  isSet = true;
2650 
2651 }
2652 
2653 //--------------------------------------------------------------------------
2654 
2655 // Destructor.
2656 
2657 LHAPDF::~LHAPDF() {
2658  if (!infoPtr) return;
2659  if (!isSet) return;
2660 
2661  // Delete the PDF.
2662  DeleteLHAPDF* deleteLHAPDF = (DeleteLHAPDF*)symbol("deleteLHAPDF");
2663  if (deleteLHAPDF) deleteLHAPDF(pdfPtr);
2664 
2665  // Close the plugin library if not needed by other instances.
2666  map<string, pair<void*, int> >::iterator plugin =
2667  infoPtr->plugins.find(libName);
2668  if (plugin == infoPtr->plugins.end()) return;
2669  --plugin->second.second;
2670  if (plugin->second.first && plugin->second.second == 0) {
2671  dlclose(plugin->second.first);
2672  dlerror();
2673  infoPtr->plugins.erase(plugin);
2674  }
2675 
2676 }
2677 
2678 //--------------------------------------------------------------------------
2679 
2680 // Access a plugin library symbol.
2681 
2682 LHAPDF::Symbol LHAPDF::symbol(string symName) {
2683  Symbol sym(0);
2684  const char* error(0);
2685  if (!infoPtr) return sym;
2686 
2687  // Load the symbol.
2688  sym = (Symbol)dlsym(lib, symName.c_str());
2689  error = dlerror();
2690  if (error) printErr("Error in LHAPDF::symbol: " + string(error), infoPtr);
2691  dlerror();
2692  return sym;
2693 
2694 }
2695 
2696 //==========================================================================
2697 
2698 // Gives the CJKL leading order parton distribution function set
2699 // in parametrized form for the real photons. Authors: F.Cornet, P.Jankowski,
2700 // M.Krawczyk and A.Lorca, Phys. Rev. D68: 014010, 2003.
2701 // Valid for 10^(-5) < x < 1 and 1 < Q^2 < 2*10^5 GeV^2.
2702 // Below Q^2 = 1 a logarithmic approximation in Q^2 is used.
2703 
2704 // Constants related to the fit.
2705 const double CJKL::ALPHAEM = 0.007297353080;
2706 const double CJKL::Q02 = 0.25;
2707 const double CJKL::Q2MIN = 0.05;
2708 const double CJKL::Q2REF = 1.0;
2709 const double CJKL::LAMBDA = 0.221;
2710 const double CJKL::MC = 1.3;
2711 const double CJKL::MB = 4.3;
2712 
2713 //--------------------------------------------------------------------------
2714 
2715 void CJKL::xfUpdate(int , double x, double Q2) {
2716 
2717  // Parameters:
2718  double lambda2 = pow2(LAMBDA);
2719 
2720  // When below reference scale calculate first with the reference scale and
2721  // later scale with log(Q^2).
2722  double Q2Save = Q2;
2723  bool belowRef = (Q2 < Q2REF);
2724  if ( belowRef) Q2 = Q2REF;
2725 
2726  // Evolution variable.
2727  double s = log( log(Q2/lambda2)/log(Q02/lambda2) );
2728  double plLog = 9.0/(4.0*M_PI)*log(Q2/lambda2);
2729 
2730  // Point-like contributions.
2731  double plGluon = pointlikeG(x,s);
2732  double plUp = pointlikeU(x,s);
2733  double plDown = pointlikeD(x,s);
2734  double plStrange = plDown;
2735 
2736  // Hadron-like contributions.
2737  double hlGluon = hadronlikeG(x,s);
2738  double hlVal = hadronlikeVal(x,s);
2739  double hlSea = hadronlikeSea(x,s);
2740 
2741  // Heavy quarks. Undo the ACOT_X rescaling for DIS kinematics.
2742  double xMaxC = 1 - 6.76/(6.76 + Q2);
2743  double xMaxB = 1 - 73.96/(73.96 + Q2);
2744  double plCharm = pointlikeC(x*xMaxC,s,Q2)*xMaxC;
2745  double plBottom = pointlikeB(x*xMaxB,s,Q2)*xMaxB;
2746  double hlCharm = hadronlikeC(x*xMaxC,s,Q2)*xMaxC;
2747  double hlBottom = hadronlikeB(x*xMaxB,s,Q2)*xMaxB;
2748 
2749  // Sum different contributions together.
2750  xg = ALPHAEM*( plLog*plGluon + hlGluon );
2751  xu = ALPHAEM*( plLog*plUp + 0.5*hlVal + hlSea );
2752  xd = ALPHAEM*( plLog*plDown + 0.5*hlVal + hlSea );
2753  xubar = xu;
2754  xdbar = xd;
2755  xs = ALPHAEM*( plLog*plStrange + hlSea );
2756  xsbar = xs;
2757  xc = ALPHAEM*( plLog*plCharm + hlCharm );
2758  xb = ALPHAEM*( plLog*plBottom + hlBottom );
2759  xgamma = 0;
2760 
2761  // Subdivision of valence and sea.
2762  xuVal = ALPHAEM*( plLog*plUp + 0.5*hlVal );
2763  xuSea = ALPHAEM*( hlSea );
2764  xdVal = ALPHAEM*( plLog*plDown + 0.5*hlVal );
2765  xdSea = ALPHAEM*( hlSea );
2766  xsVal = ALPHAEM*( plLog*plStrange );
2767  xsSea = ALPHAEM*( hlSea );
2768  xcVal = ALPHAEM*( plLog*plCharm );
2769  xcSea = ALPHAEM*( hlCharm );
2770  xbVal = ALPHAEM*( plLog*plBottom );
2771  xbSea = ALPHAEM*( hlBottom );
2772 
2773  // When below valid Q^2 values approximate scale evolution with log(Q^2).
2774  // Approximation derived by integrating xf over x and calculating the
2775  // derivative at Q2REF.
2776  if ( belowRef) {
2777  double logApprox = max( log(Q2Save/Q2MIN) / log(Q2REF/Q2MIN ), 0.);
2778 
2779  // Scale the PDFs according to log(Q^2) approx.
2780  xg *= logApprox;
2781  xd *= logApprox;
2782  xu *= logApprox;
2783  xubar *= logApprox;
2784  xdbar *= logApprox;
2785  xs *= logApprox;
2786  xsbar *= logApprox;
2787  xc *= logApprox;
2788  xb *= logApprox;
2789  xuVal *= logApprox;
2790  xuSea *= logApprox;
2791  xdVal *= logApprox;
2792  xdSea *= logApprox;
2793  xsVal *= logApprox;
2794  xsSea *= logApprox;
2795  xcVal *= logApprox;
2796  xcSea *= logApprox;
2797  xbVal *= logApprox;
2798  xbSea *= logApprox;
2799  }
2800 
2801  // idSav = 9 to indicate that all flavours reset.
2802  idSav = 9;
2803 
2804 }
2805 
2806 //--------------------------------------------------------------------------
2807 
2808 // Returns the x-dependence decoupled from the logarithmic scale
2809 // dependence to approximate the PDFs from below for ISR.
2810 // Currently flat in x (no second argument), could be improved.
2811 
2812 double CJKL::gammaPDFxDependence(int id, double) {
2813  if (abs(id) == 1) return 0.013 * ALPHAEM;
2814  else if (abs(id) == 2) return 0.026 * ALPHAEM;
2815  else if (abs(id) == 3) return 0.010 * ALPHAEM;
2816  else if (abs(id) == 4) return 0.020 * ALPHAEM;
2817  else if (abs(id) == 5) return 0.010 * ALPHAEM;
2818  else return 0;
2819 }
2820 
2821 //--------------------------------------------------------------------------
2822 
2823 // Returns the reference scale for the logarithmic scale dependence to
2824 // approximate the PDFs in ISR. Mass squared for heavy quarks and 0.2
2825 // for others.
2826 
2827 double CJKL::gammaPDFRefScale(int id) {
2828  if (abs(id) == 4) return pow2(MC);
2829  else if (abs(id) == 5) return pow2(MB);
2830  else return 0.20;
2831 }
2832 
2833 //--------------------------------------------------------------------------
2834 
2835 // Set valence content of the photon beam using parametrized Q2-dependence.
2836 
2837 int CJKL::sampleGammaValFlavor(double Q2) {
2838 
2839  // Freeze the scale below the initial scale.
2840  if(Q2 < Q02) Q2 = Q02;
2841 
2842  // Calculate the x-integrated valence part of hadron-like contribution.
2843  double lambda2 = pow2(LAMBDA);
2844  double s = log( log(Q2/lambda2)/log(Q02/lambda2) );
2845  double a = 1.0898 + 0.38087 * s;
2846  double b = 0.42654 - 1.2128 * s;
2847  double c = -1.6576 + 1.7075 * s;
2848  double d = 0.96155 + 1.8441 * s;
2849  double aa = 0.78391 - 0.06872 * s;
2850  double a1 = tgamma(1+aa)*tgamma(1+d)/tgamma(2+aa+d);
2851  double b1 = tgamma(1.5+aa)*tgamma(1+d)/tgamma(2.5+aa+d);
2852  double c1 = tgamma(2+aa)*tgamma(1+d)/tgamma(3+aa+d);
2853  double xfValHad = ALPHAEM*a*(a1 + b*b1 + c*c1);
2854 
2855  // Set the reference scales and charges.
2856  double mq2[5] = { Q02, Q02, Q02, pow2(MC), pow2(MB) };
2857  double eq2[5] = { 1.0/9.0, 4.0/9.0, 1.0/9.0, 4.0/9.0, 1.0/9.0 };
2858 
2859  // For u- and d-quarks valence contribution from hadron-like part.
2860  double qEvo[5] = { xfValHad/2, xfValHad/2, 0, 0, 0 };
2861  double qEvoTot = 0;
2862 
2863  // Normalization of the point-like part.
2864  double plNorm = 0.000936;
2865 
2866  // Logarithmic Q^2 evolution of gamma -> qqbar splitting for each flavor.
2867  for(int i = 0;i < 5;++i) {
2868  qEvo[i] += plNorm*eq2[i]*max(0.0,log(Q2/mq2[i]));
2869  qEvoTot += qEvo[i];
2870  }
2871 
2872  // Sample the valence flavor.
2873  double qEvoRand = qEvoTot*rndmPtr->flat();
2874  for(int i = 0; i < 5; ++i) {
2875  qEvoRand -= qEvo[i];
2876  if(qEvoRand <= 0.0) {
2877  idVal1 = i+1;
2878  idVal2 = -idVal1;
2879  break;
2880  }
2881  }
2882 
2883  return idVal1;
2884 }
2885 
2886 //--------------------------------------------------------------------------
2887 
2888 // Sum of integrated PDFs \int dx x f(x,Q^2) at given scale Q^2.
2889 // Integrals parametrized as a0 + a1*log(Q^2/Q0^2).
2890 
2891 double CJKL::xfIntegratedTotal(double Q2) {
2892 
2893  // Freeze the scale below the initial scale.
2894  if(Q2 < Q02) Q2 = Q02;
2895 
2896  // Set the reference scales and relative contributions.
2897  // Gluons and u/d quarks has some non-perturbative contribution, others
2898  // only radiative contributions. Derived by fitting by eye to
2899  // a0 + a1*log(Q^2/Q0^2).
2900  double fq0[6] = { 0.0018, 0.0006, 0.0006, 0., 0., 0. };
2901  double mq2[6] = { Q02, Q02, Q02, Q02, pow2(MC), pow2(MB) };
2902  double eq2[6] = { 3.0/9.0, 1.0/9.0, 4.0/9.0, 1.0/9.0, 4.0/9.0, 1.0/9.0 };
2903  double a1 = 0.000981;
2904 
2905  // Logarithmic Q^2 evolution for each flavor. quarks two times, gluon
2906  // coefficents scaled appropriately.
2907  double xIntegrated = 0;
2908  for(int i = 0;i < 6;++i) {
2909  xIntegrated += fq0[i] + 2*a1*eq2[i]*max(0.0,log(Q2/mq2[i]));
2910  }
2911 
2912  return xIntegrated;
2913 
2914 }
2915 
2916 //--------------------------------------------------------------------------
2917 
2918 // Returns the point-like part of the gluon.
2919 
2920 double CJKL::pointlikeG(double x, double s) {
2921 
2922  // Exponents.
2923  double alpha1 = -0.43865;
2924  double alpha2 = 2.7174;
2925  double beta = 0.36752;
2926 
2927  // Scale dependent parameters.
2928  double a = 0.086893 - 0.34992 * s;
2929  double b = 0.010556 + 0.049525 * s;
2930  double c = -0.099005 + 0.34830 * s;
2931  double d = 1.0648 + 0.143421 * s;
2932  double e = 3.6717 + 2.5071 * s;
2933  double f = 2.1944 + 1.9358 * s;
2934  double aa = 0.23679 - 0.11849 * s;
2935  double bb = -0.19994 + 0.028124 * s;
2936 
2937  // Point-like gluon parametrization.
2938  return max(0.0,( pow(s,alpha1)*pow(x,aa)*( a + b*sqrt(x) + c*pow(x,bb) )
2939  + pow(s,alpha2)*exp( -e + sqrt( f*pow(s,beta)*log(1.0/x) ) ) )
2940  * pow(1-x,d) );
2941 }
2942 
2943 //--------------------------------------------------------------------------
2944 
2945 // Returns the point-like part of the u-quark.
2946 
2947 double CJKL::pointlikeU(double x, double s) {
2948 
2949  // Exponents.
2950  double alpha1 = -1.0711;
2951  double alpha2 = 3.1320;
2952  double beta = 0.69243;
2953 
2954  // Scale dependent parameters.
2955  double a = -0.058266 + 0.20506 * s;
2956  double b = 0.0097377 - 0.10617 * s;
2957  double c = -0.0068345 + 0.15211 * s;
2958  double d = 0.22297 + 0.013567 * s;
2959  double e = 6.4289 + 2.2802 * s;
2960  double f = 1.7302 + 0.76997 * s;
2961  double aa = 0.87940 - 0.110241 * s;
2962  double bb = 2.6878 - 0.040252 * s;
2963 
2964  // Point-like u-quark parametrization.
2965  return max(0.0, ( pow(s,alpha1)*pow(x,aa)*( a + b*sqrt(x) + c*pow(x,bb) )
2966  + pow(s,alpha2)*exp( -e + sqrt( f*pow(s,beta)*log(1.0/x) ) ) )
2967  * pow(1-x,d) );
2968 }
2969 
2970 //--------------------------------------------------------------------------
2971 
2972 // Returns the point-like part of the d-quark.
2973 
2974 double CJKL::pointlikeD(double x, double s) {
2975 
2976  // Exponents.
2977  double alpha1 = -1.1357;
2978  double alpha2 = 3.1187;
2979  double beta = 0.66290;
2980 
2981  // Scale dependent parameters.
2982  double a = 0.098814 - 0.067300 * s;
2983  double b = -0.092892 + 0.049949 * s;
2984  double c = -0.0066140 + 0.020427 * s;
2985  double d = -0.31385 - 0.0037558 * s;
2986  double e = 6.4671 + 2.2834 * s;
2987  double f = 1.6996 + 0.84262 * s;
2988  double aa = 11.777 + 0.034760 * s;
2989  double bb = -11.124 - 0.20135 * s;
2990 
2991  // Regulate the x->1 divergence of (1-x)^d in the parameterization.
2992  if(x > 0.995) x = 0.995;
2993 
2994  // Point-like d-quark parametrization.
2995  return max( 0.0, ( pow(s,alpha1)*pow(x,aa)*( a + b*sqrt(x) + c*pow(x,bb) )
2996  + pow(s,alpha2)*exp( -e + sqrt( f*pow(s,beta)*log(1.0/x) ) ) )
2997  * pow(1-x,d) );
2998 }
2999 
3000 //--------------------------------------------------------------------------
3001 
3002 // Returns the point-like part of the c-quark.
3003 
3004 double CJKL::pointlikeC(double x, double s, double Q2) {
3005 
3006  // Scaled variable for c quarks with m = 1.3 GeV.
3007  double y = x + 1 - Q2/(Q2 + 6.76);
3008 
3009  // Kinematic boundary.
3010  if (y >= 1.0) return 0;
3011 
3012  // Declaration of parameters.
3013  double alpha1, alpha2, beta, a, b, c, d, e, f, aa, bb;
3014 
3015  // Parameters for Q^2 <= 10 GeV^2.
3016  if (Q2 <= 10) {
3017 
3018  // Exponents.
3019  alpha1 = 2.9808;
3020  alpha2 = 28.682;
3021  beta = 2.4863;
3022 
3023  // Scale dependent parameters.
3024  a = -0.18826 + 0.13565 * s;
3025  b = 0.18508 - 0.11764 * s;
3026  c = -0.0014153 - 0.011510 * s;
3027  d = -0.48961 + 0.18810 * s;
3028  e = 0.20911 - 2.8544 * s + 14.256 *s*s;
3029  f = 2.7644 + 0.93717 * s;
3030  aa = -7.6307 + 5.6807 * s;
3031  bb = 394.58 - 541.82 * s + 200.82 *s*s;
3032 
3033  // Parameters for Q^2 > 10 GeV^2.
3034  } else {
3035 
3036  // Exponents.
3037  alpha1 = -1.8095;
3038  alpha2 = 7.9399;
3039  beta = 0.041563;
3040 
3041  // Scale dependent parameters.
3042  a = -0.54831 + 0.33412 * s;
3043  b = 0.19484 + 0.041562 * s;
3044  c = -0.39046 + 0.37194 * s;
3045  d = 0.12717 + 0.059280 * s;
3046  e = 8.7191 + 3.0194 * s;
3047  f = 4.2616 + 0.73993 * s;
3048  aa = -0.30307 + 0.29430 * s;
3049  bb = 7.2383 - 1.5995 * s;
3050  }
3051 
3052  // Point-like c-quark parametrization.
3053  return max( 0.0, ( pow(s,alpha1)*pow(y,aa)*( a + b*sqrt(y) + c*pow(y,bb) )
3054  + pow(s,alpha2)*exp( -e + sqrt( f*pow(s,beta)*log(1.0/x) ) ) )
3055  * pow(1-y,d) );
3056 }
3057 
3058 //--------------------------------------------------------------------------
3059 
3060 // Returns the point-like part of the b-quark.
3061 
3062 double CJKL::pointlikeB(double x, double s, double Q2) {
3063 
3064  //Scaled variable for b quarks with m = 4.3 GeV.
3065  double y = x + 1 - Q2/(Q2 + 73.96);
3066 
3067  // Kinematic boundary.
3068  if (y >= 1.0) return 0;
3069 
3070  // Declaration of parameters.
3071  double alpha1, alpha2, beta, a, b, c, d, e, f, aa, bb;
3072 
3073  // Parameters for Q^2 <= 100 GeV^2.
3074  if (Q2 <= 100) {
3075 
3076  // Exponents.
3077  alpha1 = 2.2849;
3078  alpha2 = 6.0408;
3079  beta = -0.11577;
3080 
3081  // Scale dependent parameters.
3082  a = -0.26971 + 0.17942 * s;
3083  b = 0.27033 - 0.18358 * s + 0.0061059 *s*s;
3084  c = 0.0022862 - 0.0016837 * s;
3085  d = 0.30807 - 0.10490 * s;
3086  e = 14.812 - 1.2977 * s;
3087  f = 1.7148 + 2.3532 * s + 0.053734 *sqrt(s);
3088  aa = 3.8140 - 1.0514 * s;
3089  bb = 2.2292 + 20.194 * s;
3090 
3091  // Parameters for Q^2 > 100 GeV^2.
3092  } else {
3093 
3094  // Exponents.
3095  alpha1 = -5.0607;
3096  alpha2 = 16.590;
3097  beta = 0.87190;
3098 
3099  // Scale dependent parameters.
3100  a = -0.72790 + 0.36549 * s;
3101  b = -0.62903 + 0.56817 * s;
3102  c = -2.4467 + 1.6783 * s;
3103  d = 0.56575 - 0.19120 * s;
3104  e = 1.4687 + 9.6071 * s;
3105  f = 1.1706 + 0.99674 * s;
3106  aa = -0.084651 - 0.083206 * s;
3107  bb = 9.6036 - 3.4864 * s;
3108  }
3109 
3110  // Point-like b-quark parametrization.
3111  return max( 0.0, ( pow(s,alpha1)*pow(y,aa)*( a + b*sqrt(y) + c*pow(y,bb) )
3112  + pow(s,alpha2)*exp( -e + sqrt( f*pow(s,beta)*log(1.0/x) ) ) )
3113  * pow(1-y,d) );
3114 }
3115 
3116 //--------------------------------------------------------------------------
3117 
3118 // Returns the hadron-like part of the gluon pdf.
3119 
3120 double CJKL::hadronlikeG(double x, double s) {
3121 
3122  // Exponents.
3123  double alpha = 0.59945;
3124  double beta = 1.1285;
3125 
3126  // Scale dependent parameters.
3127  double a = -0.19898 + 0.57414 * s;
3128  double b = 1.9942 - 1.8306 * s;
3129  double c = -1.9848 + 1.4136 * s;
3130  double d = 0.21294 + 2.7450 * s;
3131  double e = 1.2287 + 2.4447 * s;
3132  double f = 4.9230 + 0.18526 * s;
3133  double aa = -0.34948 + 0.47058 * s;
3134 
3135  // Hadron-like gluon parametrization.
3136  return max( 0.0, pow(1-x,d)*( pow(x,aa)*( a + b*sqrt(x) + c*x )
3137  + pow(s,alpha)*exp( -e + sqrt( f*pow(s,beta)*log(1.0/x) ) ) ) );
3138 }
3139 
3140 //--------------------------------------------------------------------------
3141 
3142 // Returns the hadron-like part of the valence quarks.
3143 
3144 double CJKL::hadronlikeVal(double x, double s) {
3145 
3146  // Scale dependent parameters.
3147  double a = 1.0898 + 0.38087 * s;
3148  double b = 0.42654 - 1.2128 * s;
3149  double c = -1.6576 + 1.7075 * s;
3150  double d = 0.96155 + 1.8441 * s;
3151  double aa = 0.78391 - 0.068720 * s;
3152 
3153  // Hadron-like valence quarks parametrization.
3154  return max( 0.0, pow(1-x,d)*pow(x,aa)*a*( 1 + b*sqrt(x) + c*x ) );
3155 }
3156 
3157 //--------------------------------------------------------------------------
3158 
3159 // Returns the hadron-like part of the sea quarks.
3160 
3161 double CJKL::hadronlikeSea(double x, double s) {
3162 
3163  // Exponents.
3164  double alpha = 0.71660;
3165  double beta = 1.0497;
3166 
3167  // Scale dependent parameters.
3168  double a = 0.60478 + 0.036160 * s;
3169  double b = 4.2106 - 0.85835 * s;
3170  double d = 4.1494 + 0.34866 * s;
3171  double e = 4.5179 + 1.9219 * s;
3172  double f = 5.2812 - 0.15200 * s;
3173  double aa = 0.72289 - 0.21562 * s;
3174 
3175  // Pre-calculate the logarithm.
3176  double logx = log(1.0/x);
3177 
3178  // Hadron-like sea quark parametrization.
3179  return max( 0.0, pow(1-x,d)*pow(s,alpha)*( 1 + a*sqrt(x) + b*x )
3180  * exp( -e + sqrt( f*pow(s,beta)*logx ) )*pow(logx,-aa) );
3181 }
3182 
3183 //--------------------------------------------------------------------------
3184 
3185 // Returns the hadron-like part of the c-quarks.
3186 
3187 double CJKL::hadronlikeC(double x, double s, double Q2) {
3188 
3189  //Scaled variable for c quarks with m = 1.3 GeV.
3190  double y = x + 1 - Q2/(Q2 + 6.76);
3191 
3192  // Kinematic boundary.
3193  if (y >= 1.0) return 0;
3194 
3195  // Pre-calculate the logarithm.
3196  double logx = log(1.0/x);
3197 
3198  // Declaration of parameters.
3199  double alpha, beta, a, b, d, e, f, aa;
3200 
3201  // Parameters for Q^2 <= 10 GeV^2.
3202  if (Q2 <= 10) {
3203 
3204  // Exponents.
3205  alpha = 5.6729;
3206  beta = 1.4575;
3207 
3208  // Scale dependent parameters.
3209  a = -2586.4 + 1910.1 * s;
3210  b = 2695.0 - 1688.2 * s;
3211  d = 1.5146 + 3.1028 * s;
3212  e = -3.9185 + 11.738 * s;
3213  f = 3.6126 - 1.0291 * s;
3214  aa = 1.6248 - 0.70433 * s;
3215 
3216  // Parameters for Q^2 > 10 GeV^2.
3217  } else {
3218 
3219  // Exponents.
3220  alpha = -1.6470;
3221  beta = 0.72738;
3222 
3223  // Scale dependent parameters.
3224  a = -2.0561 + 0.75576 * s;
3225  b = 2.1266 + 0.66383 * s;
3226  d = 3.0301 - 1.7499 * s + 1.6466 *s*s;
3227  e = 4.1282 + 1.6929 * s - 0.26292 *s*s;
3228  f = 0.89599 + 1.2761 * s - 0.15061 *s*s;
3229  aa = -0.78809 + 0.90278 * s;
3230 
3231  }
3232 
3233  // Hadron-like c-quark parametrization. Note typo in the CJKL paper.
3234  return max( 0.0, pow(1-y,d)*pow(s,alpha)*( 1 + a*sqrt(y) + b*y )
3235  * exp( -e + f*sqrt( pow(s,beta)*logx ) )*pow(logx,-aa) );
3236 }
3237 
3238 //--------------------------------------------------------------------------
3239 
3240 // Returns the hadron-like part of the b-quarks.
3241 
3242 double CJKL::hadronlikeB(double x, double s, double Q2) {
3243 
3244  // Scaled variable for b quarks with m = 4.3 GeV.
3245  double y = x + 1 - Q2/(Q2 + 73.96);
3246 
3247  // Kinematic boundary.
3248  if (y >= 1.0) return 0;
3249 
3250  // Pre-calculate the logarithm.
3251  double logx = log(1.0/x);
3252 
3253  // Declaration of parameters.
3254  double alpha, beta, a, b, d, e, f, aa;
3255 
3256  // Parameters for Q^2 <= 100 GeV^2.
3257  if (Q2 <= 100) {
3258 
3259  // Exponents.
3260  alpha = -10.210;
3261  beta = -2.2296;
3262 
3263  // Scale dependent parameters.
3264  a = -99.613 + 171.25 * s;
3265  b = 492.61 - 420.45 * s;
3266  d = 3.3917 + 0.084256 * s;
3267  e = 5.6829 - 0.23571 * s;
3268  f = -2.0137 + 4.6955 * s;
3269  aa = 0.82278 + 0.081818 * s;
3270 
3271  // Parameters for Q^2 > 100 GeV^2.
3272  } else {
3273 
3274  // Exponents.
3275  alpha = 2.4198;
3276  beta = 0.40703;
3277 
3278  // Scale dependent parameters.
3279  a = -2.1109 + 1.2711 * s;
3280  b = 9.0196 - 3.6082 * s;
3281  d = 3.6455 - 4.1353 * s + 2.3615 *s*s;
3282  e = 4.6196 + 2.4212 * s;
3283  f = 0.66454 + 1.1109 * s;
3284  aa = -0.98933 + 0.42366 * s + 0.15817 *s*s;
3285  }
3286 
3287  // Hadron-like b-quark parametrization. Note typo in the CJKL paper.
3288  return max( 0.0, pow(1-y,d)*pow(s,alpha)*( 1 + a*sqrt(y) + b*y )
3289  * exp( -e + f*sqrt( pow(s,beta)*logx ) )*pow(logx,-aa) );
3290 }
3291 
3292 //==========================================================================
3293 
3294 // The LHAGrid1 class.
3295 // Codes to read files in the LHAPDF6 lhagrid1 format,
3296 // assuming that the same x grid is used for all Q subgrids.
3297 // Results are not identical with LHAPDF6, owing to different interpolation.
3298 
3299 //--------------------------------------------------------------------------
3300 
3301 // Initialize PDF: select data file and open stream.
3302 
3303 void LHAGrid1::init(string pdfWord, string xmlPath, Info* infoPtr) {
3304 
3305  // Identify whether file number or name.
3306  if (pdfWord.length() > 9 && toLower(pdfWord).substr(0,9) == "lhagrid1:")
3307  pdfWord = pdfWord.substr(9, pdfWord.length() - 9);
3308  istringstream pdfStream(pdfWord);
3309  int pdfSet = 0;
3310  pdfStream >> pdfSet;
3311 
3312  // Input is file name.
3313  string dataFile = "";
3314  if ( xmlPath[ xmlPath.length() - 1 ] != '/') xmlPath += "/";
3315  if (pdfWord[0] == '/') dataFile = pdfWord;
3316  else if (pdfSet == 0) dataFile = xmlPath + pdfWord;
3317 
3318  // Input is fit number. Current selection for NNPDF3.1 and modified NNLO.
3319  else if (pdfSet == 17) dataFile = xmlPath + "NNPDF31_lo_as_0130_0000.dat";
3320  else if (pdfSet == 18) dataFile = xmlPath + "NNPDF31_lo_as_0118_0000.dat";
3321  else if (pdfSet == 19) dataFile = xmlPath
3322  + "NNPDF31_nlo_as_0118_luxqed_0000.dat";
3323  else if (pdfSet == 20) dataFile = xmlPath
3324  + "NNPDF31_nnlo_as_0118_luxqed_0000.dat";
3325  else if (pdfSet == 21) dataFile = xmlPath + "mcpdf_test_replicas_0000.dat";
3326 
3327  // Pomeron PDFs, currently the GKG18 sets.
3328  else if (pdfSet == 112) dataFile = xmlPath + "GKG18_DPDF_FitA_0000.dat";
3329  else if (pdfSet == 113) dataFile = xmlPath + "GKG18_DPDF_FitB_0000.dat";
3330 
3331  // Open files from which grids should be read in.
3332  ifstream is( dataFile.c_str() );
3333  if (!is.good()) {
3334  printErr("Error in LHAGrid1::init: did not find data file", infoPtr);
3335  isSet = false;
3336  return;
3337  }
3338 
3339  // Initialization with a stream.
3340  init( is, infoPtr);
3341  is.close();
3342 
3343 }
3344 
3345 //--------------------------------------------------------------------------
3346 
3347 // Initialize PDF: read in data grid from stream and set up interpolation.
3348 
3349 void LHAGrid1::init(istream& is, Info* infoPtr) {
3350 
3351  // Check that data stream is available.
3352  if (!is.good()) {
3353  printErr("Error in LHAGrid1::init: cannot read from stream", infoPtr);
3354  isSet = false;
3355  return;
3356  }
3357 
3358  // Some local variables.
3359  string line;
3360  vector<string> idlines, pdflines;
3361  int nqNow, idNow, idNowMap;
3362  double xNow, qNow, pdfNow;
3363 
3364  // Skip lines of header, until ---. Probe for next subgrid in Q space.
3365  nqSub = 0;
3366  do getline( is, line);
3367  while (line.find("---") == string::npos);
3368  if (!is.good()) {
3369  printErr("Error in LHAGrid1::init: could not read data file", infoPtr);
3370  isSet = false;
3371  return;
3372  }
3373  while (getline( is, line)) {
3374  ++nqSub;
3375 
3376  // Read in x grid; save for first, check it matches for later ones.
3377  istringstream isx(line);
3378  if (nqSub == 1) {
3379  while (isx >> xNow) {
3380  xGrid.push_back( xNow);
3381  lnxGrid.push_back( log(xNow));
3382  }
3383  nx = xGrid.size();
3384  xMin = xGrid.front();
3385  xMax = xGrid.back();
3386  } else {
3387  int ixc = -1;
3388  while (isx >> xNow)
3389  if ( abs(log(xNow) - lnxGrid[++ixc]) > 1e-5) {
3390  printErr("Error in LHAGrid1::init: mismatched subgrid x spacing",
3391  infoPtr);
3392  isSet = false;
3393  return;
3394  }
3395  }
3396 
3397  // Read in Q grid; append as needed. Check that subgrids match.
3398  getline( is, line);
3399  istringstream isq(line);
3400  nqNow = 0;
3401  while (isq >> qNow) {
3402  ++nqNow;
3403  qGrid.push_back( qNow);
3404  lnqGrid.push_back( log(qNow));
3405  }
3406  if (nqSub > 1) {
3407  if (abs(qGrid[nq] / qGrid[nq-1] - 1.) > 1e-5) {
3408  printErr("Error in LHAGrid1::init: mismatched subgrid Q borders",
3409  infoPtr);
3410  isSet = false;
3411  return;
3412  }
3413  qGrid[nq-1] = 0.5 * (qGrid[nq-1] + qGrid[nq]);
3414  qGrid[nq] = qGrid[nq-1];
3415  }
3416  nq = qGrid.size();
3417  qMin = qGrid.front();
3418  qMax = qGrid.back();
3419  nqSum.push_back(nq);
3420  qDiv.push_back(qMax);
3421 
3422  // Read in and store flavour mapping and pdf data. Separator line.
3423  getline( is, line);
3424  idlines.push_back( line);
3425  for (int ixq = 0; ixq < nx * nqNow; ++ixq) {
3426  getline( is, line);
3427  pdflines.push_back( line);
3428  }
3429  getline( is, line);
3430  }
3431 
3432  // Create array big enough to hold (flavour, x, Q) grid.
3433  pdfGrid = new double**[12];
3434  for (int iid = 0; iid < 12; ++iid) {
3435  pdfGrid[iid] = new double*[nx];
3436  for (int ix = 0; ix < nx; ++ix) {
3437  pdfGrid[iid][ix] = new double[nq];
3438  for (int iq = 0; iq < nq; ++iq) pdfGrid[iid][ix][iq] = 0.;
3439  }
3440  }
3441 
3442  // Second pass through the Q subranges.
3443  int iln = -1;
3444  for (int iqSub = 0; iqSub < nqSub; ++iqSub) {
3445  vector<int> idGridMap;
3446 
3447  // Study flavour grid and decide flavour mapping.
3448  istringstream isid( idlines[iqSub] );
3449  while (isid >> idNow) {
3450  idNowMap = -1;
3451  if (idNow == 21 || idNow == 0) idNowMap = 0;
3452  if (idNow > 0 && idNow < 6) idNowMap = idNow;
3453  if (idNow < 0 && idNow > -6) idNowMap = 5 - idNow;
3454  if (idNow == 22) idNowMap = 11;
3455  idGridMap.push_back( idNowMap);
3456  }
3457  int nid = idGridMap.size();
3458 
3459  // Read in data grid, line by line.
3460  int iq0 = (iqSub == 0) ? 0 : nqSum[iqSub - 1];
3461  for (int ix = 0; ix < nx; ++ix)
3462  for (int iq = iq0; iq < nqSum[iqSub]; ++iq) {
3463  istringstream ispdf( pdflines[++iln] );
3464  for (int iid = 0; iid < nid; ++iid) {
3465  ispdf >> pdfNow;
3466  if (idGridMap[iid] >= 0) pdfGrid[idGridMap[iid]][ix][iq] = pdfNow;
3467  }
3468  }
3469  }
3470 
3471  // For extrapolation to small x: create array for b values of x^b shape.
3472  pdfSlope = new double*[12];
3473  for (int iid = 0; iid < 12; ++iid) {
3474  pdfSlope[iid] = new double[nq];
3475  for (int iq = 0; iq < nq; ++iq) { pdfSlope[iid][iq] =
3476  ( min( pdfGrid[iid][0][iq], pdfGrid[iid][1][iq]) > 1e-5)
3477  ? ( log(pdfGrid[iid][1][iq]) - log(pdfGrid[iid][0][iq]) )
3478  / (lnxGrid[1] - lnxGrid[0]) : 0.;
3479  }
3480  }
3481 
3482 }
3483 
3484 //--------------------------------------------------------------------------
3485 
3486 void LHAGrid1::xfUpdate(int , double x, double Q2) {
3487 
3488  // No PDF values if not properly set up.
3489  if (!isSet) {
3490  xg = xu = xd = xubar = xdbar = xs = xsbar = xc = xb = xgamma
3491  = xuVal = xuSea = xdVal = xdSea = 0.;
3492  return;
3493  }
3494 
3495  // Update within allowed (x, q) range.
3496  xfxevolve( x, Q2);
3497 
3498  // Then transfer to Pythia8 notation.
3499  xg = pdfVal[0];
3500  xu = pdfVal[2];
3501  xd = pdfVal[1];
3502  xubar = pdfVal[7];
3503  xdbar = pdfVal[6];
3504  xs = pdfVal[3];
3505  xsbar = pdfVal[8];
3506  xc = 0.5 * (pdfVal[4] + pdfVal[9]);
3507  xb = 0.5 * (pdfVal[5] + pdfVal[10]);
3508  xgamma = pdfVal[11];
3509 
3510  // Subdivision of valence and sea.
3511  xuVal = xu - xubar;
3512  xuSea = xubar;
3513  xdVal = xd - xdbar;
3514  xdSea = xdbar;
3515 
3516  // idSav = 9 to indicate that all flavours reset.
3517  idSav = 9;
3518 
3519 }
3520 
3521 //--------------------------------------------------------------------------
3522 
3523 void LHAGrid1::xfxevolve(double x, double Q2) {
3524 
3525  // Find if (x, Q) inside our outside grid.
3526  double q = sqrt(Q2);
3527  int inx = (x <= xMin) ? -1 : ((x >= xMax) ? 1 : 0);
3528  int inq = (q <= qMin) ? -1 : ((q >= qMax) ? 1 : 0);
3529 
3530  // Set up default for x interpolation.
3531  int minx = 0;
3532  int maxx = nx - 1;
3533  int m3x = 0;
3534  double wx[4] = {1., 1., 1., 1.};
3535 
3536  // Find grid value on either side of x.
3537  if (inx == 0) {
3538  int midx;
3539  while (maxx - minx > 1) {
3540  midx = (minx + maxx) / 2;
3541  if (x < xGrid[midx]) maxx = midx;
3542  else minx = midx;
3543  }
3544 
3545  // Weights for cubic interpolation in ln(x).
3546  double lnx = log(x);
3547  if (minx == 0) m3x = 0;
3548  else if (maxx == nx - 1) m3x = nx - 4;
3549  else m3x = minx - 1;
3550  for (int i3 = 0; i3 < 4; ++i3)
3551  for (int j = 0; j < 4; ++j) if (j != i3)
3552  wx[i3] *= (lnx - lnxGrid[m3x+j]) / (lnxGrid[m3x+i3] - lnxGrid[m3x+j]);
3553  }
3554 
3555  // Find q subgrid and set up default for q interpolation.
3556  int iqDiv = 0;
3557  for (int iqSub = 1; iqSub < nqSub; ++iqSub)
3558  if (q > qDiv[iqSub - 1]) iqDiv = iqSub;
3559  int minS = (iqDiv == 0) ? 0 : nqSum[iqDiv - 1];
3560  int maxS = nqSum[iqDiv] - 1;
3561  int minq = minS;
3562  int maxq = maxS;
3563  int n3q = 4;
3564  int m3q = 0.;
3565  double wq[4] = {1., 1., 1., 1.};
3566 
3567  // Find grid value on either side of q.
3568  if (inq == 0) {
3569  int midq;
3570  while (maxq - minq > 1) {
3571  midq = (minq + maxq) / 2;
3572  if (q < qGrid[midq]) maxq = midq;
3573  else minq = midq;
3574  }
3575 
3576  // Weights for linear or cubic interpolation in ln(q).
3577  double lnq = log(q);
3578  if (maxS - minS < 3) {
3579  n3q = 2;
3580  m3q = minq;
3581  wq[1] = (lnq - lnqGrid[minq]) / (lnqGrid[maxq] - lnqGrid[minq]);
3582  wq[0] = 1. - wq[1];
3583  } else {
3584  if (minq == minS) m3q = minS;
3585  else if (maxq == maxS) m3q = maxS - 3;
3586  else m3q = minq - 1;
3587  for (int i3 = 0; i3 < 4; ++i3)
3588  for (int j = 0; j < 4; ++j) if (j != i3)
3589  wq[i3] *= (lnq - lnqGrid[m3q+j]) / (lnqGrid[m3q+i3] - lnqGrid[m3q+j]);
3590  }
3591 
3592  // Freeze at border of q range.
3593  } else {
3594  n3q = 1;
3595  if (inq == 1) m3q = nq - 1;
3596  }
3597 
3598  // Interpolate between grid elements, normally bicubic, or simpler in ln(q).
3599  for (int iid = 0; iid < 12; ++iid) pdfVal[iid] = 0.;
3600  if (inx == 0) {
3601  for (int iid = 0; iid < 12; ++iid)
3602  for (int i3x = 0; i3x < 4; ++i3x)
3603  for (int i3q = 0; i3q < n3q; ++i3q)
3604  pdfVal[iid] += wx[i3x] * wq[i3q] * pdfGrid[iid][m3x+i3x][m3q+i3q];
3605 
3606  // Special: extrapolate to small x. (Let vanish at large x, so no such code.)
3607  } else if (inx == -1) {
3608  for (int iid = 0; iid < 12; ++iid)
3609  for (int i3q = 0; i3q < n3q; ++i3q)
3610  pdfVal[iid] += wq[i3q] * pdfGrid[iid][0][m3q+i3q]
3611  * (doExtraPol ? pow( x / xMin, pdfSlope[iid][m3q+i3q]) : 1.);
3612  }
3613 
3614 }
3615 
3616 //==========================================================================
3617 
3618 // Convolution with photon flux from leptons and photon PDFs.
3619 // Contains a pointer to a photon PDF set and samples the
3620 // convolution integral event-by-event basis.
3621 // Includes also a overestimate for the PDF set in order to set up
3622 // the phase-space sampling correctly.
3623 
3624 // Constants related to the fit.
3625 const double Lepton2gamma::ALPHAEM = 0.007297353080;
3626 const double Lepton2gamma::Q2MIN = 1.;
3627 
3628 //--------------------------------------------------------------------------
3629 
3630 // Update PDFs and sample a value for x_gamma.
3631 
3632 void Lepton2gamma::xfUpdate(int , double x, double Q2) {
3633 
3634  // Find the maximum x value at given Q2max and sqrt(s).
3635  double sCM = infoPtr->s();
3636  double xGamMax = ( 2. - 2. * Q2max / sCM - 8. * m2lepton / sCM )
3637  / ( 1. + sqrt( (1. + 4. * m2lepton / Q2max) * (1. - 4. * m2lepton/sCM) ) );
3638 
3639  // If outside allowed x values set PDFs to zero.
3640  if ( x > xGamMax ) {
3641  xg = 0.;
3642  xd = 0.;
3643  xu = 0.;
3644  xs = 0.;
3645  xc = 0.;
3646  xb = 0.;
3647  xubar = 0.;
3648  xdbar = 0.;
3649  xsbar = 0.;
3650  xGm = 1.;
3651  return;
3652  }
3653 
3654  // Pre-calculate some logs.
3655  double log2x = pow2( log( Q2max / (m2lepton * pow2(x)) ) );
3656  double log2xMax = pow2( log( Q2max / (m2lepton * pow2(xGamMax)) ) );
3657 
3658  // Sample x_gamma.
3659  if ( sampleXgamma) {
3660  xGm = sqrt( (Q2max / m2lepton)
3661  * exp( -sqrt( log2x + rndmPtr->flat() * (log2xMax - log2x) ) ) );
3662  }
3663 
3664  // Evaluate the PDFs at x/x_gamma.
3665  double xInGamma = x/xGm;
3666  double xgGm = gammaPDFPtr->xf(21, xInGamma, Q2);
3667  double xdGm = gammaPDFPtr->xf(1 , xInGamma, Q2);
3668  double xuGm = gammaPDFPtr->xf(2 , xInGamma, Q2);
3669  double xsGm = gammaPDFPtr->xf(3 , xInGamma, Q2);
3670  double xcGm = gammaPDFPtr->xf(4 , xInGamma, Q2);
3671  double xbGm = gammaPDFPtr->xf(5 , xInGamma, Q2);
3672 
3673  // Calculate the Q^2_min for sampled x_gamma.
3674  double m2s = 4. * m2lepton / sCM;
3675  double Q2min = 2. * m2lepton * pow2(xGm)
3676  / ( 1. - xGm - m2s + sqrt(1. - m2s) * sqrt( pow2(1. - xGm) - m2s ) );
3677 
3678  // Correct with weight.
3679  double alphaLog = (ALPHAEM / (2. * M_PI)) * (1. + pow2(1. - xGm) )
3680  * 0.25 * (log2x - log2xMax) * log(Q2max / Q2min)
3681  / log( Q2max / ( m2lepton * pow2(xGm) ) );
3682 
3683  // Calculate the PDF value.
3684  xg = alphaLog * xgGm;
3685  xd = alphaLog * xdGm;
3686  xu = alphaLog * xuGm;
3687  xs = alphaLog * xsGm;
3688  xc = alphaLog * xcGm;
3689  xb = alphaLog * xbGm;
3690  xubar = xu;
3691  xdbar = xd;
3692  xsbar = xs;
3693 
3694  // Photon inside electron not currently implemented (Use point-like lepton).
3695  xgamma = 0;
3696 
3697  // idSav = 9 to indicate that all flavours reset.
3698  idSav = 9;
3699 
3700 }
3701 
3702 //--------------------------------------------------------------------------
3703 
3704 // Approximate the maximum of convoluted PDF to correctly set up the
3705 // sampling of the phase space.
3706 
3707 double Lepton2gamma::xfMax(int id, double x, double Q2) {
3708 
3709  // Find the maximum x value at given Q2max and sqrt(s).
3710  double sCM = infoPtr->s();
3711  double xGamMax = ( 2. - 2. * Q2max / sCM - 8. * m2lepton / sCM )
3712  / ( 1. + sqrt( (1. + 4. * m2lepton / Q2max) * (1. - 4. * m2lepton/sCM) ) );
3713 
3714  // Set PDFs to zero outside allowed x values.
3715  if ( x > xGamMax ) return 0;
3716 
3717  // Pre-calculate some logs.
3718  double log2x = pow2( log( Q2max / (m2lepton * pow2(x)) ) );
3719  double log2xMax = pow2( log( Q2max / (m2lepton * pow2(xGamMax)) ) );
3720 
3721  // Find approximate x-behaviour for each flavour. Optimized for CJKL.
3722  double xApprox = 0.;
3723  int idAbs = abs(id);
3724  if (idAbs == 21 || idAbs == 0) xApprox = 2.35;
3725  else if (idAbs == 1) xApprox = (pow(x, 0.2) + pow(1. - x, -0.15)) * 0.8;
3726  else if (idAbs == 2) xApprox = (pow(x, 1.0) + pow(1. - x, -0.4)) * 0.4;
3727  else if (idAbs == 3) xApprox = (pow(x, 0.2) + pow(1. - x, -0.5)) * 0.5;
3728  else if (idAbs == 4) xApprox = (pow(x, 1.0) + pow(1. - x, -0.4)) * 0.7;
3729  else if (idAbs == 5) xApprox = (pow(x, 0.2) + pow(1. -x, -0.5)) * 0.5;
3730  else xApprox = 0.;
3731 
3732  // Direct photons in usual lepton PDFs.
3733  if ( idAbs == 22 ) return 0;
3734 
3735  // Return the approximation.
3736  return (ALPHAEM / (2. * M_PI)) * (log2x - log2xMax) * 0.5
3737  * gammaPDFPtr->xf(id, x, Q2) / xApprox;
3738 }
3739 
3740 //--------------------------------------------------------------------------
3741 
3742 // Return PDF without sampling x_gamma values to compute cross section with
3743 // rescaled sHat. Not very elegant but no need to modify the xfUpdate call.
3744 
3745 double Lepton2gamma::xfSame(int id, double x, double Q2) {
3746  sampleXgamma = false;
3747  xfUpdate(id, x, Q2);
3748  double xfNow = xf(id, x, Q2);
3749  sampleXgamma = true;
3750  return xfNow;
3751 }
3752 
3753 //==========================================================================
3754 
3755 // Approximated photon flux that used for process sampling with external flux.
3756 
3757 const double EPAexternal::ALPHAEM = 0.007297353080;
3758 
3759 // Initilaize kinematics and find the normalization.
3760 
3761 void EPAexternal::init() {
3762 
3763  // Collision kinematics.
3764  double sCM = pow2(infoPtr->eCM());
3765  double m2s = 4. * m2 / sCM;
3766 
3767  // Photon kinematics.
3768  xMin = pow2(settingsPtr->parm("Photon:Wmin")) / sCM;
3769  xMax = 1.0;
3770  Q2min = 2. * m2 * pow2(xMin) / ( 1. - xMin - m2s
3771  + sqrt(1. - m2s) * sqrt( pow2(1. - xMin) - m2s) );
3772  Q2max = settingsPtr->parm("Photon:Q2max");
3773  bool sampleQ2 = settingsPtr->flag("Photon:sampleQ2");
3774 
3775  // Initial values for normalization.
3776  double ratio, ratioMax = 0.0;
3777  norm = 1.0;
3778 
3779  // Scan through x and Q2 grid to find normalization.
3780  // Mainly required for flux from heavy ions with large charge.
3781  for (int i = 0; i < 10; ++i) {
3782  double xi = xMin + (xMax - xMin)*i/(10.);
3783  for (int j = 0; j < 10; ++j) {
3784  double Q2j = Q2min * exp( log(Q2max/Q2min)*j/(10. - 1.0));
3785 
3786  // When not sampling virtuality use Q2-integrated flux.
3787  if (sampleQ2) ratio = xfFlux(22,xi,Q2j) / xfApprox(22,xi,Q2j);
3788  else ratio = xfFlux(22,xi,Q2j) / xf(22,xi,Q2j);
3789 
3790  // Save the largest value.
3791  if (ratio > ratioMax) ratioMax = ratio;
3792  }
3793  }
3794 
3795  // Store the found normalization.
3796  norm = ratioMax;
3797 
3798 }
3799 
3800 //--------------------------------------------------------------------------
3801 
3802 // Approximate the differential photon flux with alphaEM/PI/x/Q2.
3803 // Derived from EPA for leptons but provides leading (small-x)
3804 // behaviour for hadrons as well.
3805 
3806 void EPAexternal::xfUpdate(int , double x, double Q2) {
3807 
3808  // Calculate (Q2-integrated) approximation for xfGamma.
3809  double alphaLog = norm * ALPHAEM / M_PI * log (Q2max/Q2min);
3810 
3811  // Integrated in Q2, to be used for direct process sampling.
3812  xgamma = alphaLog;
3813 
3814  // Approximate the convolution with photon PDFs.
3815  if (gammaPDFPtr != 0) {
3816 
3817  // To preserve x/xGamma < 1.
3818  xHadr = x;
3819 
3820  // Multiply the approximated flux with PDFs.
3821  double alphaLogX = alphaLog * log (xMax / xHadr);
3822  xg = alphaLogX * gammaPDFPtr->xf(21, x, Q2);
3823  xd = alphaLogX * gammaPDFPtr->xf( 1, x, Q2);
3824  xu = alphaLogX * gammaPDFPtr->xf( 2, x, Q2);
3825  xs = alphaLogX * gammaPDFPtr->xf( 3, x, Q2);
3826  xc = alphaLogX * gammaPDFPtr->xf( 4, x, Q2);
3827  xb = alphaLogX * gammaPDFPtr->xf( 5, x, Q2);
3828  xdbar = xd;
3829  xubar = xu;
3830  xsbar = xs;
3831  }
3832 
3833  // idSav = 9 to indicate that all flavours reset.
3834  idSav = 9;
3835 
3836 }
3837 
3838 //--------------------------------------------------------------------------
3839 
3840 // The approximated photon flux x*f^{gamma}(x,Q2).
3841 
3842 double EPAexternal::xfApprox(int , double , double Q2) {
3843 
3844  // Differetial in Q2.
3845  return norm * ALPHAEM / M_PI / Q2;
3846 }
3847 
3848 //--------------------------------------------------------------------------
3849 
3850 // Accurate flux, provided externally.
3851 
3852 double EPAexternal::xfFlux(int id, double x, double Q2) {
3853 
3854  // The external flux, check that pointer exists.
3855  if ( gammaFluxPtr != 0 ) return gammaFluxPtr->xf(id, x, Q2);
3856  else return 0.;
3857 }
3858 
3859 //--------------------------------------------------------------------------
3860 
3861 // Photon PDFs used for the convolution with the flux.
3862 
3863 double EPAexternal::xfGamma(int id, double x, double Q2) {
3864 
3865  // Return xf from the photon PDF.
3866  if ( gammaPDFPtr != 0 ) return gammaPDFPtr->xf(id, x, Q2);
3867  else return 0.;
3868 }
3869 
3870 //==========================================================================
3871 
3872 // Inherited class for nuclear PDFs. Needs a proton PDF as a baseline.
3873 
3874 void nPDF::initNPDF(PDF* protonPDFPtrIn) {
3875 
3876  // Derive mass number and number of protons.
3877  a = (idBeam/10) % 1000;
3878  z = (idBeam/10000) % 1000;
3879 
3880  // Normalized number of protons and neutrons in nuclei.
3881  resetMode();
3882 
3883  // Initialize proton PDF pointer.
3884  protonPDFPtr = protonPDFPtrIn;
3885 
3886  // No modifications yet.
3887  ruv = 1.;
3888  rdv = 1.;
3889  ru = 1.;
3890  rd = 1.;
3891  rs = 1.;
3892  rc = 1.;
3893  rb = 1.;
3894  rg = 1.;
3895 }
3896 
3897 //--------------------------------------------------------------------------
3898 
3899 // Updates the nPDF using provided proton PDF and nuclear modification.
3900 
3901 void nPDF::xfUpdate(int id, double x, double Q2) {
3902 
3903  if (protonPDFPtr == 0) {
3904  printErr("Error in nPDF: No free proton PDF pointer set.");
3905  return;
3906  }
3907 
3908  // Update the proton PDFs and nuclear modifications.
3909  this->rUpdate(id, x, Q2);
3910 
3911  // u(bar) and d(bar) pdfs for proton.
3912  double xfd = protonPDFPtr->xf( 1, x, Q2);
3913  double xfu = protonPDFPtr->xf( 2, x, Q2);
3914  double xfdb = protonPDFPtr->xf(-1, x, Q2);
3915  double xfub = protonPDFPtr->xf(-2, x, Q2);
3916 
3917  // Neutron nPDFs using isospin symmetry.
3918  xd = za * (rdv * (xfd - xfdb) + rd * xfdb)
3919  + na * (ruv * (xfu - xfub) + ru * xfub);
3920  xu = za * (ruv * (xfu - xfub) + ru * xfub)
3921  + na * (rdv * (xfd - xfdb) + rd * xfdb);
3922  xdbar = za * xfdb * rd + na * xfub * ru;
3923  xubar = za * xfub * ru + na * xfdb * rd;
3924  xs = rs * protonPDFPtr->xf( 3, x, Q2);
3925  xsbar = rs * protonPDFPtr->xf(-3, x, Q2);
3926  xc = rc * protonPDFPtr->xf( 4, x, Q2);
3927  xb = rb * protonPDFPtr->xf( 5, x, Q2);
3928  xg = rg * protonPDFPtr->xf(21, x, Q2);
3929  xgamma = 0.;
3930 
3931  // idSav = 9 to indicate that all flavours reset.
3932  idSav = 9;
3933 
3934 }
3935 
3936 //==========================================================================
3937 
3938 // Nuclear modifications of the PDFs from EPS09 fit, either LO or NLO.
3939 // Ref: K.J. Eskola, H. Paukkunen and C.A. Salgado, JHEP 0904 (2009) 065.
3940 // Grids files of different nuclei can be found from
3941 // https://www.jyu.fi/science/en/physics/research/highenergy/urhic/npdfs/eps09
3942 
3943 // Constants related to the fit.
3944 const double EPS09::Q2MIN = 1.69;
3945 const double EPS09::Q2MAX = 1000000.;
3946 const double EPS09::XMIN = 0.000001;
3947 const double EPS09::XMAX = 1.;
3948 const double EPS09::XCUT = 0.1;
3949 const int EPS09::XSTEPS = 50;
3950 const int EPS09::Q2STEPS = 50;
3951 
3952 //--------------------------------------------------------------------------
3953 
3954 // Initialize EPS09 nPDFs with given order (1=LO, 2=NLO) and error set.
3955 
3956 void EPS09::init(int iOrderIn, int iSetIn, string xmlPath) {
3957 
3958  // Save the order and error set number.
3959  iOrder = iOrderIn;
3960  iSet = iSetIn;
3961 
3962  // Select which data file to read for current fit.
3963  if (xmlPath[ xmlPath.length() - 1 ] != '/') xmlPath += "/";
3964  stringstream fileSS;
3965 
3966  if (iOrder == 1) fileSS << xmlPath << "EPS09LOR_" << getA();
3967  if (iOrder == 2) fileSS << xmlPath << "EPS09NLOR_" << getA();
3968  string gridFile = fileSS.str();
3969 
3970  // Open grid file.
3971  ifstream fileStream( gridFile.c_str() );
3972  if (!fileStream.good()) {
3973  printErr("Error in EPS09::init: did not find grid file " + gridFile,
3974  infoPtr);
3975  isSet = false;
3976  return;
3977  }
3978 
3979  // Dump additional grid information here.
3980  double dummy;
3981 
3982  // Read in the interpolation grid.
3983  for (int i = 0;i < 31; ++i) {
3984  for (int j = 0;j < 51; ++j) {
3985  fileStream >> dummy;
3986  for (int k = 0;k < 51; ++k) {
3987  for (int l = 0;l < 8; ++l) fileStream >> grid[i][j][k][l];
3988  }
3989  }
3990  }
3991  fileStream.close();
3992 
3993 }
3994 
3995 //--------------------------------------------------------------------------
3996 
3997 // Interpolation from the grid.
3998 
3999 void EPS09::rUpdate(int , double x, double Q2) {
4000 
4001  // Freeze the x and Q2 values if outside the grid.
4002  if( x < XMIN ) x = XMIN;
4003  if( x > XMAX ) x = XMAX;
4004  if( Q2 < Q2MIN ) Q2 = Q2MIN;
4005  if( Q2 > Q2MAX ) Q2 = Q2MAX;
4006 
4007  // Calculate the position in log(log Q^2) grid:
4008  double dQ2 = Q2STEPS * log( log(Q2) / log(Q2MIN) )
4009  / log( log(Q2MAX) / log(Q2MIN) );
4010  int iQ2 = int(dQ2);
4011 
4012  // Set the Q2 index to interval [1,...,49].
4013  if ( iQ2 < 1 ) iQ2 = 1;
4014  else if ( iQ2 > Q2STEPS - 1 ) iQ2 = Q2STEPS - 1;
4015 
4016  // Calculate the three nearest points in log(log Q^2) grid.
4017  double Q2Near[3];
4018  Q2Near[0] = iQ2 - 1;
4019  Q2Near[1] = iQ2 + 0;
4020  Q2Near[2] = iQ2 + 1;
4021 
4022  // Interpolate the grid values.
4023  for ( int iFlavour = 0; iFlavour < 8; ++iFlavour) {
4024 
4025  // Calculate the position in log(x) or x grid.
4026  int ix;
4027  int nxlog = XSTEPS/2;
4028  int nxlin = XSTEPS - nxlog;
4029  if ( x <= XCUT ) ix = int( nxlog * log(x / XMIN) / log( XCUT / XMIN ) );
4030  else ix = int( ( x - XCUT ) * nxlin / ( XMAX - XCUT ) + nxlog );
4031 
4032  // Set the x-index to interval [1,...,48].
4033  if ( ix < 1 ) ix = 1;
4034 
4035  // Do not use the last grid points for interpolation.
4036  if ( iFlavour == 0 || iFlavour == 1 || iFlavour == 7)
4037  if ( ix >= XSTEPS - 4 ) ix = XSTEPS - 4;
4038  if ( iFlavour > 1 && iFlavour < 7 )
4039  if ( ix >= XSTEPS - 7 ) ix = XSTEPS - 7;
4040 
4041  // Calculate the four nearest points in log-x or lin-x grid.
4042  double xNear[4];
4043  for(int i = 0;i < 4;i++) {
4044  if ( ix - 1 + i < nxlog ) {
4045  xNear[i] = XMIN * exp( ( double( ix - 1 + i ) / nxlog )
4046  * log( XCUT / XMIN ) );
4047  } else {
4048  xNear[i] = ( double( ix - 1 + i - nxlog) / nxlin )
4049  * ( XMAX - XCUT ) + XCUT;
4050  }
4051  }
4052 
4053  // Grid points used for interpolation.
4054  double xGrid[4];
4055  double Q2Grid[3];
4056 
4057  // Read in the relevant values from table and interpolate in x.
4058  for ( int j = 0; j < 3; ++j) {
4059  xGrid[0] = grid[iSet - 1][iQ2 - 1 + j][ix - 1][iFlavour];
4060  xGrid[1] = grid[iSet - 1][iQ2 - 1 + j][ix][iFlavour];
4061  xGrid[2] = grid[iSet - 1][iQ2 - 1 + j][ix + 1][iFlavour];
4062  xGrid[3] = grid[iSet - 1][iQ2 - 1 + j][ix + 2][iFlavour];
4063  Q2Grid[j] = polInt(xGrid, xNear, 4, x);
4064  }
4065 
4066  // Interpolate in Q2.
4067  double result = polInt(Q2Grid, Q2Near, 3, dQ2);
4068 
4069  // Save the values.
4070  if (iFlavour == 0) ruv = max(result, 0.);
4071  if (iFlavour == 1) rdv = max(result, 0.);
4072  if (iFlavour == 2) ru = max(result, 0.);
4073  if (iFlavour == 3) rd = max(result, 0.);
4074  if (iFlavour == 4) rs = max(result, 0.);
4075  if (iFlavour == 5) rc = max(result, 0.);
4076  if (iFlavour == 6) rb = max(result, 0.);
4077  if (iFlavour == 7) rg = max(result, 0.);
4078 
4079  }
4080 
4081 }
4082 
4083 //--------------------------------------------------------------------------
4084 
4085 // Polynomial interpolation with Newton's divided difference method.
4086 
4087 double EPS09::polInt(double* fi, double* xi, int n, double x) {
4088 
4089  for(int i = 1;i < n;i++) {
4090  for(int j = n-1;j > i - 1;j--) {
4091  fi[j] = (fi[j] - fi[j-1])/(xi[j] - xi[j-i]);
4092  }
4093  }
4094  double f = fi[n-1];
4095  for(int i = n-2;i > -1;i--) {
4096  f = (x - xi[i])*f + fi[i];
4097  }
4098 
4099  return f;
4100 
4101 }
4102 
4103 //==========================================================================
4104 
4105 // Nuclear modifications of the PDFs from EPPS16 NLO fit.
4106 // Ref: K.J. Eskola, P. Paakkinen, H. Paukkunen and C.A. Salgado,
4107 // Eur.Phys.J. C77 (2017) no.3, 163 [arXiv:1612.05741]
4108 // Grids files for different nuclei can be found from
4109 // https://www.jyu.fi/science/en/physics/research/highenergy/urhic/npdfs/
4110 // epps16-nuclear-pdfs.
4111 
4112 // Constants related to the fit.
4113 const double EPPS16::Q2MIN = 1.69;
4114 const double EPPS16::Q2MAX = 100000000.;
4115 const double EPPS16::XMIN = 0.0000001;
4116 const double EPPS16::XMAX = 1.;
4117 const int EPPS16::XSTEPS = 80;
4118 const int EPPS16::Q2STEPS = 30;
4119 const int EPPS16::NINTQ2 = 4;
4120 const int EPPS16::NINTX = 4;
4121 const int EPPS16::NSETS = 41;
4122 
4123 //--------------------------------------------------------------------------
4124 
4125 // Initialize EPPS16 nPDFs with given order (1=LO, 2=NLO) and error set.
4126 
4127 void EPPS16::init(int iSetIn, string xmlPath) {
4128 
4129  // Save the error set number and derive useful values.
4130  iSet = iSetIn;
4131  logQ2min = log(Q2MIN);
4132  loglogQ2maxmin = log( log(Q2MAX)/logQ2min );
4133  logX2min = log(XMIN) - 2. * (1. - XMIN);
4134 
4135  // Select which data file to read for current fit.
4136  if (xmlPath[ xmlPath.length() - 1 ] != '/') xmlPath += "/";
4137  stringstream fileSS;
4138  fileSS << xmlPath << "EPPS16NLOR_" << getA();
4139  string gridFile = fileSS.str();
4140 
4141  // Open grid file.
4142  ifstream fileStream( gridFile.c_str() );
4143  if (!fileStream.good()) {
4144  printErr("Error in EPPS16::init: did not find grid file " + gridFile,
4145  infoPtr);
4146  isSet = false;
4147  return;
4148  }
4149 
4150  // Dump additional grid information here.
4151  double dummy;
4152 
4153  // Read in the interpolation grid.
4154  for (int i = 0;i < NSETS; ++i) {
4155  for (int j = 0;j < Q2STEPS+1; ++j) {
4156  fileStream >> dummy;
4157  for (int k = 0;k < XSTEPS; ++k) {
4158  for (int l = 0;l < 8; ++l) fileStream >> grid[i][j][k][l];
4159  }
4160  }
4161  }
4162  fileStream.close();
4163 
4164 }
4165 
4166 //--------------------------------------------------------------------------
4167 
4168 // Interpolation from the grid.
4169 
4170 void EPPS16::rUpdate(int , double x, double Q2) {
4171 
4172  // Freeze the x and Q2 values if outside the grid.
4173  if( x < XMIN ) x = XMIN;
4174  if( x > XMAX ) x = XMAX;
4175  if( Q2 < Q2MIN ) Q2 = Q2MIN;
4176  if( Q2 > Q2MAX ) Q2 = Q2MAX;
4177 
4178  // Do not use the points at mass threshold for interpolation.
4179  int cThreshold = 0;
4180  int bThreshold = 0;
4181 
4182  // Calculate the position in log(log Q^2) grid.
4183  double dQ2 = Q2STEPS * log( log(Q2) / logQ2min ) / loglogQ2maxmin;
4184  int iQ2 = int(dQ2);
4185 
4186  // Set the Q2 index to interval [1,...,28].
4187  if ( iQ2 < 1 ) iQ2 = 1;
4188  else if ( iQ2 > Q2STEPS - 3 ) iQ2 = Q2STEPS - 2;
4189 
4190  // Calculate the position in x grid.
4191  double dx = XSTEPS * ( 1. - (log(x) - 2. * (1. - x) ) / logX2min );
4192  int ix = int(dx);
4193 
4194  // Set the x-index interval.
4195  if ( ix < 1 ) ix = 1;
4196 
4197  // Interpolate the grid values.
4198  for ( int iFlavour = 0; iFlavour < 8; ++iFlavour) {
4199 
4200  // Do not use the last grid points for interpolation.
4201  if ( (iFlavour > 1) && (iFlavour < 7) ) {
4202  if ( ix > XSTEPS - 6 ) ix = XSTEPS - 6;
4203  } else {
4204  if ( ix > XSTEPS - 4 ) ix = XSTEPS - 4;
4205  }
4206 
4207  // Calculate the four nearest points in x grid.
4208  double xNear[4];
4209  for(int i = 0;i < 4;i++) xNear[i] = ix - 1 + i;
4210 
4211  // Reject point Q=1.3 GeV from interpoilation for charm.
4212  if ( (iFlavour == 5) && (iQ2 == 1) ) {
4213  cThreshold = iQ2;
4214  iQ2 = 2;
4215  }
4216 
4217  // Reject points Q<4.75 GeV from interpoilation for bottom.
4218  if ( (iFlavour == 6) && (iQ2 < 17) && (iQ2 > 1) ) {
4219  bThreshold = iQ2;
4220  iQ2 = 17;
4221  }
4222 
4223  // Calculate the three nearest points in log(log Q^2) grid.
4224  double Q2Near[4];
4225  for(int i = 0;i < 4;i++) Q2Near[i] = iQ2 - 1 + i;
4226 
4227  // Grid points used for interpolation.
4228  double xGrid[4];
4229  double Q2Grid[4];
4230 
4231  // Read in the relevant values from table and interpolate in x.
4232  for ( int j = 0; j < 4; ++j) {
4233  xGrid[0] = grid[iSet - 1][iQ2 - 1 + j][ix - 1][iFlavour];
4234  xGrid[1] = grid[iSet - 1][iQ2 - 1 + j][ix][iFlavour];
4235  xGrid[2] = grid[iSet - 1][iQ2 - 1 + j][ix + 1][iFlavour];
4236  xGrid[3] = grid[iSet - 1][iQ2 - 1 + j][ix + 2][iFlavour];
4237  Q2Grid[j] = polInt(xGrid, xNear, NINTX, dx);
4238  }
4239 
4240  // Interpolate in Q2.
4241  double result = polInt(Q2Grid, Q2Near, NINTQ2, dQ2);
4242 
4243  // Save the values, for b non-zero only above the mass threshold.
4244  if (iFlavour == 0) ruv = result;
4245  if (iFlavour == 1) rdv = result;
4246  if (iFlavour == 2) ru = result;
4247  if (iFlavour == 3) rd = result;
4248  if (iFlavour == 4) rs = result;
4249  if (iFlavour == 5) rc = result;
4250  if (iFlavour == 6) rb = ( sqrt(Q2) < 4.75 ) ? 0. : result;
4251  if (iFlavour == 7) rg = result;
4252 
4253  // Revert back to original interpolation points.
4254  if (cThreshold > 0) {
4255  iQ2 = cThreshold;
4256  cThreshold = 0;
4257  } else if (bThreshold > 0) {
4258  iQ2 = bThreshold;
4259  bThreshold = 0;
4260  }
4261 
4262  }
4263 
4264 }
4265 
4266 //--------------------------------------------------------------------------
4267 
4268 // Polynomial interpolation with Newton's divided difference method.
4269 
4270 double EPPS16::polInt(double* fi, double* xi, int n, double x) {
4271 
4272  for(int i = 1;i < n;i++) {
4273  for(int j = n-1;j > i - 1;j--) {
4274  fi[j] = (fi[j] - fi[j-1])/(xi[j] - xi[j-i]);
4275  }
4276  }
4277  double f = fi[n-1];
4278  for(int i = n-2;i > -1;i--) {
4279  f = (x - xi[i])*f + fi[i];
4280  }
4281 
4282  return f;
4283 
4284 }
4285 
4286 //==========================================================================
4287 
4288 } // end namespace Pythia8
void rd(int hits=0, bool clear=false)
This function redraws all hits and/or tracks from the current event.
Definition: Ed.C:69
void ae(int tracks=-1, int hits=-1)
This function is to search for the next non-empty event and draw it by looping over StBFChain (readin...
Definition: Ed.C:102
Definition: rb.hh:21