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
G4PhysListRegistry.cc
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//
27//
28// -------------------------------------------------------------------
29//
30// GEANT4 Class file
31//
32// File name: G4PhysListRegistry
33//
34// Author R. Hatcher 2014-10-15
35//
36// Modifications: based on G4PhysicsConstructorRegistry
37//
38//#define G4VERBOSE 1
39
40#include "G4ios.hh"
41#include <iomanip>
42#include <algorithm>
43
44#include "G4PhysListRegistry.hh"
46#include "G4PhysListStamper.hh"
47
49// include G4_REFERENCE_PHYSCONSTR_FACTORY() macros here to pull them in
50// for static builds. Would do this in G4PhysicsConstructorRegistry
51// but that causes a circular dependency when the phys_ctor libs
52// are broken in a "granular" build.
53#define REGREF PhysListReg // REGREF is used to make instances unique
54#include "G4RegisterPhysicsConstructors.icc"
55
56// include this with this compilation unit so static builds pull them in
57#include "G4RegisterPhysLists.icc"
58
59G4ThreadLocal G4PhysListRegistry* G4PhysListRegistry::theInstance = 0;
60
61const int doReplace = 0x01; // _ (ReplacePhysics) vs. + (RegisterPhysics)
62const int isCtorName = 0x02; // true if actual physCtor name vs. ext name
63
65{
66 if ( 0 == theInstance) {
67 static G4ThreadLocal G4PhysListRegistry *manager_G4MT_TLS_ = 0;
68 if (!manager_G4MT_TLS_) manager_G4MT_TLS_ = new G4PhysListRegistry;
69 G4PhysListRegistry &manager = *manager_G4MT_TLS_;
70 theInstance = &manager;
71 }
72
73 // common EM overrides
74 theInstance->AddPhysicsExtension("EM0","G4EmStandardPhysics");
75 theInstance->AddPhysicsExtension("EMV","G4EmStandardPhysics_option1");
76 theInstance->AddPhysicsExtension("EMX","G4EmStandardPhysics_option2");
77 theInstance->AddPhysicsExtension("EMY","G4EmStandardPhysics_option3");
78 theInstance->AddPhysicsExtension("EMZ","G4EmStandardPhysics_option4");
79 theInstance->AddPhysicsExtension("LIV","G4EmLivermorePhysics");
80 theInstance->AddPhysicsExtension("PEN","G4EmPenelopePhysics");
81 // the GS EM extension originally required double underscores
82 // support either one or two as __GS is confusing to users
83 // same for __SS
84 theInstance->AddPhysicsExtension("GS" ,"G4EmStandardPhysicsGS");
85 theInstance->AddPhysicsExtension("_GS","G4EmStandardPhysicsGS");
86 theInstance->AddPhysicsExtension("SS" ,"G4EmStandardPhysicsSS");
87 theInstance->AddPhysicsExtension("_SS","G4EmStandardPhysicsSS");
88
89 theInstance->AddPhysicsExtension("EM0","G4EmStandardPhysics");
90 theInstance->AddPhysicsExtension("WVI","G4EmStandardPhysicsWVI");
91 theInstance->AddPhysicsExtension("LE" ,"G4EmLowEPPhysics");
92 theInstance->AddPhysicsExtension("_LE","G4EmLowEPPhysics");
93
94 return theInstance;
95}
96
97G4PhysListRegistry::G4PhysListRegistry()
98 : verbose(1)
99 , unknownFatal(0)
100 , systemDefault("FTFP_BERT")
101{
103}
104
106{
107}
108
110{
111 if ( name == "" ) userDefault = systemDefault;
112 else userDefault = name;
113}
114
116{
117 factories[name] = factory;
118}
119
121{
122 // a mapping from short extension names to actual physics process constructors
123 physicsExtensions[name] = procname;
124}
125
128{
129 //
130 //
131 G4String plBase = "";
132 std::vector<G4String> physExt;
133 std::vector<G4int> physReplace;
134 G4bool allKnown =
135 DeconstructPhysListName(name,plBase,physExt,physReplace,verbose);
136
137 size_t npc = physExt.size();
138 if ( verbose > 0 ) {
139 G4cout << "G4PhysListRegistry::GetModularPhysicsList <"
140 << name << ">"
141 << ", as \"" << plBase << "\" with extensions \"";
142 for ( size_t ipc = 0; ipc < npc; ++ipc )
143 G4cout << ((physReplace[ipc]&doReplace)?"_":"+") << physExt[ipc];
144 G4cout << "\"" << G4endl;
145 }
146
147 if ( ! allKnown ) {
148 // couldn't match what the user wanted ...
149 G4cout << "### G4PhysListRegistry WARNING: " << name
150 << " is not known" << G4endl << G4endl;
151 if ( ! unknownFatal ) return 0;
152
154 ED << "The factory for the physicslist ["<< name << "] does not exist!"
155 << G4endl;
156 if ( plBase == "" ) {
157 ED << "Could determine no sensible base physics list" << G4endl;
158 } else {
159 ED << "One or more of the extensions does not exist [ ";
160 for ( size_t ipc = 0; ipc < physExt.size(); ++ipc ) {
161 ED << physExt[ipc] << " ";
162 }
163 ED << "]" << G4endl;
164 }
165 G4Exception("G4PhysListRegistry::GetModularPhysicsList",
166 "PhysicsList002", FatalException, ED);
167 return 0;
168 }
169
170 // if we want this method "const" then the next line becomes more complex
171 // because there is no const version of [] (which adds an entry if the
172 // key doesn't exist)
173 G4VModularPhysicsList* pl = factories[plBase]->Instantiate(verbose);
174 G4PhysicsConstructorRegistry* pcRegistry =
176 G4int ver = pl->GetVerboseLevel();
177 pl->SetVerboseLevel(0);
178 for ( size_t ipc = 0; ipc < npc; ++ipc ) {
179 // got back a list of short names, need to use the map to get the
180 // full physics constructor name
181 G4String extName = physExt[ipc];
182 G4String pcname =
183 ((physReplace[ipc]&isCtorName)) ? extName : physicsExtensions[extName];
184 // this doesn't have a verbose option ... it should
185 // but G4PhysicsConstructorFactory doesn't support it
186 G4VPhysicsConstructor* pctor = pcRegistry->GetPhysicsConstructor(pcname);
187 G4String reporreg = "";
188 if (( physReplace[ipc] & doReplace)) {
189 pl->ReplacePhysics(pctor);
190 reporreg = "ReplacePhysics ";
191 } else {
192 pl->RegisterPhysics(pctor);
193 reporreg = "RegisterPhysics";
194 }
195 if ( verbose > 0 ) G4cout << "<<< " << reporreg << " with " << pcname
196 << " \"" << extName << "\"" << G4endl;
197 }
198 pl->SetVerboseLevel(ver);
199 G4cout << "<<< Reference Physics List " << name << " is built" << G4endl;
200 G4cout << G4endl; // old factory has this
201
202 return pl;
203}
204
207{
208 //
209 // instantiate PhysList by environment variable "PHYSLIST"
210 // if not set use default
211 G4String name = "";
212 char* path = std::getenv("PHYSLIST");
213 if (path) {
214 name = G4String(path);
215 } else {
216 name = userDefault;
217 G4cout << "### G4PhysListRegistry WARNING: "
218 << " environment variable PHYSLIST is not defined"
219 << G4endl
220 << " Default Physics Lists " << name
221 << " is instantiated"
222 << G4endl;
223 }
224 return GetModularPhysicsList(name);
225}
226
228{
229 G4String plBase = "";
230 std::vector<G4String> physExt;
231 std::vector<G4int> physReplace;
232 G4bool allKnown = DeconstructPhysListName(name,plBase,physExt,physReplace,1);
233 return allKnown;
234}
235
237 G4String& plBase,
238 std::vector<G4String>& physExt,
239 std::vector<G4int>& replace,
240 G4int verb) const
241{
242 // Take apart a name given to us by the user
243 // this name might be a base PhysList + unknown number of extensions
244 // Extensions preceeded with a "_" should use
245 // ReplacePhysics()
246 // those proceeded with a "+" should use
247 // RegisterPhysics()
248 // the former is in line with previous behaviour, while the second allows
249 // additional flexibility
250 plBase = "";
251 physExt.clear();
252 replace.clear();
253 bool allKnown = false;
254
255 G4String workingName = name;
256
257 const std::vector<G4String>& availBases = AvailablePhysLists();
258 const std::vector<G4String>& availExtras = AvailablePhysicsExtensions();
259
260 G4PhysicsConstructorRegistry* physConstRegistry =
262
263 const std::vector<G4String>& availPhysCtors =
264 physConstRegistry->AvailablePhysicsConstructors();
265
266 // find the longest base list that is contained in the user supplied name
267 // and starts at the beginning
268 G4String bestBase = "";
269 allKnown = FindLongestMatch(workingName,"base",availBases,plBase);
270 if ( verb > 2 ) {
271 G4cout << " " << name << ", base known=" << ((allKnown)?"true":"false")
272 << " chosen plBase \"" << plBase << "\"" << G4endl;
273 }
274 if ( ! allKnown ) {
275 // didn't find any matching base physics list
276 // no point of going on to the extensions
277 return allKnown;
278 }
279 // remove base name for working name
280 workingName.erase(0,plBase.size());
281
282 // now start trying to match up extensions and/or physCtors
283 // each should be preceeded by at "_" (replace) or "+" (register)
284 // but don't freak if it isn't, just assume "_"
285 while ( ! workingName.empty() ) {
286 char c = workingName.data()[0]; // leading character
287 if ( '_' == c || '+' == c ) workingName.erase(0,1); // and remove it
288 G4int replaceExtra = (( c != '+' ) ? doReplace : 0 );
289 G4String extraName = "";
290 G4bool extraKnown = false;
291
292 extraKnown = FindLongestMatch(workingName,"extNames",availExtras,extraName);
293 if ( extraKnown ) {
294 // physics mapping name is known, but is it actually linked to physics?
295 //const issue// G4String pcname = physicsExtensions[extraName];
296 std::map<G4String,G4String>::const_iterator itr =
297 physicsExtensions.find(extraName);
298 G4String pcname = "";
299 if ( itr != physicsExtensions.end() ) pcname = itr->second;
300 bool realknown = physConstRegistry->IsKnownPhysicsConstructor(pcname);
301 if ( ! realknown ) allKnown = false;
302#ifdef G4VERBOSE
303 if ( verb > 2 ) {
304 G4cout << " extraName \"" << extraName << "\" maps to physics ctor \""
305 << pcname << "\" which is itself realknown " << realknown
306 << G4endl;
307 }
308#endif
309 } else {
310 // perhaps it's an explicit physCtor name
311 extraKnown =
312 FindLongestMatch(workingName,"physCtors",availPhysCtors,extraName);
313 if ( extraKnown ) replaceExtra |= isCtorName; // flag it
314 }
315#ifdef G4VERBOSE
316 if ( verb > 2 ) {
317 G4cout << " physextra " << name << " [" << workingName << "]"
318 <<", extra known " << extraKnown
319 << " chosen extra \"" << extraName << "\""
320 << " replace " << replaceExtra << G4endl;
321 }
322#endif
323 if ( extraKnown ) {
324 physExt.push_back(extraName);
325 replace.push_back(replaceExtra);
326 // and remove it so we can look for the next bit
327 workingName.erase(0,extraName.size());
328
329 } else {
330#ifdef G4VERBOSE
331 if ( verb > 2 ) {
332 G4cout << " workingName \"" << workingName << "\""
333 << " couldn't be found in the extensions list"
334 << G4endl;
335 }
336#endif
337 allKnown = false;
338 // found a pattern that we can't map
339 return allKnown;
340 }
341 } // workingName not empty
342
343 return allKnown;
344}
345
347 const G4String& searchName,
348 const std::vector<G4String>& validNames,
349 G4String& bestMatch,
350 G4int verb) const
351{
352 bestMatch = "";
353 bool found = false;
354
355 size_t n = validNames.size();
356 for (size_t i=0; i<n; ++i) {
357 const G4String& testName = validNames[i];
358 size_t ipos = workingName.find(testName);
359 if ( ipos == 0 ) {
360 if ( testName.size() > bestMatch.size() ) {
361 bestMatch = testName;
362 found = true;
363 if ( verb > 3 ) {
364 G4cout << " " << searchName << " current best guess: "
365 << testName << G4endl;
366 }
367 } else {
368 if ( verb > 3 ) {
369 G4cout << " " << searchName << " match but shorter: "
370 << testName << G4endl;
371 }
372 }
373 } else {
374 if ( verb > 3 ) {
375 G4cout << " " << searchName << " reject: " << testName << G4endl;
376 }
377 }
378 }
379 return found;
380}
381
382
383const std::vector<G4String>& G4PhysListRegistry::AvailablePhysLists() const
384{
385 availBasePhysLists.clear();
386 std::map<G4String,G4VBasePhysListStamper*>::const_iterator itr;
387 for ( itr = factories.begin(); itr != factories.end(); ++itr ) {
388 availBasePhysLists.push_back(itr->first);
389 }
390
391 return availBasePhysLists;
392}
393
394const std::vector<G4String>& G4PhysListRegistry::AvailablePhysicsExtensions() const
395{
396 availExtensions.clear();
397 std::map<G4String,G4String>::const_iterator itr;
398 for ( itr = physicsExtensions.begin(); itr != physicsExtensions.end(); ++itr ) {
399 availExtensions.push_back(itr->first);
400 }
401
402 return availExtensions;
403}
404
405const std::vector<G4String>& G4PhysListRegistry::AvailablePhysListsEM() const
406{
407 // in principle this method could weed out all the extensions that aren't
408 // EM replacements ... but for now just use it as a synonym for
409 // AvailablePhysicsExtensions()
411}
412
414{
415 std::vector<G4String> avail = AvailablePhysLists();
416 G4cout << "Base G4VModularPhysicsLists in G4PhysListRegistry are:"
417 << G4endl;
418 if ( avail.empty() ) G4cout << "... no registered lists" << G4endl;
419 else {
420 size_t n = avail.size();
421 for (size_t i=0; i<n; ++i ) {
422 G4cout << " [" << std::setw(3) << i << "] "
423 << " \"" << avail[i] << "\"" << G4endl;
424 }
425 }
426
428
429 std::map<G4String,G4String>::const_iterator itr;
430 G4cout << "Replacement mappings in G4PhysListRegistry are:"
431 << G4endl;
432 for ( itr = physicsExtensions.begin(); itr != physicsExtensions.end(); ++itr ) {
433 bool known = physConstRegistry->IsKnownPhysicsConstructor(itr->second);
434
435 G4cout << " " << std::setw(10) << itr->first << " => "
436 << std::setw(30) << itr->second << " "
437 << ( (known)?"":"[unregistered physics]")
438 << G4endl;
439 }
440 G4cout << "Use these mapping to extend physics list; append with _EXT or +EXT" << G4endl
441 << " to use ReplacePhysics() (\"_\") or RegisterPhysics() (\"+\")."
442 << G4endl;
443}
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
const int isCtorName
const int doReplace
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
void PrintAvailablePhysLists() const
G4VModularPhysicsList * GetModularPhysicsListFromEnv()
const std::vector< G4String > & AvailablePhysLists() const
void AddFactory(G4String name, G4VBasePhysListStamper *)
void SetUserDefaultPhysList(const G4String &name="")
const std::vector< G4String > & AvailablePhysListsEM() const
const std::vector< G4String > & AvailablePhysicsExtensions() const
static G4PhysListRegistry * Instance()
G4bool DeconstructPhysListName(const G4String &name, G4String &plBase, std::vector< G4String > &physExt, std::vector< G4int > &replace, G4int verbose=0) const
G4bool IsReferencePhysList(G4String nam) const
G4VModularPhysicsList * GetModularPhysicsList(const G4String &name)
void AddPhysicsExtension(G4String name, G4String procname)
G4bool FindLongestMatch(const G4String &workName, const G4String &searchName, const std::vector< G4String > &validNames, G4String &bestMatch, G4int verbose=0) const
G4VPhysicsConstructor * GetPhysicsConstructor(const G4String &name)
static G4PhysicsConstructorRegistry * Instance()
std::vector< G4String > AvailablePhysicsConstructors() const
G4bool IsKnownPhysicsConstructor(const G4String &name)
void SetVerboseLevel(G4int value)
void RegisterPhysics(G4VPhysicsConstructor *)
void ReplacePhysics(G4VPhysicsConstructor *)
#define G4ThreadLocal
Definition: tls.hh:77