Geant4Manager.cc
Go to the documentation of this file.
1 #include "Geant4Manager.h"
2 
3 #include <G4RunManager.hh>
4 #include <G4UImanager.hh>
5 #include <G4ParticleTable.hh>
6 #include <G4VUserDetectorConstruction.hh>
7 #include <G4VUserPrimaryGeneratorAction.hh>
8 #include <G4VUserPhysicsList.hh>
9 
10 #include <G4ParticleDefinition.hh>
11 #include <G4ProcessVector.hh>
12 #include <G4VisManager.hh>
13 #include <G4UImanager.hh>
14 
15 #include "GlobalGeometry.h"
16 #include "GlobalPhysicsList.h"
18 
19 #include <fwk/CentralConfig.h>
20 #include <fwk/RandomEngineRegistry.h>
21 #include <utl/ErrorLogger.h>
22 
23 #include <utl/AugerException.h>
24 #include <tls/DefaultPhysicsList.h>
25 #include <tls/G4OutputHandler.h>
26 
27 using namespace std;
28 
29 
30 namespace tls {
31 
32  Geant4Manager::Geant4Manager() :
33  fRunManager(new G4RunManager()),
34  fMasterPhysicsList(new GlobalPhysicsList()),
35  fVisManager(nullptr),
36  fPhysicsInitialized(false),
37  fClosedModules(0),
38  fVerboseLevel(0)
39  //fCurrentCustomization
40  {
41  INFO("creating and initializing runmanager..");
42 
43  // Set CLHEP random engine to the framework-specified one
44  CLHEP::HepRandom::setTheEngine(
45  &fwk::RandomEngineRegistry::GetInstance().Get(fwk::RandomEngineRegistry::eDetector).GetEngine()
46  );
47 
48  // send output to utl::ErrorLogger
49  G4UImanager::GetUIpointer()->SetCoutDestination(new G4OutputHandler());
50 
51  // Create the default physics list and geometry
52  GlobalGeometry* const globalGeometry = new GlobalGeometry();
53  DefaultPhysicsList* const defaultPhysicsList = new DefaultPhysicsList(0);
54  Geant4Customization defaultMode("Default", globalGeometry, defaultPhysicsList);
55  AddCustomization(defaultMode);
56 
57  // Physics list needs to be set before creating the primary injector
58  fRunManager->SetUserInitialization(fMasterPhysicsList);
59  // Not setting the dummy geometry because materials are initialized and G4TankFastCerenkov fails
60  // If it is not set, it magically works.
61  fRunManager->SetUserInitialization(globalGeometry);
62  }
63 
64 
65  void
66  Geant4Manager::SetDefaultPhysicsList(G4VUserPhysicsList* const physicsList)
67  {
69  throw utl::AugerException("Cannot set default physics list after Geant4 run manager is initialized.");
70  auto& cd = fCustomizations["Default"];
71  cd.SetPhysicsList(physicsList);
72  fMasterPhysicsList->RegisterPhysics("Default", cd.GetPhysicsList());
73  }
74 
75 
76  void
78  {
79  if (!fPhysicsInitialized) {
80  INFO("Initializing physics...");
81  fRunManager->Initialize();
82 
83  // Additional processes (those in addition to DefaultPhysicsList) cannot be disabled while in
84  // G4State_PreInit or G4State_Init, so we have to do it here. We call the Inactivate-methods
85  // to restore the default configuration of active processes
86  for (auto& c : fCustomizations) {
87  G4VPhysicsListCustomization* const custom = c.second.GetPhysicsListCustomization();
88  if (custom)
89  custom->InactivateCustomProcesses();
90  }
91 
92  fPhysicsInitialized = true;
93  }
94  }
95 
96 
97  void
99  {
100  Reset();
101  ++fClosedModules;
102  if (fClosedModules + 1 >= fCustomizations.size()) {
103  fRunManager = G4RunManager::GetRunManager();
104  if (fRunManager) {
105  INFO("deleting G4RunManager..");
106  delete fRunManager;
107  fRunManager = nullptr;
108  } else
109  WARNING("RunManger was already deleted at an earlier stage!");
110 
111  if (fVisManager) {
112  INFO("deleting G4VisManager..");
113  delete fVisManager;
114  fVisManager = nullptr;
115  }
116  if (fClosedModules > fCustomizations.size())
117  ERROR("The use of Geant4Manager seems inconsistent! More Modules ask for deletion than initially registered!");
118  } else {
119  ostringstream msg;
120  msg << fClosedModules << " < " << fCustomizations.size() << ", not deleting yet";
121  INFO(msg);
122  }
123  }
124 
125 
126  void
127  Geant4Manager::AddVisManager(G4VisManager* const visManager)
128  {
129  if (fVisManager)
130  throw utl::AugerException("Trying to register a second instance of G4VisManager. "
131  "G4 should have already failed at this point..");
132 
133  fVisManager = visManager;
134  }
135 
136 
137  void
139  {
140  fCustomizations[custom.GetName()] = custom;
142  if (custom.GetDetectorConstruction())
143  custom.GetDetectorConstruction()->Construct();
144  }
145 
146 
147  void
148  Geant4Manager::Customize(const std::string& name)
149  {
150  if (fCurrentCustomization == name)
151  return;
152 
153  const auto it = fCustomizations.find(name);
154  if (it == fCustomizations.end()) {
155  ostringstream msg;
156  msg << "Unknown Geant4 customization: " << name;
157  throw utl::AugerException(msg.str());
158  }
159 
160  cout << "Customizing " << name << endl;
161  Reset();
162  G4VUserDetectorConstruction* const detectorConstruction = it->second.GetDetectorConstruction();
163 
164  fRunManager->SetUserInitialization(detectorConstruction);
165 
166  if (!fPhysicsInitialized) {
167  InitPhysics();
168  } else {
169  INFO("Updating geometry...");
170  fRunManager->DefineWorldVolume(detectorConstruction->Construct(), true);
171  }
172 
173  INFO("Updating processes...");
174  G4VPhysicsListCustomization* const physicsListCustomization = it->second.GetPhysicsListCustomization();
175  if (physicsListCustomization) {
176  physicsListCustomization->SetCustomCuts();
177  if (physicsListCustomization->ActivateCustomProcesses()) {
178  fRunManager->PhysicsHasBeenModified();
179  }
180  }
181 
182  // if (it->second.GetPrimaryGenerator())
183  fRunManager->SetUserAction(it->second.GetPrimaryGenerator());
184 
185  fRunManager->SetUserAction(it->second.GetStackingAction());
186  fRunManager->SetUserAction(it->second.GetTrackingAction());
187  fRunManager->SetUserAction(it->second.GetSteppingAction());
188  fRunManager->SetUserAction(it->second.GetEventAction());
189  fRunManager->SetUserAction(it->second.GetRunAction());
190 
191  fCurrentCustomization = it->first;
192 
193  if (fVerboseLevel > 0)
194  DumpProcesses();
195  }
196 
197 
198  void
200  {
201  // geometry is not reset.
202  if (!fCurrentCustomization.empty()) {
203  INFO("Setting default geometry...");
204  G4VUserDetectorConstruction* const detectorConstruction = fCustomizations["Default"].GetDetectorConstruction();
205 
206  fRunManager->SetUserInitialization(detectorConstruction);
207  fRunManager->DefineWorldVolume(detectorConstruction->Construct(), true);
208 
209  G4VPhysicsListCustomization* const physicsListCustomization = fCustomizations[fCurrentCustomization].GetPhysicsListCustomization();
210  if (physicsListCustomization && physicsListCustomization->InactivateCustomProcesses())
211  fRunManager->PhysicsHasBeenModified();
213  }
214 
215  fRunManager->SetUserAction(static_cast<G4VUserPrimaryGeneratorAction*>(nullptr));
216  fRunManager->SetUserAction(static_cast<G4UserStackingAction*>(nullptr));
217  fRunManager->SetUserAction(static_cast<G4UserTrackingAction*>(nullptr));
218  fRunManager->SetUserAction(static_cast<G4UserSteppingAction*>(nullptr));
219  fRunManager->SetUserAction(static_cast<G4UserEventAction*>(nullptr));
220  fRunManager->SetUserAction(static_cast<G4UserRunAction*>(nullptr));
221  }
222 
223 
224  void
226  {
227  INFO("dumping process info for all particles--");
228  auto& partIt = *G4ParticleTable::GetParticleTable()->GetIterator();
229  for (partIt.reset(); partIt(); ) {
230  auto& particle = *partIt.value();
231  cout << "particle " << particle.GetParticleName() << endl;
232  const auto procMan = particle.GetProcessManager();
233  if (!procMan)
234  ERROR("ProcessManager not found!");
235  else {
236  auto& procList = *procMan->GetProcessList();
237  for (unsigned int j = 0, n = procList.size(); j < n; ++j)
238  G4cerr << "process " << procList[j]->GetProcessName() << ' '
239  << (procMan->GetProcessActivation(procList[j]) ? "active" : "inactive") << G4endl;
240  }
241  }
242  }
243 
244 
245  void
246  Geant4Manager::SetVerbosity(const int verbosity)
247  {
248  fVerboseLevel = verbosity;
249 
250  auto& partIt = *G4ParticleTable::GetParticleTable()->GetIterator();
251  std::ostringstream msg;
252  for (partIt.reset(); partIt(); ) {
253  auto& particle = *partIt.value();
254  auto& procMan = *particle.GetProcessManager();
255  auto& proc = *procMan.GetProcessList();
256  for (int i = 0, n = procMan.GetProcessListLength(); i < n; ++i) {
257  proc[i]->SetVerboseLevel(0);
258  msg << "process: " << proc[i]->GetProcessName() << " for "
259  << particle.GetParticleName() << ": " << proc[i]->GetVerboseLevel() << '\n';
260  }
261  }
262  INFO(msg);
263  }
264 
265 }
G4VUserPhysicsList to aggregate physics lists to be used by multiple Geant4 modules in one offline se...
Base class for all exceptions used in the auger offline code.
G4VisManager * fVisManager
Definition: Geant4Manager.h:97
virtual bool InactivateCustomProcesses()=0
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
void Reset()
Undo the customizations introduced by the current configuration.
void AddCustomization(Geant4Customization &custom)
unsigned int fClosedModules
Definition: Geant4Manager.h:99
void AddVisManager(G4VisManager *visManager)
Add a visualization manager. Only one visualization manager is accepted.
GlobalPhysicsList * fMasterPhysicsList
Definition: Geant4Manager.h:96
void RegisterPhysics(const G4String &name, G4VUserPhysicsList *userList)
This class redirects Geant4&#39;s streams G4cerr and G4cerr to the framework&#39;s utl::ErrorLogger.
std::string GetName() const
virtual bool ActivateCustomProcesses()=0
G4RunManager * fRunManager
Definition: Geant4Manager.h:94
void NotifyDelete()
Book-keeping method. Call this to let the manager know your module does not need Geant4 anymore...
std::map< std::string, Geant4Customization > fCustomizations
Data structure to hold the different Geant4 global objects required to run a single module...
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
void SetVerbosity(int verbosity)
std::string fCurrentCustomization
unsigned int fVerboseLevel
G4VUserPhysicsList * GetPhysicsList()
struct particle_info particle[80]
G4VUserDetectorConstruction * GetDetectorConstruction()
utl::CoordinateSystemPtr Get(const std::string &id)
Get a well-known Coordinate System.
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
void Customize(const std::string &name)
void SetDefaultPhysicsList(G4VUserPhysicsList *physicsList)
Set the default physics list. This will throw an exception if the run manager has been initialized al...
Class to specify customization of the standard global PhysicsList that are handled by the Geant4Manag...
Default physics list to be used by multiple Geant4 modules in one offline session.

, generated on Tue Sep 26 2023.