Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/global/management/include/G4EnvironmentUtils.hh

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 //
  2 // ********************************************************************
  3 // * License and Disclaimer                                           *
  4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.                             *
 10 // *                                                                  *
 11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                                                  *
 18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // ********************************************************************
 25 //
 26 // Global environment utility functions:
 27 //
 28 // G4GetEnv<T>
 29 //      Simplifies getting environment variables
 30 //      Automatic conversion to non-string types
 31 //      Records the values used from the environment
 32 // G4GetDataEnv
 33 //      For data library paths
 34 //      Will issue a G4Exception if not set
 35 // G4PrintEnv
 36 //      Provide a way for users to determine (and log) the environment
 37 //      variables were used as settings in simulation
 38 
 39 // Author: Jonathan Madsen, 25 October 2018
 40 // ---------------------------------------------------------------------------
 41 #ifndef G4ENVIRONMENTUTILS_HH
 42 #define G4ENVIRONMENTUTILS_HH
 43 
 44 #include <cstdlib>
 45 #include <iomanip>
 46 #include <iostream>
 47 #include <map>
 48 #include <mutex>
 49 #include <sstream>
 50 #include <string>
 51 
 52 #include "G4Exception.hh"
 53 #include "G4ExceptionSeverity.hh"
 54 #include "G4String.hh"
 55 #include "G4ios.hh"
 56 
 57 class G4EnvSettings
 58 {
 59   // Static singleton class storing environment variables and
 60   // their values that were used by Geant4 in the simulation
 61 
 62  public:
 63   using string_t   = std::string;
 64   using env_map_t  = std::map<string_t, string_t>;
 65   using env_pair_t = std::pair<string_t, string_t>;
 66 
 67   static G4EnvSettings* GetInstance()
 68   {
 69     static auto* _instance = new G4EnvSettings();
 70     return _instance;
 71   }
 72 
 73   template <typename _Tp>
 74   void insert(const std::string& env_id, _Tp val)
 75   {
 76     std::stringstream ss;
 77     ss << val;
 78     // lock for MT mode, use C++ type not Geant4 because this file
 79     // is included by the those headers
 80     static std::mutex _mutex;
 81     _mutex.lock();
 82     m_env.insert(env_pair_t(env_id, ss.str()));
 83     _mutex.unlock();
 84   }
 85 
 86   const env_map_t& get() const { return m_env; }
 87 
 88   friend std::ostream& operator<<(std::ostream& os, const G4EnvSettings& env)
 89   {
 90     std::stringstream filler;
 91     filler.fill('#');
 92     filler << std::setw(90) << "";
 93     std::stringstream ss;
 94     ss << filler.str() << "\n# Environment settings:\n";
 95     for(const auto& itr : env.get())
 96     {
 97       ss << "# " << std::setw(35) << std::right << itr.first << "\t = \t"
 98          << std::left << itr.second << "\n";
 99     }
100     ss << filler.str();
101     os << ss.str() << std::endl;
102     return os;
103   }
104 
105  private:
106   env_map_t m_env;
107 };
108 
109 // ---------------------------------------------------------------------------
110 //  Use this function to get an environment variable setting +
111 //  a default if not defined, e.g.
112 //      int num_threads =
113 //          G4GetEnv<int>("G4FORCENUMBEROFTHREADS",
114 //                        std::thread::hardware_concurrency());
115 template <typename _Tp>
116 _Tp G4GetEnv(const std::string& env_id, _Tp _default = _Tp())
117 {
118   char* env_var = std::getenv(env_id.c_str());
119   if(env_var)
120   {
121     std::string str_var = std::string(env_var);
122     std::istringstream iss(str_var);
123     _Tp var = _Tp();
124     iss >> var;
125     // record value defined by environment
126     G4EnvSettings::GetInstance()->insert<_Tp>(env_id, var);
127     return var;
128   }
129   // record default value
130   G4EnvSettings::GetInstance()->insert<_Tp>(env_id, _default);
131 
132   // return default if not specified in environment
133   return _default;
134 }
135 
136 // ---------------------------------------------------------------------------
137 //  Use this function to get an environment variable setting +
138 //  a default if not defined, e.g.
139 //      int num_threads =
140 //          GetEnv<int>("FORCENUMBEROFTHREADS",
141 //                      std::thread::hardware_concurrency());
142 template <>
143 inline G4bool G4GetEnv(const std::string& env_id, bool _default)
144 {
145   char* env_var = std::getenv(env_id.c_str());
146   if(env_var != nullptr)
147   {
148     // record value defined by environment
149     G4EnvSettings::GetInstance()->insert<bool>(env_id, true);
150     return true;
151   }
152   // record default value
153   G4EnvSettings::GetInstance()->insert<bool>(env_id, false);
154 
155   // return default if not specified in environment
156   return _default;
157 }
158 
159 // ---------------------------------------------------------------------------
160 //  Use this function to get an environment variable setting +
161 //  a default if not defined and a message about the setting, e.g.
162 //      int num_threads =
163 //          G4GetEnv<int>("G4FORCENUMBEROFTHREADS",
164 //                        std::thread::hardware_concurrency(),
165 //                        "Forcing number of threads");
166 template <typename _Tp>
167 _Tp G4GetEnv(const std::string& env_id, _Tp _default, const std::string& msg)
168 {
169   char* env_var = std::getenv(env_id.c_str());
170   if(env_var)
171   {
172     std::string str_var = std::string(env_var);
173     std::istringstream iss(str_var);
174     _Tp var = _Tp();
175     iss >> var;
176     G4cout << "Environment variable \"" << env_id << "\" enabled with "
177            << "value == " << var << ". " << msg << G4endl;
178     // record value defined by environment
179     G4EnvSettings::GetInstance()->insert<_Tp>(env_id, var);
180     return var;
181   }
182   // record default value
183   G4EnvSettings::GetInstance()->insert<_Tp>(env_id, _default);
184 
185   // return default if not specified in environment
186   return _default;
187 }
188 
189 // ---------------------------------------------------------------------------
190 //  Use this function to get a data directory environment variable setting +
191 //  and raise a G4Exception if the value is not set, e.g.
192 //
193 //      G4String filename = G4GetDataEnv("G4ENSDFSTATEDATA",
194 //                                       "G4NuclideTable", "PART70000",
195 //                                       FatalException,
196 //                                       "G4ENSDFSTATEDATA environment variable"
197 //                                       " must be set");
198 inline G4String G4GetDataEnv(const std::string& env_id,
199                              const char* originOfException,
200                              const char* exceptionCode,
201                              G4ExceptionSeverity severity,
202                              const char* description)
203 {
204   char* env_var = std::getenv(env_id.c_str());
205   if(env_var != nullptr)
206   {
207     std::string str_var = std::string(env_var);
208     std::istringstream iss(str_var);
209     G4String var = "";
210     iss >> var;
211     // record value defined by environment
212     G4EnvSettings::GetInstance()->insert<G4String>(env_id, var);
213     return var;
214   }
215 
216   // issue an exception
217   G4Exception(originOfException, exceptionCode, severity, description);
218 
219   // return default initialized
220   return "";
221 }
222 
223 const char* G4FindDataDir(const char*);
224 
225 // ---------------------------------------------------------------------------
226 // Use this function to print the environment
227 //
228 inline void G4PrintEnv(std::ostream& os = G4cout)
229 {
230   os << (*G4EnvSettings::GetInstance());
231 }
232 
233 #endif /* G4ENVIRONMENTUTILS_HH */
234