GEMC  2.3
Geant4 Monte-Carlo Framework
gemc.cc
Go to the documentation of this file.
1 
32 const char *GEMC_VERSION = "gemc 2.3";
33 
34 // G4 headers
35 #include "G4RunManager.hh"
36 #include "G4UImanager.hh"
37 #include "G4UIterminal.hh"
38 #include "G4VisExecutive.hh"
39 #include "G4VModularPhysicsList.hh"
40 #include "G4PropagatorInField.hh"
41 #include "G4TransportationManager.hh"
42 #include "G4UIQt.hh"
43 #include "G4Qt.hh"
44 
45 // Qt headers
46 #include <QApplication>
47 #include <QSplashScreen>
48 
49 // gemc headers
50 #include "HitProcess_MapRegister.h"
51 #include "detector_factory.h"
52 #include "gemc_MainGui.h"
53 #include "gbank.h"
54 #include "MDetectorConstruction.h"
55 #include "outputFactory.h"
56 #include "HitProcess.h"
57 #include "PhysicsList.h"
58 #include "options.h"
59 #include "dmesg_init.h"
60 #include "run_conditions.h"
61 #include "fieldFactory.h"
62 #include "material_factory.h"
63 #include "mirrors_factory.h"
64 #include "parameter_factory.h"
65 #include "string_utilities.h"
66 #include "utils.h"
67 #include "ActionInitialization.h"
68 
69 // c++ headers
70 #include <unistd.h> // needed for get_pid
71 
87 
88 
89 // get_pid is useful only on the farm to set the seed
90 // can set to zero in Windows environment
91 // ideally we'd want __get_pid();
92 #ifdef _MSC_VER
93 #include <stdio.h>
94 #include <process.h>
95  //int get_pid(){return __get_pid();}
96  int get_pid(){return 0;}
97 #endif
98 
99 // distinguishing between graphical and batch mode
100 QCoreApplication* createApplication(int &argc, char *argv[], double use_gui)
101 {
102  if(!use_gui)
103  return new QCoreApplication(argc, argv);
104  return new QApplication(argc, argv);
105 }
106 
107 
108 int main( int argc, char **argv )
109 {
110  clock_t startTime = clock();
111  cout << endl;
112 
113 
114  goptions gemcOpt;
115  gemcOpt.setGoptions();
116  gemcOpt.setOptMap(argc, argv);
117 
118  double use_gui = gemcOpt.optMap["USE_GUI"].arg;
119 
120  cout << endl << " > Initializing GEant4 MonteCarlo: " << GEMC_VERSION << endl << endl;
121 
122  QScopedPointer<QCoreApplication> app(createApplication(argc, argv, use_gui));
123 
124  // Initializing gemc splash class
125  // This class will log initialization messages
126  // This class will show a splashscreen if use_gui is non zero
127  // The screen log verbosity is controlled by LOG_VERBOSITY
128  gui_splash gemc_splash(gemcOpt);
129  gemc_splash.message(" Initializing GEant4 MonteCarlo version " + string(GEMC_VERSION));
130 
131 
132  // random seed initialization
133  CLHEP::HepRandom::setTheEngine(new CLHEP::MTwistEngine);
134  G4int seed;
135 
136  if(gemcOpt.optMap["RANDOM"].args=="TIME")
137  {
138  gemc_splash.message(" Initializing CLHEP Random Engine from local time " \
139  + stringify((double) time(NULL)) \
140  + ", cpu clock " \
141  + stringify((double) clock()) \
142  + " and process id " \
143  + stringify(getpid()) + ".");
144  seed = (G4int) ( (double) time(NULL)- (double) clock()-getpid() );
145  }
146  else
147  {
148  seed = atoi(gemcOpt.optMap["RANDOM"].args.c_str());
149  gemc_splash.message(" Initializing CLHEP Random Engine from user defined seed.");
150  }
151 
152  CLHEP::HepRandom::setTheSeed(seed);
153  gemc_splash.message(" Seed initialized to: " + stringify(seed));
154 
155  // Construct the default G4 run manager
156  gemc_splash.message(" Instantiating Run Manager...");
157  G4RunManager *runManager = new G4RunManager;
158 
159  // Initializing run_condition class
160  gemc_splash.message(" Instantiating Run Conditions...");
161  runConditions runConds(gemcOpt);
162 
163 
164  // GEMC Detector Map
165  gemc_splash.message(" Registering Detectors Factories...");
166  // Initializing Detector Factory
167  map<string, detectorFactoryInMap> detectorFactoryMap = registerDetectorFactory();
168  // Building detector with factories
169  map<string, detector> hallMap = buildDetector(detectorFactoryMap, gemcOpt, runConds);
170 
171 
172  // Initialize Materials Map Factory
173  gemc_splash.message(" Initializing Material Factories..." );
174  map<string, materialFactory> materialFactoriesMap = registerMaterialFactories();
175  // Build all materials
176  map<string, G4Material*> mats = buildMaterials(materialFactoriesMap, gemcOpt, runConds);
177 
178  // Initialize Mirrors Map Factory
179  gemc_splash.message(" Initializing Mirrors Factories..." );
180  map<string, mirrorFactory> mirrorFactoriesMap = registerMirrorFactories();
181  // Build all mirrors
182  map<string, mirror*> mirs = buildMirrors(mirrorFactoriesMap, gemcOpt, runConds);
183 
184 
185  // Initialize Parameters Map Factory
186  gemc_splash.message(" Registering Parameters Factories...");
187  map<string, parameterFactoryInMap> parameterFactoriesMap = registerParameterFactories();
188  // All Parameters with factories
189  map<string, double> gParameters = loadAllParameters(parameterFactoriesMap, gemcOpt, runConds);
190 
191 
192  // Process Hit Map
193  gemc_splash.message(" Building gemc Process Hit Factory...");
194  map<string, HitProcess_Factory> hitProcessMap = HitProcess_Map(gemcOpt.optMap["HIT_PROCESS_LIST"].args);
195 
197  gemc_splash.message(" Creating fields Map...");
198  map<string, fieldFactoryInMap> fieldFactoryMap = registerFieldFactories();
199  map<string, gfield> fieldsMap = loadAllFields(fieldFactoryMap, gemcOpt);
200 
201  // Build the detector
202  gemc_splash.message(" Building Detector Map...");
203  MDetectorConstruction* ExpHall = new MDetectorConstruction(gemcOpt);
204  ExpHall->hallMap = &hallMap;
205  ExpHall->mirs = &mirs;
206  ExpHall->mats = &mats;
207  ExpHall->fieldsMap = &fieldsMap;
208  // this is what calls Construct inside MDetectorConstruction
209  runManager->SetUserInitialization(ExpHall);
210 
211 
213  string phys_list = gemcOpt.optMap["PHYSICS"].args ;
214  gemc_splash.message(" Initializing Physics List " + phys_list + "...");
215  runManager->SetUserInitialization(new PhysicsList(gemcOpt));
216 
217  // Setting Max step for all the simulation.
218  // Notice: on the forum:
219  // http://hypernews.slac.stanford.edu/HyperNews/geant4/get/emfields/183/1.html
220  // it is mentioned that going through volumes of different materials could create problems.
221  // this is verified in clas12 when going from target to "hall" - even when vacuum was not involved.
222  // the solution to that was to create a transitional tube from target to the vacuum line
223  // This solution allowed to avoid setting MAX_FIELD_STEP to a value that would slow down the
224  // simulation by a factor of 5
225 
226 
227  double max_step = gemcOpt.optMap["MAX_FIELD_STEP"].arg;
228  if(max_step != 0)
229  G4TransportationManager::GetTransportationManager()->GetPropagatorInField()->SetLargestAcceptableStep(max_step);
230 
231 
232  // User action initialization
233  gemc_splash.message(" Initializing User Actions...");
234  ActionInitialization* gActions = new ActionInitialization(&gemcOpt, &gParameters);
235  runManager->SetUserInitialization(gActions);
236 
238  gemc_splash.message(" Initializing User Interface...");
239  G4UIsession *session = NULL;
240 
242  G4VisManager *visManager = NULL;
243  if(use_gui)
244  {
245  // G4VisManager* visManager = new G4VisExecutive;
246  // G4VisExecutive can take a verbosity argument - see /vis/verbose guidance.
247 
248  visManager = new G4VisExecutive("Quiet");
249  visManager->Initialize();
250  }
251 
252  if(use_gui)
253  session = new G4UIQt(1, argv);
254 
255 
256 
257  // Output File: registering output type, output process factory,
258  // sensitive detectors into Event Action
259  gemc_splash.message(" Initializing Output Action...");
260  outputContainer outContainer(gemcOpt);
261  map<string, outputFactoryInMap> outputFactoryMap = registerOutputFactories();
262 
263  // Initialize G4 kernel
264  gemc_splash.message(" Initializing Run Manager...\n");
265  // physical volumes, sensitive detectors are built here
266  runManager->Initialize();
267 
268 
269 
270  // registering activated field in the option so they're written out
271  if(ExpHall->activeFields.size())
272  gemcOpt.optMap["ACTIVEFIELDS"].args = "";
273 
274  for(set<string>::iterator fit = ExpHall->activeFields.begin(); fit != ExpHall->activeFields.end(); fit++)
275  gemcOpt.optMap["ACTIVEFIELDS"].args = gemcOpt.optMap["ACTIVEFIELDS"].args + *fit + " ";
276 
277 
278  // Creating the sim_condition map to save to the output
279  gemc_splash.message(" Writing simulation parameters in the output...");
280 
281  // filling gcard option content
282  map<string, string> sim_condition = gemcOpt.getOptMap();
283  // adding detectors conditions to sim_condition
284  mergeMaps(sim_condition, runConds.getDetectorConditionsMap());
285  // adding parameters value to sim_condition
286  mergeMaps(sim_condition, getParametersMap(gParameters));
287 
288 
289  // Bank Map, derived from sensitive detector map
290  gemc_splash.message(" Creating gemc Banks Map...");
291  map<string, gBank> banksMap = read_banks(gemcOpt, runConds.get_systems());
292 
293  // Getting UI manager, restoring G4Out to cout
294  G4UImanager* UImanager = G4UImanager::GetUIpointer();
295  UImanager->SetCoutDestination(NULL);
296 
297 
298  // saving simulation condition in the output file
299  if(outContainer.outType != "no")
300  {
301  outputFactory *processOutputFactory = getOutputFactory(&outputFactoryMap, outContainer.outType);
302  processOutputFactory->recordSimConditions(&outContainer, sim_condition);
303  // then deleting process output pointer, not needed anymore
304  delete processOutputFactory;
305  }
306 
307 
308  gActions->evtAction->outContainer = &outContainer;
309  gActions->evtAction->outputFactoryMap = &outputFactoryMap;
310  gActions->evtAction->hitProcessMap = &hitProcessMap;
311  gActions->evtAction->SeDe_Map = ExpHall->SeDe_Map;
312  gActions->evtAction->banksMap = &banksMap;
313  gActions->evtAction->gen_action = gActions->genAction;
314 
316  map<string, sensitiveDetector*>::iterator it;
317  for(it = ExpHall->SeDe_Map.begin(); it != ExpHall->SeDe_Map.end(); it++)
318  it->second->hitProcessMap = &hitProcessMap;
319 
320 
321 
322 
323  gemc_splash.message(" Executing initial directives...\n");
324  vector<string> init_commands = init_dmesg(gemcOpt);
325  for(unsigned int i=0; i<init_commands.size(); i++)
326  UImanager->ApplyCommand(init_commands[i].c_str());
327  string exec_macro = "/control/execute " + gemcOpt.optMap["EXEC_MACRO"].args;
328 
329  clock_t start_events;
330 
331  if(use_gui)
332  {
333  gemc_splash.message("Starting GUI...");
334  qApp->processEvents();
335 
336  gemcMainWidget gemcW(&gemcOpt, runManager, ExpHall->SeDe_Map, &hallMap, mats);
337  gemcW.setWindowTitle(GEMC_VERSION);
338  vector<string> wpos = get_info(gemcOpt.optMap["GUIPOS"].args);
339 
340  gemcW.move(get_number(wpos[0]), get_number(wpos[1]));
341  gemcW.show();
342 
343  // splash can finish once gemcW is up
344  gemc_splash.splash->finish(&gemcW);
345 
346  gemc_splash.message(" Executing initial visual directives...\n");
347  vector<string> init_vcommands = init_dvmesg(gemcOpt, visManager);
348  for(unsigned int i=0; i<init_vcommands.size(); i++)
349  {
350  gemc_splash.message(" Now executing: " + init_vcommands[i]);
351 
352  UImanager->ApplyCommand(init_vcommands[i].c_str());
353  }
354 
355  if(exec_macro != "/control/execute no") UImanager->ApplyCommand(exec_macro.c_str());
356  if(gemcOpt.optMap["N"].arg>0)
357  {
358  char command[100];
359  sprintf(command, "/run/beamOn %d", (int) gemcOpt.optMap["N"].arg);
360  UImanager->ApplyCommand(command);
361  }
362 
363  start_events = clock();
364  return qApp->exec();
365  // deleting and runManager is now taken care
366  // in the gemc_quit slot
367  delete visManager;
368  if(session != NULL) delete session;
369  }
370  else
371  {
372 
373  if(exec_macro != "/control/execute no") UImanager->ApplyCommand(exec_macro.c_str());
374  start_events = clock();
375  if(gemcOpt.optMap["N"].arg>0)
376  {
377  char command[100];
378  sprintf(command, "/run/beamOn %d", (int) gemcOpt.optMap["N"].arg);
379  UImanager->ApplyCommand(command);
380  }
381  }
382 
383  clock_t endTime = clock();
384  clock_t clockAllTaken = endTime - startTime;
385  clock_t clockEventTaken = endTime - start_events;
386 
387  cout << " > Total gemc time: " << clockAllTaken / (double) CLOCKS_PER_SEC << " seconds. "
388  << " Events only time: " << clockEventTaken / (double) CLOCKS_PER_SEC << " seconds. " << endl;
389 
390 
391  delete runManager;
392  return 1;
393 }
394 
395 
396 
397 
398 
399 
400 
401 
vector< string > init_dvmesg(goptions gemcOpt, G4VisManager *VM)
Initialization Routine for Visualization.
Definition: dmesg_init.cc:100
map< string, detector > buildDetector(map< string, detectorFactoryInMap > detectorFactoryMap, goptions go, runConditions rc)
QSplashScreen * splash
Definition: utils.h:38
map< string, parameterFactoryInMap > registerParameterFactories()
map< string, string > getOptMap()
Returns a map<string, string> with all options and values.
Definition: options.cc:444
map< string, fieldFactoryInMap > registerFieldFactories()
Definition: fieldFactory.cc:19
map< string, string > getDetectorConditionsMap()
void message(string)
Definition: utils.cc:60
map< string, gfield > loadAllFields(map< string, fieldFactoryInMap > fieldFactoryMap, goptions opts)
Definition: fieldFactory.cc:30
map< string, detector > * hallMap
vector< string > get_info(string input, string chars)
get information from strings such as "5*GeV, 2*deg, 10*deg", parses out strings in second argument ...
map< string, mirror * > buildMirrors(map< string, mirrorFactory > mirrorFactoryMap, goptions go, runConditions rc)
map< string, double > loadAllParameters(map< string, parameterFactoryInMap > parameterFactoryMap, goptions go, runConditions rc)
map< string, materialFactory > registerMaterialFactories()
map< string, mirrorFactory > registerMirrorFactories()
map< string, gfield > * fieldsMap
virtual void setGoptions()
Function to fill optMap.
Definition: gemc_options.cc:4
double get_number(string v, int warn_no_unit)
Returns number with dimension from string, i.e. 100*cm.
int setOptMap(int argc, char **args)
Sets map from command line arguments.
Definition: options.cc:142
map< string, G4Material * > * mats
map< string, string > getParametersMap(map< string, double > dataMap)
MPrimaryGeneratorAction * gen_action
Generator Action.
Definition: MEventAction.h:120
map< string, sensitiveDetector * > SeDe_Map
Sensitive detector Map.
Definition: MEventAction.h:116
string stringify(double x)
map< string, aopt > optMap
Options map.
Definition: options.h:75
map< string, gBank > * banksMap
Bank Map.
Definition: MEventAction.h:118
virtual void recordSimConditions(outputContainer *, map< string, string >)=0
QCoreApplication * createApplication(int &argc, char *argv[], double use_gui)
Main Program
Definition: gemc.cc:100
Action initialization class.
map< string, gBank > read_banks(goptions gemcOpt, map< string, string > allSystems)
Definition: gbank.cc:30
outputFactory * getOutputFactory(map< string, outputFactoryInMap > *outputFactoryMap, string outputType)
map< string, sensitiveDetector * > SeDe_Map
map< string, mirror * > * mirs
map< string, outputFactoryInMap > * outputFactoryMap
outputFactory map
Definition: MEventAction.h:115
map< string, HitProcess_Factory > * hitProcessMap
Hit Process Routine Factory Map.
Definition: MEventAction.h:117
MPrimaryGeneratorAction * genAction
void mergeMaps(map< string, string > &lhs, const map< string, string > &rhs)
Definition: utils.cc:75
map< string, HitProcess_Factory > HitProcess_Map(string experiments)
< flux hit process common to all
outputContainer * outContainer
outputContainer class - contains the output format.
Definition: MEventAction.h:114
const char * GEMC_VERSION
Definition: gemc.cc:32
map< string, outputFactoryInMap > registerOutputFactories()
int main(int argc, char **argv)
Definition: gemc.cc:108
map< string, string > get_systems()
map< string, detectorFactoryInMap > registerDetectorFactory()
map< string, G4Material * > buildMaterials(map< string, materialFactory > materialFactoryMap, goptions go, runConditions rc)
vector< string > init_dmesg(goptions gemcOpt)
General Initialization Routine.
Definition: dmesg_init.cc:19