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 // G4tgrUtils implementation 26 // G4tgrUtils implementation 27 // 27 // 28 // Author: P.Arce, CIEMAT (November 2007) 28 // Author: P.Arce, CIEMAT (November 2007) 29 // ------------------------------------------- 29 // -------------------------------------------------------------------- 30 30 31 #include <iomanip> 31 #include <iomanip> 32 #include <set> 32 #include <set> 33 33 34 #include "G4tgrUtils.hh" 34 #include "G4tgrUtils.hh" 35 35 36 #include "geomdefs.hh" 36 #include "geomdefs.hh" 37 #include "G4PhysicalConstants.hh" 37 #include "G4PhysicalConstants.hh" 38 #include "G4tgrParameterMgr.hh" 38 #include "G4tgrParameterMgr.hh" 39 #include "G4tgrMessenger.hh" 39 #include "G4tgrMessenger.hh" 40 #include "G4UnitsTable.hh" 40 #include "G4UnitsTable.hh" 41 #include "G4GeometryTolerance.hh" 41 #include "G4GeometryTolerance.hh" 42 #include "G4UIcommand.hh" 42 #include "G4UIcommand.hh" 43 43 44 G4ThreadLocal G4tgrEvaluator* G4tgrUtils::theE 44 G4ThreadLocal G4tgrEvaluator* G4tgrUtils::theEvaluator = nullptr; 45 45 46 // ------------------------------------------- 46 // -------------------------------------------------------------------- 47 G4tgrUtils::G4tgrUtils() 47 G4tgrUtils::G4tgrUtils() 48 { 48 { 49 if(theEvaluator == nullptr) 49 if(theEvaluator == nullptr) 50 { 50 { 51 theEvaluator = new G4tgrEvaluator; 51 theEvaluator = new G4tgrEvaluator; 52 } 52 } 53 } 53 } 54 54 55 // ------------------------------------------- 55 // -------------------------------------------------------------------- 56 G4tgrUtils::~G4tgrUtils() 56 G4tgrUtils::~G4tgrUtils() 57 { 57 { 58 delete theEvaluator; 58 delete theEvaluator; 59 theEvaluator = nullptr; 59 theEvaluator = nullptr; 60 } 60 } 61 61 62 // ------------------------------------------- 62 // -------------------------------------------------------------------- 63 G4bool G4tgrUtils::IsSeparator(const char ch) 63 G4bool G4tgrUtils::IsSeparator(const char ch) 64 { 64 { 65 char nonCharacters[7] = { "()+-*/" }; 65 char nonCharacters[7] = { "()+-*/" }; 66 for(std::size_t ii = 0; ii < 6; ++ii) 66 for(std::size_t ii = 0; ii < 6; ++ii) 67 { 67 { 68 if(ch == nonCharacters[ii]) 68 if(ch == nonCharacters[ii]) 69 { 69 { 70 return true; 70 return true; 71 } 71 } 72 } 72 } 73 return false; 73 return false; 74 } 74 } 75 75 76 // ------------------------------------------- 76 // -------------------------------------------------------------------- 77 G4bool G4tgrUtils::IsNumber(const G4String& st 77 G4bool G4tgrUtils::IsNumber(const G4String& str) 78 { 78 { 79 G4int isnum = 1; 79 G4int isnum = 1; 80 G4int numE = 0; 80 G4int numE = 0; 81 for(G4int ii = 0; ii < (G4int)str.length(); 81 for(G4int ii = 0; ii < (G4int)str.length(); ++ii) 82 { 82 { 83 if(!isdigit(str[ii]) && (str[ii] != '.') & 83 if(!isdigit(str[ii]) && (str[ii] != '.') && (str[ii] != '-') && 84 (str[ii] != '+')) 84 (str[ii] != '+')) 85 { 85 { 86 //--- check for E(xponential) 86 //--- check for E(xponential) 87 if(str[ii] == 'E' || str[ii] == 'e') 87 if(str[ii] == 'E' || str[ii] == 'e') 88 { 88 { 89 if(ii == 0) 89 if(ii == 0) 90 { 90 { 91 return 0; 91 return 0; 92 } 92 } 93 if(numE != 0 || ii == G4int(str.length 93 if(numE != 0 || ii == G4int(str.length() - 1)) 94 { 94 { 95 isnum = 0; 95 isnum = 0; 96 break; 96 break; 97 } 97 } 98 numE++; 98 numE++; 99 } 99 } 100 else 100 else 101 { 101 { 102 isnum = 0; 102 isnum = 0; 103 break; 103 break; 104 } 104 } 105 } 105 } 106 } 106 } 107 return isnum; 107 return isnum; 108 } 108 } 109 109 110 // ------------------------------------------- 110 // -------------------------------------------------------------------- 111 G4bool G4tgrUtils::IsInteger(const G4double va 111 G4bool G4tgrUtils::IsInteger(const G4double val, const G4double precision) 112 { 112 { 113 if(G4int(val) / val - 1 > precision) 113 if(G4int(val) / val - 1 > precision) 114 { 114 { 115 return false; 115 return false; 116 } 116 } 117 else 117 else 118 { 118 { 119 return true; 119 return true; 120 } 120 } 121 } 121 } 122 122 123 // ------------------------------------------- 123 // -------------------------------------------------------------------- 124 void G4tgrUtils::Dump3v(const G4ThreeVector& v 124 void G4tgrUtils::Dump3v(const G4ThreeVector& vec, const char* msg) 125 { 125 { 126 G4cout << msg << std::setprecision(8) << vec 126 G4cout << msg << std::setprecision(8) << vec << std::setprecision(6) 127 << G4endl; 127 << G4endl; 128 } 128 } 129 129 130 // ------------------------------------------- 130 // -------------------------------------------------------------------- 131 void G4tgrUtils::Dumprm(const G4RotationMatrix 131 void G4tgrUtils::Dumprm(const G4RotationMatrix& rm, const char* msg) 132 { 132 { 133 G4cout << msg << G4endl << " xx=" << rm.xx() 133 G4cout << msg << G4endl << " xx=" << rm.xx() << " yx=" << rm.yx() 134 << " zx=" << rm.zx() << G4endl << " x 134 << " zx=" << rm.zx() << G4endl << " xy=" << rm.xy() 135 << " yy=" << rm.yy() << " zy=" << rm. 135 << " yy=" << rm.yy() << " zy=" << rm.zy() << G4endl 136 << " xz=" << rm.xz() << " yz=" << rm. 136 << " xz=" << rm.xz() << " yz=" << rm.yz() << " zz=" << rm.zz() 137 << G4endl; 137 << G4endl; 138 } 138 } 139 139 140 // ------------------------------------------- 140 // -------------------------------------------------------------------- 141 void G4tgrUtils::DumpVS(const std::vector<G4St 141 void G4tgrUtils::DumpVS(const std::vector<G4String>& wl, const char* msg, 142 std::ostream& outs) 142 std::ostream& outs) 143 { 143 { 144 outs << msg << G4endl; 144 outs << msg << G4endl; 145 for(auto ite = wl.cbegin(); ite != wl.cend() 145 for(auto ite = wl.cbegin(); ite != wl.cend(); ++ite) 146 { 146 { 147 outs << *ite << " "; 147 outs << *ite << " "; 148 } 148 } 149 outs << G4endl; 149 outs << G4endl; 150 } 150 } 151 151 152 // ------------------------------------------- 152 // -------------------------------------------------------------------- 153 void G4tgrUtils::DumpVS(const std::vector<G4St 153 void G4tgrUtils::DumpVS(const std::vector<G4String>& wl, const char* msg) 154 { 154 { 155 DumpVS(wl, msg, G4cout); 155 DumpVS(wl, msg, G4cout); 156 } 156 } 157 157 158 // ------------------------------------------- 158 // -------------------------------------------------------------------- 159 G4String G4tgrUtils::SubColon(const G4String& 159 G4String G4tgrUtils::SubColon(const G4String& str) 160 { 160 { 161 if(str.find(':') != 0) 161 if(str.find(':') != 0) 162 { 162 { 163 G4String ErrMessage = "Trying to subtract 163 G4String ErrMessage = "Trying to subtract leading colon from a word\n" + 164 G4String("that has n 164 G4String("that has no leading colon: ") + str; 165 G4Exception("G4tgrUtils::SubColon()", "Par 165 G4Exception("G4tgrUtils::SubColon()", "ParseError", FatalException, 166 ErrMessage); 166 ErrMessage); 167 } 167 } 168 G4String strt = str.substr(1, str.size() - 1 168 G4String strt = str.substr(1, str.size() - 1); 169 return strt; 169 return strt; 170 } 170 } 171 171 172 // ------------------------------------------- 172 // -------------------------------------------------------------------- 173 G4String G4tgrUtils::GetString(const G4String& 173 G4String G4tgrUtils::GetString(const G4String& str) 174 { 174 { 175 //----------- first check if it is parameter 175 //----------- first check if it is parameter 176 const char* cstr = str.c_str(); 176 const char* cstr = str.c_str(); 177 if(cstr[0] == '$') 177 if(cstr[0] == '$') 178 { 178 { 179 #ifdef G4VERBOSE 179 #ifdef G4VERBOSE 180 if(G4tgrMessenger::GetVerboseLevel() >= 3) 180 if(G4tgrMessenger::GetVerboseLevel() >= 3) 181 { 181 { 182 G4cout << " G4tgrUtils::GetString() - Su 182 G4cout << " G4tgrUtils::GetString() - Substitute parameter: " 183 << G4tgrParameterMgr::GetInstance 183 << G4tgrParameterMgr::GetInstance()->FindParameter( 184 str.substr(1, str.size())) 184 str.substr(1, str.size())) 185 << G4endl; 185 << G4endl; 186 } 186 } 187 #endif 187 #endif 188 return G4tgrParameterMgr::GetInstance()->F 188 return G4tgrParameterMgr::GetInstance()->FindParameter( 189 str.substr(1, str.size())); 189 str.substr(1, str.size())); 190 } 190 } 191 else 191 else 192 { 192 { 193 return str; 193 return str; 194 } 194 } 195 } 195 } 196 196 197 // ------------------------------------------- 197 // -------------------------------------------------------------------- 198 G4double G4tgrUtils::GetDouble(const G4String& 198 G4double G4tgrUtils::GetDouble(const G4String& str, G4double unitval) 199 { 199 { 200 if(!theEvaluator) 200 if(!theEvaluator) 201 { 201 { 202 theEvaluator = new G4tgrEvaluator; 202 theEvaluator = new G4tgrEvaluator; 203 } 203 } 204 #ifdef G4VERBOSE 204 #ifdef G4VERBOSE 205 if(G4tgrMessenger::GetVerboseLevel() >= 3) 205 if(G4tgrMessenger::GetVerboseLevel() >= 3) 206 { 206 { 207 G4cout << "G4tgrUtils::GetDouble() - Proce 207 G4cout << "G4tgrUtils::GetDouble() - Processing: " << str 208 << " default unit " << unitval << G 208 << " default unit " << unitval << G4endl; 209 } 209 } 210 #endif 210 #endif 211 if(str == "DBL_MAX") 211 if(str == "DBL_MAX") 212 { 212 { 213 return DBL_MAX; 213 return DBL_MAX; 214 } 214 } 215 else if(str == "DBL_MIN") 215 else if(str == "DBL_MIN") 216 { 216 { 217 return DBL_MIN; 217 return DBL_MIN; 218 } 218 } 219 else if(str == "FLT_MAX") 219 else if(str == "FLT_MAX") 220 { 220 { 221 return FLT_MAX; 221 return FLT_MAX; 222 } 222 } 223 else if(str == "FLT_MIN") 223 else if(str == "FLT_MIN") 224 { 224 { 225 return FLT_MIN; 225 return FLT_MIN; 226 } 226 } 227 else if(str == "INT_MAX") 227 else if(str == "INT_MAX") 228 { 228 { 229 return INT_MAX; 229 return INT_MAX; 230 } 230 } 231 else if(str == "INT_MIN") 231 else if(str == "INT_MIN") 232 { 232 { 233 return INT_MIN; 233 return INT_MIN; 234 } 234 } 235 //----- Look for arithmetic symbols, (, ) 235 //----- Look for arithmetic symbols, (, ) 236 const char* cstr = str.c_str(); 236 const char* cstr = str.c_str(); 237 std::set<G4int> separators; 237 std::set<G4int> separators; 238 separators.insert(-1); 238 separators.insert(-1); 239 G4int strlen = G4int(str.length()); 239 G4int strlen = G4int(str.length()); 240 for(G4int ii = 0; ii < strlen; ++ii) 240 for(G4int ii = 0; ii < strlen; ++ii) 241 { 241 { 242 char cs = cstr[ii]; 242 char cs = cstr[ii]; 243 if(cs == '*' || cs == '/' || cs == '(' || 243 if(cs == '*' || cs == '/' || cs == '(' || cs == ')') 244 { 244 { 245 separators.insert(ii); 245 separators.insert(ii); 246 } 246 } 247 else if(cs == '+' || cs == '-') 247 else if(cs == '+' || cs == '-') 248 { 248 { 249 // Check if it is not an exponential 249 // Check if it is not an exponential 250 // 250 // 251 if((ii < 2) || ((cstr[ii - 1] != 'E') && 251 if((ii < 2) || ((cstr[ii - 1] != 'E') && (cstr[ii - 1] != 'e')) || 252 !IsNumber(G4String(1,cstr[ii - 2]))) 252 !IsNumber(G4String(1,cstr[ii - 2]))) 253 { 253 { 254 separators.insert(ii); 254 separators.insert(ii); 255 } 255 } 256 } 256 } 257 } 257 } 258 separators.insert(strlen); 258 separators.insert(strlen); 259 std::string strnew; // build a new word wit 259 std::string strnew; // build a new word with Parameters 260 // and units substitute 260 // and units substituted by values 261 //----- Process words, defined as characters 261 //----- Process words, defined as characters between two separators 262 G4int nUnits = 0; 262 G4int nUnits = 0; 263 std::set<G4int>::const_iterator site, site2; 263 std::set<G4int>::const_iterator site, site2; 264 site = separators.cbegin(); 264 site = separators.cbegin(); 265 site2 = site; 265 site2 = site; 266 ++site2; 266 ++site2; 267 for(; site2 != separators.cend(); ++site, ++ 267 for(; site2 != separators.cend(); ++site, ++site2) 268 { 268 { 269 #ifdef G4VERBOSE 269 #ifdef G4VERBOSE 270 if(G4tgrMessenger::GetVerboseLevel() >= 3) 270 if(G4tgrMessenger::GetVerboseLevel() >= 3) 271 { 271 { 272 G4cout << " Loop to find word between 272 G4cout << " Loop to find word between " << *site << " " << *site2 273 << G4endl; 273 << G4endl; 274 } 274 } 275 #endif 275 #endif 276 276 277 if(*site != -1) 277 if(*site != -1) 278 { 278 { 279 strnew += str.substr(*site, 1); 279 strnew += str.substr(*site, 1); 280 } 280 } 281 281 282 G4int wlen = (*site2) - (*site) - 1; // d 282 G4int wlen = (*site2) - (*site) - 1; // do not count contiguous separators 283 std::string word; 283 std::string word; 284 if(wlen != 0) 284 if(wlen != 0) 285 { 285 { 286 word = str.substr((*site) + 1, (*site2) 286 word = str.substr((*site) + 1, (*site2) - (*site) - 1); 287 } 287 } 288 else 288 else 289 { 289 { 290 //--- Check combination of separators 290 //--- Check combination of separators 291 //--- Check number of parentheses 291 //--- Check number of parentheses 292 continue; 292 continue; 293 } 293 } 294 294 295 #ifdef G4VERBOSE 295 #ifdef G4VERBOSE 296 if(G4tgrMessenger::GetVerboseLevel() >= 3) 296 if(G4tgrMessenger::GetVerboseLevel() >= 3) 297 { 297 { 298 G4cout << " Processing word: " << word 298 G4cout << " Processing word: " << word << G4endl; 299 } 299 } 300 #endif 300 #endif 301 //----------- first check if it is paramet 301 //----------- first check if it is parameter 302 const char* cword = word.c_str(); 302 const char* cword = word.c_str(); 303 if(cword[0] == '$') 303 if(cword[0] == '$') 304 { 304 { 305 G4String parstr = G4tgrParameterMgr::Get 305 G4String parstr = G4tgrParameterMgr::GetInstance()->FindParameter( 306 word.substr(1, word.size())); 306 word.substr(1, word.size())); 307 if(parstr.substr(0, 1) == "-") 307 if(parstr.substr(0, 1) == "-") 308 { 308 { 309 strnew += "("; 309 strnew += "("; 310 } 310 } 311 strnew += parstr; 311 strnew += parstr; 312 if(parstr.substr(0, 1) == "-") 312 if(parstr.substr(0, 1) == "-") 313 { 313 { 314 strnew += ")"; 314 strnew += ")"; 315 } 315 } 316 #ifdef G4VERBOSE 316 #ifdef G4VERBOSE 317 if(G4tgrMessenger::GetVerboseLevel() >= 317 if(G4tgrMessenger::GetVerboseLevel() >= 3) 318 { 318 { 319 G4cout << " G4tgrutils::GetDouble() - 319 G4cout << " G4tgrutils::GetDouble() - Param found: " << word 320 << " in string " << str << " , 320 << " in string " << str << " , substituted by " << parstr 321 << G4endl; 321 << G4endl; 322 } 322 } 323 #endif 323 #endif 324 } 324 } 325 else 325 else 326 { 326 { 327 //----- Get if it is a number 327 //----- Get if it is a number 328 if(IsNumber(word)) 328 if(IsNumber(word)) 329 { 329 { 330 //--- left separator cannot be ')' 330 //--- left separator cannot be ')' 331 if((*site != -1) && (cstr[*site] == ') 331 if((*site != -1) && (cstr[*site] == ')')) 332 { 332 { 333 G4String ErrMessage = 333 G4String ErrMessage = 334 "There cannot be a ')' before a nu 334 "There cannot be a ')' before a number: " + word + 335 " in string: " + str; 335 " in string: " + str; 336 G4Exception("G4tgrUtils::GetDouble() 336 G4Exception("G4tgrUtils::GetDouble()", "ParseError", FatalException, 337 ErrMessage); 337 ErrMessage); 338 } 338 } 339 //--- right separator cannot be '(' 339 //--- right separator cannot be '(' 340 if((*site2 != strlen) && (cstr[*site2] 340 if((*site2 != strlen) && (cstr[*site2] == '(')) 341 { 341 { 342 G4String ErrMessage = 342 G4String ErrMessage = 343 "There cannot be a '(' after a num 343 "There cannot be a '(' after a number: " + word + 344 " in string: " + str; 344 " in string: " + str; 345 G4Exception("G4tgrUtils::GetDouble() 345 G4Exception("G4tgrUtils::GetDouble()", "ParseError", FatalException, 346 ErrMessage); 346 ErrMessage); 347 } 347 } 348 strnew += word; 348 strnew += word; 349 349 350 //------ If it is an string, check if 350 //------ If it is an string, check if it is a unit 351 } 351 } 352 else 352 else 353 { 353 { 354 //--- First character cannot be a digi 354 //--- First character cannot be a digit 355 if(isdigit(word[0])) 355 if(isdigit(word[0])) 356 { 356 { 357 G4String ErrMessage = 357 G4String ErrMessage = 358 "String words cannot start with a 358 "String words cannot start with a digit: " + word + 359 " in string: " + str; 359 " in string: " + str; 360 G4Exception("G4tgrUtils::GetDouble() 360 G4Exception("G4tgrUtils::GetDouble()", "ParseError", FatalException, 361 ErrMessage); 361 ErrMessage); 362 } 362 } 363 363 364 //----- Check if it is a function 364 //----- Check if it is a function 365 G4bool bWordOK = false; 365 G4bool bWordOK = false; 366 if(G4tgrUtils::IsFunction(word)) 366 if(G4tgrUtils::IsFunction(word)) 367 { 367 { 368 //--- It must be followed by '(' 368 //--- It must be followed by '(' 369 if((*site2 == strlen) || (cstr[*site 369 if((*site2 == strlen) || (cstr[*site2] != '(')) 370 { 370 { 371 G4String ErrMessage = 371 G4String ErrMessage = 372 "There must be a '(' after a fun 372 "There must be a '(' after a function: " + word + 373 " in string: " + str; 373 " in string: " + str; 374 G4Exception("G4tgrUtils::GetDouble 374 G4Exception("G4tgrUtils::GetDouble()", "ParseError", FatalException, 375 ErrMessage); 375 ErrMessage); 376 } 376 } 377 strnew += word; 377 strnew += word; 378 bWordOK = true; 378 bWordOK = true; 379 //----- Check if it is a unit 379 //----- Check if it is a unit 380 } 380 } 381 else if(G4tgrUtils::WordIsUnit(word)) 381 else if(G4tgrUtils::WordIsUnit(word)) 382 { 382 { 383 //--- It must be preceded by a * 383 //--- It must be preceded by a * 384 if((*site == -1) || ((cstr[*site] != 384 if((*site == -1) || ((cstr[*site] != '*') && (cstr[*site] != '/'))) 385 { 385 { 386 G4String ErrMess = 386 G4String ErrMess = 387 "There must be a '*' before a un 387 "There must be a '*' before a unit definition: " + word + 388 " in string " + str; 388 " in string " + str; 389 G4Exception("G4tgrUtils::GetDouble 389 G4Exception("G4tgrUtils::GetDouble()", "ParseError", FatalException, 390 ErrMess); 390 ErrMess); 391 } 391 } 392 //--- check that it is indeed a CLHE 392 //--- check that it is indeed a CLHEP unit 393 if(G4UnitDefinition::GetValueOf(word 393 if(G4UnitDefinition::GetValueOf(word) != 0.) 394 { 394 { 395 bWordOK = true; 395 bWordOK = true; 396 nUnits++; 396 nUnits++; 397 if(nUnits > 1) 397 if(nUnits > 1) 398 { 398 { 399 // G4String ErrMess = "There can 399 // G4String ErrMess = "There cannot be two unit definitions: " 400 // + word + " i 400 // + word + " in string " + str; 401 // G4Exception("G4tgrUtils::GetD 401 // G4Exception("G4tgrUtils::GetDouble()", "ParseError", 402 // FatalException, E 402 // FatalException, ErrMess ); 403 } 403 } 404 strnew += 404 strnew += 405 G4UIcommand::ConvertToString(G4U 405 G4UIcommand::ConvertToString(G4UnitDefinition::GetValueOf(word)); 406 } 406 } 407 } 407 } 408 if(!bWordOK) 408 if(!bWordOK) 409 { 409 { 410 G4String ErrMess = "String word is n 410 G4String ErrMess = "String word is not a parameter, nor a unit\n" + 411 G4String("definit 411 G4String("definition nor a function: ") + word + 412 G4String(" in str 412 G4String(" in string: ") + str; 413 G4Exception("G4tgrUtils::GetDouble() 413 G4Exception("G4tgrUtils::GetDouble()", "ParseError", FatalException, 414 ErrMess); 414 ErrMess); 415 } 415 } 416 } 416 } 417 } 417 } 418 } 418 } 419 419 420 G4double val = theEvaluator->evaluate(strnew 420 G4double val = theEvaluator->evaluate(strnew.c_str()); 421 if(theEvaluator->status() != HepTool::Evalua 421 if(theEvaluator->status() != HepTool::Evaluator::OK) 422 { 422 { 423 theEvaluator->print_error(theEvaluator->st 423 theEvaluator->print_error(theEvaluator->status()); 424 G4String ErrMessage = "Evaluator error: " 424 G4String ErrMessage = "Evaluator error: " + strnew; 425 G4Exception("G4tgrUtils::GetDouble()", "Pa 425 G4Exception("G4tgrUtils::GetDouble()", "ParseError", FatalException, 426 ErrMessage); 426 ErrMessage); 427 } 427 } 428 428 429 if(nUnits == 0) 429 if(nUnits == 0) 430 { 430 { 431 val *= unitval; 431 val *= unitval; 432 } 432 } 433 433 434 #ifdef G4VERBOSE 434 #ifdef G4VERBOSE 435 if(G4tgrMessenger::GetVerboseLevel() >= 3) 435 if(G4tgrMessenger::GetVerboseLevel() >= 3) 436 { 436 { 437 G4cout << " G4tgrUtils::GetDouble() - RESU 437 G4cout << " G4tgrUtils::GetDouble() - RESULT= " << val << G4endl 438 << " from string: " << str << " c 438 << " from string: " << str << " converted to: " << strnew.c_str() 439 << " with unit val: " << unitval << 439 << " with unit val: " << unitval << G4endl; 440 } 440 } 441 #endif 441 #endif 442 442 443 return val; 443 return val; 444 } 444 } 445 445 446 // ------------------------------------------- 446 // -------------------------------------------------------------------- 447 G4int G4tgrUtils::GetInt(const G4String& str) 447 G4int G4tgrUtils::GetInt(const G4String& str) 448 { 448 { 449 //----- Convert it to a number (it can be a 449 //----- Convert it to a number (it can be a parameter) 450 G4double val = GetDouble(str); 450 G4double val = GetDouble(str); 451 451 452 //----- Check it is an integer 452 //----- Check it is an integer 453 if(!IsInteger(val)) 453 if(!IsInteger(val)) 454 { 454 { 455 G4String ErrMessage = G4String("Trying to 455 G4String ErrMessage = G4String("Trying to get the integer from a number") + 456 G4String(" which is 456 G4String(" which is not an integer ") + str; 457 G4Exception("G4tgrUtils::GetInt()", "Parse 457 G4Exception("G4tgrUtils::GetInt()", "ParseError", FatalException, 458 ErrMessage); 458 ErrMessage); 459 } 459 } 460 return G4int(val); 460 return G4int(val); 461 } 461 } 462 462 463 // ------------------------------------------- 463 // -------------------------------------------------------------------- 464 G4bool G4tgrUtils::GetBool(const G4String& str 464 G4bool G4tgrUtils::GetBool(const G4String& str) 465 { 465 { 466 G4bool val = false; 466 G4bool val = false; 467 467 468 //----------- first check that it is a not n 468 //----------- first check that it is a not number 469 if((str == "ON") || (str == "TRUE")) 469 if((str == "ON") || (str == "TRUE")) 470 { 470 { 471 val = true; 471 val = true; 472 } 472 } 473 else if((str == "OFF") || (str == "FALSE")) 473 else if((str == "OFF") || (str == "FALSE")) 474 { 474 { 475 val = false; 475 val = false; 476 } 476 } 477 else 477 else 478 { 478 { 479 G4String ErrMessage = G4String("Trying to 479 G4String ErrMessage = G4String("Trying to get a float from a string") + 480 G4String(" which is 480 G4String(" which is not 'ON'/'OFF'/'TRUE'/'FALSE' ") + 481 str; 481 str; 482 G4Exception("G4tgrUtils::GetBool()", "Pars 482 G4Exception("G4tgrUtils::GetBool()", "ParseError", FatalException, 483 ErrMessage); 483 ErrMessage); 484 } 484 } 485 485 486 return val; 486 return val; 487 } 487 } 488 488 489 // ------------------------------------------- 489 // -------------------------------------------------------------------- 490 void G4tgrUtils::CheckWLsize(const std::vector 490 void G4tgrUtils::CheckWLsize(const std::vector<G4String>& wl, 491 unsigned int nWch 491 unsigned int nWcheck, WLSIZEtype st, 492 const G4String& m 492 const G4String& methodName) 493 { 493 { 494 G4String outStr = methodName + G4String(". 494 G4String outStr = methodName + G4String(". Line read with number of words "); 495 unsigned int wlsize = (unsigned int)wl.size( 495 unsigned int wlsize = (unsigned int)wl.size(); 496 496 497 G4bool isOK = CheckListSize(wlsize, nWcheck, 497 G4bool isOK = CheckListSize(wlsize, nWcheck, st, outStr); 498 498 499 if(!isOK) 499 if(!isOK) 500 { 500 { 501 G4String chartmp = G4UIcommand::ConvertToS 501 G4String chartmp = G4UIcommand::ConvertToString(G4int(nWcheck)); 502 outStr += chartmp + G4String(" words"); 502 outStr += chartmp + G4String(" words"); 503 DumpVS(wl, outStr.c_str()); 503 DumpVS(wl, outStr.c_str()); 504 G4String ErrMessage = 504 G4String ErrMessage = 505 " NUMBER OF WORDS: " + G4UIcommand::Conv 505 " NUMBER OF WORDS: " + G4UIcommand::ConvertToString(G4int(wlsize)); 506 G4Exception("G4tgrUtils::CheckWLsize()", " 506 G4Exception("G4tgrUtils::CheckWLsize()", "ParseError", FatalException, 507 ErrMessage); 507 ErrMessage); 508 } 508 } 509 } 509 } 510 510 511 // ------------------------------------------- 511 // -------------------------------------------------------------------- 512 G4bool G4tgrUtils::CheckListSize(unsigned int 512 G4bool G4tgrUtils::CheckListSize(unsigned int nWreal, unsigned int nWcheck, 513 WLSIZEtype st 513 WLSIZEtype st, G4String& outStr) 514 { 514 { 515 G4bool isOK = true; 515 G4bool isOK = true; 516 switch(st) 516 switch(st) 517 { 517 { 518 case WLSIZE_EQ: 518 case WLSIZE_EQ: 519 if(nWreal != nWcheck) 519 if(nWreal != nWcheck) 520 { 520 { 521 isOK = false; 521 isOK = false; 522 outStr += G4String("not equal than "); 522 outStr += G4String("not equal than "); 523 } 523 } 524 break; 524 break; 525 case WLSIZE_NE: 525 case WLSIZE_NE: 526 if(nWreal == nWcheck) 526 if(nWreal == nWcheck) 527 { 527 { 528 isOK = false; 528 isOK = false; 529 outStr += G4String("equal than "); 529 outStr += G4String("equal than "); 530 } 530 } 531 break; 531 break; 532 case WLSIZE_LE: 532 case WLSIZE_LE: 533 if(nWreal > nWcheck) 533 if(nWreal > nWcheck) 534 { 534 { 535 isOK = false; 535 isOK = false; 536 outStr += G4String("greater than "); 536 outStr += G4String("greater than "); 537 } 537 } 538 break; 538 break; 539 case WLSIZE_LT: 539 case WLSIZE_LT: 540 if(nWreal >= nWcheck) 540 if(nWreal >= nWcheck) 541 { 541 { 542 isOK = false; 542 isOK = false; 543 outStr += G4String("greater or equal t 543 outStr += G4String("greater or equal than "); 544 } 544 } 545 break; 545 break; 546 case WLSIZE_GE: 546 case WLSIZE_GE: 547 if(nWreal < nWcheck) 547 if(nWreal < nWcheck) 548 { 548 { 549 isOK = false; 549 isOK = false; 550 outStr += G4String("less than "); 550 outStr += G4String("less than "); 551 } 551 } 552 break; 552 break; 553 case WLSIZE_GT: 553 case WLSIZE_GT: 554 if(nWreal <= nWcheck) 554 if(nWreal <= nWcheck) 555 { 555 { 556 isOK = false; 556 isOK = false; 557 outStr += G4String("less or equal than 557 outStr += G4String("less or equal than "); 558 } 558 } 559 break; 559 break; 560 default: 560 default: 561 G4cerr << " ERROR!! - G4tgrUtils::CheckL 561 G4cerr << " ERROR!! - G4tgrUtils::CheckListSize()" << G4endl 562 << " Type of WLSIZE typ 562 << " Type of WLSIZE type not found " << st << G4endl; 563 break; 563 break; 564 } 564 } 565 565 566 return isOK; 566 return isOK; 567 } 567 } 568 568 569 // ------------------------------------------- 569 // -------------------------------------------------------------------- 570 G4bool G4tgrUtils::WordIsUnit(const G4String& 570 G4bool G4tgrUtils::WordIsUnit(const G4String& word) 571 { 571 { 572 return !IsNumber(word); 572 return !IsNumber(word); 573 if(word == "mm" || word == "cm" || word == " 573 if(word == "mm" || word == "cm" || word == "m" || word == "km" || 574 word == "millimeter" || word == "centimet 574 word == "millimeter" || word == "centimeter" || word == "meter" || 575 word == "kilometer" || word == "parsec" | 575 word == "kilometer" || word == "parsec" || word == "micrometer" || 576 word == "nanometer" || word == "angstrom" 576 word == "nanometer" || word == "angstrom" || word == "fermi" || 577 word == "nm" || word == "um" || word == " 577 word == "nm" || word == "um" || word == "pc" || word == "radian" || 578 word == "milliradian" || word == "degree" 578 word == "milliradian" || word == "degree" || word == "rad" || 579 word == "mrad" || word == "deg" || word = 579 word == "mrad" || word == "deg" || word == "ns" || word == "becquerel" || 580 word == "curie") 580 word == "curie") 581 { 581 { 582 return true; 582 return true; 583 } 583 } 584 else 584 else 585 { 585 { 586 return false; 586 return false; 587 } 587 } 588 } 588 } 589 589 590 // ------------------------------------------- 590 // -------------------------------------------------------------------- 591 G4bool G4tgrUtils::IsFunction(const G4String& 591 G4bool G4tgrUtils::IsFunction(const G4String& word) 592 { 592 { 593 if(word == "sin" || word == "cos" || word == 593 if(word == "sin" || word == "cos" || word == "tan" || word == "asin" || 594 word == "acos" || word == "atan" || word 594 word == "acos" || word == "atan" || word == "atan2" || word == "sinh" || 595 word == "cosh" || word == "tanh" || word 595 word == "cosh" || word == "tanh" || word == "asinh" || word == "acosh" || 596 word == "atanh" || word == "sqrt" || word 596 word == "atanh" || word == "sqrt" || word == "exp" || word == "log" || 597 word == "log10" || word == "pow") 597 word == "log10" || word == "pow") 598 { 598 { 599 return true; 599 return true; 600 } 600 } 601 else 601 else 602 { 602 { 603 return false; 603 return false; 604 } 604 } 605 } 605 } 606 606 607 // ------------------------------------------- 607 // -------------------------------------------------------------------- 608 G4RotationMatrix G4tgrUtils::GetRotationFromDi 608 G4RotationMatrix G4tgrUtils::GetRotationFromDirection(G4ThreeVector dir) 609 { 609 { 610 G4RotationMatrix rotation; 610 G4RotationMatrix rotation; 611 611 612 if(std::fabs(dir.mag() - 1.) > 612 if(std::fabs(dir.mag() - 1.) > 613 G4GeometryTolerance::GetInstance()->GetSu 613 G4GeometryTolerance::GetInstance()->GetSurfaceTolerance()) 614 { 614 { 615 G4String WarMessage = "Direction cosines h 615 G4String WarMessage = "Direction cosines have been normalized to one.\n" + 616 G4String("They were 616 G4String("They were normalized to ") + 617 G4UIcommand::Convert 617 G4UIcommand::ConvertToString(dir.mag()); 618 G4Exception("G4tgrUtils::GetRotationFromDi 618 G4Exception("G4tgrUtils::GetRotationFromDirection()", "WrongArgument", 619 JustWarning, WarMessage); 619 JustWarning, WarMessage); 620 dir /= dir.mag(); 620 dir /= dir.mag(); 621 } 621 } 622 G4double angx = -std::asin(dir.y()); 622 G4double angx = -std::asin(dir.y()); 623 623 624 // There are always two solutions angx, angy 624 // There are always two solutions angx, angy and PI-angx, 625 // PI+angy, choose first 625 // PI+angy, choose first 626 // 626 // 627 G4double angy; 627 G4double angy; 628 if(dir.y() == 1.) 628 if(dir.y() == 1.) 629 { 629 { 630 angy = 0.; 630 angy = 0.; 631 } 631 } 632 else if(dir.y() == 0.) 632 else if(dir.y() == 0.) 633 { 633 { 634 angy = 0.; 634 angy = 0.; 635 } 635 } 636 else 636 else 637 { 637 { 638 angy = std::asin(dir.x() / std::sqrt(1 - d 638 angy = std::asin(dir.x() / std::sqrt(1 - dir.y() * dir.y())); 639 } 639 } 640 640 641 // choose between angy and PI-angy 641 // choose between angy and PI-angy 642 if(dir.z() * std::cos(angx) * std::cos(angy) 642 if(dir.z() * std::cos(angx) * std::cos(angy) < 0) 643 { 643 { 644 angy = pi - angy; 644 angy = pi - angy; 645 } 645 } 646 rotation.rotateX(angx); 646 rotation.rotateX(angx); 647 rotation.rotateY(angy); 647 rotation.rotateY(angy); 648 648 649 return rotation; 649 return rotation; 650 } 650 } 651 651 652 // ------------------------------------------- 652 // -------------------------------------------------------------------- 653 G4bool G4tgrUtils::AreWordsEquivalent(const G4 653 G4bool G4tgrUtils::AreWordsEquivalent(const G4String& word1, 654 const G4 654 const G4String& word2) 655 { 655 { 656 G4bool bEqual = true; 656 G4bool bEqual = true; 657 std::vector<std::pair<size_t, size_t>> strin 657 std::vector<std::pair<size_t, size_t>> stringPairs; 658 // start of substring, number of characters 658 // start of substring, number of characters 659 659 660 //--- Get string limits between asterisks in 660 //--- Get string limits between asterisks in word1 661 661 662 std::size_t cStart = 0; 662 std::size_t cStart = 0; 663 for(;;) 663 for(;;) 664 { 664 { 665 size_t cAster = word1.find("*", cStart); 665 size_t cAster = word1.find("*", cStart); 666 if(cAster != std::string::npos) 666 if(cAster != std::string::npos) 667 { 667 { 668 if(cAster == cStart) 668 if(cAster == cStart) 669 { 669 { 670 if(cAster != 0) 670 if(cAster != 0) 671 { 671 { 672 G4Exception("G4tgrUtils::AreWordsEqu 672 G4Exception("G4tgrUtils::AreWordsEquivalent()", 673 "A word has two asterisk 673 "A word has two asterisks together, please correct it", 674 FatalException, ("Offend 674 FatalException, ("Offending word is: " + word1).c_str()); 675 } 675 } 676 else 676 else 677 { 677 { 678 // word1 == * 678 // word1 == * 679 if(word1.size() == 1) 679 if(word1.size() == 1) 680 { 680 { 681 return true; 681 return true; 682 } 682 } 683 } 683 } 684 } 684 } 685 if(cAster != cStart) 685 if(cAster != cStart) 686 { 686 { 687 stringPairs.push_back( 687 stringPairs.push_back( 688 std::pair<size_t, size_t>(cStart, cA 688 std::pair<size_t, size_t>(cStart, cAster - cStart)); 689 } 689 } 690 cStart = cAster + 1; 690 cStart = cAster + 1; 691 } 691 } 692 else 692 else 693 { 693 { 694 if(cStart == 0) 694 if(cStart == 0) 695 { 695 { 696 //--- If there is no asterisk check if 696 //--- If there is no asterisk check if they are the same 697 return word1 == word2; 697 return word1 == word2; 698 } 698 } 699 break; 699 break; 700 } 700 } 701 } 701 } 702 702 703 //---- Add characters after last asterisk as 703 //---- Add characters after last asterisk as string pair 704 if(cStart <= word1.length()) 704 if(cStart <= word1.length()) 705 { 705 { 706 if(word1.length() != cStart) 706 if(word1.length() != cStart) 707 { 707 { 708 stringPairs.push_back( 708 stringPairs.push_back( 709 std::pair<size_t, size_t>(cStart, word 709 std::pair<size_t, size_t>(cStart, word1.length() - cStart)); 710 } 710 } 711 } 711 } 712 712 713 //--- If there are not asterisk, simple comp 713 //--- If there are not asterisk, simple comparison 714 if(stringPairs.size() == 0) 714 if(stringPairs.size() == 0) 715 { 715 { 716 if(word1 == word2) 716 if(word1 == word2) 717 { 717 { 718 return true; 718 return true; 719 } 719 } 720 else 720 else 721 { 721 { 722 return false; 722 return false; 723 } 723 } 724 } 724 } 725 725 726 //--- Find substrings in word2, in same orde 726 //--- Find substrings in word2, in same order as in word1 727 cStart = 0; 727 cStart = 0; 728 for(std::size_t ii = 0; ii < stringPairs.siz 728 for(std::size_t ii = 0; ii < stringPairs.size(); ++ii) 729 { 729 { 730 std::pair<size_t, size_t> spair = stringPa 730 std::pair<size_t, size_t> spair = stringPairs[ii]; 731 size_t sFound = word2.find(word1.substr(sp 731 size_t sFound = word2.find(word1.substr(spair.first, spair.second), cStart); 732 if(sFound == std::string::npos) 732 if(sFound == std::string::npos) 733 { 733 { 734 bEqual = false; 734 bEqual = false; 735 break; 735 break; 736 } 736 } 737 else 737 else 738 { 738 { 739 //---- If there is no asterisk before fi 739 //---- If there is no asterisk before first character, 740 // the fisrt string pair found has t 740 // the fisrt string pair found has to start at the first character 741 if(spair.first == 0 && sFound != 0) 741 if(spair.first == 0 && sFound != 0) 742 { 742 { 743 bEqual = false; 743 bEqual = false; 744 break; 744 break; 745 //---- If there is no asterisk after l 745 //---- If there is no asterisk after last character, 746 // the last string pair found has 746 // the last string pair found has to end at the last character 747 } 747 } 748 else if((spair.first + spair.second - 1 748 else if((spair.first + spair.second - 1 == word1.length()) && 749 (sFound + spair.second - 1 != wo 749 (sFound + spair.second - 1 != word2.length())) 750 { 750 { 751 bEqual = false; 751 bEqual = false; 752 break; 752 break; 753 } 753 } 754 cStart += spair.second; 754 cStart += spair.second; 755 } 755 } 756 } 756 } 757 757 758 return bEqual; 758 return bEqual; 759 } 759 } 760 760