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