|
|
|||
File indexing completed on 2025-12-16 10:19:20
0001 // -*- C++ -*- 0002 // 0003 // This file is part of LHAPDF 0004 // Copyright (C) 2012-2024 The LHAPDF collaboration (see AUTHORS for details) 0005 // 0006 #pragma once 0007 #ifndef LHAPDF_PDF_H 0008 #define LHAPDF_PDF_H 0009 0010 #include "LHAPDF/PDFInfo.h" 0011 #include "LHAPDF/PDFIndex.h" 0012 #include "LHAPDF/Factories.h" 0013 #include "LHAPDF/AlphaS.h" 0014 #include "LHAPDF/Utils.h" 0015 #include "LHAPDF/Paths.h" 0016 #include "LHAPDF/Exceptions.h" 0017 #include "LHAPDF/Version.h" 0018 #include "LHAPDF/Config.h" 0019 0020 namespace LHAPDF { 0021 0022 0023 /// @defgroup partonids Parton ID codes 0024 /// @{ 0025 /// Convenience/clarity enum for specifying parton IDs 0026 namespace PIDs { //< for scoping to avoid conflicts, e.g. PID::GLUON rather than just GLUON 0027 enum PIDCode { 0028 ATOP = -6, ABOTTOM = -5, ACHARM = -4, ASTRANGE = -3, AUP = -2, ADOWN = -1, 0029 GLUON = 0, // equivalent to 21 0030 DOWN = 1, UP = 2, STRANGE = 3, CHARM = 4, BOTTOM = 5, TOP = 6 0031 }; 0032 } 0033 /// @} 0034 0035 0036 0037 /// @brief PDF is the general interface for access to parton density information. 0038 /// 0039 /// The PDF interface declares the general form of all PDF types, such as Grid based or analytic. 0040 class PDF { 0041 protected: //< These constructors should only be called by subclasses 0042 0043 /// Internal convenience typedef for the AlphaS object handle 0044 typedef unique_ptr<AlphaS> AlphaSPtr; 0045 0046 /// Force initialization of the only non-class member. 0047 PDF() : _forcePos(0) { } 0048 0049 0050 public: 0051 0052 /// Virtual destructor, to allow unfettered inheritance 0053 virtual ~PDF() { } 0054 0055 0056 protected: 0057 0058 0059 /// @name Helper methods for info loading / path setting, used by derived types 0060 ///@{ 0061 0062 void _loadInfo(const std::string& mempath); 0063 0064 void _loadInfo(const std::string& setname, int member) { 0065 const string searchpath = findpdfmempath(setname, member); 0066 if (searchpath.empty()) 0067 throw UserError("Can't find a valid PDF " + setname + "/" + to_str(member)); 0068 _loadInfo(searchpath); 0069 } 0070 0071 void _loadInfo(int lhaid) { 0072 const pair<string,int> setname_memid = lookupPDF(lhaid); 0073 if (setname_memid.second == -1) 0074 throw IndexError("Can't find a PDF with LHAPDF ID = " + to_str(lhaid)); 0075 _loadInfo(setname_memid.first, setname_memid.second); 0076 } 0077 0078 ///@} 0079 0080 0081 public: 0082 0083 /// @name PDF values 0084 ///@{ 0085 0086 /// @brief Get the PDF xf(x) value at (x,q2) for the given PID. 0087 /// 0088 /// All grids are defined in Q2 rather than Q since the natural value 0089 /// in MC programs is squared, so we typically avoid an expensive sqrt() call. 0090 /// 0091 /// @param id PDG parton ID 0092 /// @param x Momentum fraction 0093 /// @param q2 Squared energy (renormalization) scale 0094 /// @return The value of xf(x,q2) 0095 double xfxQ2(int id, double x, double q2) const; 0096 0097 0098 /// @brief Get the PDF xf(x) value at (x,q) for the given PID. 0099 /// 0100 /// xfxQ will square the given q and return the value from xfxQ2. 0101 /// All grids are defined in q2 rather than q since the natural value 0102 /// in MC programs is squared, so we typically avoid an expensive sqrt() call. 0103 /// 0104 /// @param id PDG parton ID 0105 /// @param x Momentum fraction 0106 /// @param q Energy (renormalization) scale 0107 /// @return The value of xf(x,q2) 0108 double xfxQ(int id, double x, double q) const { 0109 return xfxQ2(id, x, q*q); 0110 } 0111 0112 0113 /// @brief Get the PDF xf(x) value at (x,q2) for all supported PIDs. 0114 /// 0115 /// This version fills a user-supplied map to avoid container construction 0116 /// costs on every call. 0117 /// 0118 /// @param x Momentum fraction 0119 /// @param q2 Squared energy (renormalization) scale 0120 /// @param rtn Map of PDF xf(x,q2) values, to be filled 0121 void xfxQ2(double x, double q2, std::map<int, double>& rtn) const; 0122 0123 0124 /// @brief Get the PDF xf(x) value at (x,q) for all supported PIDs. 0125 /// 0126 /// This version fills a user-supplied map to avoid container construction 0127 /// costs on every call. 0128 /// 0129 /// @param x Momentum fraction 0130 /// @param q Energy (renormalization) scale 0131 /// @param rtn Map of PDF xf(x,q) values, to be filled 0132 void xfxQ(double x, double q, std::map<int, double>& rtn) const { 0133 xfxQ2(x, q*q, rtn); 0134 } 0135 0136 0137 /// @brief Get the PDF xf(x) value at (x,q2) for "standard" PIDs. 0138 /// 0139 /// This version fills a user-supplied vector to avoid container 0140 /// construction costs on every call. 0141 /// 0142 /// The filled vector follows the LHAPDF5 convention, with 13 entries 0143 /// running in the PDF ID order [-6, -5, ..., -1, 21, 1, ... 5, 6], i.e. 0144 /// quark PDF values will be at vector index pid+6 and the gluon at index 6. 0145 /// 0146 /// @param x Momentum fraction 0147 /// @param q2 Squared energy (renormalization) scale 0148 /// @param rtn Vector of PDF xf(x,q2) values, to be filled 0149 void xfxQ2(double x, double q2, std::vector<double>& rtn) const; 0150 0151 0152 /// @brief Get the PDF xf(x) value at (x,q) for "standard" PIDs. 0153 /// 0154 /// This version fills a user-supplied vector to avoid container 0155 /// construction costs on every call. 0156 /// 0157 /// The filled vector follows the LHAPDF5 convention, with 13 entries 0158 /// running in the PDF ID order [-6, -5, ..., -1, 21, 1, ... 5, 6], i.e. 0159 /// quark PDF values will be at vector index pid+6 and the gluon at index 6. 0160 /// 0161 /// @param x Momentum fraction 0162 /// @param q Energy (renormalization) scale 0163 /// @param rtn Vector of PDF xf(x,q) values, to be filled 0164 void xfxQ(double x, double q, std::vector<double>& rtn) const { 0165 xfxQ2(x, q*q, rtn); 0166 } 0167 0168 0169 /// @brief Get the PDF xf(x) value at (x,q2) for all supported PIDs. 0170 /// 0171 /// This version creates a new map on every call: prefer to use the 0172 /// fill-in-place version with a user-supplied map for many calls. 0173 /// 0174 /// @param x Momentum fraction 0175 /// @param q2 Squared energy (renormalization) scale 0176 /// @return A map of PDF xf(x,q2) values 0177 std::map<int, double> xfxQ2(double x, double q2) const; 0178 0179 /// @brief Get the PDF xf(x) value at (x,q) for all supported PIDs. 0180 /// 0181 /// This version creates a new map on every call: prefer to use the 0182 /// fill-in-place version with a user-supplied map for many calls. 0183 /// 0184 /// xfxQ will square the given q and return the value from xfxQ2. 0185 /// All grids are defined in q2 rather than q since the natural value 0186 /// in MC programs is squared, so we typically avoid an expensive sqrt() call. 0187 /// 0188 /// @param x Momentum fraction 0189 /// @param q Energy (renormalization) scale 0190 /// @return A map of PDF xf(x,q) values 0191 std::map<int, double> xfxQ(double x, double q) const { 0192 return xfxQ2(x, q*q); 0193 } 0194 0195 0196 protected: 0197 0198 /// @brief Calculate the PDF xf(x) value at (x,q2) for the given PID. 0199 /// 0200 /// This is the key function to be overridden in concrete PDF types, since 0201 /// it actually does the calculation of xf(x,Q2) by analytic, interpolation, 0202 /// or other means. The user-called xfxQ2 method exists so that the physical 0203 /// range and PID checks need only be done in one place, rather than need to 0204 /// be re-implemented in each concrete implementation. 0205 /// 0206 /// @param id Parton ID in the PDG scheme 0207 /// @param x Momentum fraction 0208 /// @param q2 Squared energy (renormalization) scale 0209 /// @return the value of xf(x,q2) 0210 virtual double _xfxQ2(int id, double x, double q2) const = 0; 0211 0212 virtual void _xfxQ2(double x, double q2, std::vector<double>& ret) const = 0; 0213 0214 ///@} 0215 0216 0217 public: 0218 0219 /// @name Ranges of validity 0220 ///@{ 0221 0222 /// Minimum valid x value for this PDF. 0223 virtual double xMin() { 0224 if (info().has_key("XMin")) 0225 return info().get_entry_as<double>("XMin"); 0226 return numeric_limits<double>::epsilon(); 0227 } 0228 0229 /// Maximum valid x value for this PDF. 0230 virtual double xMax() { 0231 if (info().has_key("XMax")) 0232 return info().get_entry_as<double>("XMax"); 0233 return 1.0; 0234 } 0235 0236 /// Minimum valid Q value for this PDF (in GeV). 0237 /// @note This function calls sqrt(q2Min()). For better CPU efficiency and accuracy use q2Min() directly. 0238 virtual double qMin() { 0239 return info().get_entry_as<double>("QMin", 0); 0240 } 0241 0242 /// @brief Maximum valid Q value for this PDF (in GeV). 0243 /// @note This function calls sqrt(q2Max()). For better CPU efficiency and accuracy use q2Max() directly. 0244 virtual double qMax() { 0245 return info().get_entry_as<double>("QMax", numeric_limits<double>::max()); 0246 } 0247 0248 /// Minimum valid Q2 value for this PDF (in GeV2). 0249 virtual double q2Min() { 0250 return sqr(this->qMin()); 0251 } 0252 0253 /// Maximum valid Q2 value for this PDF (in GeV2). 0254 virtual double q2Max() { 0255 // Explicitly re-access this from the info, to avoid an overflow from squaring double_max 0256 return (info().has_key("QMax")) ? sqr(info().get_entry_as<double>("QMax")) : numeric_limits<double>::max(); 0257 } 0258 0259 0260 /// @brief Check whether the PDF is set to only return positive (definite) values or not. 0261 /// 0262 /// This is to avoid overshooting in to negative values when 0263 /// interpolating/extrapolating PDFs that sharply decrease towards zero. 0264 /// 0 = unforced, 1 = forced positive, 2 = forced positive definite (>= 1e-10) 0265 int forcePositive() const { 0266 if (_forcePos < 0) //< Caching 0267 _forcePos = info().get_entry_as<unsigned int>("ForcePositive", 0); 0268 return _forcePos; 0269 } 0270 /// @brief Set whether the PDF will only return positive (definite) values or not. 0271 void setForcePositive(int mode) { 0272 _forcePos = mode; 0273 } 0274 0275 0276 /// @brief Check whether the given x is physically valid 0277 /// 0278 /// Returns false for x less than 0 or greater than 1, since it 0279 /// is a momentum fraction and not valid outside those values. 0280 bool inPhysicalRangeX(double x) const { 0281 return x >= 0.0 && x <= 1.0; 0282 } 0283 0284 /// @brief Check whether the given Q2 is physically valid 0285 /// 0286 /// Returns false for Q2 less than 0 (Q must be real-valued). 0287 bool inPhysicalRangeQ2(double q2) const { 0288 return q2 >= 0.0; 0289 } 0290 0291 /// @brief Check whether the given Q is physically valid 0292 /// 0293 /// Returns false for Q less than 0 (Q must be positive). 0294 bool inPhysicalRangeQ(double q) const { 0295 return inPhysicalRangeQ2(q*q); 0296 } 0297 0298 /// Check whether the given (x,Q2) is physically valid 0299 bool inPhysicalRangeXQ2(double x, double q2) const { 0300 return inPhysicalRangeX(x) && inPhysicalRangeQ2(q2); 0301 } 0302 0303 /// Check whether the given (x,Q) is physically valid 0304 bool inPhysicalRangeXQ(double x, double q) const { 0305 return inPhysicalRangeX(x) && inPhysicalRangeQ(q); 0306 } 0307 0308 /// @brief Grid range check for Q 0309 /// 0310 /// Return true when given Q is in the coverage range of this PDF. 0311 /// It actually squares the given Q and returns value from inRangeQ2. 0312 /// 0313 /// @param q Energy scale 0314 /// @return Whether q is in range 0315 virtual bool inRangeQ(double q) const { 0316 return inRangeQ2(q*q); 0317 } 0318 0319 /// @brief Grid range check for Q2 0320 /// 0321 /// Return true when given Q2 is in the coverage range of this PDF. 0322 /// 0323 /// @param q2 Squared energy scale 0324 /// @return Whether q2 is in range 0325 virtual bool inRangeQ2(double q2) const = 0; 0326 0327 /// @brief Grid range check for x 0328 /// 0329 /// Return true when given x is in the coverage range of this PDF. 0330 /// 0331 /// @param x Momentum fraction 0332 /// @return Whether x is in range 0333 virtual bool inRangeX(double x) const = 0; 0334 0335 /// Combined range check for x and Q 0336 virtual bool inRangeXQ(double x, double q) const { 0337 return inRangeX(x) && inRangeQ(q); 0338 } 0339 0340 /// Combined range check for x and Q2 0341 bool inRangeXQ2(double x, double q2) const { 0342 return inRangeX(x) && inRangeQ2(q2); 0343 } 0344 0345 ///@} 0346 0347 0348 /// @name Generic member-level metadata (including cascaded metadata from set & config level) 0349 ///@{ 0350 0351 /// Get the info class that actually stores and handles the metadata 0352 PDFInfo& info() { return _info; } 0353 0354 /// Get the info class that actually stores and handles the metadata (const version) 0355 const PDFInfo& info() const { return _info; } 0356 0357 /// @brief Get the PDF set of which this is a member 0358 /// 0359 /// Obtained from the member file path, not Info-based metadata. 0360 PDFSet& set() const { 0361 return getPDFSet(_setname()); 0362 } 0363 0364 ///@} 0365 0366 0367 /// @name Member-level metadata 0368 ///@{ 0369 0370 /// @brief PDF member local ID number 0371 /// 0372 /// Obtained from the member file path, not Info-based metadata. 0373 int memberID() const { 0374 const string memname = file_stem(_mempath); 0375 assert(memname.length() > 5); // There must be more to the filename stem than just the _nnnn suffix 0376 const int memid = lexical_cast<int>(memname.substr(memname.length()-4)); //< Last 4 chars should be the member number 0377 return memid; 0378 } 0379 0380 /// @brief PDF member global LHAPDF ID number 0381 /// 0382 /// Obtained from the member ID and the set's LHAPDF ID index 0383 int lhapdfID() const; 0384 0385 /// Description of this PDF member 0386 std::string description() const { 0387 return info().get_entry("MemDesc", info().get_entry("PdfDesc", "")); 0388 } 0389 0390 /// Version of this PDF's data file 0391 int dataversion() const { 0392 return info().get_entry_as<int>("DataVersion", -1); 0393 } 0394 0395 /// Get the type of PDF member that this object represents (central, error) 0396 std::string type() const { 0397 return to_lower(info().get_entry("MemType", info().get_entry("PdfType"))); 0398 } 0399 0400 ///@} 0401 0402 0403 /// Summary printout 0404 void print(std::ostream& os=std::cout, int verbosity=1) const; 0405 0406 0407 /// @name Parton content and QCD parameters 0408 ///@{ 0409 0410 /// @brief List of flavours defined by this PDF set. 0411 /// 0412 /// This list is stored locally after its initial read from the Info object 0413 /// to avoid unnecessary lookups and string decoding, since e.g. it is 0414 /// looked at by every call to the GridPDF's Interpolator and Extrapolator 0415 /// classes. 0416 /// 0417 /// @todo Make virtual for AnalyticPDF? Or allow manual setting of the Info? 0418 virtual const std::vector<int>& flavors() const { 0419 if (_flavors.empty()) { 0420 _flavors = info().get_entry_as< vector<int> >("Flavors"); 0421 sort(_flavors.begin(), _flavors.end()); 0422 } 0423 return _flavors; 0424 } 0425 0426 /// @brief Manually set/override the list of flavours defined by this PDF set. 0427 /// 0428 /// @note The provided vector will be internally sorted into ascending numeric order. 0429 void setFlavors(std::vector<int> const& flavors) { 0430 _flavors = flavors; 0431 sort(_flavors.begin(), _flavors.end()); 0432 } 0433 0434 /// Checks whether @a id is a valid parton for this PDF. 0435 bool hasFlavor(int id) const; 0436 0437 /// @brief Order of QCD at which this PDF has been constructed 0438 /// 0439 /// "Order" is defined here and throughout LHAPDF as the maximum number of 0440 /// loops included in the matrix elements, in order to have an integer value 0441 /// for easy use in comparisons, as opposed to "LO", "NLO", etc. strings. 0442 /// 0443 /// @todo Provide a setter function? 0444 int orderQCD() const { 0445 return info().get_entry_as<int>("OrderQCD"); 0446 } 0447 /// @deprecated Use orderQCD instead 0448 int qcdOrder() const { return orderQCD(); } 0449 0450 /// @brief Get a quark mass in GeV by PDG code (|PID| = 1-6 only) 0451 /// 0452 /// Convenience interface to the Mass* info keywords. 0453 /// Returns -1 for an undefined PID. 0454 /// 0455 /// @todo Provide a setter function? 0456 double quarkMass(int id) const; 0457 0458 /// @brief Get a flavor scale threshold in GeV by PDG code (|PID| = 1-6 only) 0459 /// Convenience interface to the Mass* and Threshold* info keywords. 0460 /// Returns -1 for an undefined PID. 0461 /// 0462 /// @todo Provide a setter function? 0463 double quarkThreshold(int id) const; 0464 0465 ///@} 0466 0467 0468 /// @name QCD running coupling calculation 0469 ///@{ 0470 0471 /// @brief Set the AlphaS calculator by pointer 0472 /// 0473 /// The provided AlphaS must have been new'd, as it will not be copied and 0474 /// ownership passes to this GridPDF: it will be deleted when this PDF goes 0475 /// out of scope or another setAlphaS call is made. 0476 void setAlphaS(AlphaS* alphas) { 0477 _alphas.reset(alphas); 0478 } 0479 0480 /// @brief Set the AlphaS calculator by smart pointer 0481 void setAlphaS(AlphaSPtr alphas) { 0482 _alphas = std::move(alphas); 0483 } 0484 0485 /// @brief Check if an AlphaS calculator is set 0486 bool hasAlphaS() const { 0487 return bool(_alphas); 0488 } 0489 0490 /// @brief Retrieve the AlphaS object for this PDF 0491 AlphaS& alphaS() { 0492 return *_alphas; 0493 } 0494 0495 /// @brief Retrieve the AlphaS object for this PDF (const) 0496 const AlphaS& alphaS() const { 0497 return *_alphas; 0498 } 0499 0500 /// @brief Value of alpha_s(Q2) used by this PDF 0501 /// 0502 /// Calculated numerically, analytically, or interpolated according to 0503 /// metadata, using the AlphaS classes. 0504 double alphasQ(double q) const { 0505 return alphasQ2(q*q); 0506 } 0507 0508 /// @brief Value of alpha_s(Q2) used by this PDF 0509 /// 0510 /// Calculated numerically, analytically, or interpolated according to 0511 /// metadata, using the AlphaS classes. 0512 double alphasQ2(double q2) const { 0513 if (!hasAlphaS()) throw Exception("No AlphaS pointer has been set"); 0514 return _alphas->alphasQ2(q2); 0515 } 0516 0517 ///@} 0518 0519 0520 protected: 0521 0522 void _loadAlphaS() { 0523 _alphas.reset( mkAlphaS(info()) ); 0524 } 0525 0526 /// Get the set name from the member data file path (for internal use only) 0527 std::string _setname() const { 0528 return basename(dirname(_mempath)); 0529 } 0530 0531 /// Member data file path 0532 std::string _mempath; 0533 0534 /// Metadata container 0535 PDFInfo _info; 0536 0537 /// Locally cached list of supported PIDs (mutable for laziness/caching) 0538 mutable vector<int> _flavors; 0539 0540 /// Optionally loaded AlphaS object (mutable for laziness/caching) 0541 mutable AlphaSPtr _alphas; 0542 0543 /// @brief Cached flag for whether to return only positive (or positive definite) PDF values 0544 /// 0545 /// A negative value indicates that the flag has not been set. 0 = no 0546 /// forcing, 1 = force positive (i.e. 0 is permitted, negative values are 0547 /// not), 2 = force positive definite (i.e. no values less than 1e-10). 0548 mutable int _forcePos; 0549 0550 }; 0551 0552 0553 } 0554 #endif
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|