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