Merge lp:~maddevelopers/mg5amcnlo/2.6.1_lhapdf62 into lp:~mg5core2/mg5amcnlo/2.6.1

Proposed by marco zaro
Status: Merged
Merged at revision: 304
Proposed branch: lp:~maddevelopers/mg5amcnlo/2.6.1_lhapdf62
Merge into: lp:~mg5core2/mg5amcnlo/2.6.1
Diff against target: 1593 lines (+1576/-2)
2 files modified
Template/NLO/Source/PDF/makefile (+7/-2)
Template/NLO/Source/PDF/pdf_lhapdf62.cc (+1569/-0)
To merge this branch: bzr merge lp:~maddevelopers/mg5amcnlo/2.6.1_lhapdf62
Reviewer Review Type Date Requested Status
Olivier Mattelaer Approve
Rikkert Frederix Pending
Review via email: mp+331340@code.launchpad.net

Description of the change

Small changes in order to have LHAPDF 6.2 working. Compatibility with 6.1X is kept. Eventually, the pdf_lhapdf62.cc will probably be removed in favour of the LHAPDF fortran interface functions

To post a comment you must log in.
Revision history for this message
Olivier Mattelaer (olivier-mattelaer) wrote :

Hi Marco,

Thanks for this is works really nicely.
At the same time, I would prefer to move to a complete fortran interface such that we do not have to rely on that c++ script.
I will try to move on that new interface (but if you want to do it) and then we will see if we include this or not.

Cheers and thanks,

Olivier

review: Abstain
Revision history for this message
marco zaro (marco-zaro) wrote :

Hi Olivier,
in practice, what shall we do?
I would tend to make the support to LHAPDF6.2 available asap (so in 2.6.1). So I think that if we manage to have a cleaner version of the wrapper functions by the 2.6.1 release then we drop this branch, otherwise we should merge it. The changes are trivial, so merging at a later stage or even just before the release should still be ok.
What do you think?

Cheers,

Marco

Revision history for this message
Olivier Mattelaer (olivier-mattelaer) wrote :

Yes I fully agree on that.

Olivier
> On 2 Oct 2017, at 09:44, marco zaro <email address hidden> wrote:
>
> Hi Olivier,
> in practice, what shall we do?
> I would tend to make the support to LHAPDF6.2 available asap (so in 2.6.1). So I think that if we manage to have a cleaner version of the wrapper functions by the 2.6.1 release then we drop this branch, otherwise we should merge it. The changes are trivial, so merging at a later stage or even just before the release should still be ok.
> What do you think?
>
> Cheers,
>
> Marco
> --
> https://code.launchpad.net/~maddevelopers/mg5amcnlo/2.6.1_lhapdf62/+merge/331340
> You are reviewing the proposed merge of lp:~maddevelopers/mg5amcnlo/2.6.1_lhapdf62 into lp:~mg5core2/mg5amcnlo/2.6.1.

Revision history for this message
Olivier Mattelaer (olivier-mattelaer) wrote :

Did not have the time to really move forward on this, so I will merge this branch.
Thanks Marco.

