ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4EnvironmentUtils.hh
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4EnvironmentUtils.hh
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 //
27 // Global environment utility functions:
28 //
29 // G4GetEnv<T>
30 // Simplifies getting environment variables
31 // Automatic conversion to non-string types
32 // Records the values used from the environment
33 // G4GetDataEnv
34 // For data library paths
35 // Will issue a G4Exception if not set
36 // G4PrintEnv
37 // Provide a way for users to determine (and log) the environment
38 // variables were used as settings in simulation
39 //
40 // ---------------------------------------------------------------------------
41 #ifndef G4ENVIRONMENTUTILS_HH_
42 #define G4ENVIRONMENTUTILS_HH_
43 
44 #include <cstdlib>
45 #include <string>
46 #include <sstream>
47 #include <map>
48 #include <iostream>
49 #include <iomanip>
50 #include <mutex>
51 
52 #include "G4ios.hh"
53 #include "G4String.hh"
54 #include "G4Exception.hh"
55 #include "G4ExceptionSeverity.hh"
56 
57 // ---------------------------------------------------------------------------
58 
60 {
61  // Static singleton class storing environment variables and
62  // their values that were used by Geant4 in the simulation
63 
64  public:
65  typedef std::string string_t;
66  typedef std::map<string_t, string_t> env_map_t;
67  typedef std::pair<string_t, string_t> env_pair_t;
68 
69  public:
71  {
72  static G4EnvSettings* _instance = new G4EnvSettings();
73  return _instance;
74  }
75 
76  public:
77  template <typename _Tp>
78  void insert(const std::string& env_id, _Tp val)
79  {
80  std::stringstream ss;
81  ss << val;
82  // lock for MT mode, use C++ type not Geant4 because this file
83  // is included by the those headers
84  static std::mutex _mutex;
85  _mutex.lock();
86  m_env.insert(env_pair_t(env_id, ss.str()));
87  _mutex.unlock();
88  }
89 
90  const env_map_t& get() const { return m_env; }
91 
92  friend std::ostream& operator<<(std::ostream& os, const G4EnvSettings& env)
93  {
94  std::stringstream filler;
95  filler.fill('#');
96  filler << std::setw(90) << "";
97  std::stringstream ss;
98  ss << filler.str() << "\n# Environment settings:\n";
99  for(const auto& itr : env.get())
100  {
101  ss << "# " << std::setw(35) << std::right << itr.first
102  << "\t = \t" << std::left << itr.second << "\n";
103  }
104  ss << filler.str();
105  os << ss.str() << std::endl;
106  return os;
107  }
108 
109  private:
111 };
112 
113 // ---------------------------------------------------------------------------
114 // Use this function to get an environment variable setting +
115 // a default if not defined, e.g.
116 // int num_threads =
117 // G4GetEnv<int>("G4FORCENUMBEROFTHREADS",
118 // std::thread::hardware_concurrency());
119 template <typename _Tp>
120 _Tp G4GetEnv(const std::string& env_id, _Tp _default = _Tp())
121 {
122  char* env_var = std::getenv(env_id.c_str());
123  if(env_var)
124  {
125  std::string str_var = std::string(env_var);
126  std::istringstream iss(str_var);
127  _Tp var = _Tp();
128  iss >> var;
129  // record value defined by environment
130  G4EnvSettings::GetInstance()->insert<_Tp>(env_id, var);
131  return var;
132  }
133  // record default value
134  G4EnvSettings::GetInstance()->insert<_Tp>(env_id, _default);
135 
136  // return default if not specified in environment
137  return _default;
138 }
139 
140 // ---------------------------------------------------------------------------
141 // Use this function to get an environment variable setting +
142 // a default if not defined, e.g.
143 // int num_threads =
144 // GetEnv<int>("FORCENUMBEROFTHREADS",
145 // std::thread::hardware_concurrency());
146 template <> inline
147 G4bool G4GetEnv(const std::string& env_id, bool _default)
148 {
149  char* env_var = std::getenv(env_id.c_str());
150  if(env_var)
151  {
152  // record value defined by environment
153  G4EnvSettings::GetInstance()->insert<bool>(env_id, true);
154  return true;
155  }
156  // record default value
157  G4EnvSettings::GetInstance()->insert<bool>(env_id, false);
158 
159  // return default if not specified in environment
160  return _default;
161 }
162 
163 // ---------------------------------------------------------------------------
164 // Use this function to get an environment variable setting +
165 // a default if not defined and a message about the setting, e.g.
166 // int num_threads =
167 // G4GetEnv<int>("G4FORCENUMBEROFTHREADS",
168 // std::thread::hardware_concurrency(),
169 // "Forcing number of threads");
170 template <typename _Tp>
171 _Tp G4GetEnv(const std::string& env_id, _Tp _default, const std::string& msg)
172 {
173  char* env_var = std::getenv(env_id.c_str());
174  if(env_var)
175  {
176  std::string str_var = std::string(env_var);
177  std::istringstream iss(str_var);
178  _Tp var = _Tp();
179  iss >> var;
180  G4cout << "Environment variable \"" << env_id << "\" enabled with "
181  << "value == " << var << ". " << msg << G4endl;
182  // record value defined by environment
183  G4EnvSettings::GetInstance()->insert<_Tp>(env_id, var);
184  return var;
185  }
186  // record default value
187  G4EnvSettings::GetInstance()->insert<_Tp>(env_id, _default);
188 
189  // return default if not specified in environment
190  return _default;
191 }
192 
193 // ---------------------------------------------------------------------------
194 // Use this function to get a data directory environment variable setting +
195 // and raise a G4Exception if the value is not set, e.g.
196 //
197 // G4String filename = G4GetDataEnv("G4ENSDFSTATEDATA",
198 // "G4NuclideTable", "PART70000",
199 // FatalException,
200 // "G4ENSDFSTATEDATA environment variable"
201 // " must be set");
202 inline G4String
203 G4GetDataEnv(const std::string& env_id,
204  const char* originOfException,
205  const char* exceptionCode,
206  G4ExceptionSeverity severity,
207  const char* description)
208 {
209  char* env_var = std::getenv(env_id.c_str());
210  if(env_var)
211  {
212  std::string str_var = std::string(env_var);
213  std::istringstream iss(str_var);
214  G4String var = "";
215  iss >> var;
216  // record value defined by environment
217  G4EnvSettings::GetInstance()->insert<G4String>(env_id, var);
218  return var;
219  }
220 
221  // issue an exception
222  G4Exception(originOfException, exceptionCode, severity, description);
223 
224  // return default initialized
225  return "";
226 }
227 
228 // ---------------------------------------------------------------------------
229 // Use this function to print the environment
230 //
231 inline void G4PrintEnv(std::ostream& os = G4cout)
232 {
233  os << (*G4EnvSettings::GetInstance());
234 }
235 
236 //----------------------------------------------------------------------------//
237 
238 #endif /* G4ENVIRONMENTUTILS_HH_ */