3
// This file is part of LHAPDF
4
// Copyright (C) 2012-2014 The LHAPDF collaboration (see AUTHORS for details)
6
#include "LHAPDF/PDF.h"
7
#include "LHAPDF/PDFSet.h"
8
#include "LHAPDF/PDFIndex.h"
9
#include "LHAPDF/Factories.h"
10
#include "LHAPDF/Utils.h"
11
#include "LHAPDF/Paths.h"
12
#include "LHAPDF/Version.h"
13
#include "LHAPDF/LHAGlue.h"
14
#include <boost/shared_ptr.hpp>
15
#include <boost/foreach.hpp>
16
#include <boost/algorithm/string.hpp>
22
// We have to create and initialise some common blocks here for backwards compatibility
29
double xmin, xmax, q2min, q2max;
34
double qcdlha4, qcdlha5;
41
namespace lhapdf_amc { //< Unnamed namespace to restrict visibility to this file
43
/// @brief PDF object storage here is a smart pointer to ensure deletion of created PDFs
45
/// NB. std::auto_ptr cannot be stored in STL containers, hence we use
46
/// boost::shared_ptr. std::unique_ptr is the nature replacement when C++11
47
/// is globally available.
48
typedef boost::shared_ptr<LHAPDF::PDF> PDFPtr;
50
/// @brief A struct for handling the active PDFs for the Fortran interface.
52
/// We operate in a string-based way, since maybe there will be sets with names, but no
53
/// index entry in pdfsets.index.
55
/// @todo Can we avoid the strings and just work via the LHAPDF ID and factory construction?
57
/// Smart pointers are used in the native map used for PDF member storage so
58
/// that they auto-delete if the PDFSetHandler that holds them goes out of
59
/// scope (i.e. is overwritten).
60
struct PDFSetHandler {
62
/// Default constructor
63
PDFSetHandler() : currentmem(0)
64
{ } //< It'll be stored in a map so we need one of these...
66
/// Constructor from a PDF set name
67
PDFSetHandler(const string& name)
73
/// Constructor from a PDF set's LHAPDF ID code
74
PDFSetHandler(int lhaid) {
75
pair<string,int> set_mem = LHAPDF::lookupPDF(lhaid);
76
// First check that the lookup was successful, i.e. it was a valid ID for the LHAPDF6 set collection
77
if (set_mem.first.empty() || set_mem.second < 0)
78
throw LHAPDF::UserError("Could not find a valid PDF with LHAPDF ID = " + LHAPDF::to_str(lhaid));
79
// Try to load this PDF (checking that the member number is in the set's range is done in mkPDF, called by loadMember)
80
setname = set_mem.first;
81
loadMember(set_mem.second);
84
/// @brief Load a new PDF member
86
/// If it's already loaded, the existing object will not be reloaded.
87
void loadMember(int mem) {
89
throw LHAPDF::UserError("Tried to load a negative PDF member ID: " + LHAPDF::to_str(mem) + " in set " + setname);
90
if (members.find(mem) == members.end())
91
members[mem] = PDFPtr(LHAPDF::mkPDF(setname, mem));
95
/// Actively delete a PDF member to save memory
96
void unloadMember(int mem) {
98
const int nextmem = (!members.empty()) ? members.begin()->first : 0;
102
/// @brief Get a PDF member
104
/// Non-const because it can secretly load the member. Not that constness
105
/// matters in a Fortran interface utility function!
106
const PDFPtr member(int mem) {
108
return members.find(mem)->second;
111
/// Get the currently active PDF member
113
/// Non-const because it can secretly load the member. Not that constness
114
/// matters in a Fortran interface utility function!
115
const PDFPtr activemember() {
116
return member(currentmem);
119
/// The currently active member in this set
125
/// Map of pointers to selected member PDFs
127
// /// It's mutable so that a "const" member-getting operation can implicitly
128
// /// load a new PDF object. Good idea / bad idea? Disabled for now.
129
// mutable map<int, PDFPtr> members;
130
map<int, PDFPtr> members;
134
/// Collection of active sets
135
static map<int, PDFSetHandler> ACTIVESETS;
137
/// The currently active set
144
string lhaglue_get_current_pdf(int nset) {
145
if (lhapdf_amc::ACTIVESETS.find(nset) == lhapdf_amc::ACTIVESETS.end())
147
lhapdf_amc::CURRENTSET = nset;
148
return lhapdf_amc::ACTIVESETS[nset].activemember()->set().name() + " (" +
149
LHAPDF::to_str(lhapdf_amc::ACTIVESETS[nset].activemember()->lhapdfID()) + ")";
156
// NEW FORTRAN INTERFACE FUNCTIONS
158
/// List of available sets
159
void lhapdf_getversion_(char* s, size_t len) {
160
strncpy(s, LHAPDF_VERSION, len);
163
/// List of available PDF sets, returned as a space-separated string
164
void lhapdf_getpdfsetlist_(char* s, size_t len) {
166
BOOST_FOREACH(const string& setname, LHAPDF::availablePDFSets()) {
167
if (!liststr.empty()) liststr += " ";
170
strncpy(s, liststr.c_str(), len);
176
// LHAPDF5 / PDFLIB COMPATIBILITY INTERFACE FUNCTIONS
181
/// LHAPDF library version
182
void getlhapdfversion_(char* s, size_t len) {
183
/// @todo Works? Need to check Fortran string return, string macro treatment, etc.
184
strncpy(s, LHAPDF_VERSION, len);
188
/// Does nothing, only provided for backward compatibility
189
void lhaprint_(int& a) { }
192
/// Set LHAPDF parameters -- does nothing in LHAPDF6!
193
void setlhaparm_(const char* par, int parlength) {
194
/// @todo Can any Fortran LHAPDF params be usefully mapped?
198
/// Return a dummy max number of sets (there is no limitation now)
199
void getmaxnumsets_(int& nmax) {
204
/// Set PDF data path
205
void setpdfpath_(const char* s, size_t len) {
206
/// @todo Works? Need to check C-string copying, null termination
210
LHAPDF::pathsPrepend(s2);
213
/// Get PDF data path (colon-separated if there is more than one element)
214
void getdatapath_(char* s, size_t len) {
215
/// @todo Works? Need to check Fortran string return, string macro treatment, etc.
217
BOOST_FOREACH(const string& path, LHAPDF::paths()) {
218
if (!pathstr.empty()) pathstr += ":";
221
strncpy(s, pathstr.c_str(), len);
225
// PDF initialisation and focus-switching
229
/// @todo Does this version actually take a *path*? What to do?
230
void initpdfsetm_(const int& nset, const char* setpath, int setpathlength) {
231
// Strip file extension for backward compatibility
232
string fullp = string(setpath, setpathlength);
233
// Remove trailing whitespace
234
fullp.erase( std::remove_if( fullp.begin(), fullp.end(), ::isspace ), fullp.end() );
235
// Use only items after the last /
236
const string pap = LHAPDF::dirname(fullp);
237
const string p = LHAPDF::basename(fullp);
238
// Prepend path to search area
239
LHAPDF::pathsPrepend(pap);
241
string path = LHAPDF::file_extn(p).empty() ? p : LHAPDF::file_stem(p);
242
/// @note We correct the misnamed CTEQ6L1/CTEQ6ll set name as a backward compatibility special case.
243
if (boost::algorithm::to_lower_copy(path) == "cteq6ll") path = "cteq6l1";
244
// Create the PDF set with index nset
245
// if (lhapdf_amc::ACTIVESETS.find(nset) == lhapdf_amc::ACTIVESETS.end())
246
lhapdf_amc::ACTIVESETS[nset] = lhapdf_amc::PDFSetHandler(path); //< @todo Will be wrong if a structured path is given
247
lhapdf_amc::CURRENTSET = nset;
249
/// Load a PDF set (non-multiset version)
250
void initpdfset_(const char* setpath, int setpathlength) {
252
initpdfsetm_(nset1, setpath, setpathlength);
256
/// Load a PDF set by name
257
void initpdfsetbynamem_(const int& nset, const char* setname, int setnamelength) {
258
// Truncate input to size setnamelength
260
p.erase(setnamelength, std::string::npos);
261
// Strip file extension for backward compatibility
262
string name = LHAPDF::file_extn(p).empty() ? p : LHAPDF::file_stem(p);
263
// Remove trailing whitespace
264
name.erase( std::remove_if( name.begin(), name.end(), ::isspace ), name.end() );
265
/// @note We correct the misnamed CTEQ6L1/CTEQ6ll set name as a backward compatibility special case.
266
if (boost::algorithm::to_lower_copy(name) == "cteq6ll") name = "cteq6l1";
267
// Create the PDF set with index nset
268
// if (lhapdf_amc::ACTIVESETS.find(nset) == lhapdf_amc::ACTIVESETS.end())
269
lhapdf_amc::ACTIVESETS[nset] = lhapdf_amc::PDFSetHandler(name);
270
// Update current set focus
271
lhapdf_amc::CURRENTSET = nset;
273
/// Load a PDF set by name (non-multiset version)
274
void initpdfsetbyname_(const char* setname, int setnamelength) {
276
initpdfsetbynamem_(nset1, setname, setnamelength);
280
/// Load a PDF in current set
281
void initpdfm_(const int& nset, const int& nmember) {
282
if (lhapdf_amc::ACTIVESETS.find(nset) == lhapdf_amc::ACTIVESETS.end())
283
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
284
lhapdf_amc::ACTIVESETS[nset].loadMember(nmember);
285
// Update current set focus
286
lhapdf_amc::CURRENTSET = nset;
288
/// Load a PDF in current set (non-multiset version)
289
void initpdf_(const int& nmember) {
291
initpdfm_(nset1, nmember);
295
/// Get the current set number (i.e. allocation slot index)
296
void getnset_(int& nset) {
297
nset = lhapdf_amc::CURRENTSET;
298
if (lhapdf_amc::ACTIVESETS.find(nset) == lhapdf_amc::ACTIVESETS.end())
299
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
302
/// Explicitly set the current set number (i.e. allocation slot index)
303
void setnset_(const int& nset) {
304
if (lhapdf_amc::ACTIVESETS.find(nset) == lhapdf_amc::ACTIVESETS.end())
305
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
306
lhapdf_amc::CURRENTSET = nset;
310
/// Get the current member number in slot nset
311
void getnmem_(int& nset, int& nmem) {
312
if (lhapdf_amc::ACTIVESETS.find(nset) == lhapdf_amc::ACTIVESETS.end())
313
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
314
nmem = lhapdf_amc::ACTIVESETS[nset].currentmem;
315
// Update current set focus
316
lhapdf_amc::CURRENTSET = nset;
319
/// Set the current member number in slot nset
320
void setnmem_(const int& nset, const int& nmem) {
321
if (lhapdf_amc::ACTIVESETS.find(nset) == lhapdf_amc::ACTIVESETS.end())
322
throw LHAPDF::UserError("Trying to use LHAGLUE set #" +
323
LHAPDF::to_str(nset) + " but it is not initialised");
324
lhapdf_amc::ACTIVESETS[nset].loadMember(nmem);
325
// Update current set focus
326
lhapdf_amc::CURRENTSET = nset;
331
// PDF evolution functions
333
/// Get xf(x) values for common partons from current PDF
334
void evolvepdfm_(const int& nset, const double& x, const double& q, double* fxq) {
335
if (lhapdf_amc::ACTIVESETS.find(nset) == lhapdf_amc::ACTIVESETS.end())
336
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
337
// Evaluate for the 13 LHAPDF5 standard partons (-6..6)
338
for (size_t i = 0; i < 13; ++i) {
340
fxq[i] = lhapdf_amc::ACTIVESETS[nset].activemember()->xfxQ(i-6, x, q);
341
} catch (const exception& e) {
345
// Update current set focus
346
lhapdf_amc::CURRENTSET = nset;
348
/// Get xf(x) values for common partons from current PDF (non-multiset version)
349
void evolvepdf_(const double& x, const double& q, double* fxq) {
351
evolvepdfm_(nset1, x, q, fxq);
354
// PDF evolution functions
355
// NEW BY MZ to evolve one single parton
357
/// Get xf(x) values for common partons from current PDF
358
void evolvepartm_(const int& nset, const int& ipart, const double& x, const double& q, double& fxq) {
359
if (lhapdf_amc::ACTIVESETS.find(nset) == lhapdf_amc::ACTIVESETS.end())
360
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
361
int ipart_copy; // this is to deal with photons, which are labeled 7 in MG5aMC
363
if (ipart==7) ipart_copy = 22;
365
fxq = lhapdf_amc::ACTIVESETS[nset].activemember()->xfxQ(ipart_copy, x, q);
366
} catch (const exception& e) {
369
// Update current set focus
370
lhapdf_amc::CURRENTSET = nset;
372
/// Get xf(x) values for common partons from current PDF (non-multiset version)
373
void evolvepart_( const int& ipart, const double& x, const double& q, double& fxq) {
375
evolvepartm_(nset1, ipart, x, q, fxq);
379
/// Determine if the current PDF has a photon flavour (historically only MRST2004QED)
380
/// @todo Function rather than subroutine?
381
/// @note There is no multiset version. has_photon will respect the current set slot.
383
return lhapdf_amc::ACTIVESETS[lhapdf_amc::CURRENTSET].activemember()->hasFlavor(22);
387
/// Get xfx values from current PDF, including an extra photon flavour
388
void evolvepdfphotonm_(const int& nset, const double& x, const double& q, double* fxq, double& photonfxq) {
389
if (lhapdf_amc::ACTIVESETS.find(nset) == lhapdf_amc::ACTIVESETS.end())
390
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
391
// First evaluate the "normal" partons
392
evolvepdfm_(nset, x, q, fxq);
393
// Then evaluate the photon flavor (historically only for MRST2004QED)
395
photonfxq = lhapdf_amc::ACTIVESETS[nset].activemember()->xfxQ(22, x, q);
396
} catch (const exception& e) {
399
// Update current set focus
400
lhapdf_amc::CURRENTSET = nset;
402
/// Get xfx values from current PDF, including an extra photon flavour (non-multiset version)
403
void evolvepdfphoton_(const double& x, const double& q, double* fxq, double& photonfxq) {
405
evolvepdfphotonm_(nset1, x, q, fxq, photonfxq);
409
/// Get xf(x) values for common partons from a photon PDF
410
void evolvepdfpm_(const int& nset, const double& x, const double& q, const double& p2, const int& ip2, double& fxq) {
411
// Update current set focus
412
lhapdf_amc::CURRENTSET = nset;
413
throw LHAPDF::NotImplementedError("Photon structure functions are not yet supported in LHAPDF6");
415
/// Get xf(x) values for common partons from a photon PDF (non-multiset version)
416
void evolvepdfp_(const double& x, const double& q, const double& p2, const int& ip2, double& fxq) {
418
evolvepdfpm_(nset1, x, q, p2, ip2, fxq);
424
/// Get the alpha_s order for the set
425
void getorderasm_(const int& nset, int& oas) {
426
if (lhapdf_amc::ACTIVESETS.find(nset) == lhapdf_amc::ACTIVESETS.end())
427
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
428
// Set equal to the number of members for the requested set
429
oas = lhapdf_amc::ACTIVESETS[nset].activemember()->info().get_entry_as<int>("AlphaS_OrderQCD");
430
// Update current set focus
431
lhapdf_amc::CURRENTSET = nset;
433
/// Get the alpha_s order for the set (non-multiset version)
434
void getorderas_(int& oas) {
436
getorderasm_(nset1, oas);
440
/// Get the alpha_s(Q) value for set nset
441
double alphaspdfm_(const int& nset, const double& Q){
442
if (lhapdf_amc::ACTIVESETS.find(nset) == lhapdf_amc::ACTIVESETS.end())
443
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
444
return lhapdf_amc::ACTIVESETS[nset].activemember()->alphasQ(Q);
445
// Update current set focus
446
lhapdf_amc::CURRENTSET = nset;
448
/// Get the alpha_s(Q) value for the set (non-multiset version)
449
double alphaspdf_(const double& Q){
451
return alphaspdfm_(nset1, Q);
455
// Metadata functions
457
/// Get the number of error members in the set (with special treatment for single member sets)
458
void numberpdfm_(const int& nset, int& numpdf) {
459
if (lhapdf_amc::ACTIVESETS.find(nset) == lhapdf_amc::ACTIVESETS.end())
460
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
461
// Set equal to the number of members for the requested set
462
numpdf= lhapdf_amc::ACTIVESETS[nset].activemember()->info().get_entry_as<int>("NumMembers");
463
// Reproduce old LHAPDF v5 behaviour, i.e. subtract 1 if more than 1 member set
464
if (numpdf > 1) numpdf -= 1;
465
// Update current set focus
466
lhapdf_amc::CURRENTSET = nset;
468
/// Get the number of error members in the set (non-multiset version)
469
void numberpdf_(int& numpdf) {
471
numberpdfm_(nset1, numpdf);
475
/// Get the max number of active flavours
476
void getnfm_(const int& nset, int& nf) {
477
//nf = lhapdf_amc::ACTIVESETS[nset].activemember()->info().get_entry_as<int>("AlphaS_NumFlavors");
478
nf = lhapdf_amc::ACTIVESETS[nset].activemember()->info().get_entry_as<int>("NumFlavors");
479
// Update current set focus
480
lhapdf_amc::CURRENTSET = nset;
482
/// Get the max number of active flavours (non-multiset version)
483
void getnf_(int& nf) {
489
/// Get nf'th quark mass
490
void getqmassm_(const int& nset, const int& nf, double& mass) {
491
if (lhapdf_amc::ACTIVESETS.find(nset) == lhapdf_amc::ACTIVESETS.end())
492
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
493
if (nf*nf == 1) mass = lhapdf_amc::ACTIVESETS[nset].activemember()->info().get_entry_as<double>("MDown");
494
else if (nf*nf == 4) mass = lhapdf_amc::ACTIVESETS[nset].activemember()->info().get_entry_as<double>("MUp");
495
else if (nf*nf == 9) mass = lhapdf_amc::ACTIVESETS[nset].activemember()->info().get_entry_as<double>("MStrange");
496
else if (nf*nf == 16) mass = lhapdf_amc::ACTIVESETS[nset].activemember()->info().get_entry_as<double>("MCharm");
497
else if (nf*nf == 25) mass = lhapdf_amc::ACTIVESETS[nset].activemember()->info().get_entry_as<double>("MBottom");
498
else if (nf*nf == 36) mass = lhapdf_amc::ACTIVESETS[nset].activemember()->info().get_entry_as<double>("MTop");
499
else throw LHAPDF::UserError("Trying to get quark mass for invalid quark ID #" + LHAPDF::to_str(nf));
500
// Update current set focus
501
lhapdf_amc::CURRENTSET = nset;
503
/// Get nf'th quark mass (non-multiset version)
504
void getqmass_(const int& nf, double& mass) {
506
getqmassm_(nset1, nf, mass);
510
/// Get the nf'th quark threshold
511
void getthresholdm_(const int& nset, const int& nf, double& Q) {
513
if (lhapdf_amc::ACTIVESETS.find(nset) == lhapdf_amc::ACTIVESETS.end())
514
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
515
if (nf*nf == 1) Q = lhapdf_amc::ACTIVESETS[nset].activemember()->info().get_entry_as<double>("ThresholdDown");
516
else if (nf*nf == 4) Q = lhapdf_amc::ACTIVESETS[nset].activemember()->info().get_entry_as<double>("ThresholdUp");
517
else if (nf*nf == 9) Q = lhapdf_amc::ACTIVESETS[nset].activemember()->info().get_entry_as<double>("ThresholdStrange");
518
else if (nf*nf == 16) Q = lhapdf_amc::ACTIVESETS[nset].activemember()->info().get_entry_as<double>("ThresholdCharm");
519
else if (nf*nf == 25) Q = lhapdf_amc::ACTIVESETS[nset].activemember()->info().get_entry_as<double>("ThresholdBottom");
520
else if (nf*nf == 36) Q = lhapdf_amc::ACTIVESETS[nset].activemember()->info().get_entry_as<double>("ThresholdTop");
521
//else throw LHAPDF::UserError("Trying to get quark threshold for invalid quark ID #" + LHAPDF::to_str(nf));
523
getqmassm_(nset, nf, Q);
525
// Update current set focus
526
lhapdf_amc::CURRENTSET = nset;
528
/// Get the nf'th quark threshold
529
void getthreshold_(const int& nf, double& Q) {
531
getthresholdm_(nset1, nf, Q);
535
/// Print PDF set's description to stdout
536
void getdescm_(const int& nset) {
537
if (lhapdf_amc::ACTIVESETS.find(nset) == lhapdf_amc::ACTIVESETS.end())
538
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
539
cout << lhapdf_amc::ACTIVESETS[nset].activemember()->description() << endl;
540
// Update current set focus
541
lhapdf_amc::CURRENTSET = nset;
549
void getxminm_(const int& nset, const int& nmem, double& xmin) {
550
if (lhapdf_amc::ACTIVESETS.find(nset) == lhapdf_amc::ACTIVESETS.end())
551
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
552
const int activemem = lhapdf_amc::ACTIVESETS[nset].currentmem;
553
lhapdf_amc::ACTIVESETS[nset].loadMember(nmem);
554
xmin = lhapdf_amc::ACTIVESETS[nset].activemember()->info().get_entry_as<double>("XMin");
555
lhapdf_amc::ACTIVESETS[nset].loadMember(activemem);
556
// Update current set focus
557
lhapdf_amc::CURRENTSET = nset;
559
void getxmin_(const int& nmem, double& xmin) {
561
getxminm_(nset1, nmem, xmin);
565
void getxmaxm_(const int& nset, const int& nmem, double& xmax) {
566
if (lhapdf_amc::ACTIVESETS.find(nset) == lhapdf_amc::ACTIVESETS.end())
567
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
568
const int activemem = lhapdf_amc::ACTIVESETS[nset].currentmem;
569
lhapdf_amc::ACTIVESETS[nset].loadMember(nmem);
570
xmax = lhapdf_amc::ACTIVESETS[nset].activemember()->info().get_entry_as<double>("XMax");
571
lhapdf_amc::ACTIVESETS[nset].loadMember(activemem);
572
// Update current set focus
573
lhapdf_amc::CURRENTSET = nset;
575
void getxmax_(const int& nmem, double& xmax) {
577
getxmaxm_(nset1, nmem, xmax);
581
void getq2minm_(const int& nset, const int& nmem, double& q2min) {
582
if (lhapdf_amc::ACTIVESETS.find(nset) == lhapdf_amc::ACTIVESETS.end())
583
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
584
const int activemem = lhapdf_amc::ACTIVESETS[nset].currentmem;
585
lhapdf_amc::ACTIVESETS[nset].loadMember(nmem);
586
q2min = LHAPDF::sqr(lhapdf_amc::ACTIVESETS[nset].activemember()->info().get_entry_as<double>("QMin"));
587
lhapdf_amc::ACTIVESETS[nset].loadMember(activemem);
588
// Update current set focus
589
lhapdf_amc::CURRENTSET = nset;
591
void getq2min_(const int& nmem, double& q2min) {
593
getq2minm_(nset1, nmem, q2min);
597
void getq2maxm_(const int& nset, const int& nmem, double& q2max) {
598
if (lhapdf_amc::ACTIVESETS.find(nset) == lhapdf_amc::ACTIVESETS.end())
599
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
600
const int activemem = lhapdf_amc::ACTIVESETS[nset].currentmem;
601
lhapdf_amc::ACTIVESETS[nset].loadMember(nmem);
602
q2max = LHAPDF::sqr(lhapdf_amc::ACTIVESETS[nset].activemember()->info().get_entry_as<double>("QMax"));
603
lhapdf_amc::ACTIVESETS[nset].loadMember(activemem);
604
// Update current set focus
605
lhapdf_amc::CURRENTSET = nset;
607
void getq2max_(const int& nmem, double& q2max) {
609
getq2maxm_(nset1, nmem, q2max);
613
void getminmaxm_(const int& nset, const int& nmem, double& xmin, double& xmax, double& q2min, double& q2max) {
614
if (lhapdf_amc::ACTIVESETS.find(nset) == lhapdf_amc::ACTIVESETS.end())
615
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
616
const int activemem = lhapdf_amc::ACTIVESETS[nset].currentmem;
617
lhapdf_amc::ACTIVESETS[nset].loadMember(nmem);
618
xmin = lhapdf_amc::ACTIVESETS[nset].activemember()->info().get_entry_as<double>("XMin");
619
xmax = lhapdf_amc::ACTIVESETS[nset].activemember()->info().get_entry_as<double>("XMax");
620
q2min = LHAPDF::sqr(lhapdf_amc::ACTIVESETS[nset].activemember()->info().get_entry_as<double>("QMin"));
621
q2max = LHAPDF::sqr(lhapdf_amc::ACTIVESETS[nset].activemember()->info().get_entry_as<double>("QMax"));
622
lhapdf_amc::ACTIVESETS[nset].loadMember(activemem);
623
// Update current set focus
624
lhapdf_amc::CURRENTSET = nset;
626
void getminmax_(const int& nmem, double& xmin, double& xmax, double& q2min, double& q2max) {
628
getminmaxm_(nset1, nmem, xmin, xmax, q2min, q2max);
633
/// Backwards compatibility functions for LHAPDF5 calculations of
634
/// PDF uncertainties and PDF correlations (G. Watt, March 2014).
636
// subroutine GetPDFUncTypeM(nset,lMonteCarlo,lSymmetric)
637
void getpdfunctypem_(const int& nset, int& lmontecarlo, int& lsymmetric) {
638
if (lhapdf_amc::ACTIVESETS.find(nset) == lhapdf_amc::ACTIVESETS.end())
639
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
640
const string errorType = lhapdf_amc::ACTIVESETS[nset].activemember()->set().errorType();
641
if (errorType == "replicas") { // Monte Carlo PDF sets
644
} else if (errorType == "symmhessian") { // symmetric eigenvector PDF sets
647
} else { // default: assume asymmetric Hessian eigenvector PDF sets
651
// Update current set focus
652
lhapdf_amc::CURRENTSET = nset;
654
// subroutine GetPDFUncType(lMonteCarlo,lSymmetric)
655
void getpdfunctype_(int& lmontecarlo, int& lsymmetric) {
657
getpdfunctypem_(nset1, lmontecarlo, lsymmetric);
661
// subroutine GetPDFuncertaintyM(nset,values,central,errplus,errminus,errsym)
662
void getpdfuncertaintym_(const int& nset, const double* values, double& central, double& errplus, double& errminus, double& errsymm) {
663
if (lhapdf_amc::ACTIVESETS.find(nset) == lhapdf_amc::ACTIVESETS.end())
664
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
665
const size_t nmem = lhapdf_amc::ACTIVESETS[nset].activemember()->set().size()-1;
666
const vector<double> vecvalues(values, values + nmem + 1);
667
LHAPDF::PDFUncertainty err = lhapdf_amc::ACTIVESETS[nset].activemember()->set().uncertainty(vecvalues, -1);
668
central = err.central;
669
errplus = err.errplus;
670
errminus = err.errminus;
671
errsymm = err.errsymm;
672
// Update current set focus
673
lhapdf_amc::CURRENTSET = nset;
675
// subroutine GetPDFuncertainty(values,central,errplus,errminus,errsym)
676
void getpdfuncertainty_(const double* values, double& central, double& errplus, double& errminus, double& errsymm) {
678
getpdfuncertaintym_(nset1, values, central, errplus, errminus, errsymm);
682
// subroutine GetPDFcorrelationM(nset,valuesA,valuesB,correlation)
683
void getpdfcorrelationm_(const int& nset, const double* valuesA, const double* valuesB, double& correlation) {
684
if (lhapdf_amc::ACTIVESETS.find(nset) == lhapdf_amc::ACTIVESETS.end())
685
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
686
const size_t nmem = lhapdf_amc::ACTIVESETS[nset].activemember()->set().size()-1;
687
const vector<double> vecvaluesA(valuesA, valuesA + nmem + 1);
688
const vector<double> vecvaluesB(valuesB, valuesB + nmem + 1);
689
correlation = lhapdf_amc::ACTIVESETS[nset].activemember()->set().correlation(vecvaluesA,vecvaluesB);
690
// Update current set focus
691
lhapdf_amc::CURRENTSET = nset;
693
// subroutine GetPDFcorrelation(valuesA,valuesB,correlation)
694
void getpdfcorrelation_(const double* valuesA, const double* valuesB, double& correlation) {
696
getpdfcorrelationm_(nset1, valuesA, valuesB, correlation);
700
///////////////////////////////////////
703
/// REALLY OLD PDFLIB COMPATILITY FUNCTIONS
705
/// PDFLIB initialisation function
706
void pdfset_(const char* par, const double* value, int parlength) {
708
// Identify the calling program (yuck!)
710
if (my_par.find("NPTYPE") != string::npos) {
711
cout << "==== LHAPDF6 USING PYTHIA-TYPE LHAGLUE INTERFACE ====" << endl;
712
// Take PDF ID from value[2]
713
lhapdf_amc::ACTIVESETS[1] = lhapdf_amc::PDFSetHandler(value[2]+1000*value[1]);
714
} else if (my_par.find("HWLHAPDF") != string::npos) {
715
cout << "==== LHAPDF6 USING HERWIG-TYPE LHAGLUE INTERFACE ====" << endl;
716
// Take PDF ID from value[0]
717
lhapdf_amc::ACTIVESETS[1] = lhapdf_amc::PDFSetHandler(value[0]);
718
} else if (my_par.find("DEFAULT") != string::npos) {
719
cout << "==== LHAPDF6 USING DEFAULT-TYPE LHAGLUE INTERFACE ====" << endl;
720
// Take PDF ID from value[0]
721
lhapdf_amc::ACTIVESETS[1] = lhapdf_amc::PDFSetHandler(value[0]);
723
cout << "==== LHAPDF6 USING PDFLIB-TYPE LHAGLUE INTERFACE ====" << endl;
724
// Take PDF ID from value[2]
725
lhapdf_amc::ACTIVESETS[1] = lhapdf_amc::PDFSetHandler(value[2]+1000*value[1]);
728
lhapdf_amc::CURRENTSET = 1;
730
// Extract parameters for common blocks (with sensible fallback values)
731
lhapdf_amc::PDFPtr pdf = lhapdf_amc::ACTIVESETS[1].activemember();
732
w50513_.xmin = pdf->info().get_entry_as<double>("XMin", 0.0);
733
w50513_.xmax = pdf->info().get_entry_as<double>("XMax", 1.0);
734
w50513_.q2min = LHAPDF::sqr(pdf->info().get_entry_as<double>("QMin", 1.0));
735
w50513_.q2max = LHAPDF::sqr(pdf->info().get_entry_as<double>("QMax", 1.0e5));
736
w50512_.qcdl4 = pdf->info().get_entry_as<double>("AlphaS_Lambda4", 0.0);
737
w50512_.qcdl5 = pdf->info().get_entry_as<double>("AlphaS_Lambda5", 0.0);
738
lhapdfr_.qcdlha4 = pdf->info().get_entry_as<double>("AlphaS_Lambda4", 0.0);
739
lhapdfr_.qcdlha5 = pdf->info().get_entry_as<double>("AlphaS_Lambda5", 0.0);
741
// Activate legacy/compatibility LHAPDF5-type behaviour re. broken Lambda values
742
if (pdf->info().get_entry_as<bool>("Pythia6LambdaV5Compat", true)) {
743
w50512_.qcdl4 = 0.192;
744
w50512_.qcdl5 = 0.192;
745
lhapdfr_.qcdlha4 = 0.192;
746
lhapdfr_.qcdlha5 = 0.192;
750
/// PDFLIB nucleon structure function querying
751
void structm_(const double& x, const double& q,
752
double& upv, double& dnv, double& usea, double& dsea,
753
double& str, double& chm, double& bot, double& top, double& glu) {
754
lhapdf_amc::CURRENTSET = 1;
755
/// Fill (partial) parton return variables
756
lhapdf_amc::PDFPtr pdf = lhapdf_amc::ACTIVESETS[1].activemember();
757
dsea = pdf->xfxQ(-1, x, q);
758
usea = pdf->xfxQ(-2, x, q);
759
dnv = pdf->xfxQ(1, x, q) - dsea;
760
upv = pdf->xfxQ(2, x, q) - usea;
761
str = pdf->xfxQ(3, x, q);
762
chm = (pdf->hasFlavor(4)) ? pdf->xfxQ(4, x, q) : 0;
763
bot = (pdf->hasFlavor(5)) ? pdf->xfxQ(5, x, q) : 0;
764
top = (pdf->hasFlavor(6)) ? pdf->xfxQ(6, x, q) : 0;
765
glu = pdf->xfxQ(21, x, q);
768
/// PDFLIB photon structure function querying
769
void structp_(const double& x, const double& q2, const double& p2, const double& ip2,
770
double& upv, double& dnv, double& usea, double& dsea,
771
double& str, double& chm, double& bot, double& top, double& glu) {
772
throw LHAPDF::NotImplementedError("Photon structure functions are not yet supported");
775
/// PDFLIB statistics on PDF under/overflows
777
/// @note Can't do anything...
784
// LHAPDF namespace C++ compatibility code
785
#ifdef ENABLE_LHAGLUE_CXX
788
void LHAPDF::setVerbosity(LHAPDF::Verbosity noiselevel) {
789
LHAPDF::setVerbosity((int) noiselevel);
792
void LHAPDF::setPDFPath(const string& path) {
796
string LHAPDF::pdfsetsPath() {
800
int LHAPDF::numberPDF() {
805
int LHAPDF::numberPDF(int nset) {
807
numberpdfm_(nset,nmem);
811
void LHAPDF::initPDF( int memset) {
813
initpdfm_(nset1, memset);
815
void LHAPDF::initPDF(int nset, int memset) {
816
initpdfm_(nset, memset);
820
double LHAPDF::xfx(double x, double Q, int fl) {
821
vector<double> r(13);
822
evolvepdf_(x, Q, &r[0]);
825
double LHAPDF::xfx(int nset, double x, double Q, int fl) {
826
vector<double> r(13);
827
evolvepdfm_(nset, x, Q, &r[0]);
831
vector<double> LHAPDF::xfx(double x, double Q) {
832
vector<double> r(13);
833
evolvepdf_(x, Q, &r[0]);
836
vector<double> LHAPDF::xfx(int nset, double x, double Q) {
837
vector<double> r(13);
838
evolvepdfm_(nset, x, Q, &r[0]);
842
void LHAPDF::xfx(double x, double Q, double* results) {
843
evolvepdf_(x, Q, results);
845
void LHAPDF::xfx(int nset, double x, double Q, double* results) {
846
evolvepdfm_(nset, x, Q, results);
850
vector<double> LHAPDF::xfxphoton(double x, double Q) {
851
vector<double> r(13);
853
evolvepdfphoton_(x, Q, &r[0], mphoton);
854
r.push_back(mphoton);
857
vector<double> LHAPDF::xfxphoton(int nset, double x, double Q) {
858
vector<double> r(13);
860
evolvepdfphotonm_(nset, x, Q, &r[0], mphoton);
861
r.push_back(mphoton);
865
void LHAPDF::xfxphoton(double x, double Q, double* results) {
866
evolvepdfphoton_(x, Q, results, results[13]);
868
void LHAPDF::xfxphoton(int nset, double x, double Q, double* results) {
869
evolvepdfphotonm_(nset, x, Q, results, results[13]);
872
double LHAPDF::xfxphoton(double x, double Q, int fl) {
873
vector<double> r(13);
875
evolvepdfphoton_(x, Q, &r[0], mphoton);
876
if (fl == 7) return mphoton;
879
double LHAPDF::xfxphoton(int nset, double x, double Q, int fl) {
880
vector<double> r(13);
882
evolvepdfphotonm_(nset, x, Q, &r[0], mphoton);
883
if ( fl == 7 ) return mphoton;
888
void LHAPDF::initPDFSet(const string& filename, int nmem) {
889
initPDFSet(1,filename, nmem);
892
void LHAPDF::initPDFSet(int nset, const string& filename, int nmem) {
893
initPDFSetByName(nset,filename);
894
ACTIVESETS[nset].loadMember(nmem);
899
void LHAPDF::initPDFSet(const string& filename, SetType type ,int nmem) {
900
// silently ignore type
901
initPDFSet(1,filename, nmem);
904
void LHAPDF::initPDFSet(int nset, const string& filename, SetType type ,int nmem) {
905
// silently ignore type
906
initPDFSetByName(nset,filename);
907
ACTIVESETS[nset].loadMember(nmem);
911
void LHAPDF::initPDFSet(int nset, int setid, int nmem) {
912
ACTIVESETS[nset] = PDFSetHandler(setid); //
916
void LHAPDF::initPDFSet(int setid, int nmem) {
917
initPDFSet(1,setid,nmem);
921
void LHAPDF::initPDFSetByName(const string& filename) {
922
std::cout << "initPDFSetByName: " << filename << std::endl;
923
char cfilename[SIZE+1];
924
strncpy(cfilename, filename.c_str(), SIZE);
925
initpdfsetbyname_(cfilename, filename.length());
928
void LHAPDF::initPDFSetByName(int nset, const string& filename) {
929
char cfilename[SIZE+1];
930
strncpy(cfilename, filename.c_str(), SIZE);
931
initpdfsetbynamem_(nset, cfilename, filename.length());
934
void LHAPDF::initPDFSetByName(const string& filename, SetType type) {
935
//silently ignore type
936
std::cout << "initPDFSetByName: " << filename << std::endl;
937
char cfilename[SIZE+1];
938
strncpy(cfilename, filename.c_str(), SIZE);
939
initpdfsetbyname_(cfilename, filename.length());
942
void LHAPDF::initPDFSetByName(int nset, const string& filename, SetType type) {
943
//silently ignore type
944
char cfilename[SIZE+1];
945
strncpy(cfilename, filename.c_str(), SIZE);
946
initpdfsetbynamem_(nset, cfilename, filename.length());
950
void LHAPDF::getDescription() {
954
void LHAPDF::getDescription(int nset) {
955
if (ACTIVESETS.find(nset) == ACTIVESETS.end())
956
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
957
cout << ACTIVESETS[nset].activemember()->set().description() << endl;
961
double LHAPDF::alphasPDF(double Q) {
962
return LHAPDF::alphasPDF(1, Q) ;
965
double LHAPDF::alphasPDF(int nset, double Q) {
966
if (ACTIVESETS.find(nset) == ACTIVESETS.end())
967
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
969
// return alphaS for the requested set
970
return ACTIVESETS[nset].activemember()->alphasQ(Q);
974
bool LHAPDF::hasPhoton(){
975
return has_photon_();
979
int LHAPDF::getOrderAlphaS() {
980
return LHAPDF::getOrderAlphaS(1) ;
983
int LHAPDF::getOrderAlphaS(int nset) {
984
if (ACTIVESETS.find(nset) == ACTIVESETS.end())
985
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
987
// return alphaS Order for the requested set
988
return ACTIVESETS[nset].activemember()->info().get_entry_as<int>("AlphaS_OrderQCD", -1);
992
int LHAPDF::getOrderPDF() {
993
return LHAPDF::getOrderPDF(1) ;
996
int LHAPDF::getOrderPDF(int nset) {
997
if (ACTIVESETS.find(nset) == ACTIVESETS.end())
998
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
1000
// return PDF order for the requested set
1001
return ACTIVESETS[nset].activemember()->info().get_entry_as<int>("OrderQCD", -1);
1005
double LHAPDF::getLam4(int nmem) {
1006
return LHAPDF::getLam4(1, nmem) ;
1009
double LHAPDF::getLam4(int nset, int nmem) {
1010
if (ACTIVESETS.find(nset) == ACTIVESETS.end())
1011
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
1013
ACTIVESETS[nset].loadMember(nmem);
1014
return ACTIVESETS[nset].activemember()->info().get_entry_as<double>("AlphaS_Lambda4", -1.0);
1018
double LHAPDF::getLam5(int nmem) {
1019
return LHAPDF::getLam5(1, nmem) ;
1022
double LHAPDF::getLam5(int nset, int nmem) {
1023
if (ACTIVESETS.find(nset) == ACTIVESETS.end())
1024
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
1026
ACTIVESETS[nset].loadMember(nmem);
1027
return ACTIVESETS[nset].activemember()->info().get_entry_as<double>("AlphaS_Lambda5", -1.0);
1031
int LHAPDF::getNf() {
1032
return LHAPDF::getNf(1) ;
1035
int LHAPDF::getNf(int nset) {
1036
if (ACTIVESETS.find(nset) == ACTIVESETS.end())
1037
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
1039
// return alphaS Order for the requested set
1040
return ACTIVESETS[nset].activemember()->info().get_entry_as<int>("NumFlavors");
1044
double LHAPDF::getXmin(int nmem) {
1045
return LHAPDF::getXmin(1, nmem) ;
1048
double LHAPDF::getXmin(int nset, int nmem) {
1049
if (ACTIVESETS.find(nset) == ACTIVESETS.end())
1050
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
1052
// return alphaS Order for the requested set
1053
ACTIVESETS[nset].loadMember(nmem);
1054
return ACTIVESETS[nset].activemember()->info().get_entry_as<double>("XMin");
1057
double LHAPDF::getXmax(int nmem) {
1058
return LHAPDF::getXmax(1, nmem) ;
1061
double LHAPDF::getXmax(int nset, int nmem) {
1062
if (ACTIVESETS.find(nset) == ACTIVESETS.end())
1063
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
1065
// return alphaS Order for the requested set
1066
ACTIVESETS[nset].loadMember(nmem);
1067
return ACTIVESETS[nset].activemember()->info().get_entry_as<double>("XMax");
1070
double LHAPDF::getQ2min(int nmem) {
1071
return LHAPDF::getQ2min(1, nmem) ;
1074
double LHAPDF::getQ2min(int nset, int nmem) {
1075
if (ACTIVESETS.find(nset) == ACTIVESETS.end())
1076
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
1078
// return alphaS Order for the requested set
1079
ACTIVESETS[nset].loadMember(nmem);
1080
return pow(ACTIVESETS[nset].activemember()->info().get_entry_as<double>("QMin"),2);
1083
double LHAPDF::getQ2max(int nmem) {
1084
return LHAPDF::getQ2max(1,nmem) ;
1087
double LHAPDF::getQ2max(int nset, int nmem) {
1088
if (ACTIVESETS.find(nset) == ACTIVESETS.end())
1089
throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
1091
// return alphaS Order for the requested set
1092
ACTIVESETS[nset].loadMember(nmem);
1093
return pow(ACTIVESETS[nset].activemember()->info().get_entry_as<double>("QMax"),2);
1096
double LHAPDF::getQMass(int nf) {
1097
return LHAPDF::getQMass(1, nf) ;
1100
double LHAPDF::getQMass(int nset, int nf) {
1102
getqmassm_(nset, nf, mass);
1106
double LHAPDF::getThreshold(int nf) {
1107
return LHAPDF::getThreshold(1, nf) ;
1110
double LHAPDF::getThreshold(int nset, int nf) {
1112
getthresholdm_(nset, nf, thres);
1116
void LHAPDF::usePDFMember(int member) {
1120
void LHAPDF::usePDFMember(int nset, int member) {
1121
initpdfm_(nset, member);
1124
#endif // ENABLE_LHAGLUE_CXX