Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 // G4PhysListRegistry 27 // 28 // Author: R. Hatcher, 2014-10-15 29 // ------------------------------------------- 30 31 #include <iomanip> 32 #include <algorithm> 33 34 #include "G4ios.hh" 35 #include "G4PhysListRegistry.hh" 36 #include "G4VModularPhysicsList.hh" 37 #include "G4PhysListStamper.hh" 38 39 #include "G4PhysicsConstructorRegistry.hh" 40 // include G4_REFERENCE_PHYSCONSTR_FACTORY() m 41 // for static builds. Would do this in G4Ph 42 // but that causes a circular dependency when 43 // are broken in a "granular" build. 44 #define REGREF PhysListReg // REGREF is used t 45 #include "G4RegisterPhysicsConstructors.icc" 46 47 // include this with this compilation unit so 48 #include "G4RegisterPhysLists.icc" 49 50 G4ThreadLocal G4PhysListRegistry* G4PhysListRe 51 52 const G4int doReplace = 0x01; // _ (ReplaceP 53 const G4int isCtorName = 0x02; // true if act 54 55 G4PhysListRegistry* G4PhysListRegistry::Instan 56 { 57 if ( nullptr == theInstance) { 58 theInstance = new G4PhysListRegistry; 59 60 // common EM overrides 61 theInstance->AddPhysicsExtension("EM0","G4 62 theInstance->AddPhysicsExtension("EMV","G4 63 theInstance->AddPhysicsExtension("EMX","G4 64 theInstance->AddPhysicsExtension("EMY","G4 65 theInstance->AddPhysicsExtension("EMZ","G4 66 theInstance->AddPhysicsExtension("LIV","G4 67 theInstance->AddPhysicsExtension("PEN","G4 68 // the GS EM extension originally required 69 // support either one or two as __GS is co 70 // same for __SS 71 theInstance->AddPhysicsExtension("GS" ,"G4 72 theInstance->AddPhysicsExtension("_GS","G4 73 theInstance->AddPhysicsExtension("SS" ,"G4 74 theInstance->AddPhysicsExtension("_SS","G4 75 76 theInstance->AddPhysicsExtension("EM0","G4 77 theInstance->AddPhysicsExtension("WVI","G4 78 theInstance->AddPhysicsExtension("LE" ,"G4 79 theInstance->AddPhysicsExtension("_LE","G4 80 81 theInstance->AddPhysicsExtension("HPT","G4 82 } 83 84 return theInstance; 85 } 86 87 G4PhysListRegistry::G4PhysListRegistry() 88 : verbose(1) 89 , unknownFatal(0) 90 , systemDefault("FTFP_BERT") 91 { 92 SetUserDefaultPhysList(); 93 } 94 95 G4PhysListRegistry::~G4PhysListRegistry() 96 { 97 } 98 99 void G4PhysListRegistry::SetUserDefaultPhysLis 100 { 101 if ( name == "" ) userDefault = systemDefaul 102 else userDefault = name; 103 } 104 105 void G4PhysListRegistry::AddFactory(G4String n 106 { 107 factories[name] = factory; 108 } 109 110 void G4PhysListRegistry::AddPhysicsExtension(G 111 { 112 // a mapping from short extension names to a 113 physicsExtensions[name] = procname; 114 } 115 116 G4VModularPhysicsList* 117 G4PhysListRegistry::GetModularPhysicsList(cons 118 { 119 // 120 // 121 G4String plBase = ""; 122 std::vector<G4String> physExt; 123 std::vector<G4int> physReplace; 124 G4bool allKnown = 125 DeconstructPhysListName(name,plBase,physEx 126 127 std::size_t npc = physExt.size(); 128 if ( verbose > 0 ) { 129 G4cout << "G4PhysListRegistry::GetModularP 130 << name << ">" 131 << ", as \"" << plBase << "\" with 132 for ( std::size_t ipc = 0; ipc < npc; ++ip 133 G4cout << ((physReplace[ipc]&doReplace)? 134 G4cout << "\"" << G4endl; 135 } 136 137 if ( ! allKnown ) { 138 // couldn't match what the user wanted ... 139 G4cout << "### G4PhysListRegistry WARNING: 140 << " is not known" << G4endl << G4e 141 if ( ! unknownFatal ) return nullptr; 142 143 G4ExceptionDescription ED; 144 ED << "The factory for the physicslist ["< 145 << G4endl; 146 if ( plBase == "" ) { 147 ED << "Could determine no sensible base 148 } else { 149 ED << "One or more of the extensions doe 150 for ( std::size_t ipc = 0; ipc < physExt 151 ED << physExt[ipc] << " "; 152 } 153 ED << "]" << G4endl; 154 } 155 G4Exception("G4PhysListRegistry::GetModula 156 "PhysicsList002", FatalExcepti 157 return nullptr; 158 } 159 160 // if we want this method "const" then the n 161 // because there is no const version of [] ( 162 // key doesn't exist) 163 G4VModularPhysicsList* pl = factories[plBase 164 G4PhysicsConstructorRegistry* pcRegistry = 165 G4PhysicsConstructorRegistry::Instance(); 166 G4int ver = pl->GetVerboseLevel(); 167 pl->SetVerboseLevel(0); 168 for ( std::size_t ipc = 0; ipc < npc; ++ipc 169 // got back a list of short names, need to 170 // full physics constructor name 171 G4String extName = physExt[ipc]; 172 G4String pcname = 173 ((physReplace[ipc]&isCtorName)) ? extNam 174 // this doesn't have a verbose option ... 175 // but G4PhysicsConstructorFactory doesn't 176 G4VPhysicsConstructor* pctor = pcRegistry- 177 G4String reporreg = ""; 178 if (( physReplace[ipc] & doReplace)) { 179 pl->ReplacePhysics(pctor); 180 reporreg = "ReplacePhysics "; 181 } else { 182 pl->RegisterPhysics(pctor); 183 reporreg = "RegisterPhysics"; 184 } 185 if ( verbose > 0 ) G4cout << "<<< " << rep 186 << " \"" << extN 187 } 188 pl->SetVerboseLevel(ver); 189 G4cout << "<<< Reference Physics List " << n 190 G4cout << G4endl; // old factory has this 191 192 return pl; 193 } 194 195 G4VModularPhysicsList* 196 G4PhysListRegistry::GetModularPhysicsListFromE 197 { 198 // 199 // instantiate PhysList by environment varia 200 // if not set use default 201 G4String name = ""; 202 char* path = std::getenv("PHYSLIST"); 203 if (path) { 204 name = G4String(path); 205 } else { 206 name = userDefault; 207 G4cout << "### G4PhysListRegistry WARNING: 208 << " environment variable PHYSLIST 209 << G4endl 210 << " Default Physics Lists " << 211 << " is instantiated" 212 << G4endl; 213 } 214 return GetModularPhysicsList(name); 215 } 216 217 G4bool G4PhysListRegistry::IsReferencePhysList 218 { 219 G4String plBase = ""; 220 std::vector<G4String> physExt; 221 std::vector<G4int> physReplace; 222 G4bool allKnown = DeconstructPhysListName(na 223 return allKnown; 224 } 225 226 G4bool G4PhysListRegistry::DeconstructPhysList 227 228 229 230 231 { 232 // Take apart a name given to us by the user 233 // this name might be a base PhysList + unkn 234 // Extensions preceeded with a "_" should us 235 // ReplacePhysics() 236 // those proceeded with a "+" should use 237 // RegisterPhysics() 238 // the former is in line with previous behav 239 // additional flexibility 240 plBase = ""; 241 physExt.clear(); 242 replace.clear(); 243 G4bool allKnown = false; 244 245 G4String workingName = name; 246 247 const std::vector<G4String>& availBases = A 248 const std::vector<G4String>& availExtras = A 249 250 G4PhysicsConstructorRegistry* physConstRegis 251 G4PhysicsConstructorRegistry::Instance(); 252 253 const std::vector<G4String>& availPhysCtors 254 physConstRegistry->AvailablePhysicsConstru 255 256 // find the longest base list that is contai 257 // and starts at the beginning 258 G4String bestBase = ""; 259 allKnown = FindLongestMatch(workingName,"bas 260 if ( verb > 2 ) { 261 G4cout << " " << name << ", base known=" 262 << " chosen plBase \"" << plBase << 263 } 264 if ( ! allKnown ) { 265 // didn't find any matching base physics l 266 // no point of going on to the extensions 267 return allKnown; 268 } 269 // remove base name for working name 270 workingName.erase(0,plBase.size()); 271 272 // now start trying to match up extensions a 273 // each should be preceeded by at "_" (repla 274 // but don't freak if it isn't, just assume 275 while ( ! workingName.empty() ) { 276 char c = workingName.data()[0]; // leadin 277 if ( '_' == c || '+' == c ) workingName.er 278 G4int replaceExtra = (( c != '+' ) ? do 279 G4String extraName = ""; 280 G4bool extraKnown = false; 281 282 extraKnown = FindLongestMatch(workingName, 283 if ( extraKnown ) { 284 // physics mapping name is known, but is 285 //const issue// G4String pcname = physic 286 std::map<G4String,G4String>::const_itera 287 physicsExtensions.find(extraName); 288 G4String pcname = ""; 289 if ( itr != physicsExtensions.end() ) pc 290 G4bool realknown = physConstRegistry->Is 291 if ( ! realknown ) allKnown = false; 292 #ifdef G4VERBOSE 293 if ( verb > 2 ) { 294 G4cout << " extraName \"" << extraNam 295 << pcname << "\" which is itsel 296 << G4endl; 297 } 298 #endif 299 } else { 300 // perhaps it's an explicit physCtor nam 301 extraKnown = 302 FindLongestMatch(workingName,"physCtor 303 if ( extraKnown ) replaceExtra |= isCtor 304 } 305 #ifdef G4VERBOSE 306 if ( verb > 2 ) { 307 G4cout << " physextra " << name << " [" 308 <<", extra known " << extraKnown 309 << " chosen extra \"" << extraNam 310 << " replace " << replaceExtra << 311 } 312 #endif 313 if ( extraKnown ) { 314 physExt.push_back(extraName); 315 replace.push_back(replaceExtra); 316 // and remove it so we can look for the 317 workingName.erase(0,extraName.size()); 318 319 } else { 320 #ifdef G4VERBOSE 321 if ( verb > 2 ) { 322 G4cout << " workingName \"" << workin 323 << " couldn't be found in the e 324 << G4endl; 325 } 326 #endif 327 allKnown = false; 328 // found a pattern that we can't map 329 return allKnown; 330 } 331 } // workingName not empty 332 333 return allKnown; 334 } 335 336 G4bool G4PhysListRegistry::FindLongestMatch(co 337 co 338 co 339 G4 340 G4 341 { 342 bestMatch = ""; 343 G4bool found = false; 344 345 std::size_t n = validNames.size(); 346 for (std::size_t i=0; i<n; ++i) { 347 const G4String& testName = validNames[i]; 348 std::size_t ipos = workingName.find(testNa 349 if ( ipos == 0 ) { 350 std::size_t testNameSize = testName.size 351 std::size_t workNameSize = workingName.s 352 G4bool match = true; 353 if ( searchName == "base" ) { 354 // if searching for a valid base impos 355 // either must exactly match or the ne 356 // one of the standard delimiters of " 357 if (workNameSize > testNameSize) { 358 char nextChar = workingName[(G4int)t 359 if ( nextChar != '_' && nextChar != 360 if ( verb > 3 ) { 361 G4cout << " " << searchName << " 362 << testName << " nextChar " 363 } 364 } 365 } 366 if ( verb > 3 ) { 367 G4cout << " " << searchName << " matc 368 << " " << testName << G4endl; 369 } 370 if ( match ) { 371 if ( testName.size() > bestMatch.size( 372 bestMatch = testName; 373 found = true; 374 if ( verb > 3 ) { 375 G4cout << " " << searchName << " 376 << testName << G4endl; 377 } 378 } else { 379 if ( verb > 3 ) { 380 G4cout << " " << searchName << " 381 << testName << G4endl; 382 } 383 } 384 } else { 385 if ( verb > 3 ) { 386 G4cout << " " << searchName << " 387 << testName << G4endl; 388 } 389 } 390 } else { 391 if ( verb > 3 ) { 392 G4cout << " " << searchName << " reje 393 } 394 } 395 } 396 return found; 397 } 398 399 400 const std::vector<G4String>& G4PhysListRegistr 401 { 402 availBasePhysLists.clear(); 403 std::map<G4String,G4VBasePhysListStamper*>:: 404 for ( itr = factories.begin(); itr != factor 405 availBasePhysLists.push_back(itr->first); 406 } 407 408 return availBasePhysLists; 409 } 410 411 const std::vector<G4String>& G4PhysListRegistr 412 { 413 availExtensions.clear(); 414 std::map<G4String,G4String>::const_iterator 415 for ( itr = physicsExtensions.begin(); itr ! 416 availExtensions.push_back(itr->first); 417 } 418 419 return availExtensions; 420 } 421 422 const std::vector<G4String>& G4PhysListRegistr 423 { 424 // in principle this method could weed out a 425 // EM replacements ... but for now just use 426 // AvailablePhysicsExtensions() 427 return AvailablePhysicsExtensions(); 428 } 429 430 void G4PhysListRegistry::PrintAvailablePhysLis 431 { 432 std::vector<G4String> avail = AvailablePhysL 433 G4cout << "Base G4VModularPhysicsLists in G4 434 << G4endl; 435 if ( avail.empty() ) G4cout << "... no regis 436 else { 437 std::size_t n = avail.size(); 438 for (std::size_t i=0; i<n; ++i ) { 439 G4cout << " [" << std::setw(3) << i << " 440 << " \"" << avail[i] << "\"" << G 441 } 442 } 443 444 G4PhysicsConstructorRegistry* physConstRegis 445 446 std::map<G4String,G4String>::const_iterator 447 G4cout << "Replacement mappings in G4PhysLis 448 << G4endl; 449 for ( itr = physicsExtensions.begin(); itr ! 450 G4bool known = physConstRegistry->IsKnownP 451 452 G4cout << " " << std::setw(10) << itr-> 453 << std::setw(30) << itr->second << 454 << ( (known)?"":"[unregistered phys 455 << G4endl; 456 } 457 G4cout << "Use these mapping to extend physi 458 << " to use ReplacePhysics() (\"_\" 459 << G4endl; 460 } 461