Geant4  10.01.p02
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 //
34 // File name: G4PhysListRegistry
35 //
36 // Author R. Hatcher 2014-10-15
37 //
38 // Modifications: based on G4PhysicsConstructorRegistry
39 //
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 
51 
53 {
54  if ( 0 == theInstance) {
55  static G4ThreadLocal G4PhysListRegistry *manager_G4MT_TLS_ = 0;
56  if (!manager_G4MT_TLS_) manager_G4MT_TLS_ = new G4PhysListRegistry;
57  G4PhysListRegistry &manager = *manager_G4MT_TLS_;
58  theInstance = &manager;
59  }
60 
61  // common EM overrides
62  theInstance->AddPhysicsExtension("EMV","G4EmStandardPhysics_option1");
63  theInstance->AddPhysicsExtension("EMX","G4EmStandardPhysics_option2");
64  theInstance->AddPhysicsExtension("EMY","G4EmStandardPhysics_option3");
65  theInstance->AddPhysicsExtension("EMZ","G4EmStandardPhysics_option4");
66  theInstance->AddPhysicsExtension("LIV","G4EmLivermorePhysics");
67  theInstance->AddPhysicsExtension("PEN","G4EmPenelopePhysics");
68 
69  return theInstance;
70 }
71 
72 G4PhysListRegistry::G4PhysListRegistry() : verbose(1), unknownFatal(0)
73 {}
74 
76 {
77 }
78 
80 {
81  factories[name] = factory;
82 }
83 
85 {
86  // a mapping from short extension names to actual physics process constructors
87  physicsExtensions[name] = procname;
88 }
89 
92 {
93  //
94  //
95  G4String plBase = "";
96  std::vector<G4String> physExt;
97  std::vector<G4int> physReplace;
98  G4bool allKnown = DeconstructPhysListName(name,plBase,physExt,physReplace,1);
99 
100  if ( ! allKnown ) {
101  // couldn't match what the user wanted ...
102  if ( ! unknownFatal ) return 0;
103 
105  ED << "The factory for the physicslist ["<< name << "] does not exist!" << G4endl;
106  if ( plBase == "" ) {
107  ED << "Could determine no sensible base physics list" << G4endl;
108  } else {
109  ED << "One or more of the extensions does not exist [ ";
110  for ( size_t ipc = 0; ipc < physExt.size(); ++ipc ) {
111  ED << physExt[ipc] << " ";
112  }
113  ED << "]" << G4endl;
114  }
115  G4Exception("G4PhysListRegistry::GetModularPhysicsList", "PhysicsList001", FatalException, ED);
116  return 0;
117  }
118 
119  // if we want this method "const" then the next line becomes more complex
120  // because there is no const version of [] (which adds an entry if the key doesn't exist)
121  G4VModularPhysicsList* pl = factories[plBase]->Instantiate(verbose);
123  size_t npc = physExt.size();
124  for ( size_t ipc = 0; ipc < npc; ++ipc ) {
125  // got back a list of short names, need to use the map to get the full physics constructor name
126  G4String extName = physExt[ipc];
127  G4String pcname = physicsExtensions[extName];
128  G4VPhysicsConstructor* pc = pcRegistry->GetPhysicsConstructor(pcname);
129  if ( physReplace[ipc] > 0 ) {
130  pl->ReplacePhysics(pc);
131  } else {
132  pl->RegisterPhysics(pc);
133  }
134  }
135  return pl;
136 }
137 
139 {
140  G4String plBase = "";
141  std::vector<G4String> physExt;
142  std::vector<G4int> physReplace;
143  G4bool allKnown = DeconstructPhysListName(name,plBase,physExt,physReplace,1);
144  return allKnown;
145 }
146 
148  G4String& plBase,
149  std::vector<G4String>& physExt,
150  std::vector<G4int>& replace,
151  G4int verb) const
152 {
153  // Take apart a name given to us by the user
154  // this name might be a base PhysList + unknown number of extensions
155  // Extensions preceeded with a "_" should use
156  // ReplacePhysics()
157  // those proceeded with a "+" should use
158  // RegisterPhysics()
159  // the former is in line with previous behaviour, while the second allows
160  // additional flexibility
161  plBase = "";
162  physExt.clear();
163  replace.clear();
164  bool allKnown = false;
165 
166  G4String workingName = name;
167 
168  const std::vector<G4String>& availBases = AvailablePhysLists();
169  const std::vector<G4String>& availExtras = AvailablePhysicsExtensions();
170 
171  // find the longest base list that is contained in the user supplied name
172  // and starts at the beginning
173  size_t nb = availBases.size();
174  for (size_t ib=0; ib<nb; ++ib) {
175  const G4String& testBase = availBases[ib];
176  size_t ipos = workingName.find(testBase);
177  if ( ipos == 0 ) {
178  if ( testBase.size() > plBase.size() ) {
179  plBase = testBase;
180  allKnown = true;
181  if ( verb > 3 ) { G4cout << " physlist current best guess: " << testBase << G4endl; }
182  } else {
183  if ( verb > 3 ) { G4cout << " physlist match but shorter: " << testBase << G4endl; }
184  }
185  } else {
186  if ( verb > 3 ) { G4cout << " physlist reject: " << testBase << G4endl; }
187  }
188  }
189  if ( verb > 2 ) {
190  G4cout << " physlist " << name << ", base known " << allKnown
191  << " chosen plBase \"" << plBase << "\"" << G4endl;
192  }
193  if ( ! allKnown ) {
194  // didn't find any matching base physics list
195  // no point of going on to the extensions
196  return allKnown;
197  }
198  // remove base name for working name
199  workingName.erase(0,plBase.size());
200 
201  // now start trying to match up extensions
202  // each should be preceeded by at "_" (replace) or "+" (register)
203  // but don't freak if it isn't, just assume "_"
204  size_t ne = availExtras.size();
205  while ( ! workingName.empty() ) {
206  char c = workingName.data()[0]; // leading character
207  if ( '_' == c || '+' == c ) workingName.erase(0,1); // and remove it
208  G4int replaceExtra = ( c != '+' );
209  G4String extraName = "";
210  G4bool extraKnown = false;
211  for (size_t ie=0; ie<ne; ++ie) {
212  const G4String& testExtra = availExtras[ie];
213  size_t ipos = workingName.find(testExtra);
214  if ( ipos == 0 ) {
215  if ( testExtra.size() > extraName.size() ) {
216  extraName = testExtra;
217  extraKnown = true;
218 #ifdef G4VERBOSE
219  if ( verb > 3 ) { G4cout << " physextra current best guess: " << testExtra << G4endl; }
220  } else {
221  if ( verb > 3 ) { G4cout << " physextra match but shorter: " << testExtra << G4endl; }
222 #endif
223  }
224  } else {
225 #ifdef G4VERBOSE
226  if ( verb > 3 ) { G4cout << " physextra reject: " << testExtra << G4endl; }
227 #endif
228  }
229  }
230 #ifdef G4VERBOSE
231  if ( verb > 2 ) {
232  G4cout << " physextra " << name << " [" << workingName << "]"
233  <<", extra known " << extraKnown
234  << " chosen extra \"" << extraName << "\""
235  << " replace " << replaceExtra << G4endl;
236  }
237 #endif
238  if ( extraKnown ) {
239  physExt.push_back(extraName);
240  replace.push_back(replaceExtra);
241  // and remove it so we can look for the next bit
242  workingName.erase(0,extraName.size());
243  } else {
244  allKnown = false;
245  }
246  } // workingName not empty
247 
248  return allKnown;
249 }
250 
251 const std::vector<G4String>& G4PhysListRegistry::AvailablePhysLists() const
252 {
253  availBasePhysLists.clear();
254  std::map<G4String,G4VBasePhysListStamper*>::const_iterator itr;
255  for ( itr = factories.begin(); itr != factories.end(); ++itr ) {
256  availBasePhysLists.push_back(itr->first);
257  }
258 
259  return availBasePhysLists;
260 }
261 
262 const std::vector<G4String>& G4PhysListRegistry::AvailablePhysicsExtensions() const
263 {
264  availExtensions.clear();
265  std::map<G4String,G4String>::const_iterator itr;
266  for ( itr = physicsExtensions.begin(); itr != physicsExtensions.end(); ++itr ) {
267  availExtensions.push_back(itr->first);
268  }
269 
270  return availExtensions;
271 }
272 
273 const std::vector<G4String>& G4PhysListRegistry::AvailablePhysListsEM() const
274 {
275  // in principle this method could weed out all the extensions that aren't
276  // EM replacements ... but for now just use it as a synonym for AvailablePhysicsExtensions()
278 }
279 
281 {
282  std::vector<G4String> avail = AvailablePhysLists();
283  G4cout << "Base G4VModularPhysicsLists in G4PhysListRegistry are:"
284  << G4endl;
285  if ( avail.empty() ) G4cout << "... no registered lists" << G4endl;
286  else {
287  size_t n = avail.size();
288  for (size_t i=0; i<n; ++i ) {
289  G4cout << " [" << std::setw(3) << i << "] "
290  << " \"" << avail[i] << "\"" << G4endl;
291  }
292  }
293 
296 
297  std::map<G4String,G4String>::const_iterator itr;
298  G4cout << "Replacement mappings in G4PhysListRegistry are:"
299  << G4endl;
300  for ( itr = physicsExtensions.begin(); itr != physicsExtensions.end(); ++itr ) {
301  //bool known = ( find(physConstNames.begin(),physConstName.end(),itr->second) != physConstNames.end() );
302  bool known = physConstRegistry->IsKnownPhysicsConstructor(itr->second);
303 
304  G4cout << " " << std::setw(10) << itr->first << " => "
305  << std::setw(30) << itr->second << " "
306  << ( (known)?"":"[unregistered physics]")
307  << G4endl;
308 
309  }
310 
311 }
312 
313 // need something that will trigger compilation
314 //#include "RegisterPhysLists.icc"
315 
std::vector< G4String > availExtensions
void RegisterPhysics(G4VPhysicsConstructor *)
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76
G4String name
Definition: TRTMaterials.hh:40
G4bool IsKnownPhysicsConstructor(const G4String &name)
void AddFactory(G4String name, G4VBasePhysListStamper *)
std::map< G4String, G4VBasePhysListStamper * > factories
#define G4ThreadLocal
Definition: tls.hh:89
int G4int
Definition: G4Types.hh:78
G4GLOB_DLL std::ostream G4cout
G4VPhysicsConstructor * GetPhysicsConstructor(const G4String &name)
bool G4bool
Definition: G4Types.hh:79
std::vector< G4String > availBasePhysLists
static G4PhysListRegistry * Instance()
const G4int n
static const double pc
Definition: G4SIunits.hh:118
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()
static G4ThreadLocal G4PhysListRegistry * theInstance
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
std::map< G4String, G4String > physicsExtensions
G4bool IsReferencePhysList(G4String nam) const
const std::vector< G4String > & AvailablePhysLists() const
G4VModularPhysicsList * GetModularPhysicsList(const G4String &name)
void AddPhysicsExtension(G4String name, G4String procname)