Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:19:19

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_Info_H
0008 #define LHAPDF_Info_H
0009 
0010 #include "LHAPDF/Utils.h"
0011 #include "LHAPDF/Paths.h"
0012 #include "LHAPDF/Exceptions.h"
0013 
0014 namespace LHAPDF {
0015 
0016 
0017   /// Get the singleton global configuration object
0018   ///
0019   /// @todo Move this out of Info. To Factories.h or SystemConfig.h?
0020   ///
0021   /// The global config is populated by reading from lhapdf.conf if it is
0022   /// found in the search paths.
0023   // class Info;
0024   // Info& config();
0025 
0026 
0027 
0028   /// Metadata base class for PDFs, PDF sets, or global configuration
0029   class Info {
0030   public:
0031 
0032     /// Default constructor
0033     Info() { }
0034 
0035     /// Constructor
0036     Info(const std::string& path) {
0037       load(path);
0038     }
0039 
0040     /// Virtual destructor to allow inheritance
0041     virtual ~Info() { }
0042 
0043 
0044     /// @name Loading info from YAML files
0045     ///@{
0046 
0047     /// Populate this info object from the specified YAML file path.
0048     ///
0049     /// This function may be called several times to read metadata from several
0050     /// YAML source files. Values for existing keys will be overwritten.
0051     void load(const std::string& filepath);
0052 
0053     ///@}
0054 
0055 
0056     /// @name General metadata accessors
0057     ///@{
0058 
0059     // /// Get all metadata as a map
0060     // const std::map<std::string, std::string>& metadata() const {
0061     //   return _metadict;
0062     // }
0063 
0064     // /// Get all metadata as a map (non-const)
0065     // std::map<std::string, std::string>& metadata() {
0066     //   return _metadict;
0067     // }
0068 
0069     /// Get the keys defined on this specific object
0070     std::vector<std::string> keys_local() const {
0071       std::vector<std::string> rtn;
0072       rtn.reserve(_metadict.size());
0073       for (const auto& kv : _metadict) rtn.push_back(kv.first);
0074       return rtn;
0075     }
0076 
0077     /// Get the keys defined on this object or cascaded into it
0078     ///
0079     /// The default implementation is equivalent to keys_local(). This is
0080     /// appropriate for Config, but should be overridden for more specific info
0081     /// types.
0082     std::vector<std::string> keys() const {
0083       return keys_local();
0084     }
0085 
0086     /// Is a value defined for the given key on this specific object?
0087     bool has_key_local(const std::string& key) const {
0088       return _metadict.find(key) != _metadict.end();
0089     }
0090 
0091     /// Can this object return a value for the given key?
0092     ///
0093     /// The given key may be defined non-locally, in which case the cascading
0094     /// member -> set -> config info lookup is needed. These are implemented
0095     /// using has_key_local() and metadata_local().
0096     ///
0097     /// The default implementation is equivalent to has_key_local(). This is
0098     /// appropriate for Config, but should be overridden for more specific info
0099     /// types.
0100     virtual bool has_key(const std::string& key) const {
0101       return has_key_local(key);
0102     }
0103 
0104 
0105     /// Retrieve a metadata string by key name, as defined on this specific object
0106     const std::string& get_entry_local(const std::string& key) const {
0107       if (has_key_local(key)) return _metadict.find(key)->second;
0108       throw MetadataError("Metadata for key: " + key + " not found.");
0109     }
0110 
0111     /// Retrieve a metadata string by key name
0112     ///
0113     /// The given key may be defined non-locally, in which case the cascading
0114     /// member -> set -> config info lookup is needed. These are implemented
0115     /// using has_key_local() and get_entry_local().
0116     ///
0117     /// The default implementation is equivalent to get_entry_local(). This is
0118     /// appropriate for Config, but should be overridden for more specific info types.
0119     virtual const std::string& get_entry(const std::string& key) const {
0120       return get_entry_local(key);
0121     }
0122 
0123 
0124     /// Retrieve a metadata string by key name, with a default fallback
0125     virtual const std::string& get_entry(const std::string& key, const std::string& fallback) const {
0126       try {
0127         return get_entry(key);
0128       } catch (...) {
0129         return fallback;
0130       }
0131     }
0132 
0133 
0134     /// Retrieve a metadata entry by key name, with an inline type cast
0135     ///
0136     /// Specialisations are defined below for unpacking of comma-separated lists
0137     /// of strings, ints, and doubles.
0138     template <typename T>
0139     T get_entry_as(const std::string& key) const {
0140       const string& s = get_entry(key);
0141       return lexical_cast<T>(s);
0142     }
0143 
0144 
0145     /// Retrieve a metadata entry by key name, with an inline type cast and default fallback
0146     template <typename T>
0147     T get_entry_as(const std::string& key, const T& fallback) const {
0148       try {
0149         return get_entry_as<T>(key);
0150       } catch (...) {
0151         return fallback;
0152       }
0153     }
0154 
0155 
0156     /// Set a keyed value entry
0157     template <typename T>
0158     void set_entry(const std::string& key, const T& val) {
0159       _metadict[key] = to_str(val);
0160     }
0161 
0162     ///@}
0163 
0164 
0165   protected:
0166 
0167     /// The string -> string native metadata storage container
0168     std::map<std::string, std::string> _metadict;
0169 
0170   };
0171 
0172 
0173 
0174   /// @name Info metadata function template specialisations
0175   ///@{
0176 
0177   template <>
0178   inline bool Info::get_entry_as(const std::string& key) const {
0179     const string& s = get_entry(key);
0180     try {
0181       bool rtn = lexical_cast<bool>(s);
0182       return rtn;
0183     } catch (...) {
0184       if (s == "true" || s == "on" || s == "yes") return true;
0185       if (s == "false" || s == "off" || s == "no") return false;
0186     }
0187     throw MetadataError("'" + s + "' is not a valid string for conversion to bool type");
0188   }
0189 
0190   template <>
0191   inline std::vector<std::string> Info::get_entry_as(const std::string& key) const {
0192     static const string delim = ",";
0193     string strval = trim(get_entry(key));
0194     // cout << "@@ " << strval << endl;
0195     if (startswith(strval, "[")) strval = strval.substr(1, strval.size()-1);
0196     if (endswith(strval, "]")) strval = strval.substr(0, strval.size()-1);
0197     // cout << "## " << strval << endl;
0198     return split(strval, delim);
0199   }
0200 
0201   template <>
0202   inline std::vector<int> Info::get_entry_as(const std::string& key) const {
0203     const vector<string> strs = get_entry_as< vector<string> >(key);
0204     vector<int> rtn;
0205     rtn.reserve(strs.size());
0206     for (const string& s : strs) rtn.push_back( lexical_cast<int>(s) );
0207     assert(rtn.size() == strs.size());
0208     return rtn;
0209   }
0210 
0211   template <>
0212   inline std::vector<double> Info::get_entry_as(const std::string& key) const {
0213     const vector<string> strs = get_entry_as< vector<string> >(key);
0214     vector<double> rtn;
0215     rtn.reserve(strs.size());
0216     for (const string& s : strs) rtn.push_back( lexical_cast<double>(s) );
0217     assert(rtn.size() == strs.size());
0218     return rtn;
0219   }
0220 
0221   ///@}
0222 
0223 
0224 }
0225 #endif