Geant4 10.7.0
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 return theInstance;
90}
91
92G4PhysListRegistry::G4PhysListRegistry()
93 : verbose(1)
94 , unknownFatal(0)
95 , systemDefault("FTFP_BERT")
96{
98}
99
101{
102}
103
105{
106 if ( name == "" ) userDefault = systemDefault;
107 else userDefault = name;
108}
109
111{
112 factories[name] = factory;
113}
114
116{
117 // a mapping from short extension names to actual physics process constructors
118 physicsExtensions[name] = procname;
119}
120
123{
124 //
125 //
126 G4String plBase = "";
127 std::vector<G4String> physExt;
128 std::vector<G4int> physReplace;
129 G4bool allKnown =
130 DeconstructPhysListName(name,plBase,physExt,physReplace,verbose);
131
132 size_t npc = physExt.size();
133 if ( verbose > 0 ) {
134 G4cout << "G4PhysListRegistry::GetModularPhysicsList <"
135 << name << ">"
136 << ", as \"" << plBase << "\" with extensions \"";
137 for ( size_t ipc = 0; ipc < npc; ++ipc )
138 G4cout << ((physReplace[ipc]&doReplace)?"_":"+") << physExt[ipc];
139 G4cout << "\"" << G4endl;
140 }
141
142 if ( ! allKnown ) {
143 // couldn't match what the user wanted ...
144 G4cout << "### G4PhysListRegistry WARNING: " << name
145 << " is not known" << G4endl << G4endl;
146 if ( ! unknownFatal ) return 0;
147
149 ED << "The factory for the physicslist ["<< name << "] does not exist!"
150 << G4endl;
151 if ( plBase == "" ) {
152 ED << "Could determine no sensible base physics list" << G4endl;
153 } else {
154 ED << "One or more of the extensions does not exist [ ";
155 for ( size_t ipc = 0; ipc < physExt.size(); ++ipc ) {
156 ED << physExt[ipc] << " ";
157 }
158 ED << "]" << G4endl;
159 }
160 G4Exception("G4PhysListRegistry::GetModularPhysicsList",
161 "PhysicsList002", FatalException, ED);
162 return 0;
163 }
164
165 // if we want this method "const" then the next line becomes more complex
166 // because there is no const version of [] (which adds an entry if the
167 // key doesn't exist)
168 G4VModularPhysicsList* pl = factories[plBase]->Instantiate(verbose);
169 G4PhysicsConstructorRegistry* pcRegistry =
171 G4int ver = pl->GetVerboseLevel();
172 pl->SetVerboseLevel(0);
173 for ( size_t ipc = 0; ipc < npc; ++ipc ) {
174 // got back a list of short names, need to use the map to get the
175 // full physics constructor name
176 G4String extName = physExt[ipc];
177 G4String pcname =
178 ((physReplace[ipc]&isCtorName)) ? extName : physicsExtensions[extName];
179 // this doesn't have a verbose option ... it should
180 // but G4PhysicsConstructorFactory doesn't support it
181 G4VPhysicsConstructor* pctor = pcRegistry->GetPhysicsConstructor(pcname);
182 G4String reporreg = "";
183 if (( physReplace[ipc] & doReplace)) {
184 pl->ReplacePhysics(pctor);
185 reporreg = "ReplacePhysics ";
186 } else {
187 pl->RegisterPhysics(pctor);
188 reporreg = "RegisterPhysics";
189 }
190 if ( verbose > 0 ) G4cout << "<<< " << reporreg << " with " << pcname
191 << " \"" << extName << "\"" << G4endl;
192 }
193 pl->SetVerboseLevel(ver);
194 G4cout << "<<< Reference Physics List " << name << " is built" << G4endl;
195 G4cout << G4endl; // old factory has this
196
197 return pl;
198}
199
202{
203 //
204 // instantiate PhysList by environment variable "PHYSLIST"
205 // if not set use default
206 G4String name = "";
207 char* path = std::getenv("PHYSLIST");
208 if (path) {
209 name = G4String(path);
210 } else {
211 name = userDefault;
212 G4cout << "### G4PhysListRegistry WARNING: "
213 << " environment variable PHYSLIST is not defined"
214 << G4endl
215 << " Default Physics Lists " << name
216 << " is instantiated"
217 << G4endl;
218 }
219 return GetModularPhysicsList(name);
220}
221
223{
224 G4String plBase = "";
225 std::vector<G4String> physExt;
226 std::vector<G4int> physReplace;
227 G4bool allKnown = DeconstructPhysListName(name,plBase,physExt,physReplace,1);
228 return allKnown;
229}
230
232 G4String& plBase,
233 std::vector<G4String>& physExt,
234 std::vector<G4int>& replace,
235 G4int verb) const
236{
237 // Take apart a name given to us by the user
238 // this name might be a base PhysList + unknown number of extensions
239 // Extensions preceeded with a "_" should use
240 // ReplacePhysics()
241 // those proceeded with a "+" should use
242 // RegisterPhysics()
243 // the former is in line with previous behaviour, while the second allows
244 // additional flexibility
245 plBase = "";
246 physExt.clear();
247 replace.clear();
248 bool allKnown = false;
249
250 G4String workingName = name;
251
252 const std::vector<G4String>& availBases = AvailablePhysLists();
253 const std::vector<G4String>& availExtras = AvailablePhysicsExtensions();
254
255 G4PhysicsConstructorRegistry* physConstRegistry =
257
258 const std::vector<G4String>& availPhysCtors =
259 physConstRegistry->AvailablePhysicsConstructors();
260
261 // find the longest base list that is contained in the user supplied name
262 // and starts at the beginning
263 G4String bestBase = "";
264 allKnown = FindLongestMatch(workingName,"base",availBases,plBase);
265 if ( verb > 2 ) {
266 G4cout << " " << name << ", base known=" << ((allKnown)?"true":"false")
267 << " chosen plBase \"" << plBase << "\"" << G4endl;
268 }
269 if ( ! allKnown ) {
270 // didn't find any matching base physics list
271 // no point of going on to the extensions
272 return allKnown;
273 }
274 // remove base name for working name
275 workingName.erase(0,plBase.size());
276
277 // now start trying to match up extensions and/or physCtors
278 // each should be preceeded by at "_" (replace) or "+" (register)
279 // but don't freak if it isn't, just assume "_"
280 while ( ! workingName.empty() ) {
281 char c = workingName.data()[0]; // leading character
282 if ( '_' == c || '+' == c ) workingName.erase(0,1); // and remove it
283 G4int replaceExtra = (( c != '+' ) ? doReplace : 0 );
284 G4String extraName = "";
285 G4bool extraKnown = false;
286
287 extraKnown = FindLongestMatch(workingName,"extNames",availExtras,extraName);
288 if ( extraKnown ) {
289 // physics mapping name is known, but is it actually linked to physics?
290 //const issue// G4String pcname = physicsExtensions[extraName];
291 std::map<G4String,G4String>::const_iterator itr =
292 physicsExtensions.find(extraName);
293 G4String pcname = "";
294 if ( itr != physicsExtensions.end() ) pcname = itr->second;
295 bool realknown = physConstRegistry->IsKnownPhysicsConstructor(pcname);
296 if ( ! realknown ) allKnown = false;
297#ifdef G4VERBOSE
298 if ( verb > 2 ) {
299 G4cout << " extraName \"" << extraName << "\" maps to physics ctor \""
300 << pcname << "\" which is itself realknown " << realknown
301 << G4endl;
302 }
303#endif
304 } else {
305 // perhaps it's an explicit physCtor name
306 extraKnown =
307 FindLongestMatch(workingName,"physCtors",availPhysCtors,extraName);
308 if ( extraKnown ) replaceExtra |= isCtorName; // flag it
309 }
310#ifdef G4VERBOSE
311 if ( verb > 2 ) {
312 G4cout << " physextra " << name << " [" << workingName << "]"
313 <<", extra known " << extraKnown
314 << " chosen extra \"" << extraName << "\""
315 << " replace " << replaceExtra << G4endl;
316 }
317#endif
318 if ( extraKnown ) {
319 physExt.push_back(extraName);
320 replace.push_back(replaceExtra);
321 // and remove it so we can look for the next bit
322 workingName.erase(0,extraName.size());
323
324 } else {
325#ifdef G4VERBOSE
326 if ( verb > 2 ) {
327 G4cout << " workingName \"" << workingName << "\""
328 << " couldn't be found in the extensions list"
329 << G4endl;
330 }
331#endif
332 allKnown = false;
333 // found a pattern that we can't map
334 return allKnown;
335 }
336 } // workingName not empty
337
338 return allKnown;
339}
340
342 const G4String& searchName,
343 const std::vector<G4String>& validNames,
344 G4String& bestMatch,
345 G4int verb) const
346{
347 bestMatch = "";
348 bool found = false;
349
350 size_t n = validNames.size();
351 for (size_t i=0; i<n; ++i) {
352 const G4String& testName = validNames[i];
353 size_t ipos = workingName.find(testName);
354 if ( ipos == 0 ) {
355 if ( testName.size() > bestMatch.size() ) {
356 bestMatch = testName;
357 found = true;
358 if ( verb > 3 ) {
359 G4cout << " " << searchName << " current best guess: "
360 << testName << G4endl;
361 }
362 } else {
363 if ( verb > 3 ) {
364 G4cout << " " << searchName << " match but shorter: "
365 << testName << G4endl;
366 }
367 }
368 } else {
369 if ( verb > 3 ) {
370 G4cout << " " << searchName << " reject: " << testName << G4endl;
371 }
372 }
373 }
374 return found;
375}
376
377
378const std::vector<G4String>& G4PhysListRegistry::AvailablePhysLists() const
379{
380 availBasePhysLists.clear();
381 std::map<G4String,G4VBasePhysListStamper*>::const_iterator itr;
382 for ( itr = factories.begin(); itr != factories.end(); ++itr ) {
383 availBasePhysLists.push_back(itr->first);
384 }
385
386 return availBasePhysLists;
387}
388
389const std::vector<G4String>& G4PhysListRegistry::AvailablePhysicsExtensions() const
390{
391 availExtensions.clear();
392 std::map<G4String,G4String>::const_iterator itr;
393 for ( itr = physicsExtensions.begin(); itr != physicsExtensions.end(); ++itr ) {
394 availExtensions.push_back(itr->first);
395 }
396
397 return availExtensions;
398}
399
400const std::vector<G4String>& G4PhysListRegistry::AvailablePhysListsEM() const
401{
402 // in principle this method could weed out all the extensions that aren't
403 // EM replacements ... but for now just use it as a synonym for
404 // AvailablePhysicsExtensions()
406}
407
409{
410 std::vector<G4String> avail = AvailablePhysLists();
411 G4cout << "Base G4VModularPhysicsLists in G4PhysListRegistry are:"
412 << G4endl;
413 if ( avail.empty() ) G4cout << "... no registered lists" << G4endl;
414 else {
415 size_t n = avail.size();
416 for (size_t i=0; i<n; ++i ) {
417 G4cout << " [" << std::setw(3) << i << "] "
418 << " \"" << avail[i] << "\"" << G4endl;
419 }
420 }
421
423
424 std::map<G4String,G4String>::const_iterator itr;
425 G4cout << "Replacement mappings in G4PhysListRegistry are:"
426 << G4endl;
427 for ( itr = physicsExtensions.begin(); itr != physicsExtensions.end(); ++itr ) {
428 bool known = physConstRegistry->IsKnownPhysicsConstructor(itr->second);
429
430 G4cout << " " << std::setw(10) << itr->first << " => "
431 << std::setw(30) << itr->second << " "
432 << ( (known)?"":"[unregistered physics]")
433 << G4endl;
434 }
435 G4cout << "Use these mapping to extend physics list; append with _EXT or +EXT" << G4endl
436 << " to use ReplacePhysics() (\"_\") or RegisterPhysics() (\"+\")."
437 << G4endl;
438}
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
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)
const char * data() const
void SetVerboseLevel(G4int value)
void RegisterPhysics(G4VPhysicsConstructor *)
void ReplacePhysics(G4VPhysicsConstructor *)
#define G4ThreadLocal
Definition: tls.hh:77