Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-04-19 09:09:54

0001 #ifndef ATOOLS_Org_Settings_H
0002 #define ATOOLS_Org_Settings_H
0003 
0004 #include "ATOOLS/Org/Command_Line_Interface.H"
0005 #include "ATOOLS/Org/Settings_Keys.H"
0006 #include "ATOOLS/Org/Yaml_Reader.H"
0007 #include "ATOOLS/Org/MyStrStream.H"
0008 #include "ATOOLS/Org/Read_Write_Base.H"
0009 
0010 #include <vector>
0011 #include <unordered_set>
0012 
0013 namespace ATOOLS {
0014 
0015   class Settings_Keys;
0016   class Scoped_Settings;
0017   class Settings_Writer;
0018 
0019   /**
0020    * Settings organises the three ways run time parameters can be set.
0021    *
0022    * Overrides (`Override...`) have the highest priority, the command line
0023    * has the second highest priority, then the YAML run card is searched. If
0024    * the above do not provide the setting, the default set via SetDefault... is
0025    * returned.
0026    *
0027    * In fact, SetDefault... *must* be called before accessing a setting to make
0028    * sure that there are not suprises. Override... can be used even before
0029    * setting a default, but they will throw an exception if they conflict with
0030    * a previous override.
0031    *
0032    * To access a setting, use the [] operator (repeatedly for nested settings).
0033    * To set a default, use SetDefault..., e.g. for setting the default
0034    * YFS->MODE in the main settings singleton, use
0035    *
0036    *   auto& s = Settings::GetMainSettings();
0037    *   s["YFS"]["MODE"].SetDefault(1);
0038    *
0039    * Most functions support method chaining (i.e. they return a reference of
0040    * the called object), so if you want to read the setting immediately after
0041    * setting its default:
0042    *
0043    *   auto Nc = s["NCOLOURS"].SetDefault(3).GetScalar<int>();
0044    *
0045    * A default can be set repeatedly, but only to the same value. If a default
0046    * for a setting is set to one value, and later to a different value, an
0047    * exception is raised.
0048    *
0049    * To get around this, Get...WithOtherDefault can be called, which does the
0050    * same as SetDefault...().Get<T>() the above, but another default is passed
0051    * as an argument which is used instead of a default set by SetDefault...
0052    * earlier.  This can be useful e.g. for subclasses, that need to use a
0053    * different default for some reason.
0054    *
0055    * As we do not provide a caching functionality here, the retrieval of
0056    * defaults is rather expensive. Therefore make sure to set defaults and load
0057    * settings only during the set-up of the framework and certainly not from
0058    * within event loops.
0059    *
0060    * To access a list of subsettings, use `GetItems()`, e.g. like this:
0061    *
0062    *   for (const Scoped_Setting& s : mainsettings["PROCESSES"].GetItems()) {
0063    *     ...
0064    *   }
0065    *
0066    * When settings defaults and/or overrides, lists are ignored, i.e. for the
0067    * previous example, with
0068    * mainsettings["PROCESSES"][proc_name]["NIn"].SetDefault...(2), each
0069    * s[proc_name]["NIn"] will have its default set to 2.
0070    */
0071   class Settings {
0072 
0073     friend Scoped_Settings;
0074     friend Settings_Writer;
0075 
0076   public:
0077 
0078     static void InitializeMainSettings(int argc, char* argv[]);
0079     static void FinalizeMainSettings();
0080     static Settings& GetMainSettings();
0081 
0082     Settings();
0083     Settings(const std::string& yaml);
0084 
0085     Scoped_Settings operator[](const std::string& scope);
0086 
0087     std::vector<std::string> GetKeys();
0088 
0089     /// convenience function to declare (many) settings with empty defaults
0090     void DeclareVectorSettingsWithEmptyDefault(const std::vector<std::string>& keys);
0091     void DeclareMatrixSettingsWithEmptyDefault(const std::vector<std::string>& keys);
0092 
0093     /**
0094      * global tags will be replaced as-is, i.e. each occurrence of key will be
0095      * replaced by value; only values read as numbers are affected by this
0096      * replacement; an example is E_CMS; global tags are not defined by the
0097      * user
0098      */
0099     void AddGlobalTag(const std::string& key, const std::string& value);
0100 
0101     /**
0102      * tags will be replaced if they are found within $(...), i.e. each
0103      * occurrence of $(key) will be replaced by value; examples are NJETS or
0104      * SCF; all tags are defined by the user (on the command line or in the
0105      * config file)
0106      */
0107     void AddTag(const std::string& key, const std::string& value);
0108     const String_Map& GetTags()       { return m_tags; }
0109     void ReplaceTags(std::string&);
0110 
0111     std::string GetPath();
0112     String_Vector GetConfigFiles();
0113     String_Vector GetUserConfigFiles();
0114 
0115   private:
0116 
0117     static std::unique_ptr<Settings> mainsettings;
0118 
0119     // all defaults (and overrides) are stored as a matrix of strings
0120     typedef String_Vector Defaults_Key;
0121     typedef String_Matrix Defaults_Value;
0122     typedef std::map<Defaults_Key, Defaults_Value> Defaults;
0123     Defaults m_defaults;
0124     Defaults m_overrides;
0125 
0126     // keep records for writing out settings
0127     std::map<Settings_Keys, std::set<Defaults_Value>> m_usedvalues;
0128     std::map<Defaults_Key, std::unordered_set<std::string>> m_otherscalardefaults;
0129 
0130     std::map<Defaults_Key, String_Map> m_replacements;
0131     std::map<Defaults_Key, String_Vector> m_defaultsynonyms;
0132     std::map<Defaults_Key, String_Vector> m_synonyms;
0133 
0134     String_Map m_tags;
0135     String_Map m_globaltags;
0136 
0137     // all setting readers in their order of precedence (i.e. first one with a
0138     // match wins)
0139     std::vector<std::unique_ptr<Yaml_Reader>> m_yamlreaders;
0140 
0141     Algebra_Interpreter m_interpeter;
0142     bool m_interpreterenabled{ true };
0143 
0144     Settings(int argc, char* argv[]);
0145 
0146     std::vector<std::string> GetKeys(const Settings_Keys&);
0147 
0148     bool SetInterpreterEnabled(bool b) {
0149       const auto wasenabled = m_interpreterenabled;
0150       m_interpreterenabled = b;
0151       return wasenabled;
0152     }
0153 
0154     /**
0155      * the Get... functions already interprete strings as numbers; however, if
0156      * a value is first accessed as a string (e.g. when a list of different
0157      * value types read as a string vector first), Interprete can be used to
0158      * do this a-posteriori
0159      */
0160     template <typename T>
0161     T Interprete(std::string);
0162 
0163     void DeclareVectorSettingsWithEmptyDefault(const std::vector<std::string>& keys,
0164                                                const Settings_Keys&);
0165     void DeclareMatrixSettingsWithEmptyDefault(const std::vector<std::string>& keys,
0166                                                const Settings_Keys&);
0167 
0168     template <typename T>
0169     void SetDefault(const Settings_Keys&, const T& value);
0170     void SetDefault(const Settings_Keys&, const char* value);
0171     template <typename T>
0172     void SetDefault(const Settings_Keys&,
0173                     const std::vector<T>& values);
0174     template <typename T>
0175     void SetDefaultMatrix(const Settings_Keys&,
0176                           const std::vector<std::vector<T>>& values);
0177     template <typename T>
0178     void SetDefaultMatrix(const std::vector<std::string>& keys,
0179                           const std::vector<std::vector<T>>& values);
0180     bool HasDefault(const std::vector<std::string> &keys) const;
0181     void ResetDefault(const std::vector<std::string> &keys);
0182 
0183     bool IsSetExplicitly(const Settings_Keys&);
0184 
0185     template <typename T>
0186     void OverrideScalar(const Settings_Keys&, const T& value);
0187     template <typename T>
0188     void OverrideVector(const Settings_Keys&, const std::vector<T>& values);
0189     template <typename T>
0190     void OverrideMatrix(const Settings_Keys&,
0191                         const std::vector<std::vector<T>>& values);
0192 
0193     std::string GetScalarDefault(const Defaults_Key&, const Defaults&);
0194     String_Vector GetVectorDefault(const Defaults_Key&, const Defaults&);
0195     String_Matrix GetMatrixDefault(const Defaults_Key&, const Defaults&);
0196 
0197     template <typename T>
0198     T GetScalar(const Settings_Keys&);
0199     template <typename T>
0200     std::vector<T> GetVector(const Settings_Keys&);
0201     template <typename T>
0202     std::vector<std::vector<T>> GetMatrix(const Settings_Keys&);
0203 
0204     template <typename T>
0205     T GetScalarWithOtherDefault(const Settings_Keys&, const T& otherdefault);
0206 
0207     template <typename T>
0208     void SetReplacementList(const Settings_Keys&,
0209                             const std::map<std::string, T>& list);
0210 
0211     void SetDefaultSynonyms(const Settings_Keys&,
0212                             const String_Vector& synonyms);
0213 
0214     void SetSynonyms(const Settings_Keys&,
0215                      const String_Vector& synonyms);
0216 
0217     bool IsScalar(const Settings_Keys&);
0218     bool IsList(const Settings_Keys&);
0219     bool IsMap(const Settings_Keys&);
0220     size_t GetItemsCount(const Settings_Keys&);
0221 
0222     template <typename T>
0223     T Convert(const Settings_Keys&, const std::string&);
0224 
0225     bool IsDefaultSynonym(const Settings_Keys&,
0226                           const std::string& value);
0227 
0228     std::string ApplyReplacements(const Settings_Keys&,
0229                                   const std::string& value);
0230 
0231     // check if path is absolute, only works on Unix
0232     inline bool is_absolute(const std::string &s) {return (s.find("/") ==0);}
0233   };
0234 
0235   template <typename T>
0236   void Settings::SetDefault(const Settings_Keys& keys,
0237                                   const T& value)
0238   {
0239     SetDefaultMatrix<T>(keys, {{value}});
0240   }
0241 
0242   template <typename T>
0243   void Settings::SetDefault(const Settings_Keys& keys,
0244                             const std::vector<T>& values)
0245   {
0246     SetDefaultMatrix<T>(keys, {values});
0247   }
0248 
0249   template <typename T>
0250   void Settings::SetDefaultMatrix(const Settings_Keys& keys,
0251                                   const std::vector<std::vector<T> >& values)
0252   {
0253     SetDefaultMatrix(keys.IndicesRemoved(), values);
0254   }
0255 
0256   template <typename T>
0257   void Settings::SetDefaultMatrix(const std::vector<std::string>& keys,
0258                                   const std::vector<std::vector<T> >& values)
0259   {
0260     String_Matrix stringvalues;
0261     for (const auto& valuerow : values) {
0262       std::vector<std::string> stringvaluerow;
0263       for (const auto& value : valuerow) {
0264         stringvaluerow.push_back(ToString(value));
0265       }
0266       stringvalues.push_back(stringvaluerow);
0267     }
0268     const auto it = m_defaults.find(keys);
0269     if (it != m_defaults.end()) {
0270       if (it->second != stringvalues) {
0271         THROW(fatal_error, "The default value for " +
0272                                VectorToString(keys, 12, ":") +
0273                                " is already set to a different value.");
0274       } else {
0275         return;
0276       }
0277     }
0278     m_defaults[keys] = stringvalues;
0279   }
0280 
0281   template <typename T>
0282   void Settings::OverrideScalar(const Settings_Keys& settings_keys,
0283                                 const T& value)
0284   {
0285     OverrideVector<T>(settings_keys, {value});
0286   }
0287 
0288   template <typename T>
0289   void Settings::OverrideVector(const Settings_Keys& settings_keys,
0290                                 const std::vector<T>& values)
0291   {
0292     OverrideMatrix<T>(settings_keys, {values});
0293   }
0294 
0295   template <typename T>
0296   void Settings::OverrideMatrix(const Settings_Keys& settings_keys,
0297                                 const std::vector<std::vector<T>>& values)
0298   {
0299     String_Matrix stringvalues;
0300     for (const auto& valuerow : values) {
0301       std::vector<std::string> stringvaluerow;
0302       for (const auto& value : valuerow) {
0303         stringvaluerow.push_back(ToString(value));
0304       }
0305       stringvalues.push_back(stringvaluerow);
0306     }
0307     const std::vector<std::string> keys{ settings_keys.IndicesRemoved() };
0308     const auto it = m_overrides.find(keys);
0309     if (it != m_overrides.end()) {
0310       if (it->second != stringvalues) {
0311         THROW(fatal_error,
0312                "The override for "
0313                + keys.back() + " is already set to a different value.");
0314       } else {
0315         return;
0316       }
0317     }
0318     m_overrides[keys] = stringvalues;
0319   }
0320 
0321   template <typename T>
0322   T Settings::GetScalar(const Settings_Keys& settings_keys)
0323   {
0324     Defaults_Key keys{ settings_keys.IndicesRemoved() };
0325     Settings_Keys used_synonym_settings_keys;
0326     std::string defaultvalue;
0327     defaultvalue = GetScalarDefault(keys, m_defaults);
0328     std::string value;
0329     if (m_overrides.find(keys) != m_overrides.end()) {
0330       value = GetScalarDefault(keys, m_overrides);
0331     } else {
0332       const auto it = m_synonyms.find(keys);
0333       for (auto& reader : m_yamlreaders) {
0334         value = reader->GetScalar<std::string>(settings_keys);
0335         if (value.empty() && it != m_synonyms.end()) {
0336           auto synonym_settings_keys = settings_keys;
0337           for (const auto& synonym : it->second) {
0338             synonym_settings_keys.back() = synonym;
0339             value = reader->GetScalar<std::string>(synonym_settings_keys);
0340             if (!value.empty()) {
0341               used_synonym_settings_keys = synonym_settings_keys;
0342               keys = synonym_settings_keys.IndicesRemoved();
0343               break;
0344             }
0345           }
0346         }
0347         if (!value.empty())
0348           break;
0349       }
0350     }
0351     if (value.empty() || IsDefaultSynonym(settings_keys, value)) {
0352       value = defaultvalue;
0353     }
0354     const auto convertedvalue = Convert<T>(settings_keys, value);
0355     if (value.empty()) {
0356       if (!used_synonym_settings_keys.empty())
0357         m_usedvalues[used_synonym_settings_keys].insert(String_Matrix{{""}});
0358       else
0359         m_usedvalues[settings_keys].insert(String_Matrix{{""}});
0360     }
0361     else {
0362       if (!used_synonym_settings_keys.empty())
0363         m_usedvalues[used_synonym_settings_keys].insert(String_Matrix{{ToString<T>(convertedvalue)}});
0364       else
0365         m_usedvalues[settings_keys].insert(String_Matrix{{ToString<T>(convertedvalue)}});
0366     }
0367     return Convert<T>(settings_keys, value);
0368   }
0369 
0370   template <typename T>
0371   std::vector<T> Settings::GetVector(const Settings_Keys& settings_keys)
0372   {
0373     Defaults_Key keys{ settings_keys.IndicesRemoved() };
0374     Settings_Keys used_synonym_settings_keys;
0375     String_Vector defaultvalues;
0376     defaultvalues = GetVectorDefault(keys, m_defaults);
0377     std::vector<std::string> values;
0378     if (m_overrides.find(keys) != m_overrides.end()) {
0379       values = GetVectorDefault(keys, m_overrides);
0380     } else {
0381       const auto it = m_synonyms.find(keys);
0382       for (auto& reader : m_yamlreaders) {
0383         values = reader->GetVector<std::string>(settings_keys);
0384         if (values.empty() && it != m_synonyms.end()) {
0385           auto synonym_settings_keys = settings_keys;
0386           for (const auto& synonym : it->second) {
0387             synonym_settings_keys.back() = synonym;
0388             values = reader->GetVector<std::string>(synonym_settings_keys);
0389             if (!values.empty()) {
0390               used_synonym_settings_keys = synonym_settings_keys;
0391               keys = synonym_settings_keys.IndicesRemoved();
0392               break;
0393             }
0394           }
0395         }
0396         if (!values.empty())
0397           break;
0398       }
0399     }
0400     if (values.empty())
0401       values = defaultvalues;
0402     std::vector<T> convertedvalues;
0403     std::vector<std::string> convertedstringvalues;
0404     for (std::vector<std::string>::const_iterator it(values.begin());
0405          it != values.end();
0406          ++it) {
0407       convertedvalues.push_back(Convert<T>(settings_keys, *it));
0408       convertedstringvalues.push_back(ToString<T>(convertedvalues.back()));
0409     }
0410     if (values.empty()) {
0411       if (!used_synonym_settings_keys.empty())
0412         m_usedvalues[used_synonym_settings_keys].insert(String_Matrix{{}});
0413       else
0414         m_usedvalues[settings_keys].insert(String_Matrix{{}});
0415     }
0416     else {
0417       if (!used_synonym_settings_keys.empty())
0418         m_usedvalues[used_synonym_settings_keys].insert(String_Matrix{convertedstringvalues});
0419       else
0420         m_usedvalues[settings_keys].insert(String_Matrix{convertedstringvalues});
0421     }
0422     return convertedvalues;
0423   }
0424 
0425   template <typename T>
0426   std::vector<std::vector<T> > Settings::GetMatrix(
0427       const Settings_Keys& settings_keys)
0428   {
0429     Defaults_Key keys{ settings_keys.IndicesRemoved() };
0430     Settings_Keys used_synonym_settings_keys;
0431     String_Matrix defaultvalues;
0432     defaultvalues = GetMatrixDefault(keys, m_defaults);
0433     String_Matrix values;
0434     if (m_overrides.find(keys) != m_overrides.end()) {
0435       values = GetMatrixDefault(keys, m_overrides);
0436     } else {
0437       const auto it = m_synonyms.find(keys);
0438       for (auto& reader : m_yamlreaders) {
0439         values = reader->GetMatrix<std::string>(settings_keys);
0440         if (values.empty() && it != m_synonyms.end()) {
0441           auto synonym_settings_keys = settings_keys;
0442           for (const auto& synonym : it->second) {
0443             synonym_settings_keys.back() = synonym;
0444             values = reader->GetMatrix<std::string>(synonym_settings_keys);
0445             if (!values.empty()) {
0446               used_synonym_settings_keys = synonym_settings_keys;
0447               keys = synonym_settings_keys.IndicesRemoved();
0448               break;
0449             }
0450           }
0451         }
0452         if (!values.empty())
0453           break;
0454       }
0455     }
0456     if (values.empty())
0457       values = defaultvalues;
0458     std::vector<std::vector<T>> convertedvalues;
0459     String_Matrix convertedstringvalues;
0460     for (const auto& valuerow : values) {
0461       std::vector<T> convertedvaluerow;
0462       String_Vector convertedstringvaluerow;
0463       for (const auto& value : valuerow) {
0464         convertedvaluerow.push_back(Convert<T>(settings_keys, value));
0465         convertedstringvaluerow.push_back(ToString<T>(convertedvaluerow.back()));
0466       }
0467       convertedvalues.push_back(convertedvaluerow);
0468       convertedstringvalues.push_back(convertedstringvaluerow);
0469     }
0470     if (!used_synonym_settings_keys.empty())
0471       m_usedvalues[used_synonym_settings_keys].insert(convertedstringvalues);
0472     else
0473       m_usedvalues[settings_keys].insert(convertedstringvalues);
0474     return convertedvalues;
0475   }
0476 
0477   template <typename T>
0478   T Settings::GetScalarWithOtherDefault(const Settings_Keys& settings_keys,
0479                                         const T& otherdefault)
0480   {
0481     const Defaults_Key keys{ settings_keys.IndicesRemoved() };
0482     // temporarily replace m_defaults entry before calling GetScalar
0483     const auto it = m_defaults.find(keys);
0484     String_Matrix oldvalue;
0485     bool wasempty{ false };
0486     if (it == m_defaults.end()) {
0487       wasempty = true;
0488     } else {
0489       oldvalue = it->second;
0490       m_defaults.erase(it);
0491     }
0492     SetDefault(settings_keys, otherdefault);
0493     const T value{ GetScalar<T>(settings_keys) };
0494     if (wasempty)
0495       m_defaults.erase(m_defaults.find(keys));
0496     else
0497       m_defaults[keys] = oldvalue;
0498     m_otherscalardefaults[keys].insert(ToString<T>(otherdefault));
0499     return value;
0500   }
0501 
0502   template <typename T>
0503   void Settings::SetReplacementList(const Settings_Keys& settings_keys,
0504                                     const std::map<std::string, T>& list)
0505   {
0506     const Defaults_Key keys{ settings_keys.IndicesRemoved() };
0507     const auto it = m_replacements.find(keys);
0508     if (m_replacements.find(keys) != m_replacements.end())
0509       if (list != it->second)
0510         THROW(fatal_error, "A different scalar replacement list for "
0511                            + keys.back() + " has already been set.");
0512     m_replacements[keys] = list;
0513   }
0514 
0515 
0516   template <typename T>
0517   T Settings::Convert(const Settings_Keys& settings_keys,
0518                       const std::string& value)
0519   {
0520     std::string convertedvalue{ value };
0521     ReplaceTags(convertedvalue);
0522     convertedvalue = ApplyReplacements(settings_keys, convertedvalue);
0523     return Interprete<T>(convertedvalue);
0524   }
0525 
0526   template <typename T>
0527   T Settings::Interprete(std::string value)
0528   {
0529     T dummy;
0530     if (typeid(dummy) == typeid(int)
0531         || typeid(dummy)==typeid(unsigned int)
0532         || typeid(dummy)==typeid(long)
0533         || typeid(dummy)==typeid(float)
0534         || typeid(dummy)==typeid(double)
0535         || typeid(dummy)==typeid(unsigned long long)) {
0536       value = ReplaceUnits(value);
0537       if (m_interpreterenabled)
0538         value = m_interpeter.Interprete(value);
0539     }
0540     return ToType<T>(value);
0541   }
0542 
0543 }
0544 
0545 #endif