Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:58:13

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 // Global environment utility functions:
0027 //
0028 // G4GetEnv<T>
0029 //      Simplifies getting environment variables
0030 //      Automatic conversion to non-string types
0031 //      Records the values used from the environment
0032 // G4GetDataEnv
0033 //      For data library paths
0034 //      Will issue a G4Exception if not set
0035 // G4PrintEnv
0036 //      Provide a way for users to determine (and log) the environment
0037 //      variables were used as settings in simulation
0038 
0039 // Author: Jonathan Madsen, 25 October 2018
0040 // ---------------------------------------------------------------------------
0041 #ifndef G4ENVIRONMENTUTILS_HH
0042 #define G4ENVIRONMENTUTILS_HH
0043 
0044 #include <cstdlib>
0045 #include <iomanip>
0046 #include <iostream>
0047 #include <map>
0048 #include <mutex>
0049 #include <sstream>
0050 #include <string>
0051 
0052 #include "G4Exception.hh"
0053 #include "G4ExceptionSeverity.hh"
0054 #include "G4String.hh"
0055 #include "G4ios.hh"
0056 
0057 class G4EnvSettings
0058 {
0059   // Static singleton class storing environment variables and
0060   // their values that were used by Geant4 in the simulation
0061 
0062  public:
0063   using string_t   = std::string;
0064   using env_map_t  = std::map<string_t, string_t>;
0065   using env_pair_t = std::pair<string_t, string_t>;
0066 
0067   static G4EnvSettings* GetInstance()
0068   {
0069     static auto* _instance = new G4EnvSettings();
0070     return _instance;
0071   }
0072 
0073   template <typename _Tp>
0074   void insert(const std::string& env_id, _Tp val)
0075   {
0076     std::stringstream ss;
0077     ss << val;
0078     // lock for MT mode, use C++ type not Geant4 because this file
0079     // is included by the those headers
0080     static std::mutex _mutex;
0081     _mutex.lock();
0082     m_env.insert(env_pair_t(env_id, ss.str()));
0083     _mutex.unlock();
0084   }
0085 
0086   const env_map_t& get() const { return m_env; }
0087 
0088   friend std::ostream& operator<<(std::ostream& os, const G4EnvSettings& env)
0089   {
0090     std::stringstream filler;
0091     filler.fill('#');
0092     filler << std::setw(90) << "";
0093     std::stringstream ss;
0094     ss << filler.str() << "\n# Environment settings:\n";
0095     for(const auto& itr : env.get())
0096     {
0097       ss << "# " << std::setw(35) << std::right << itr.first << "\t = \t"
0098          << std::left << itr.second << "\n";
0099     }
0100     ss << filler.str();
0101     os << ss.str() << std::endl;
0102     return os;
0103   }
0104 
0105  private:
0106   env_map_t m_env;
0107 };
0108 
0109 // ---------------------------------------------------------------------------
0110 //  Use this function to get an environment variable setting +
0111 //  a default if not defined, e.g.
0112 //      int num_threads =
0113 //          G4GetEnv<int>("G4FORCENUMBEROFTHREADS",
0114 //                        std::thread::hardware_concurrency());
0115 template <typename _Tp>
0116 _Tp G4GetEnv(const std::string& env_id, _Tp _default = _Tp())
0117 {
0118   char* env_var = std::getenv(env_id.c_str());
0119   if(env_var)
0120   {
0121     std::string str_var = std::string(env_var);
0122     std::istringstream iss(str_var);
0123     _Tp var = _Tp();
0124     iss >> var;
0125     // record value defined by environment
0126     G4EnvSettings::GetInstance()->insert<_Tp>(env_id, var);
0127     return var;
0128   }
0129   // record default value
0130   G4EnvSettings::GetInstance()->insert<_Tp>(env_id, _default);
0131 
0132   // return default if not specified in environment
0133   return _default;
0134 }
0135 
0136 // ---------------------------------------------------------------------------
0137 //  Use this function to get an environment variable setting +
0138 //  a default if not defined, e.g.
0139 //      int num_threads =
0140 //          GetEnv<int>("FORCENUMBEROFTHREADS",
0141 //                      std::thread::hardware_concurrency());
0142 template <>
0143 inline G4bool G4GetEnv(const std::string& env_id, bool _default)
0144 {
0145   char* env_var = std::getenv(env_id.c_str());
0146   if(env_var != nullptr)
0147   {
0148     // record value defined by environment
0149     G4EnvSettings::GetInstance()->insert<bool>(env_id, true);
0150     return true;
0151   }
0152   // record default value
0153   G4EnvSettings::GetInstance()->insert<bool>(env_id, false);
0154 
0155   // return default if not specified in environment
0156   return _default;
0157 }
0158 
0159 // ---------------------------------------------------------------------------
0160 //  Use this function to get an environment variable setting +
0161 //  a default if not defined and a message about the setting, e.g.
0162 //      int num_threads =
0163 //          G4GetEnv<int>("G4FORCENUMBEROFTHREADS",
0164 //                        std::thread::hardware_concurrency(),
0165 //                        "Forcing number of threads");
0166 template <typename _Tp>
0167 _Tp G4GetEnv(const std::string& env_id, _Tp _default, const std::string& msg)
0168 {
0169   char* env_var = std::getenv(env_id.c_str());
0170   if(env_var)
0171   {
0172     std::string str_var = std::string(env_var);
0173     std::istringstream iss(str_var);
0174     _Tp var = _Tp();
0175     iss >> var;
0176     G4cout << "Environment variable \"" << env_id << "\" enabled with "
0177            << "value == " << var << ". " << msg << G4endl;
0178     // record value defined by environment
0179     G4EnvSettings::GetInstance()->insert<_Tp>(env_id, var);
0180     return var;
0181   }
0182   // record default value
0183   G4EnvSettings::GetInstance()->insert<_Tp>(env_id, _default);
0184 
0185   // return default if not specified in environment
0186   return _default;
0187 }
0188 
0189 // ---------------------------------------------------------------------------
0190 //  Use this function to get a data directory environment variable setting +
0191 //  and raise a G4Exception if the value is not set, e.g.
0192 //
0193 //      G4String filename = G4GetDataEnv("G4ENSDFSTATEDATA",
0194 //                                       "G4NuclideTable", "PART70000",
0195 //                                       FatalException,
0196 //                                       "G4ENSDFSTATEDATA environment variable"
0197 //                                       " must be set");
0198 inline G4String G4GetDataEnv(const std::string& env_id,
0199                              const char* originOfException,
0200                              const char* exceptionCode,
0201                              G4ExceptionSeverity severity,
0202                              const char* description)
0203 {
0204   char* env_var = std::getenv(env_id.c_str());
0205   if(env_var != nullptr)
0206   {
0207     std::string str_var = std::string(env_var);
0208     std::istringstream iss(str_var);
0209     G4String var = "";
0210     iss >> var;
0211     // record value defined by environment
0212     G4EnvSettings::GetInstance()->insert<G4String>(env_id, var);
0213     return var;
0214   }
0215 
0216   // issue an exception
0217   G4Exception(originOfException, exceptionCode, severity, description);
0218 
0219   // return default initialized
0220   return "";
0221 }
0222 
0223 const char* G4FindDataDir(const char*);
0224 
0225 // ---------------------------------------------------------------------------
0226 // Use this function to print the environment
0227 //
0228 inline void G4PrintEnv(std::ostream& os = G4cout)
0229 {
0230   os << (*G4EnvSettings::GetInstance());
0231 }
0232 
0233 #endif /* G4ENVIRONMENTUTILS_HH */