Olivier

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Template/NLO/Source/PDF/makefile'
2--- Template/NLO/Source/PDF/makefile 2015-12-16 10:45:46 +0000
3+++ Template/NLO/Source/PDF/makefile 2017-09-26 09:26:40 +0000
4@@ -16,8 +16,13 @@
5 else
6 ifdef applgrid
7 PDF = pdfwrap_lhapdf.o pdf_lhapdf.o pdg2pdf_lhapdf.o opendata.o
8- else
9- PDF = pdfwrap_lhapdf.o pdf_lhapdf6.o pdg2pdf_lhapdf6.o opendata.o
10+ else # lhapdf6
11+ ifeq ($(lhapdfsubversion),1) # 6.1.X
12+ PDF = pdfwrap_lhapdf.o pdf_lhapdf6.o pdg2pdf_lhapdf6.o opendata.o
13+ else # 6.2.X
14+ CXXFLAGS+=-std=c++11
15+ PDF = pdfwrap_lhapdf.o pdf_lhapdf62.o pdg2pdf_lhapdf6.o opendata.o
16+ endif
17 endif
18 endif
19 else
20
21=== added file 'Template/NLO/Source/PDF/pdf_lhapdf62.cc'
22--- Template/NLO/Source/PDF/pdf_lhapdf62.cc 1970-01-01 00:00:00 +0000
23+++ Template/NLO/Source/PDF/pdf_lhapdf62.cc 2017-09-26 09:26:40 +0000
24@@ -0,0 +1,1569 @@
25+// -*- C++ -*-
26+//
27+// This file is part of LHAPDF
28+// Copyright (C) 2012-2016 The LHAPDF collaboration (see AUTHORS for details)
29+//
30+#include "LHAPDF/PDF.h"
31+#include "LHAPDF/PDFSet.h"
32+#include "LHAPDF/PDFIndex.h"
33+#include "LHAPDF/Factories.h"
34+#include "LHAPDF/Utils.h"
35+#include "LHAPDF/Paths.h"
36+#include "LHAPDF/Version.h"
37+#include "LHAPDF/LHAGlue.h"
38+#include <cstring>
39+
40+using namespace std;
41+
42+
43+// We have to create and initialise some common blocks here for backwards compatibility
44+struct w50512 {
45+ double qcdl4, qcdl5;
46+};
47+w50512 w50512_;
48+
49+struct w50513 {
50+ double xmin, xmax, q2min, q2max;
51+};
52+w50513 w50513_;
53+
54+struct lhapdfr {
55+ double qcdlha4, qcdlha5;
56+ int nfllha;
57+};
58+lhapdfr lhapdfr_;
59+
60+
61+
62+namespace { //< Unnamed namespace to restrict visibility to this file
63+
64+
65+ /// @brief PDF object storage here is a smart pointer to ensure deletion of created PDFs
66+ typedef std::shared_ptr<LHAPDF::PDF> PDFPtr;
67+
68+
69+ /// @brief A struct for handling the active PDFs for the Fortran interface.
70+ ///
71+ /// We operate in a string-based way, since maybe there will be sets with names, but no
72+ /// index entry in pdfsets.index.
73+ ///
74+ /// @todo Can we avoid the strings and just work via the LHAPDF ID and factory construction?
75+ ///
76+ /// Smart pointers are used in the native map used for PDF member storage so
77+ /// that they auto-delete if the PDFSetHandler that holds them goes out of
78+ /// scope (i.e. is overwritten).
79+ struct PDFSetHandler {
80+
81+ /// Default constructor
82+ ///
83+ /// It'll be stored in a map so we need one of these...
84+ PDFSetHandler() : currentmem(0)
85+ { }
86+
87+ /// Constructor from a PDF set name
88+ ///
89+ /// @note If the set name contains a member specification, i.e. myname/2,
90+ /// that member rather than the central one will be initialised and made
91+ /// current.
92+ PDFSetHandler(const string& name) {
93+ pair<string, int> set_mem = LHAPDF::lookupPDF(name);
94+ // First check that the lookup was successful, i.e. it was a valid ID for the LHAPDF6 set collection
95+ if (set_mem.first.empty() || set_mem.second < 0)
96+ throw LHAPDF::UserError("Could not find a valid PDF with string = " + name);
97+ // Try to load this PDF
98+ setname = set_mem.first;
99+ loadMember(set_mem.second);
100+ }
101+
102+ /// Constructor from a PDF set's LHAPDF ID code
103+ ///
104+ /// @note The set member given by the ID (rather than the central one) will
105+ /// be initialised and made current.
106+ PDFSetHandler(int lhaid) {
107+ pair<string,int> set_mem = LHAPDF::lookupPDF(lhaid);
108+ // First check that the lookup was successful, i.e. it was a valid ID for the LHAPDF6 set collection
109+ if (set_mem.first.empty() || set_mem.second < 0)
110+ throw LHAPDF::UserError("Could not find a valid PDF with LHAPDF ID = " + LHAPDF::to_str(lhaid));
111+ // Try to load this PDF
112+ setname = set_mem.first;
113+ loadMember(set_mem.second);
114+ }
115+
116+ /// @brief Load a new PDF member, set it to be active
117+ ///
118+ /// If it's already loaded, the existing object will not be reloaded.
119+ void loadMember(int mem) {
120+ if (mem < 0)
121+ throw LHAPDF::UserError("Tried to load a negative PDF member ID: " + LHAPDF::to_str(mem) + " in set " + setname);
122+ if (members.find(mem) == members.end())
123+ members[mem] = PDFPtr(LHAPDF::mkPDF(setname, mem));
124+ currentmem = mem;
125+ //return members[mem];
126+ }
127+
128+ /// Actively delete a PDF member to save memory, set the active member to be the next available, or 0
129+ void unloadMember(int mem) {
130+ members.erase(mem);
131+ const int nextmem = (!members.empty()) ? members.begin()->first : 0;
132+ loadMember(nextmem);
133+ }
134+
135+ /// @brief Get a PDF member, making it active
136+ ///
137+ /// Non-const because it can secretly load the member. Not that constness
138+ /// matters in a Fortran interface utility function!
139+ const PDFPtr member(int mem) {
140+ loadMember(mem);
141+ return members.find(mem)->second;
142+ }
143+
144+ /// Get the currently active PDF member
145+ ///
146+ /// Non-const because it can secretly load the member. Not that constness
147+ /// matters in a Fortran interface utility function!
148+ const PDFPtr activeMember() {
149+ return member(currentmem);
150+ }
151+
152+ /// Get the currently active PDF member
153+ ///
154+ /// Non-const because it can secretly load the member. Not that constness
155+ /// matters in a Fortran interface utility function!
156+ void setActiveMember(int mem) {
157+ loadMember(mem);
158+ }
159+
160+ /// The currently active member in this set
161+ int currentmem;
162+
163+ /// Name of this set
164+ string setname;
165+
166+ /// Map of pointers to selected member PDFs
167+ ///
168+ // /// It's mutable so that a "const" member-getting operation can implicitly
169+ // /// load a new PDF object. Good idea / bad idea? Disabled for now.
170+ // mutable map<int, PDFPtr> members;
171+ map<int, PDFPtr> members;
172+ };
173+
174+
175+ /// Collection of active sets
176+ static map<int, PDFSetHandler> ACTIVESETS;
177+
178+ /// The currently active set
179+ int CURRENTSET = 0;
180+
181+}
182+
183+
184+
185+string lhaglue_get_current_pdf(int nset) {
186+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
187+ return "NONE";
188+ CURRENTSET = nset;
189+ return ACTIVESETS[nset].activeMember()->set().name() + " (" +
190+ LHAPDF::to_str(ACTIVESETS[nset].activeMember()->lhapdfID()) + ")";
191+}
192+
193+
194+
195+namespace {
196+
197+
198+ /// C-string -> Fortran-string converter
199+ ///
200+ /// Credit: https://stackoverflow.com/questions/10163485/passing-char-arrays-from-c-to-fortran
201+ void cstr_to_fstr(const char* cstring, char* fstring, std::size_t fstring_len) {
202+ std::size_t inlen = std::strlen(cstring);
203+ std::size_t cpylen = std::min(inlen, fstring_len);
204+ // TODO: truncation error or warning
205+ //if (inlen > fstring_len) FOOOOO();
206+ std::copy(cstring, cstring+cpylen, fstring);
207+ std::fill(fstring+cpylen, fstring+fstring_len, ' ');
208+ }
209+
210+
211+ /// C++-string -> Fortran-string converter
212+ void ccstr_to_fstr(const string& ccstring, char* fstring, std::size_t fstring_len) {
213+ const char* cstring = ccstring.c_str();
214+ cstr_to_fstr(cstring, fstring, fstring_len);
215+ }
216+
217+
218+ /// Fortran-string -> C++-string converter
219+ string fstr_to_ccstr(const char* fstring, const std::size_t fstring_len, bool spcpad=false) {
220+ // Allocate space for an equivalent C-string (with an extra terminating null byte)
221+ char* s = new char[fstring_len+1];
222+ // Copy all characters and add the terminating null byte
223+ strncpy(s, fstring, fstring_len);
224+ s[fstring_len] = '\0';
225+ // Replace all trailing spaces with null bytes unless explicitly stopped
226+ if (!spcpad) {
227+ for (int i = fstring_len-1; i >= 0; --i) {
228+ if (s[i] != ' ') break;
229+ s[i] = '\0';
230+ }
231+ }
232+ string rtn(s); //< copy the result to a C++ string
233+ delete[] s; //< clean up the dynamic array
234+ return rtn;
235+ }
236+
237+
238+}
239+
240+
241+extern "C" {
242+
243+
244+ // NEW FORTRAN INTERFACE FUNCTIONS
245+
246+ /// Get the LHAPDF library version as a string
247+ void lhapdf_getversion_(char* s, size_t len) {
248+ cstr_to_fstr(LHAPDF_VERSION, s, len);
249+ }
250+
251+
252+ /// List of available PDF sets, returned as a space-separated string
253+ void lhapdf_getpdfsetlist_(char* s, size_t len) {
254+ string liststr;
255+ for (const string& setname : LHAPDF::availablePDFSets()) {
256+ if (!liststr.empty()) liststr += " ";
257+ liststr += setname;
258+ }
259+ ccstr_to_fstr(liststr, s, len);
260+ }
261+
262+
263+ /// Get PDF data path (colon-separated if there is more than one element)
264+ void lhapdf_getdatapath_(char* s, size_t len) {
265+ string pathstr;
266+ for (const string& path : LHAPDF::paths()) {
267+ if (!pathstr.empty()) pathstr += ":";
268+ pathstr += path;
269+ }
270+ ccstr_to_fstr(pathstr, s, len);
271+ }
272+
273+ /// Set PDF data path(s)
274+ void lhapdf_setdatapath_(const char* s, size_t len) {
275+ LHAPDF::setPaths(fstr_to_ccstr(s, len));
276+ }
277+
278+ /// Prepend to PDF data path
279+ void lhapdf_prependdatapath_(const char* s, size_t len) {
280+ LHAPDF::pathsPrepend(fstr_to_ccstr(s, len));
281+ }
282+
283+ /// Append to PDF data path
284+ void lhapdf_appenddatapath_(const char* s, size_t len) {
285+ LHAPDF::pathsAppend(fstr_to_ccstr(s, len));
286+ }
287+
288+
289+ //------------------
290+
291+
292+ void lhapdf_initpdfset_byname_(const int& nset, const char* name, int namelength) {
293+ const string cname = fstr_to_ccstr(name, namelength);
294+ ACTIVESETS[nset] = PDFSetHandler(cname);
295+ CURRENTSET = nset;
296+ }
297+
298+ void lhapdf_initpdfset_byid_(const int& nset, const int& lhaid) {
299+ ACTIVESETS[nset] = PDFSetHandler(lhaid);
300+ CURRENTSET = nset;
301+ }
302+
303+ void lhapdf_delpdfset_(const int& nset) {
304+ ACTIVESETS.erase(nset);
305+ CURRENTSET = 0;
306+ }
307+
308+ void lhapdf_delpdf_(const int& nset, const int& nmem) {
309+ CURRENTSET = nset;
310+ ACTIVESETS[CURRENTSET].unloadMember(nmem);
311+ }
312+
313+
314+ //------------------
315+
316+
317+ void lhapdf_hasflavor(const int& nset, const int& nmem, const int& pid, int& rtn) {
318+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
319+ throw LHAPDF::UserError("Trying to use set slot " + LHAPDF::to_str(nset) + " but it is not initialised");
320+ rtn = ACTIVESETS[nset].member(nmem)->hasFlavor(pid) ? 1 : 0;
321+ // Update current set focus
322+ CURRENTSET = nset;
323+ }
324+
325+
326+ void lhapdf_xfxq2_(const int& nset, const int& nmem, const int& pid, const double& x, const double& q2, double& xf) {
327+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
328+ throw LHAPDF::UserError("Trying to use set slot " + LHAPDF::to_str(nset) + " but it is not initialised");
329+ try {
330+ xf = ACTIVESETS[nset].member(nmem)->xfxQ2(pid, x, q2);
331+ } catch (const exception& e) {
332+ xf = 0;
333+ }
334+ // Update current set focus
335+ CURRENTSET = nset;
336+ }
337+
338+ void lhapdf_xfxq_(const int& nset, const int& nmem, const int& pid, const double& x, const double& q, double& xf) {
339+ const double q2 = q*q;
340+ lhapdf_xfxq2_(nset, nmem, pid, x, q2, xf);
341+ }
342+
343+
344+ void lhapdf_xfxq2_stdpartons_(const int& nset, const int& nmem, const int& pid, const double& x, const double& q2, double* xfs) {
345+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
346+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
347+ // Evaluate for the 13 LHAPDF5 standard partons (-6..6)
348+ for (size_t i = 0; i < 13; ++i) {
349+ try {
350+ xfs[i] = ACTIVESETS[nset].member(nmem)->xfxQ2(i-6, x, q2);
351+ } catch (const exception& e) {
352+ xfs[i] = 0;
353+ }
354+ }
355+ // Update current set focus
356+ CURRENTSET = nset;
357+ }
358+
359+ void lhapdf_xfxq_stdpartons_(const int& nset, const int& nmem, const int& pid, const double& x, const double& q, double* xfs) {
360+ const double q2 = q*q;
361+ lhapdf_xfxq2_stdpartons_(nset, nmem, pid, x, q2, xfs);
362+ }
363+
364+
365+ //-----------------
366+
367+
368+ /// Get the alpha_s order for the set
369+ void lhapdf_getorderas_(const int& nset, const int& nmem, int& oas) {
370+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
371+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
372+ oas = ACTIVESETS[nset].member(nmem)->info().get_entry_as<int>("AlphaS_OrderQCD");
373+ // Update current set focus
374+ CURRENTSET = nset;
375+ }
376+
377+ /// Get the alpha_s(Q2) value for set nset
378+ void lhapdf_alphasq2_(const int& nset, const int& nmem, const double& q2, double& alphas) {
379+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
380+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
381+ alphas = ACTIVESETS[nset].member(nmem)->alphasQ2(q2);
382+ // Update current set focus
383+ CURRENTSET = nset;
384+ }
385+
386+ /// Get the alpha_s(Q) value for set nset
387+ /// @todo Return value rather than return arg? Can we do that elsewhere, too, e.g. single-value PDF xf functions?
388+ void lhapdf_alphasq_(const int& nset, const int& nmem, const double& q, double& alphas) {
389+ const double q2 = q*q;
390+ lhapdf_alphasq2_(nset, nmem, q2, alphas);
391+ }
392+
393+
394+ // Metadata functions
395+
396+ // /// Get the number of error members in the set (with special treatment for single member sets)
397+ // void numberpdfm_(const int& nset, int& numpdf) {
398+ // if (ACTIVESETS.find(nset) == ACTIVESETS.end())
399+ // throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
400+ // // Set equal to the number of members for the requested set
401+ // numpdf= ACTIVESETS[nset].activeMember()->info().get_entry_as<int>("NumMembers");
402+ // // Update current set focus
403+ // CURRENTSET = nset;
404+ // }
405+
406+ // /// Get the max number of active flavours
407+ // void getnfm_(const int& nset, int& nf) {
408+ // //nf = ACTIVESETS[nset].activeMember()->info().get_entry_as<int>("AlphaS_NumFlavors");
409+ // nf = ACTIVESETS[nset].activeMember()->info().get_entry_as<int>("NumFlavors");
410+ // // Update current set focus
411+ // CURRENTSET = nset;
412+ // }
413+
414+ // /// Get nf'th quark mass
415+ // void getqmassm_(const int& nset, const int& nf, double& mass) {
416+ // if (ACTIVESETS.find(nset) == ACTIVESETS.end())
417+ // throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
418+ // if (nf*nf == 1) mass = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("MDown");
419+ // else if (nf*nf == 4) mass = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("MUp");
420+ // else if (nf*nf == 9) mass = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("MStrange");
421+ // else if (nf*nf == 16) mass = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("MCharm");
422+ // else if (nf*nf == 25) mass = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("MBottom");
423+ // else if (nf*nf == 36) mass = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("MTop");
424+ // else throw LHAPDF::UserError("Trying to get quark mass for invalid quark ID #" + LHAPDF::to_str(nf));
425+ // // Update current set focus
426+ // CURRENTSET = nset;
427+ // }
428+
429+ // /// Get the nf'th quark threshold
430+ // void getthresholdm_(const int& nset, const int& nf, double& Q) {
431+ // try {
432+ // if (ACTIVESETS.find(nset) == ACTIVESETS.end())
433+ // throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
434+ // if (nf*nf == 1) Q = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("ThresholdDown");
435+ // else if (nf*nf == 4) Q = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("ThresholdUp");
436+ // else if (nf*nf == 9) Q = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("ThresholdStrange");
437+ // else if (nf*nf == 16) Q = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("ThresholdCharm");
438+ // else if (nf*nf == 25) Q = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("ThresholdBottom");
439+ // else if (nf*nf == 36) Q = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("ThresholdTop");
440+ // //else throw LHAPDF::UserError("Trying to get quark threshold for invalid quark ID #" + LHAPDF::to_str(nf));
441+ // } catch (...) {
442+ // getqmassm_(nset, nf, Q);
443+ // }
444+ // // Update current set focus
445+ // CURRENTSET = nset;
446+ // }
447+
448+ // void getxminm_(const int& nset, const int& nmem, double& xmin) {
449+ // if (ACTIVESETS.find(nset) == ACTIVESETS.end())
450+ // throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
451+ // const int activemem = ACTIVESETS[nset].currentmem;
452+ // ACTIVESETS[nset].loadMember(nmem);
453+ // xmin = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("XMin");
454+ // ACTIVESETS[nset].loadMember(activemem);
455+ // // Update current set focus
456+ // CURRENTSET = nset;
457+ // }
458+
459+ // void getxmaxm_(const int& nset, const int& nmem, double& xmax) {
460+ // if (ACTIVESETS.find(nset) == ACTIVESETS.end())
461+ // throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
462+ // const int activemem = ACTIVESETS[nset].currentmem;
463+ // ACTIVESETS[nset].loadMember(nmem);
464+ // xmax = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("XMax");
465+ // ACTIVESETS[nset].loadMember(activemem);
466+ // // Update current set focus
467+ // CURRENTSET = nset;
468+ // }
469+
470+ // void getq2minm_(const int& nset, const int& nmem, double& q2min) {
471+ // if (ACTIVESETS.find(nset) == ACTIVESETS.end())
472+ // throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
473+ // const int activemem = ACTIVESETS[nset].currentmem;
474+ // ACTIVESETS[nset].loadMember(nmem);
475+ // q2min = LHAPDF::sqr(ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("QMin"));
476+ // ACTIVESETS[nset].loadMember(activemem);
477+ // // Update current set focus
478+ // CURRENTSET = nset;
479+ // }
480+
481+ // void getq2maxm_(const int& nset, const int& nmem, double& q2max) {
482+ // if (ACTIVESETS.find(nset) == ACTIVESETS.end())
483+ // throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
484+ // const int activemem = ACTIVESETS[nset].currentmem;
485+ // ACTIVESETS[nset].loadMember(nmem);
486+ // q2max = LHAPDF::sqr(ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("QMax"));
487+ // ACTIVESETS[nset].loadMember(activemem);
488+ // // Update current set focus
489+ // CURRENTSET = nset;
490+ // }
491+
492+ // void getminmaxm_(const int& nset, const int& nmem, double& xmin, double& xmax, double& q2min, double& q2max) {
493+ // if (ACTIVESETS.find(nset) == ACTIVESETS.end())
494+ // throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
495+ // const int activemem = ACTIVESETS[nset].currentmem;
496+ // ACTIVESETS[nset].loadMember(nmem);
497+ // xmin = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("XMin");
498+ // xmax = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("XMax");
499+ // q2min = LHAPDF::sqr(ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("QMin"));
500+ // q2max = LHAPDF::sqr(ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("QMax"));
501+ // ACTIVESETS[nset].loadMember(activemem);
502+ // // Update current set focus
503+ // CURRENTSET = nset;
504+ // }
505+
506+
507+ // /// Backwards compatibility functions for LHAPDF5 calculations of
508+ // /// PDF uncertainties and PDF correlations (G. Watt, March 2014).
509+
510+ // // subroutine GetPDFUncTypeM(nset,lMonteCarlo,lSymmetric)
511+ // void getpdfunctypem_(const int& nset, int& lmontecarlo, int& lsymmetric) {
512+ // if (ACTIVESETS.find(nset) == ACTIVESETS.end())
513+ // throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
514+ // const string errorType = ACTIVESETS[nset].activeMember()->set().errorType();
515+ // if (errorType == "replicas") { // Monte Carlo PDF sets
516+ // lmontecarlo = 1;
517+ // lsymmetric = 1;
518+ // } else if (errorType == "symmhessian") { // symmetric eigenvector PDF sets
519+ // lmontecarlo = 0;
520+ // lsymmetric = 1;
521+ // } else { // default: assume asymmetric Hessian eigenvector PDF sets
522+ // lmontecarlo = 0;
523+ // lsymmetric = 0;
524+ // }
525+ // // Update current set focus
526+ // CURRENTSET = nset;
527+ // }
528+ // // subroutine GetPDFUncType(lMonteCarlo,lSymmetric)
529+ // void getpdfunctype_(int& lmontecarlo, int& lsymmetric) {
530+ // int nset1 = 1;
531+ // getpdfunctypem_(nset1, lmontecarlo, lsymmetric);
532+ // }
533+
534+
535+ // // subroutine GetPDFuncertaintyM(nset,values,central,errplus,errminus,errsym)
536+ // void getpdfuncertaintym_(const int& nset, const double* values, double& central, double& errplus, double& errminus, double& errsymm) {
537+ // if (ACTIVESETS.find(nset) == ACTIVESETS.end())
538+ // throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
539+ // const size_t nmem = ACTIVESETS[nset].activeMember()->set().size()-1;
540+ // const vector<double> vecvalues(values, values + nmem + 1);
541+ // LHAPDF::PDFUncertainty err = ACTIVESETS[nset].activeMember()->set().uncertainty(vecvalues, -1);
542+ // central = err.central;
543+ // errplus = err.errplus;
544+ // errminus = err.errminus;
545+ // errsymm = err.errsymm;
546+ // // Update current set focus
547+ // CURRENTSET = nset;
548+ // }
549+ // // subroutine GetPDFuncertainty(values,central,errplus,errminus,errsym)
550+ // void getpdfuncertainty_(const double* values, double& central, double& errplus, double& errminus, double& errsymm) {
551+ // int nset1 = 1;
552+ // getpdfuncertaintym_(nset1, values, central, errplus, errminus, errsymm);
553+ // }
554+
555+
556+ // // subroutine GetPDFcorrelationM(nset,valuesA,valuesB,correlation)
557+ // void getpdfcorrelationm_(const int& nset, const double* valuesA, const double* valuesB, double& correlation) {
558+ // if (ACTIVESETS.find(nset) == ACTIVESETS.end())
559+ // throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
560+ // const size_t nmem = ACTIVESETS[nset].activeMember()->set().size()-1;
561+ // const vector<double> vecvaluesA(valuesA, valuesA + nmem + 1);
562+ // const vector<double> vecvaluesB(valuesB, valuesB + nmem + 1);
563+ // correlation = ACTIVESETS[nset].activeMember()->set().correlation(vecvaluesA,vecvaluesB);
564+ // // Update current set focus
565+ // CURRENTSET = nset;
566+ // }
567+ // // subroutine GetPDFcorrelation(valuesA,valuesB,correlation)
568+ // void getpdfcorrelation_(const double* valuesA, const double* valuesB, double& correlation) {
569+ // int nset1 = 1;
570+ // getpdfcorrelationm_(nset1, valuesA, valuesB, correlation);
571+ // }
572+
573+
574+
575+
576+
577+ //////////////////
578+
579+ // LHAPDF5 / PDFLIB COMPATIBILITY INTERFACE FUNCTIONS
580+
581+
582+ // System-level info
583+
584+ /// LHAPDF library version
585+ void getlhapdfversion_(char* s, size_t len) {
586+ // strncpy(s, LHAPDF_VERSION, len);
587+ cstr_to_fstr(LHAPDF_VERSION, s, len);
588+ }
589+
590+
591+ /// Does nothing, only provided for backward compatibility
592+ void lhaprint_(int& a) { }
593+
594+
595+ /// Set LHAPDF parameters
596+ ///
597+ /// @note Only the verbosity parameters have any effect: PDF behaviour is not
598+ /// controlled globally in LHAPDF6.
599+ void setlhaparm_(const char* par, int parlength) {
600+ const string cpar = LHAPDF::to_upper(fstr_to_ccstr(par, parlength));
601+ if (cpar == "NOSTAT" || cpar == "16") {
602+ cerr << "WARNING: Fortran call to control LHAPDF statistics collection has no effect" << endl;
603+ } else if (cpar == "LHAPDF" || cpar == "17") {
604+ cerr << "WARNING: Fortran call to globally control alpha_s calculation has no effect" << endl;
605+ } else if (cpar == "EXTRAPOLATE" || cpar == "18") {
606+ cerr << "WARNING: Fortran call to globally control PDF extrapolation has no effect" << endl;
607+ } else if (cpar == "SILENT" || cpar == "LOWKEY") {
608+ LHAPDF::setVerbosity(0);
609+ } else if (cpar == "19") {
610+ LHAPDF::setVerbosity(1);
611+ }
612+ }
613+ /// Get LHAPDF parameters -- does nothing in LHAPDF6!
614+ void getlhaparm_(int dummy, char* par, int parlength) {
615+ cstr_to_fstr("", par, parlength);
616+ }
617+
618+
619+ /// Return a dummy max number of sets (there is no limitation now)
620+ void getmaxnumsets_(int& nmax) {
621+ nmax = 1000;
622+ }
623+
624+
625+ /// Set PDF data path
626+ void setpdfpath_(const char* s, size_t len) {
627+ /// @todo Works? Need to check C-string copying, null termination
628+ char s2[1024];
629+ s2[len] = '\0';
630+ strncpy(s2, s, len);
631+ LHAPDF::pathsPrepend(s2);
632+ }
633+
634+ /// Get PDF data path (colon-separated if there is more than one element)
635+ void getdatapath_(char* s, size_t len) {
636+ /// @todo Works? Need to check Fortran string return, string macro treatment, etc.
637+ string pathstr;
638+ for (const string& path : LHAPDF::paths()) {
639+ if (!pathstr.empty()) pathstr += ":";
640+ pathstr += path;
641+ }
642+ // strncpy(s, pathstr.c_str(), len);
643+ cstr_to_fstr(pathstr.c_str(), s, len);
644+ }
645+
646+
647+ // PDF initialisation and focus-switching
648+
649+ /// Load a PDF set
650+ ///
651+ /// @todo Does this version actually take a *path*? What to do?
652+ void initpdfsetm_(const int& nset, const char* setpath, int setpathlength) {
653+ // Strip file extension for backward compatibility
654+ string fullp = string(setpath, setpathlength);
655+ // Remove trailing whitespace
656+ fullp.erase( std::remove_if( fullp.begin(), fullp.end(), ::isspace ), fullp.end() );
657+ // Use only items after the last /
658+ const string pap = LHAPDF::dirname(fullp);
659+ const string p = LHAPDF::basename(fullp);
660+ // Prepend path to search area
661+ LHAPDF::pathsPrepend(pap);
662+ // Handle extensions
663+ string path = LHAPDF::file_extn(p).empty() ? p : LHAPDF::file_stem(p);
664+ /// @note We correct the misnamed CTEQ6L1/CTEQ6ll set name as a backward compatibility special case.
665+ if (LHAPDF::to_lower(path) == "cteq6ll") path = "cteq6l1";
666+ // Create the PDF set with index nset
667+ // if (ACTIVESETS.find(nset) == ACTIVESETS.end())
668+ if (path != ACTIVESETS[nset].setname)
669+ ACTIVESETS[nset] = PDFSetHandler(path); ///< @todo Will be wrong if a structured path is given
670+ CURRENTSET = nset;
671+ }
672+ /// Load a PDF set (non-multiset version)
673+ void initpdfset_(const char* setpath, int setpathlength) {
674+ int nset1 = 1;
675+ initpdfsetm_(nset1, setpath, setpathlength);
676+ }
677+
678+
679+ /// Load a PDF set by name
680+ void initpdfsetbynamem_(const int& nset, const char* setname, int setnamelength) {
681+ // Truncate input to size setnamelength
682+ string p = setname;
683+ p.erase(setnamelength, std::string::npos);
684+ // Strip file extension for backward compatibility
685+ string name = LHAPDF::file_extn(p).empty() ? p : LHAPDF::file_stem(p);
686+ // Remove trailing whitespace
687+ name.erase( std::remove_if( name.begin(), name.end(), ::isspace ), name.end() );
688+ /// @note We correct the misnamed CTEQ6L1/CTEQ6ll set name as a backward compatibility special case.
689+ if (LHAPDF::to_lower(name) == "cteq6ll") name = "cteq6l1";
690+ // Create the PDF set with index nset
691+ // if (ACTIVESETS.find(nset) == ACTIVESETS.end())
692+ if (name != ACTIVESETS[nset].setname)
693+ ACTIVESETS[nset] = PDFSetHandler(name);
694+ // Update current set focus
695+ CURRENTSET = nset;
696+ }
697+ /// Load a PDF set by name (non-multiset version)
698+ void initpdfsetbyname_(const char* setname, int setnamelength) {
699+ int nset1 = 1;
700+ initpdfsetbynamem_(nset1, setname, setnamelength);
701+ }
702+
703+
704+ /// Load a PDF in current set
705+ void initpdfm_(const int& nset, const int& nmember) {
706+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
707+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
708+ ACTIVESETS[nset].loadMember(nmember);
709+ // Update current set focus
710+ CURRENTSET = nset;
711+ }
712+ /// Load a PDF in current set (non-multiset version)
713+ void initpdf_(const int& nmember) {
714+ int nset1 = 1;
715+ initpdfm_(nset1, nmember);
716+ }
717+
718+
719+ /// Get the current set number (i.e. allocation slot index)
720+ void getnset_(int& nset) {
721+ nset = CURRENTSET;
722+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
723+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
724+ }
725+
726+ /// Explicitly set the current set number (i.e. allocation slot index)
727+ void setnset_(const int& nset) {
728+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
729+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
730+ CURRENTSET = nset;
731+ }
732+
733+
734+ /// Get the current member number in slot nset
735+ void getnmem_(int& nset, int& nmem) {
736+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
737+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
738+ nmem = ACTIVESETS[nset].currentmem;
739+ // Update current set focus
740+ CURRENTSET = nset;
741+ }
742+
743+ /// Set the current member number in slot nset
744+ void setnmem_(const int& nset, const int& nmem) {
745+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
746+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" +
747+ LHAPDF::to_str(nset) + " but it is not initialised");
748+ ACTIVESETS[nset].loadMember(nmem);
749+ // Update current set focus
750+ CURRENTSET = nset;
751+ }
752+
753+
754+
755+ // PDF evolution functions
756+
757+ // NEW BY MZ to evolve one single parton
758+
759+ /// Get xf(x) values for common partons from current PDF
760+ void evolvepartm_(const int& nset, const int& ipart, const double& x, const double& q, double& fxq) {
761+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
762+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
763+ int ipart_copy; // this is to deal with photons, which are labeled 7 in MG5aMC
764+ ipart_copy = ipart;
765+ if (ipart==7) ipart_copy = 22;
766+ try {
767+ fxq = ACTIVESETS[nset].activeMember()->xfxQ(ipart_copy, x, q);
768+ } catch (const exception& e) {
769+ fxq = 0;
770+ }
771+ // Update current set focus
772+ CURRENTSET = nset;
773+ }
774+ /// Get xf(x) values for common partons from current PDF (non-multiset version)
775+ void evolvepart_( const int& ipart, const double& x, const double& q, double& fxq) {
776+ int nset1 = 1;
777+ evolvepartm_(nset1, ipart, x, q, fxq);
778+ }
779+
780+ /// Get xf(x) values for common partons from current PDF
781+ void evolvepdfm_(const int& nset, const double& x, const double& q, double* fxq) {
782+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
783+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
784+ // Evaluate for the 13 LHAPDF5 standard partons (-6..6)
785+ for (size_t i = 0; i < 13; ++i) {
786+ try {
787+ fxq[i] = ACTIVESETS[nset].activeMember()->xfxQ(i-6, x, q);
788+ } catch (const exception& e) {
789+ fxq[i] = 0;
790+ }
791+ }
792+ // Update current set focus
793+ CURRENTSET = nset;
794+ }
795+ /// Get xf(x) values for common partons from current PDF (non-multiset version)
796+ void evolvepdf_(const double& x, const double& q, double* fxq) {
797+ int nset1 = 1;
798+ evolvepdfm_(nset1, x, q, fxq);
799+ }
800+
801+
802+ /// Determine if the current PDF has a photon flavour (historically only MRST2004QED)
803+ /// @todo Function rather than subroutine?
804+ /// @note There is no multiset version. has_photon will respect the current set slot.
805+ bool has_photon_() {
806+ return ACTIVESETS[CURRENTSET].activeMember()->hasFlavor(22);
807+ }
808+
809+
810+ /// Get xfx values from current PDF, including an extra photon flavour
811+ void evolvepdfphotonm_(const int& nset, const double& x, const double& q, double* fxq, double& photonfxq) {
812+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
813+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
814+ // First evaluate the "normal" partons
815+ evolvepdfm_(nset, x, q, fxq);
816+ // Then evaluate the photon flavor (historically only for MRST2004QED)
817+ try {
818+ photonfxq = ACTIVESETS[nset].activeMember()->xfxQ(22, x, q);
819+ } catch (const exception& e) {
820+ photonfxq = 0;
821+ }
822+ // Update current set focus
823+ CURRENTSET = nset;
824+ }
825+ /// Get xfx values from current PDF, including an extra photon flavour (non-multiset version)
826+ void evolvepdfphoton_(const double& x, const double& q, double* fxq, double& photonfxq) {
827+ int nset1 = 1;
828+ evolvepdfphotonm_(nset1, x, q, fxq, photonfxq);
829+ }
830+
831+
832+ /// Get xf(x) values for common partons from a photon PDF
833+ void evolvepdfpm_(const int& nset, const double& x, const double& q, const double& p2, const int& ip2, double& fxq) {
834+ // Update current set focus
835+ CURRENTSET = nset;
836+ throw LHAPDF::NotImplementedError("Photon structure functions are not yet supported in LHAPDF6");
837+ }
838+ /// Get xf(x) values for common partons from a photon PDF (non-multiset version)
839+ void evolvepdfp_(const double& x, const double& q, const double& p2, const int& ip2, double& fxq) {
840+ int nset1 = 1;
841+ evolvepdfpm_(nset1, x, q, p2, ip2, fxq);
842+ }
843+
844+
845+ // alpha_s evolution
846+
847+ /// Get the alpha_s order for the set
848+ void getorderasm_(const int& nset, int& oas) {
849+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
850+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
851+ // Set equal to the number of members for the requested set
852+ oas = ACTIVESETS[nset].activeMember()->info().get_entry_as<int>("AlphaS_OrderQCD");
853+ // Update current set focus
854+ CURRENTSET = nset;
855+ }
856+ /// Get the alpha_s order for the set (non-multiset version)
857+ void getorderas_(int& oas) {
858+ int nset1 = 1;
859+ getorderasm_(nset1, oas);
860+ }
861+
862+
863+ /// Get the alpha_s(Q) value for set nset
864+ double alphaspdfm_(const int& nset, const double& Q){
865+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
866+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
867+ return ACTIVESETS[nset].activeMember()->alphasQ(Q);
868+ // Update current set focus
869+ CURRENTSET = nset;
870+ }
871+ /// Get the alpha_s(Q) value for the set (non-multiset version)
872+ double alphaspdf_(const double& Q){
873+ int nset1 = 1;
874+ return alphaspdfm_(nset1, Q);
875+ }
876+
877+
878+ // Metadata functions
879+
880+ /// Get the number of error members in the set
881+ void numberpdfm_(const int& nset, int& numpdf) {
882+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
883+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
884+ // Set equal to the number of members for the requested set
885+ numpdf= ACTIVESETS[nset].activeMember()->info().get_entry_as<int>("NumMembers");
886+ // Reproduce old LHAPDF v5 behaviour, i.e. subtract 1
887+ numpdf -= 1;
888+ // Update current set focus
889+ CURRENTSET = nset;
890+ }
891+ /// Get the number of error members in the set (non-multiset version)
892+ void numberpdf_(int& numpdf) {
893+ int nset1 = 1;
894+ numberpdfm_(nset1, numpdf);
895+ }
896+
897+
898+ /// Get the max number of active flavours
899+ void getnfm_(const int& nset, int& nf) {
900+ //nf = ACTIVESETS[nset].activeMember()->info().get_entry_as<int>("AlphaS_NumFlavors");
901+ nf = ACTIVESETS[nset].activeMember()->info().get_entry_as<int>("NumFlavors");
902+ // Update current set focus
903+ CURRENTSET = nset;
904+ }
905+ /// Get the max number of active flavours (non-multiset version)
906+ void getnf_(int& nf) {
907+ int nset1 = 1;
908+ getnfm_(nset1, nf);
909+ }
910+
911+
912+ /// Get nf'th quark mass
913+ void getqmassm_(const int& nset, const int& nf, double& mass) {
914+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
915+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
916+ if (nf*nf == 1) mass = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("MDown");
917+ else if (nf*nf == 4) mass = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("MUp");
918+ else if (nf*nf == 9) mass = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("MStrange");
919+ else if (nf*nf == 16) mass = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("MCharm");
920+ else if (nf*nf == 25) mass = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("MBottom");
921+ else if (nf*nf == 36) mass = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("MTop");
922+ else throw LHAPDF::UserError("Trying to get quark mass for invalid quark ID #" + LHAPDF::to_str(nf));
923+ // Update current set focus
924+ CURRENTSET = nset;
925+ }
926+ /// Get nf'th quark mass (non-multiset version)
927+ void getqmass_(const int& nf, double& mass) {
928+ int nset1 = 1;
929+ getqmassm_(nset1, nf, mass);
930+ }
931+
932+
933+ /// Get the nf'th quark threshold
934+ void getthresholdm_(const int& nset, const int& nf, double& Q) {
935+ try {
936+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
937+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
938+ if (nf*nf == 1) Q = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("ThresholdDown");
939+ else if (nf*nf == 4) Q = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("ThresholdUp");
940+ else if (nf*nf == 9) Q = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("ThresholdStrange");
941+ else if (nf*nf == 16) Q = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("ThresholdCharm");
942+ else if (nf*nf == 25) Q = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("ThresholdBottom");
943+ else if (nf*nf == 36) Q = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("ThresholdTop");
944+ //else throw LHAPDF::UserError("Trying to get quark threshold for invalid quark ID #" + LHAPDF::to_str(nf));
945+ } catch (...) {
946+ getqmassm_(nset, nf, Q);
947+ }
948+ // Update current set focus
949+ CURRENTSET = nset;
950+ }
951+ /// Get the nf'th quark threshold
952+ void getthreshold_(const int& nf, double& Q) {
953+ int nset1 = 1;
954+ getthresholdm_(nset1, nf, Q);
955+ }
956+
957+
958+ /// Print PDF set's description to stdout
959+ void getdescm_(const int& nset) {
960+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
961+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
962+ cout << ACTIVESETS[nset].activeMember()->description() << endl;
963+ // Update current set focus
964+ CURRENTSET = nset;
965+ }
966+ void getdesc_() {
967+ int nset1 = 1;
968+ getdescm_(nset1);
969+ }
970+
971+
972+ void getxminm_(const int& nset, const int& nmem, double& xmin) {
973+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
974+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
975+ const int activemem = ACTIVESETS[nset].currentmem;
976+ ACTIVESETS[nset].loadMember(nmem);
977+ xmin = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("XMin");
978+ ACTIVESETS[nset].loadMember(activemem);
979+ // Update current set focus
980+ CURRENTSET = nset;
981+ }
982+ void getxmin_(const int& nmem, double& xmin) {
983+ int nset1 = 1;
984+ getxminm_(nset1, nmem, xmin);
985+ }
986+
987+
988+ void getxmaxm_(const int& nset, const int& nmem, double& xmax) {
989+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
990+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
991+ const int activemem = ACTIVESETS[nset].currentmem;
992+ ACTIVESETS[nset].loadMember(nmem);
993+ xmax = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("XMax");
994+ ACTIVESETS[nset].loadMember(activemem);
995+ // Update current set focus
996+ CURRENTSET = nset;
997+ }
998+ void getxmax_(const int& nmem, double& xmax) {
999+ int nset1 = 1;
1000+ getxmaxm_(nset1, nmem, xmax);
1001+ }
1002+
1003+
1004+ void getq2minm_(const int& nset, const int& nmem, double& q2min) {
1005+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
1006+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
1007+ const int activemem = ACTIVESETS[nset].currentmem;
1008+ ACTIVESETS[nset].loadMember(nmem);
1009+ q2min = LHAPDF::sqr(ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("QMin"));
1010+ ACTIVESETS[nset].loadMember(activemem);
1011+ // Update current set focus
1012+ CURRENTSET = nset;
1013+ }
1014+ void getq2min_(const int& nmem, double& q2min) {
1015+ int nset1 = 1;
1016+ getq2minm_(nset1, nmem, q2min);
1017+ }
1018+
1019+
1020+ void getq2maxm_(const int& nset, const int& nmem, double& q2max) {
1021+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
1022+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
1023+ const int activemem = ACTIVESETS[nset].currentmem;
1024+ ACTIVESETS[nset].loadMember(nmem);
1025+ q2max = LHAPDF::sqr(ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("QMax"));
1026+ ACTIVESETS[nset].loadMember(activemem);
1027+ // Update current set focus
1028+ CURRENTSET = nset;
1029+ }
1030+ void getq2max_(const int& nmem, double& q2max) {
1031+ int nset1 = 1;
1032+ getq2maxm_(nset1, nmem, q2max);
1033+ }
1034+
1035+
1036+ void getminmaxm_(const int& nset, const int& nmem, double& xmin, double& xmax, double& q2min, double& q2max) {
1037+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
1038+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
1039+ const int activemem = ACTIVESETS[nset].currentmem;
1040+ ACTIVESETS[nset].loadMember(nmem);
1041+ xmin = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("XMin");
1042+ xmax = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("XMax");
1043+ q2min = LHAPDF::sqr(ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("QMin"));
1044+ q2max = LHAPDF::sqr(ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("QMax"));
1045+ ACTIVESETS[nset].loadMember(activemem);
1046+ // Update current set focus
1047+ CURRENTSET = nset;
1048+ }
1049+ void getminmax_(const int& nmem, double& xmin, double& xmax, double& q2min, double& q2max) {
1050+ int nset1 = 1;
1051+ getminmaxm_(nset1, nmem, xmin, xmax, q2min, q2max);
1052+ }
1053+
1054+
1055+
1056+ void getlam4m_(const int& nset, const int& nmem, double& qcdl4) {
1057+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
1058+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
1059+ CURRENTSET = nset;
1060+ ACTIVESETS[nset].loadMember(nmem);
1061+ qcdl4 = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("AlphaS_Lambda4", -1.0);
1062+ }
1063+ void getlam4_(const int& nmem, double& qcdl4) {
1064+ int nset1 = 1;
1065+ getlam4m_(nset1, nmem, qcdl4);
1066+ }
1067+
1068+
1069+ void getlam5m_(const int& nset, const int& nmem, double& qcdl5) {
1070+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
1071+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
1072+ CURRENTSET = nset;
1073+ ACTIVESETS[nset].loadMember(nmem);
1074+ qcdl5 = ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("AlphaS_Lambda5", -1.0);
1075+ }
1076+ void getlam5_(const int& nmem, double& qcdl5) {
1077+ int nset1 = 1;
1078+ getlam5m_(nset1, nmem, qcdl5);
1079+ }
1080+
1081+
1082+
1083+
1084+
1085+ /// Backwards compatibility functions for LHAPDF5 calculations of
1086+ /// PDF uncertainties and PDF correlations (G. Watt, March 2014).
1087+
1088+ // subroutine GetPDFUncTypeM(nset,lMonteCarlo,lSymmetric)
1089+ void getpdfunctypem_(const int& nset, int& lmontecarlo, int& lsymmetric) {
1090+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
1091+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
1092+ const string errorType = ACTIVESETS[nset].activeMember()->set().errorType();
1093+ if (LHAPDF::startswith(errorType, "replicas")) { // Monte Carlo PDF sets
1094+ lmontecarlo = 1;
1095+ lsymmetric = 1;
1096+ } else if (LHAPDF::startswith(errorType, "symmhessian")) { // symmetric eigenvector PDF sets
1097+ lmontecarlo = 0;
1098+ lsymmetric = 1;
1099+ } else { // default: assume asymmetric Hessian eigenvector PDF sets
1100+ lmontecarlo = 0;
1101+ lsymmetric = 0;
1102+ }
1103+ // Update current set focus
1104+ CURRENTSET = nset;
1105+ }
1106+ // subroutine GetPDFUncType(lMonteCarlo,lSymmetric)
1107+ void getpdfunctype_(int& lmontecarlo, int& lsymmetric) {
1108+ int nset1 = 1;
1109+ getpdfunctypem_(nset1, lmontecarlo, lsymmetric);
1110+ }
1111+
1112+
1113+ // subroutine GetPDFuncertaintyM(nset,values,central,errplus,errminus,errsym)
1114+ void getpdfuncertaintym_(const int& nset, const double* values, double& central, double& errplus, double& errminus, double& errsymm) {
1115+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
1116+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
1117+ const size_t nmem = ACTIVESETS[nset].activeMember()->set().size()-1;
1118+ const vector<double> vecvalues(values, values + nmem + 1);
1119+ LHAPDF::PDFUncertainty err = ACTIVESETS[nset].activeMember()->set().uncertainty(vecvalues, -1);
1120+ central = err.central;
1121+ // For a combined set, the PDF and parameter variation uncertainties will be added in quadrature.
1122+ errplus = err.errplus;
1123+ errminus = err.errminus;
1124+ errsymm = err.errsymm;
1125+ // Update current set focus
1126+ CURRENTSET = nset;
1127+ }
1128+ // subroutine GetPDFuncertainty(values,central,errplus,errminus,errsym)
1129+ void getpdfuncertainty_(const double* values, double& central, double& errplus, double& errminus, double& errsymm) {
1130+ int nset1 = 1;
1131+ getpdfuncertaintym_(nset1, values, central, errplus, errminus, errsymm);
1132+ }
1133+
1134+
1135+ // subroutine GetPDFcorrelationM(nset,valuesA,valuesB,correlation)
1136+ void getpdfcorrelationm_(const int& nset, const double* valuesA, const double* valuesB, double& correlation) {
1137+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
1138+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
1139+ const size_t nmem = ACTIVESETS[nset].activeMember()->set().size()-1;
1140+ const vector<double> vecvaluesA(valuesA, valuesA + nmem + 1);
1141+ const vector<double> vecvaluesB(valuesB, valuesB + nmem + 1);
1142+ correlation = ACTIVESETS[nset].activeMember()->set().correlation(vecvaluesA,vecvaluesB);
1143+ // Update current set focus
1144+ CURRENTSET = nset;
1145+ }
1146+ // subroutine GetPDFcorrelation(valuesA,valuesB,correlation)
1147+ void getpdfcorrelation_(const double* valuesA, const double* valuesB, double& correlation) {
1148+ int nset1 = 1;
1149+ getpdfcorrelationm_(nset1, valuesA, valuesB, correlation);
1150+ }
1151+
1152+
1153+ ///////////////////////////////////////
1154+
1155+
1156+ /// REALLY OLD PDFLIB COMPATIBILITY FUNCTIONS
1157+
1158+ /// PDFLIB initialisation function
1159+ void pdfset_(const char* par, const double* value, int parlength) {
1160+
1161+ string my_par(par), message;
1162+ int id;
1163+ // Identify the calling program (yuck!)
1164+ if (my_par.find("NPTYPE") != string::npos) {
1165+ message = "==== LHAPDF6 USING PYTHIA-TYPE LHAGLUE INTERFACE ====";
1166+ // Take PDF ID from value[2]
1167+ id = value[2]+1000*value[1];
1168+ } else if (my_par.find("HWLHAPDF") != string::npos) {
1169+ message = "==== LHAPDF6 USING HERWIG-TYPE LHAGLUE INTERFACE ====";
1170+ // Take PDF ID from value[0]
1171+ id = value[0];
1172+ } else if (my_par.find("DEFAULT") != string::npos) {
1173+ message = "==== LHAPDF6 USING DEFAULT-TYPE LHAGLUE INTERFACE ====";
1174+ // Take PDF ID from value[0]
1175+ id = value[0];
1176+ } else {
1177+ message = "==== LHAPDF6 USING PDFLIB-TYPE LHAGLUE INTERFACE ====";
1178+ // Take PDF ID from value[2]
1179+ id = value[2]+1000*value[1];
1180+ }
1181+ pair<string, int> set_id = LHAPDF::lookupPDF(id);
1182+ if (set_id.first != ACTIVESETS[1].setname || set_id.second != ACTIVESETS[1].currentmem) {
1183+ if (LHAPDF::verbosity() > 0) cout << message << endl;
1184+ ACTIVESETS[1] = PDFSetHandler(id);
1185+ }
1186+
1187+ CURRENTSET = 1;
1188+
1189+ // Extract parameters for common blocks (with sensible fallback values)
1190+ PDFPtr pdf = ACTIVESETS[1].activeMember();
1191+ w50513_.xmin = pdf->info().get_entry_as<double>("XMin", 0.0);
1192+ w50513_.xmax = pdf->info().get_entry_as<double>("XMax", 1.0);
1193+ w50513_.q2min = LHAPDF::sqr(pdf->info().get_entry_as<double>("QMin", 1.0));
1194+ w50513_.q2max = LHAPDF::sqr(pdf->info().get_entry_as<double>("QMax", 1.0e5));
1195+ w50512_.qcdl4 = pdf->info().get_entry_as<double>("AlphaS_Lambda4", 0.0);
1196+ w50512_.qcdl5 = pdf->info().get_entry_as<double>("AlphaS_Lambda5", 0.0);
1197+ lhapdfr_.qcdlha4 = pdf->info().get_entry_as<double>("AlphaS_Lambda4", 0.0);
1198+ lhapdfr_.qcdlha5 = pdf->info().get_entry_as<double>("AlphaS_Lambda5", 0.0);
1199+ lhapdfr_.nfllha = 4;
1200+ // Activate legacy/compatibility LHAPDF5-type behaviour re. broken Lambda values
1201+ if (pdf->info().get_entry_as<bool>("Pythia6LambdaV5Compat", true)) {
1202+ w50512_.qcdl4 = 0.192;
1203+ w50512_.qcdl5 = 0.192;
1204+ lhapdfr_.qcdlha4 = 0.192;
1205+ lhapdfr_.qcdlha5 = 0.192;
1206+ }
1207+ }
1208+
1209+ /// PDFLIB nucleon structure function querying
1210+ void structm_(const double& x, const double& q,
1211+ double& upv, double& dnv, double& usea, double& dsea,
1212+ double& str, double& chm, double& bot, double& top, double& glu) {
1213+ CURRENTSET = 1;
1214+ /// Fill (partial) parton return variables
1215+ PDFPtr pdf = ACTIVESETS[1].activeMember();
1216+ dsea = pdf->xfxQ(-1, x, q);
1217+ usea = pdf->xfxQ(-2, x, q);
1218+ dnv = pdf->xfxQ(1, x, q) - dsea;
1219+ upv = pdf->xfxQ(2, x, q) - usea;
1220+ str = pdf->xfxQ(3, x, q);
1221+ chm = (pdf->hasFlavor(4)) ? pdf->xfxQ(4, x, q) : 0;
1222+ bot = (pdf->hasFlavor(5)) ? pdf->xfxQ(5, x, q) : 0;
1223+ top = (pdf->hasFlavor(6)) ? pdf->xfxQ(6, x, q) : 0;
1224+ glu = pdf->xfxQ(21, x, q);
1225+ }
1226+
1227+ /// PDFLIB photon structure function querying
1228+ void structp_(const double& x, const double& q2, const double& p2, const double& ip2,
1229+ double& upv, double& dnv, double& usea, double& dsea,
1230+ double& str, double& chm, double& bot, double& top, double& glu) {
1231+ throw LHAPDF::NotImplementedError("Photon structure functions are not yet supported");
1232+ }
1233+
1234+ /// PDFLIB statistics on PDF under/overflows
1235+ void pdfsta_() {
1236+ /// @note Can't do anything...
1237+ }
1238+
1239+
1240+}
1241+
1242+
1243+// LHAPDF namespace C++ compatibility code
1244+#ifdef ENABLE_LHAGLUE_CXX
1245+
1246+
1247+void LHAPDF::setVerbosity(LHAPDF::Verbosity noiselevel) {
1248+ LHAPDF::setVerbosity((int) noiselevel);
1249+}
1250+
1251+void LHAPDF::setPDFPath(const string& path) {
1252+ pathsPrepend(path);
1253+}
1254+
1255+string LHAPDF::pdfsetsPath() {
1256+ return paths()[0];
1257+}
1258+
1259+int LHAPDF::numberPDF() {
1260+ int nmem;
1261+ numberpdf_(nmem);
1262+ return nmem;
1263+}
1264+int LHAPDF::numberPDF(int nset) {
1265+ int nmem;
1266+ numberpdfm_(nset,nmem);
1267+ return nmem;
1268+}
1269+
1270+void LHAPDF::initPDF( int memset) {
1271+ int nset1 = 1;
1272+ initpdfm_(nset1, memset);
1273+}
1274+void LHAPDF::initPDF(int nset, int memset) {
1275+ initpdfm_(nset, memset);
1276+}
1277+
1278+
1279+double LHAPDF::xfx(double x, double Q, int fl) {
1280+ vector<double> r(13);
1281+ evolvepdf_(x, Q, &r[0]);
1282+ return r[fl+6];
1283+}
1284+double LHAPDF::xfx(int nset, double x, double Q, int fl) {
1285+ vector<double> r(13);
1286+ evolvepdfm_(nset, x, Q, &r[0]);
1287+ return r[fl+6];
1288+}
1289+
1290+vector<double> LHAPDF::xfx(double x, double Q) {
1291+ vector<double> r(13);
1292+ evolvepdf_(x, Q, &r[0]);
1293+ return r;
1294+}
1295+vector<double> LHAPDF::xfx(int nset, double x, double Q) {
1296+ vector<double> r(13);
1297+ evolvepdfm_(nset, x, Q, &r[0]);
1298+ return r;
1299+}
1300+
1301+void LHAPDF::xfx(double x, double Q, double* results) {
1302+ evolvepdf_(x, Q, results);
1303+}
1304+void LHAPDF::xfx(int nset, double x, double Q, double* results) {
1305+ evolvepdfm_(nset, x, Q, results);
1306+}
1307+
1308+
1309+vector<double> LHAPDF::xfxphoton(double x, double Q) {
1310+ vector<double> r(13);
1311+ double mphoton;
1312+ evolvepdfphoton_(x, Q, &r[0], mphoton);
1313+ r.push_back(mphoton);
1314+ return r;
1315+}
1316+vector<double> LHAPDF::xfxphoton(int nset, double x, double Q) {
1317+ vector<double> r(13);
1318+ double mphoton;
1319+ evolvepdfphotonm_(nset, x, Q, &r[0], mphoton);
1320+ r.push_back(mphoton);
1321+ return r;
1322+}
1323+
1324+void LHAPDF::xfxphoton(double x, double Q, double* results) {
1325+ evolvepdfphoton_(x, Q, results, results[13]);
1326+}
1327+void LHAPDF::xfxphoton(int nset, double x, double Q, double* results) {
1328+ evolvepdfphotonm_(nset, x, Q, results, results[13]);
1329+}
1330+
1331+double LHAPDF::xfxphoton(double x, double Q, int fl) {
1332+ vector<double> r(13);
1333+ double mphoton;
1334+ evolvepdfphoton_(x, Q, &r[0], mphoton);
1335+ if (fl == 7) return mphoton;
1336+ return r[fl+6];
1337+}
1338+double LHAPDF::xfxphoton(int nset, double x, double Q, int fl) {
1339+ vector<double> r(13);
1340+ double mphoton;
1341+ evolvepdfphotonm_(nset, x, Q, &r[0], mphoton);
1342+ if ( fl == 7 ) return mphoton;
1343+ return r[fl+6];
1344+}
1345+
1346+
1347+void LHAPDF::initPDFSet(const string& filename, int nmem) {
1348+ initPDFSet(1,filename, nmem);
1349+}
1350+
1351+void LHAPDF::initPDFSet(int nset, const string& filename, int nmem) {
1352+ initPDFSetByName(nset,filename);
1353+ ACTIVESETS[nset].loadMember(nmem);
1354+ CURRENTSET = nset;
1355+}
1356+
1357+
1358+void LHAPDF::initPDFSet(const string& filename, SetType type, int nmem) {
1359+ // silently ignore type
1360+ initPDFSet(1,filename, nmem);
1361+}
1362+
1363+void LHAPDF::initPDFSet(int nset, const string& filename, SetType type, int nmem) {
1364+ // silently ignore type
1365+ initPDFSetByName(nset,filename);
1366+ ACTIVESETS[nset].loadMember(nmem);
1367+ CURRENTSET = nset;
1368+}
1369+
1370+void LHAPDF::initPDFSet(int nset, int setid, int nmem) {
1371+ pair<string, int> set_id = LHAPDF::lookupPDF(setid+nmem);
1372+ if (set_id.second != nmem)
1373+ throw LHAPDF::UserError("Inconsistent member numbers: " + LHAPDF::to_str(set_id.second) + " != " + LHAPDF::to_str(nmem));
1374+ if (set_id.first != ACTIVESETS[nset].setname || nmem != ACTIVESETS[nset].currentmem)
1375+ ACTIVESETS[nset] = PDFSetHandler(setid+nmem);
1376+ CURRENTSET = nset;
1377+}
1378+
1379+void LHAPDF::initPDFSet(int setid, int nmem) {
1380+ initPDFSet(1,setid,nmem);
1381+}
1382+
1383+#define SIZE 999
1384+void LHAPDF::initPDFSetByName(const string& filename) {
1385+ std::cout << "initPDFSetByName: " << filename << std::endl;
1386+ char cfilename[SIZE+1];
1387+ strncpy(cfilename, filename.c_str(), SIZE);
1388+ initpdfsetbyname_(cfilename, filename.length());
1389+}
1390+
1391+void LHAPDF::initPDFSetByName(int nset, const string& filename) {
1392+ char cfilename[SIZE+1];
1393+ strncpy(cfilename, filename.c_str(), SIZE);
1394+ initpdfsetbynamem_(nset, cfilename, filename.length());
1395+}
1396+
1397+void LHAPDF::initPDFSetByName(const string& filename, SetType type) {
1398+ //silently ignore type
1399+ std::cout << "initPDFSetByName: " << filename << std::endl;
1400+ char cfilename[SIZE+1];
1401+ strncpy(cfilename, filename.c_str(), SIZE);
1402+ initpdfsetbyname_(cfilename, filename.length());
1403+}
1404+
1405+void LHAPDF::initPDFSetByName(int nset, const string& filename, SetType type) {
1406+ //silently ignore type
1407+ char cfilename[SIZE+1];
1408+ strncpy(cfilename, filename.c_str(), SIZE);
1409+ initpdfsetbynamem_(nset, cfilename, filename.length());
1410+}
1411+
1412+
1413+void LHAPDF::getDescription() {
1414+ getDescription(1);
1415+}
1416+
1417+void LHAPDF::getDescription(int nset) {
1418+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
1419+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
1420+ cout << ACTIVESETS[nset].activeMember()->set().description() << endl;
1421+}
1422+
1423+
1424+double LHAPDF::alphasPDF(double Q) {
1425+ return LHAPDF::alphasPDF(1, Q) ;
1426+}
1427+
1428+double LHAPDF::alphasPDF(int nset, double Q) {
1429+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
1430+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
1431+ CURRENTSET = nset;
1432+ // return alphaS for the requested set
1433+ return ACTIVESETS[nset].activeMember()->alphasQ(Q);
1434+}
1435+
1436+
1437+bool LHAPDF::hasPhoton(){
1438+ return has_photon_();
1439+}
1440+
1441+
1442+int LHAPDF::getOrderAlphaS() {
1443+ return LHAPDF::getOrderAlphaS(1) ;
1444+}
1445+
1446+int LHAPDF::getOrderAlphaS(int nset) {
1447+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
1448+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
1449+ CURRENTSET = nset;
1450+ // return alphaS Order for the requested set
1451+ return ACTIVESETS[nset].activeMember()->info().get_entry_as<int>("AlphaS_OrderQCD", -1);
1452+}
1453+
1454+
1455+int LHAPDF::getOrderPDF() {
1456+ return LHAPDF::getOrderPDF(1) ;
1457+}
1458+
1459+int LHAPDF::getOrderPDF(int nset) {
1460+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
1461+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
1462+ CURRENTSET = nset;
1463+ // return PDF order for the requested set
1464+ return ACTIVESETS[nset].activeMember()->info().get_entry_as<int>("OrderQCD", -1);
1465+}
1466+
1467+
1468+double LHAPDF::getLam4(int nmem) {
1469+ return LHAPDF::getLam4(1, nmem) ;
1470+}
1471+
1472+double LHAPDF::getLam4(int nset, int nmem) {
1473+ // if (ACTIVESETS.find(nset) == ACTIVESETS.end())
1474+ // throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
1475+ // CURRENTSET = nset;
1476+ // ACTIVESETS[nset].loadMember(nmem);
1477+ // return ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("AlphaS_Lambda4", -1.0);
1478+ double qcdl4;
1479+ getlam4m_(nset, nmem, qcdl4);
1480+ return qcdl4;
1481+}
1482+
1483+
1484+double LHAPDF::getLam5(int nmem) {
1485+ return LHAPDF::getLam5(1, nmem) ;
1486+}
1487+
1488+double LHAPDF::getLam5(int nset, int nmem) {
1489+ // if (ACTIVESETS.find(nset) == ACTIVESETS.end())
1490+ // throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
1491+ // CURRENTSET = nset;
1492+ // ACTIVESETS[nset].loadMember(nmem);
1493+ // return ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("AlphaS_Lambda5", -1.0);
1494+ double qcdl5;
1495+ getlam5m_(nset, nmem, qcdl5);
1496+ return qcdl5;
1497+}
1498+
1499+
1500+int LHAPDF::getNf() {
1501+ return LHAPDF::getNf(1) ;
1502+}
1503+
1504+int LHAPDF::getNf(int nset) {
1505+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
1506+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
1507+ CURRENTSET = nset;
1508+ // return alphaS Order for the requested set
1509+ return ACTIVESETS[nset].activeMember()->info().get_entry_as<int>("NumFlavors");
1510+}
1511+
1512+
1513+double LHAPDF::getXmin(int nmem) {
1514+ return LHAPDF::getXmin(1, nmem) ;
1515+}
1516+
1517+double LHAPDF::getXmin(int nset, int nmem) {
1518+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
1519+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
1520+ CURRENTSET = nset;
1521+ // return alphaS Order for the requested set
1522+ ACTIVESETS[nset].loadMember(nmem);
1523+ return ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("XMin");
1524+}
1525+
1526+double LHAPDF::getXmax(int nmem) {
1527+ return LHAPDF::getXmax(1, nmem) ;
1528+}
1529+
1530+double LHAPDF::getXmax(int nset, int nmem) {
1531+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
1532+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
1533+ CURRENTSET = nset;
1534+ // return alphaS Order for the requested set
1535+ ACTIVESETS[nset].loadMember(nmem);
1536+ return ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("XMax");
1537+}
1538+
1539+double LHAPDF::getQ2min(int nmem) {
1540+ return LHAPDF::getQ2min(1, nmem) ;
1541+}
1542+
1543+double LHAPDF::getQ2min(int nset, int nmem) {
1544+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
1545+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
1546+ CURRENTSET = nset;
1547+ // return alphaS Order for the requested set
1548+ ACTIVESETS[nset].loadMember(nmem);
1549+ return pow(ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("QMin"),2);
1550+}
1551+
1552+double LHAPDF::getQ2max(int nmem) {
1553+ return LHAPDF::getQ2max(1,nmem) ;
1554+}
1555+
1556+double LHAPDF::getQ2max(int nset, int nmem) {
1557+ if (ACTIVESETS.find(nset) == ACTIVESETS.end())
1558+ throw LHAPDF::UserError("Trying to use LHAGLUE set #" + LHAPDF::to_str(nset) + " but it is not initialised");
1559+ CURRENTSET = nset;
1560+ // return alphaS Order for the requested set
1561+ ACTIVESETS[nset].loadMember(nmem);
1562+ return pow(ACTIVESETS[nset].activeMember()->info().get_entry_as<double>("QMax"),2);
1563+}
1564+
1565+double LHAPDF::getQMass(int nf) {
1566+ return LHAPDF::getQMass(1, nf) ;
1567+}
1568+
1569+double LHAPDF::getQMass(int nset, int nf) {
1570+ double mass;
1571+ getqmassm_(nset, nf, mass);
1572+ return mass;
1573+}
1574+
1575+double LHAPDF::getThreshold(int nf) {
1576+ return LHAPDF::getThreshold(1, nf) ;
1577+}
1578+
1579+double LHAPDF::getThreshold(int nset, int nf) {
1580+ double thres;
1581+ getthresholdm_(nset, nf, thres);
1582+ return thres;
1583+}
1584+
1585+void LHAPDF::usePDFMember(int member) {
1586+ initpdf_(member);
1587+}
1588+
1589+void LHAPDF::usePDFMember(int nset, int member) {
1590+ initpdfm_(nset, member);
1591+}
1592+
1593+#endif // ENABLE_LHAGLUE_CXX

Subscribers

People subscribed via source and target branches

to all changes: