Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4EnvironmentUtils.hh
Go to the documentation of this file.
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"
54#include "G4String.hh"
55#include "G4ios.hh"
56
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
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());
115template <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());
142template <>
143inline 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");
166template <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");
198inline 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
213 return var;
214 }
215
216 // issue an exception
217 G4Exception(originOfException, exceptionCode, severity, description);
218
219 // return default initialized
220 return "";
221}
222
223const char* G4FindDataDir(const char*);
224
225// ---------------------------------------------------------------------------
226// Use this function to print the environment
227//
228inline void G4PrintEnv(std::ostream& os = G4cout)
229{
231}
232
233#endif /* G4ENVIRONMENTUTILS_HH */
void G4PrintEnv(std::ostream &os=G4cout)
_Tp G4GetEnv(const std::string &env_id, _Tp _default=_Tp())
const char * G4FindDataDir(const char *)
G4String G4GetDataEnv(const std::string &env_id, const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
G4ExceptionSeverity
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
bool G4bool
Definition: G4Types.hh:86
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
void insert(const std::string &env_id, _Tp val)
std::map< string_t, string_t > env_map_t
std::pair< string_t, string_t > env_pair_t
std::string string_t
static G4EnvSettings * GetInstance()
const env_map_t & get() const
friend std::ostream & operator<<(std::ostream &os, const G4EnvSettings &env)