Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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
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)
std::ostringstream G4ExceptionDescription
const int isCtorName
const int doReplace
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
#define G4endl
Definition G4ios.hh:67
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