Merge lp:~maddevelopers/mg5amcnlo/2.6.1_lhapdf62 into lp:~mg5core2/mg5amcnlo/2.6.1
- 2.6.1_lhapdf62
- Merge into 2.6.1
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Olivier Mattelaer | Approve | ||
Rikkert Frederix | Pending | ||
Review via email: mp+331340@code.launchpad.net |
Commit message
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
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
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:/
> You are reviewing the proposed merge of lp:~maddevelopers/mg5amcnlo/2.6.1_lhapdf62 into lp:~mg5core2/mg5amcnlo/2.6.1.
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
Preview Diff
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 |
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