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