edepSim.cc
Go to the documentation of this file.
4 #include "EDepSimLog.hh"
5 
6 #include "G4RunManager.hh"
7 #include "G4UImanager.hh"
8 #include "G4UIExecutive.hh"
9 
10 #include "globals.hh"
11 
12 #include <iostream>
13 #include <fstream>
14 #include <csignal>
15 #include <cstdlib>
16 
17 void usage () {
18  std::cout << "Usage: edep-sim [options] [macros]" << std::endl;
19  std::cout << " -C -- Toggle validating the geometry" << std::endl;
20  std::cout << " -d -- Increase the debug level" << std::endl;
21  std::cout << " -D <name>=[error,severe,warn,debug,trace]"
22  << std::endl
23  << " -- Change the named debug level"
24  << std::endl;
25  std::cout << " -e <n> -- Add /run/beamOn <n> after last macro."
26  << std::endl;
27  std::cout << " -g -- Set a GDML file" << std::endl;
28  std::cout << " -o -- Set the output file" << std::endl;
29  std::cout << " -p -- Select the physics list" << std::endl;
30  std::cout << " -s -- Set the seed from the time" << std::endl;
31  std::cout << " -u -- Do update before running the macros"
32  << std::endl;
33  std::cout << " -U -- Start an interactive run after the macros"
34  << std::endl
35  << " are processed."
36  << std::endl;
37  std::cout << " -v -- Increase the verbosity" << std::endl;
38  std::cout << " -V <name>=[quiet,log,info,verbose]" << std::endl
39  << " -- Change the named log level"
40  << std::endl;
41  std::cout << " -h -- This help message." << std::endl;
42 
43  exit(1);
44 }
45 
46 int main(int argc,char** argv) {
48 
49  std::string outputFilename;
50  std::string physicsList = "";
51  std::string gdmlFilename = "";
52 
53  int errflg = 0;
54  int c = 0;
55  bool useUI = false;
56  bool setSeed=false;
57  bool doUpdate=false;
58  bool validateGeometry=true;
59  int debugLevel = 0;
60  std::map<std::string, EDepSim::LogManager::ErrorPriority> namedDebugLevel;
61 
62  int logLevel = 1; // Will choose default logging level...
63  std::map<std::string, EDepSim::LogManager::LogPriority> namedLogLevel;
64 
65  // If filled, run this many events. The command line argument must be an
66  // integer or G4 will give an error. There could be error checking here,
67  // but assume the user is "intelligent", and won't try to run "-e ten"
68  // instead of "-e 10".
69  std::string beamOnCount = "";
70 
71  if (argc<2) usage();
72 
73  while (!errflg && ((c=getopt(argc,argv,"CdD:e:g:o:p:qsuUvV:h")) != -1)) {
74  switch (c) {
75  case 'C': {
76  // Toggle the validateGeometry flag. The default value is set
77  // above.
78  validateGeometry = !validateGeometry;
79  break;
80  }
81  case 'd':
82  {
83  // increase the debugging level.
84  ++debugLevel;
85  break;
86  }
87  case 'D':
88  {
89  // Set the debug level for a named trace.
90  std::string arg(optarg);
91  std::size_t sep = arg.find("=");
92  if (sep != std::string::npos) {
93  std::string name = arg.substr(0,sep);
94  std::string levelName = arg.substr(sep+1);
95  switch (levelName[0]) {
96  case 'e': case 'E':
97  namedDebugLevel[name.c_str()]
99  break;
100  case 's': case 'S':
101  namedDebugLevel[name.c_str()]
103  break;
104  case 'w': case 'W':
105  namedDebugLevel[name.c_str()]
107  break;
108  case 'd': case 'D':
109  namedDebugLevel[name.c_str()]
111  break;
112  case 't': case 'T':
113  namedDebugLevel[name.c_str()]
115  break;
116  default:
117  usage();
118  }
119  }
120  break;
121  }
122  case 'e': {
123  // Add a /run/beamOn command after the last macro has been
124  // processed.
125  beamOnCount = optarg;
126  break;
127  }
128  case 'g': {
129  gdmlFilename = optarg;
130  break;
131  }
132  case 'o': {
133  outputFilename = optarg;
134  break;
135  }
136  case 'p': {
137  physicsList = optarg;
138  break;
139  }
140  case 's': {
141  // Force a '/edep/random/timeRandomSeed'
142  setSeed = true;
143  break;
144  }
145  case 'u': {
146  // Force a '/edep/update' before running the first macro.
147  doUpdate = true;
148  break;
149  }
150  case 'U': {
151  // Use a tcsh-style command line interface
152  useUI = true;
153  break;
154  }
155  case 'q':
156  {
157  // decrease the verbosity level.
158  if (logLevel>0) --logLevel;
159  else logLevel = 0;
160  break;
161  }
162  case 'v':
163  {
164  // increase the verbosity level.
165  if (logLevel>0) ++logLevel;
166  else logLevel = 2;
167  break;
168  }
169  case 'V':
170  {
171  // Set the debug level for a named trace.
172  std::string arg(optarg);
173  std::size_t sep = arg.find("=");
174  if (sep != std::string::npos) {
175  std::string name = arg.substr(0,sep);
176  std::string levelName = arg.substr(sep+1);
177  switch (levelName[0]) {
178  case 'q': case 'Q':
179  namedLogLevel[name.c_str()]
181  break;
182  case 'l': case 'L':
183  namedLogLevel[name.c_str()]
185  break;
186  case 'i': case 'I':
187  namedLogLevel[name.c_str()]
189  break;
190  case 'v': case 'V':
191  namedLogLevel[name.c_str()]
193  break;
194  default:
195  usage();
196  }
197  }
198  break;
199  }
200  case 'h':
201  default:
202  usage();
203  }
204  }
205 
206  if (logLevel < 1) {
208  }
209  else if (logLevel == 1) {
211  EDepSimLog("Set log level to LogLevel");
212  }
213  else if (logLevel == 2) {
215  EDepSimInfo("Set log level to InfoLevel");
216  }
217  else if (logLevel >= 3) {
219  EDepSimVerbose("Set log level to VerboseLevel");
220  }
221 
223  = namedLogLevel.begin();
224  i != namedLogLevel.end();
225  ++i) {
226  EDepSim::LogManager::SetLogLevel(i->first.c_str(), i->second);
227  }
228 
229  if (debugLevel == 1) {
231  EDepSimWarn("Set debug level to WarnLevel");
232  }
233  else if (debugLevel == 2) {
235  EDepSimDebug("Set debug level to DebugLevel");
236  }
237  else if (debugLevel >= 2) {
239  EDepSimTrace("Set debug level to TraceLevel");
240  }
241 
243  = namedDebugLevel.begin();
244  i != namedDebugLevel.end();
245  ++i) {
246  EDepSim::LogManager::SetDebugLevel(i->first.c_str(), i->second);
247  }
248 
249  // Set the mandatory initialization classes
250  // Construct the default run manager
251  G4RunManager* runManager = EDepSim::CreateRunManager(physicsList);
252 
253  // Create the persistency manager. The persistency manager must derive
254  // from G4VPersistencyManager which will make this object available to the
255  // G4RunManager as a singleton. There can only be one persistency manager
256  // at a time. The Store methods will then be called by the run managers
257  // Analyze methods. The persistency manager doesn't *have* to be derived
258  // from EDepSim::RootPersistencyManager, but a lot of the trajectory and hit
259  // handling functionality is handled by that class.
260  EDepSim::PersistencyManager* persistencyManager = NULL;
261 
262  persistencyManager = new EDepSim::RootPersistencyManager();
263 
264  // Create a "no i/o" persistency manager. This doesn't actually save
265  // anything, and it may be better to stop if there isn't a real
266  // persistency manager declared. This is here as paranoia in case later
267  // gode gets clever about how the persistency manager is created.
268  if (!persistencyManager) {
269  persistencyManager = new EDepSim::PersistencyManager();
270  }
271 
272  // Get the pointer to the UI manager. This is used to control how
273  // edep-sim will run. All arguments are passed in using GEANT4 macro
274  // commands.
275  G4UImanager* UI = G4UImanager::GetUIpointer();
276 
277  // Open the file if one was declared on the command line.
278  if (gdmlFilename != "") {
279  UI->ApplyCommand("/edep/gdml/read "+gdmlFilename);
280  }
281 
282  // Set the defaults for the simulation.
283  UI->ApplyCommand("/edep/control edepsim-defaults 1.0");
284 
285  // Open the file if one was declared on the command line.
286  if (persistencyManager && ! outputFilename.empty()) {
287  UI->ApplyCommand("/edep/db/open "+outputFilename);
288  }
289 
290  std::signal(SIGILL, SIG_DFL);
291  std::signal(SIGBUS, SIG_DFL);
292  std::signal(SIGSEGV, SIG_DFL);
293 
294  // Signal that the geometry should be validated for overlaps before
295  // generating the first event. This causes the executable to throw an
296  // exception if the geometry has overlaps.
297  if (validateGeometry) UI->ApplyCommand("/edep/validateGeometry");
298 
299  // Set the random seed from the time.
300  if (setSeed) UI->ApplyCommand("/edep/random/timeRandomSeed");
301 
302  // Set the defaults for the simulation and get ready to run. This needs
303  // to be done before the first event is generated, but can also be done in
304  // the users macro file. It's executed here if the "-u" option was
305  // provided on the command line.
306  if (doUpdate) UI->ApplyCommand("/edep/update");
307 
308  if (useUI) {
309  // Make a command line available if one was requested.
310  G4UIExecutive* ui = new G4UIExecutive(argc, argv);
311  for (int i=optind; i<argc; ++i) {
312  std::string macroFilename = argv[i];
313  std::cout << "## Run macro: " << macroFilename << std::endl;
314  UI->ApplyCommand("/control/execute "+macroFilename);
315  }
316  ui->SessionStart();
317  delete ui;
318  }
319  else if (optind < argc) {
320  // Run a macro from the command line.
321  for (int i=optind; i<argc; ++i) {
322  std::string macroFilename = argv[i];
323  UI->ApplyCommand("/control/execute " +macroFilename);
324  }
325  // If a event count was provided with the -e format, then add a beamOn
326  // command. The beamOn command can also be in the users macro, but
327  // this makes it a little more convenient to write generic macros and
328  // then specify the number of interactions to simulate from the
329  // command line.
330  if (!beamOnCount.empty()) {
331  UI->ApplyCommand("/run/beamOn " + beamOnCount);
332  }
333  }
334 
335  // If we have the persistency manager, then make sure it's closed.
336  if (persistencyManager) {
337  persistencyManager->Close();
338  delete persistencyManager;
339  }
340  delete runManager;
341 
342  return 0;
343 }
static QCString name
Definition: declinfo.cpp:673
#define EDepSimLog(outStream)
Definition: EDepSimLog.hh:717
intermediate_table::iterator iterator
static void SetLogLevel(LogPriority level)
Set the default logging level.
Definition: EDepSimLog.hh:426
std::string string
Definition: nybbler.cc:12
#define EDepSimInfo(outStream)
Definition: EDepSimLog.hh:752
int main(int argc, char **argv)
Definition: edepSim.cc:46
void usage()
Definition: edepSim.cc:17
#define EDepSimTrace(outStream)
Definition: EDepSimLog.hh:653
#define EDepSimDebug(outStream)
Definition: EDepSimLog.hh:614
#define EDepSimVerbose(outStream)
Definition: EDepSimLog.hh:787
static void SetDebugLevel(ErrorPriority level)
Definition: EDepSimLog.hh:411
#define EDepSimWarn(outStream)
Definition: EDepSimLog.hh:576
G4RunManager * CreateRunManager(G4String physicsList)
static void Configure(const char *conf=NULL)
virtual G4bool Close(void)
Make sure the output file is closed.
QTextStream & endl(QTextStream &s)