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