-
Notifications
You must be signed in to change notification settings - Fork 0
/
gemc.cc
160 lines (128 loc) · 5.79 KB
/
gemc.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// c++
#include <iostream>
using namespace std;
// geant4
#include "G4UImanager.hh"
#include "G4UIsession.hh"
#include "G4RunManagerFactory.hh"
#include "G4VisExecutive.hh"
#include "G4UIQt.hh"
// gemc
#include "goptions.h"
#include "gsplash.h"
#include "eventDispenser.h"
#include "g4SceneProperties.h"
#include "gphysics.h"
#include "gemcUtilities.h"
#include "gemcConventions.h"
#include "gemcOptions.h"
#include "gActionInitialization.h"
#include "gui.h"
#include "gsession.h"
#include "gdetectorConstruction.h"
int main(int argc, char *argv[]) {
// the gemc goptions are defined in utilities/defineOptions.cc
// they are merged with the frameworks goptions definitions
// the goptions are then assigned from the jcard(s) and command line
GOptions *gopts = new GOptions(argc, argv, gemc::defineOptions());
// todo: add geant4 version here, see phys list on how
// get gui switch, overlaps check and verbosity
bool gui = gopts->getSwitch("gui");
int checkForOverlaps = gopts->getScalarInt("checkOverlaps");
int verbosity = gopts->getVerbosityFor("general");
// splash screen
GSplash *gemcSplash = nullptr;
// createQtApplication returns a QApplication if gui is not zero
// otherwise it returns a QCoreApplication
QCoreApplication *gApp = createQtApplication(argc, argv, gui);
if (gui) {
gemcSplash = new GSplash("gemcArchitecture");
}
// instantiating new User Interface Messenger
// our custom cout destination for the UIM: MasterGeant4.[log, err]
G4UImanager *UIM = G4UImanager::GetUIpointer();
UIM->SetCoutDestination(new GSession);
// init geant4 run manager with number of threads coming from options
// as of 11.2 the default is task-based parallel mode
auto runManager = G4RunManagerFactory::CreateRunManager(G4RunManagerType::Default);
runManager->SetNumberOfThreads(getNumberOfThreads(gopts));
// random engine
startRandomEngine(gopts);
// instantiating pointer to global digitization map
// the map will be filled with the gsystem information of the sensitive detectors
// the map is also used by eventDispenser to reload constants at every run number
map < string, GDynamicDigitization * > *globalDigitizationMap = new map<string, GDynamicDigitization *>;
// building detector
// this is global, changed at main scope
GDetectorConstruction *gDetectorGlobal = new GDetectorConstruction(gopts, globalDigitizationMap);
runManager->SetUserInitialization(gDetectorGlobal);
// starting gphysics
auto gphysics = new GPhysics(gopts);
// if showAvailablePhysicsX switch is on, print available physics and exit
if (gopts->getSwitch("showAvailablePhysicsX")) {
delete globalDigitizationMap;
delete gApp;
if (gui) {
delete gemcSplash;
}
delete gopts;
// Free the store: user actions, physics_list and detector_description are
// owned and deleted by the run manager
delete runManager;
return EXIT_SUCCESS;
}
runManager->SetUserInitialization(gphysics->getPhysList());
// instantiate GActionInitialization and initialize the geant4 kernel
runManager->SetUserInitialization(new GActionInitialization(gopts, globalDigitizationMap));
// this initializes g4MTRunManager, which:
// calls Construct in GDetectorConstruction
// calls ConstructSDandField in GDetectorConstruction
// which in turns builds the gsystems, the g4systems, and the sensitive detectors in each thread,
initGemcG4RunManager(runManager, gopts);
// after the detectors are built, query the digitization names and load the plugins
// maybe this should be done in GDetectorConstruction
loadDigitizationPlugins(gopts, gDetectorGlobal->getDigitizationNamesList(), globalDigitizationMap);
// G4VisExecutive can take a verbosity argument - see /vis/verbose guidance
// notice we initialize this in batch mode as well
G4VisManager *visManager = new G4VisExecutive("Quiet");
visManager->Initialize();
auto geventDispenser = new EventDispenser(gopts, globalDigitizationMap);
if (gui) {
// initializing qt session
gemcSplash->message("Starting GUI");
qApp->processEvents();
// passing executable to retrieve full path
GemcGUI gemcGui(argv[0], gopts, geventDispenser);
gemcGui.show();
gemcSplash->finish(&gemcGui);
// intializing G4UIQt session. Notice g4SceneProperties has to be declared after this, so we have to duplicate code below.
G4UIsession *session = new G4UIQt(1, argv);
G4SceneProperties *g4SceneProperties = new G4SceneProperties(gopts);
if (gDetectorGlobal->is_empty()) {
cout << GEMCLOGMSGITEM << "Warning: Detector is empty. Nothing to do." << endl;
} else {
applyInitialUIManagerCommands(true, checkForOverlaps, verbosity);
qApp->exec();
}
delete g4SceneProperties;
delete session;
} else {
// set display properties in batch mode
G4SceneProperties *g4SceneProperties = new G4SceneProperties(gopts);
applyInitialUIManagerCommands(false, checkForOverlaps, verbosity);
geventDispenser->processEvents();
delete g4SceneProperties;
}
// clearing pointers
// delete visManager; deleting this cause error. Perhaps can define / delete in the functions above
delete geventDispenser;
for (auto [key, value]: (*globalDigitizationMap)) { delete value; }
delete globalDigitizationMap;
delete gApp;
delete gopts;
// Free the store: user actions, physics_list and detector_description are
// owned and deleted by the run manager
delete runManager;
cout << GEMCLOGMSGITEM << KGRN << "Simulation completed, arrivederci! " << RST << endl << endl;
return EXIT_SUCCESS;
}