GGS(GenericGEANT4Simulation)Software  2.7.0
 All Data Structures Namespaces Files Functions Variables Typedefs Macros
GGSPenny.cpp
1 /*
2  * GGSPenny.cpp
3  *
4  * Created on: 2010-09-29
5  * Authors: Emiliano Mocchiutti and Cecilia Pizzolotto
6  */
7 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
8 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
9 // C++ and STL headers
10 #include <sys/stat.h>
11 #include <vector>
12 
13 // ROOT headers
14 #include "TROOT.h"
15 
16 // GEANT4 headers
17 #include "G4PhysListFactory.hh"
18 #include "G4UImanager.hh"
19 #include "G4Version.hh"
20 #include "Randomize.hh"
21 
22 #ifdef G4VIS_USE
23 #include "G4VisExecutive.hh"
24 #endif
25 
26 #ifdef G4UI_USE
27 #include "G4UIExecutive.hh"
28 #endif
29 
30 // GGS headers
31 #include "GGSVersion.h" //Automatically generated by the CMake configuration system
34 #include "montecarlo/generators/manager/GGSGeneratorActionsManager.h"
39 #include "utils/GGSInputParser.h"
40 #include "utils/GGSSmartLog.h"
41 #ifdef CRMC
42 #include "montecarlo/physicslists/GGSCRMCPhysicsList.h"
43 #endif
44 
45 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
46 
47 void usage() {
48  std::cout << "Usage: GGSPenny [options] \n";
49  std::cout << "This is the GGS main MonteCarlo program\n\n";
50  std::cout << "Run type selection\n";
51  std::cout << "------------------\n";
52  std::cout << " -X, --interactive interactive mode [default: false]\n\n";
53  std::cout << " -d, --data-card FILE data card filename [default: not set]\n\n";
54  std::cout << "If only -d is specified the program will run in batch mode.\n";
55  std::cout
56  << "If both options are specified, the datacard will be processed before entering the interactive mode.\n\n";
57  std::cout << "Configuration options\n";
58  std::cout << "---------------------\n";
59  std::cout << " -g, --geometry FILE full path and name of the geometry; can be a .so or a .gdml.\n";
60  std::cout << " -gd, --geo-data-card FILE data card filename for geometry configuration [default: not set]\n\n";
61  std::cout << " -pl, --physics-list NAME physics list (standard list name or full path of physics list .so "
62  "library) [default: QGSP_BERT]\n\n";
63  std::cout
64  << " -pd, --physlist-data-card FILE data card filename for physics list configuration [default: not set]\n\n";
65  std::cout << " -ap, --action-plugin FILE full path and name of the plugin user and generator action library\n";
66  std::cout << " May be repeated to load many libraries: -ap libUserAction.so -ap "
67  "libGeneratorAction.so\n\n";
68  std::cout << " -ro, --root-output-file FILE default ROOT output filename (may be overridden in datacard for each "
69  "action)\n\n";
70  std::cout << " -os, --output-suffix SUFFIX output file suffix [default: "
71  "]\n\n";
72  std::cout << " --seed1 INT first random seed [default: 1]\n\n"; // do not put default 0!
73  std::cout << " --seed2 INT second random seed [default: 2]\n\n";
74  std::cout << " -s, --input-seed-file FILE file containing input random seeds [default: not set]\n\n";
75  std::cout << "Configuration options can either be given as command line parameters or placed in an input file.\n";
76  std::cout << "File syntax is the same as the above specified commands, one command per line. Set the input file via "
77  "command line as:\n\n";
78  std::cout << " -i, --input-file FILE file containing input arguments [default: not set]\n\n";
79  std::cout << "Miscellaneous\n";
80  std::cout << "-------------\n";
81  std::cout << " -v, --verbose be verbose [default: false]\n\n";
82  std::cout << " -V, --version displays software version and exit\n\n";
83  std::cout << " -h, --help display this help and exit\n\n";
84  std::cout << "\nTo run GGSPenny either the -d (data card) or the -X (interactive) option MUST be set!\n";
85  std::cout << "Report bugs to: mori@fi.infn.it \n";
86 }
87 
88 void GGSPennyVersion() {
89  std::cout << "GGSPenny simulation software\n";
90  std::cout << "Using GGS " << GGSVERSION << std::endl;
91 }
92 
94 namespace GGSPenny {
95 G4String rootOutputFile = "";
96 G4String outputSuffix = "";
97 G4String dataCard = "";
98 G4String geoDataCard = "";
99 G4String physListDataCard = "";
100 G4String inputFile = "";
101 G4String inputSeedFile = "";
102 G4String geometry = "";
103 G4String physicsListName = "FTFP_BERT";
104 std::vector<G4String> actionPluginFiles;
105 G4bool interactiveMode = false;
106 G4long seed1 = 1;
107 G4long seed2 = 2;
108 } // namespace GGSPenny
109 using namespace GGSPenny;
110 
111 void DumpGlobals() {
112  std::cout << "==============> MonteCarlo globals used for this run <===============" << std::endl;
113  std::cout << "dataCard : " << dataCard.c_str() << std::endl;
114  std::cout << "geometry : " << geometry.c_str() << std::endl;
115  std::cout << "geoDataCard : " << geoDataCard.c_str() << std::endl;
116  std::cout << "physicsListName : " << physicsListName.c_str() << std::endl;
117  std::cout << "physListDataCard: " << physListDataCard.c_str() << std::endl;
118  std::cout << "rootOutputFile : " << rootOutputFile.c_str() << std::endl;
119  std::cout << "outputSuffix : " << outputSuffix.c_str() << std::endl;
120  std::cout << "inputSeedFile : " << inputSeedFile.c_str() << std::endl;
121  std::cout << "seed1 : " << seed1 << std::endl;
122  std::cout << "seed2 : " << seed2 << std::endl;
123  std::cout << "inputFile : " << inputFile.c_str() << std::endl;
124  std::cout << "interactiveMode : " << interactiveMode << std::endl;
125  std::cout << "======================================================================" << std::endl;
126 }
127 
128 int HandleInputPar(int argc, char **argv) {
129  static const std::string routineName("HandleInputPar");
130  // Set verbose level to print warnings about unrecognized options
131  GGSSmartLog::verboseLevel = GGSSmartLog::WARNING;
132  int vLevel = GGSSmartLog::INFO;
133  if (argc > 1) {
134  int i = 1;
135  while (i < argc) {
136  if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
137  usage();
138  return 1;
139  }
140  // -----------------------------------------------------//
141  if (!strcmp(argv[i], "-V") || !strcmp(argv[i], "--version")) {
142  GGSPennyVersion();
143  return 1;
144  }
145  // -----------------------------------------------------//
146  if (!strcmp(argv[i], "--")) {
147  return 0;
148  }
149  // -----------------------------------------------------//
150  else if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--data-card")) {
151  if (++i >= argc) {
152  usage();
153  return 1;
154  }
155  dataCard = argv[i];
156  }
157  // -----------------------------------------------------//
158  else if (!strcmp(argv[i], "-gd") || !strcmp(argv[i], "--geo-data-card")) {
159  if (++i >= argc) {
160  usage();
161  return 1;
162  }
163  geoDataCard = argv[i];
164  }
165  // -----------------------------------------------------//
166  else if (!strcmp(argv[i], "-g") || !strcmp(argv[i], "--geometry")) {
167  if (++i >= argc) {
168  usage();
169  return 1;
170  }
171  geometry = argv[i];
172  }
173  // -----------------------------------------------------//
174  else if (!strcmp(argv[i], "-pl") || !strcmp(argv[i], "--physics-list")) {
175  if (++i >= argc) {
176  usage();
177  return 1;
178  }
179  physicsListName = argv[i];
180  }
181  // -----------------------------------------------------//
182  else if (!strcmp(argv[i], "-pd") || !strcmp(argv[i], "--physlist-data-card")) {
183  if (++i >= argc) {
184  usage();
185  return 1;
186  }
187  physListDataCard = argv[i];
188  }
189  // -----------------------------------------------------//
190  else if (!strcmp(argv[i], "-ap") || !strcmp(argv[i], "--action-plugin")) {
191  if (++i >= argc) {
192  usage();
193  return 1;
194  }
195  actionPluginFiles.push_back(G4String(argv[i]));
196  }
197  // -----------------------------------------------------//
198  else if (!strcmp(argv[i], "-X") || !strcmp(argv[i], "--interactive")) {
199  interactiveMode = true;
200  }
201  // -----------------------------------------------------//
202  else if (!strcmp(argv[i], "-ro") || !strcmp(argv[i], "--root-output-file")) {
203  if (++i >= argc) {
204  usage();
205  return 1;
206  }
207  rootOutputFile = argv[i];
208  }
209  // -----------------------------------------------------//
210  else if (!strcmp(argv[i], "-os") || !strcmp(argv[i], "--output-suffix")) {
211  if (++i >= argc) {
212  usage();
213  return 1;
214  }
215  outputSuffix = argv[i];
216  }
217  // -----------------------------------------------------//
218  else if (!strcmp(argv[i], "-i") || !strcmp(argv[i], "--input-file")) {
219  if (++i >= argc) {
220  usage();
221  return 1;
222  }
223  inputFile = argv[i];
224  }
225  // -----------------------------------------------------//
226  else if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--input-seed-file")) {
227  if (++i >= argc) {
228  usage();
229  return 1;
230  }
231  inputSeedFile = argv[i];
232  }
233  // -----------------------------------------------------//
234  else if (!strcmp(argv[i], "--seed1")) {
235  if (++i >= argc) {
236  usage();
237  return 1;
238  }
239  seed1 = atoi(argv[i]);
240  }
241  // -----------------------------------------------------//
242  else if (!strcmp(argv[i], "--seed2")) {
243  if (++i >= argc) {
244  usage();
245  return 1;
246  }
247  seed2 = atoi(argv[i]);
248  }
249  // -----------------------------------------------------//
250  else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--verbose")) {
251  std::string vLevStr(argv[++i]);
252  if (vLevStr == "error")
253  vLevel = GGSSmartLog::ERROR;
254  else if (vLevStr == "warning")
255  vLevel = GGSSmartLog::WARNING;
256  else if (vLevStr == "normal" || vLevStr == "info")
257  vLevel = GGSSmartLog::INFO;
258  else if (vLevStr == "debug")
259  vLevel = GGSSmartLog::DEBUG;
260  else if (vLevStr == "deepdeb")
261  vLevel = GGSSmartLog::DEEPDEB;
262  else {
263  COUT(WARNING) << "Unrecognized verbosity level: " << vLevStr << ". Ignoring." << ENDL;
264  }
265  }
266  // -----------------------------------------------------//
267  else {
268  COUT(WARNING) << "Unidentified input argument \"" << argv[i] << "\". Ignoring." << std::endl;
269  }
270  i++;
271  }
272  } else {
273  usage();
274  return 1;
275  }
276  GGSSmartLog::verboseLevel = vLevel;
277  return 0;
278 }
279 
280 int main(int argc, char **argv) {
281 
282  static const std::string routineName("GGSPenny");
283 
284  if (HandleInputPar(argc, argv))
285  return 0;
286 
287  GGSPennyVersion();
288 
289  int nPar = 0;
290  char *cfileArgv[1000];
291  if (strcmp(inputFile.c_str(), "")) {
292  std::string mych[1000];
293  GGSInputParser::GetInstance().ReadInput(inputFile, &nPar, (std::string *)mych);
294  if (nPar > 1) {
295  int i = 0;
296  while (i < nPar - 1) {
297  cfileArgv[i] = new char[(mych[i]).length()];
298  strcpy(cfileArgv[i], (mych[i]).c_str());
299  i++;
300  }
301  if (HandleInputPar(nPar - 1, cfileArgv))
302  return 0;
303  }
304  } else {
305  if (argc > 1) {
306  nPar = argc;
307  int i = 0;
308  while (i < nPar) {
309  cfileArgv[i] = new char[1000];
310  cfileArgv[i] = (argv[i]);
311  i++;
312  }
313  }
314  }
315  if (!strcmp(dataCard.c_str(), "") && !interactiveMode) {
316  usage();
317  return 1;
318  }
319 
320  if (geometry == "") {
321  COUT(ERROR) << "No geometry provided. Exit." << ENDL;
322  return 1;
323  }
324 
325  // Check the existence of given files
326  {
327  struct stat st;
328  if (dataCard != "" && stat(dataCard.c_str(), &st) != 0) {
329  COUT(ERROR) << "Datacard " << dataCard << " not found." << ENDL;
330  return 1;
331  }
332  if (geoDataCard != "" && stat(geoDataCard.c_str(), &st) != 0) {
333  COUT(ERROR) << "Geometry datacard " << geoDataCard << " not found." << ENDL;
334  return 1;
335  }
336  if (physListDataCard != "" && stat(physListDataCard.c_str(), &st) != 0) {
337  COUT(ERROR) << "Physics list datacard " << physListDataCard << " not found." << ENDL;
338  return 1;
339  }
340  }
341 
342  // print on the screen input to this run
343  DumpGlobals();
344 
345  // Construct the default run manager
346  //
347  COUT(DEBUG) << "Create the run manager." << ENDL;
348  GGSRunManager *runManager = new GGSRunManager;
349 
350  // Set mandatory initialization classes
351  COUT(DEBUG) << "Create the detector." << ENDL;
352  GGSDetectorConstruction *detector = NULL;
353  if (geometry.length() > 4 && geometry.substr(geometry.length() - 5) == ".gdml") {
354  detector = new GGSDetectorConstruction(geometry);
355  } else {
356  detector = new GGSDetectorConstruction(geometry, geoDataCard);
357  }
358  runManager->SetUserInitialization(detector);
359 
360  G4VUserPhysicsList *physicsList = nullptr;
361  // Try to create reference physics list
362  G4PhysListFactory *physListFactory = new G4PhysListFactory;
363  if (physListFactory->IsReferencePhysList(physicsListName)) {
364  physicsList = physListFactory->GetReferencePhysList(physicsListName);
365  }
366  // Try to create standard GGS physics lists
367  if (physicsList == nullptr) {
368 #ifdef CRMC
369  if (physicsListName == "GGSCRMC") {
370  physicsList = new GGSCRMCPhysicsList;
371  }
372 #endif
373  }
374  // Try to create user-defined physics list
375  if (physicsList == nullptr) {
376  // Try to load user defined list
377  physicsList = GGSMCPluginManager::GetInstance().LoadPhysicsListPlugin(physicsListName);
378  if (physicsList == NULL) {
379  COUT(WARNING) << "User physics list has NOT been loaded. Fall back to standard list." << ENDL;
380  }
381  }
382  // Build standard list if no list have been selected or library loading wasn't successful
383  if (physicsList == NULL) {
384  COUT(INFO) << "Load standard physics list: FTFP_BERT." << ENDL;
385  physicsListName = "FTFP_BERT";
386  physicsList = physListFactory->GetReferencePhysList(physicsListName);
387  }
388 
389  // Get the pointer to the User Interface manager
390  G4UImanager *UImanager = G4UImanager::GetUIpointer();
391 
392  // Execute physics list data card
393  if (physListDataCard != "") {
394  COUT(DEBUG) << "Execute physics list data card" << ENDL;
395  G4String command = "/control/execute ";
396  if (UImanager->ApplyCommand(command + physListDataCard) != 0) {
397  COUT(ERROR) << "Error in executing physics list datacard " << physListDataCard << ENDL;
398  return 1;
399  }
400  }
401 
402  runManager->SetUserInitialization(physicsList);
403 
404  // Creates the generator actions manager
405  GGSGeneratorActionsManager::GetInstance();
406 
407  // Set user actions manager
408  COUT(DEBUG) << "Initialize the user actions manager." << ENDL;
410  runManager->SetUserAction((G4UserSteppingAction *)actionsManager);
411  runManager->SetUserAction((G4UserTrackingAction *)actionsManager);
412  runManager->SetUserAction((G4UserEventAction *)actionsManager);
413  runManager->SetUserAction((G4UserRunAction *)actionsManager);
414  runManager->SetUserAction((G4UserStackingAction *)actionsManager);
415 
416  // Add status dump
417  actionsManager->AddAction(new GGSStatusDumpAction);
418 
419  // Load user and generator actions plugin libraries
420  for (unsigned int i = 0; i < actionPluginFiles.size(); i++)
421  GGSMCPluginManager::GetInstance().LoadPlugin(actionPluginFiles[i]);
422 
423  // Set default name, suffix of ROOT files
424  COUT(DEBUG) << "Initialize output." << ENDL;
425  if (rootOutputFile != "")
426  GGSRootFileService::GetInstance().SetDefaultFileBase(rootOutputFile.data());
428  // Set the MC info to be saved on ROOT files
429  GGSTSimInfo simInfo;
430  simInfo.SetName("GGSSimInfo");
431  simInfo.G4Version = G4Version.data();
432  simInfo.GGSVersion = GGSVERSION;
433  simInfo.dataCard = dataCard.data();
434  simInfo.geometry = geometry.data();
435  simInfo.geoDataCard = geoDataCard.data();
436  simInfo.physicsList = physicsListName.data();
437  simInfo.seed1 = seed1;
438  simInfo.seed2 = seed2;
440 
441  // Initialize G4 kernel
442  COUT(DEBUG) << "Initialize run manager." << ENDL;
443  try {
444  runManager->Initialize();
445  } catch (std::runtime_error &exc) {
446  COUT(ERROR) << "Error while building the geometry: " << exc.what() << ENDL;
447  delete runManager;
448  delete physListFactory;
449  return 1;
450  } catch (...) {
451  COUT(ERROR) << "Impossible to set up the geometry due to an unknown exception. Exit." << ENDL;
452  delete runManager;
453  delete physListFactory;
454  return 1;
455  }
456 
457 #ifdef G4VIS_USE
458  // Create the ROOT cling interpreter before opening the graphical UI. This is needed to avoid
459  // loading LLVM symbols (e.g. when using open source Radeon driver for AMD chips) before
460  // creating the interpreter, which would cause a segmentation fault.
461  gROOT->GetInterpreter();
462  // Initialize visualization
463  //
464  G4VisManager *visManager = new G4VisExecutive;
465  visManager->Initialize();
466 #endif
467 
468  COUT(DEBUG) << "Initialize random generator." << ENDL;
469  // Choose the Random engine
470  CLHEP::HepRandom::setTheEngine(new CLHEP::RanecuEngine);
471  G4long seeds[2] = {seed1, seed2};
472  CLHEP::HepRandom::setTheSeeds(seeds, 0); // changing the index does not change random generation
473  if (strcmp(inputSeedFile.c_str(), "")) {
474  G4String command = "/random/resetEngineFrom ";
475  UImanager->ApplyCommand(command + inputSeedFile);
476  }
477  CLHEP::HepRandom::showEngineStatus();
478 
479  if (dataCard != "") { // batch or configured interactive mode
480  if (!interactiveMode) {
481  COUT(DEBUG) << "Start batch mode." << ENDL;
482  }
483  G4String command = "/control/execute ";
484  if (UImanager->ApplyCommand(command + dataCard) != 0) {
485  COUT(ERROR) << "Error in executing datacard " << dataCard << ENDL;
486  return 1;
487  }
488  }
489  if (interactiveMode) { // interactive mode : define UI session
490  if (dataCard != "") {
491  COUT(DEBUG) << "Start configured interactive mode." << ENDL;
492  } else {
493  COUT(DEBUG) << "Start interactive mode." << ENDL;
494  }
495 
496 #ifdef G4UI_USE
497  G4UIExecutive *ui = new G4UIExecutive(nPar, cfileArgv);
498  struct stat st;
499 #ifdef G4VIS_USE
500  if (stat("vis.mac", &st) == 0) {
501  if (UImanager->ApplyCommand("/control/execute vis.mac") != 0) {
502  COUT(ERROR) << "Error in executing vis.mac visualization macro." << ENDL;
503  return 1;
504  }
505  }
506 #endif
507  if (ui->IsGUI()) {
508  if (stat("visTutor/gui.mac", &st) == 0) {
509  if (UImanager->ApplyCommand("/control/execute visTutor/gui.mac") != 0) {
510  COUT(ERROR) << "Error in executing visTutor/gui.mac visualization macro." << ENDL;
511  return 1;
512  }
513  }
514  }
515  ui->SessionStart();
516  delete ui;
517 #endif
518  }
519 
520  COUT(DEBUG) << "Job termination." << ENDL;
521 
522  // Job termination
523  // Free the store: user actions, physics_list and detector_description are
524  // owned and deleted by the run manager, so they should not
525  // be deleted in the main() program !
526 #ifdef G4VIS_USE
527  delete visManager;
528 #endif
529  delete runManager;
530 
531  delete physListFactory;
532 
533  return 0;
534 }
535 
536 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
TString geometry
The geometry used for the simulation.
Definition: GGSTSimInfo.h:26
void AddAction(GGSUserAction *userAction)
Adds a general user action.
static GGSMCPluginManager & GetInstance()
Get the singleton instance.
static GGSInputParser & GetInstance()
Get instance of the singleton.
#define ENDL
Definition: GGSSmartLog.h:105
#define COUT(level)
Smart log macro. It writes on stdout only if the specified verbosity level is lesser than the maximum...
Definition: GGSSmartLog.h:76
Class for GGS detector construction.
TString G4Version
Geant 4 version (as defined in G4Version.hh)
Definition: GGSTSimInfo.h:23
bool LoadPlugin(const std::string &libName)
Loads a plugin library.
void SetDefaultFileBase(const path &newFileBase)
Sets the default file name.
TString physicsList
The physics list used for the simulation.
Definition: GGSTSimInfo.h:27
TString geoDataCard
The data card file used for geometry configuration.
Definition: GGSTSimInfo.h:29
The GGS ser actions manager.
Action which dumps the simulation status on standard output.
static GGSRootFileService & GetInstance()
Get reference to GGSRootFileService unique instance.
void SetSuffix(const std::string &suffix)
Sets the suffix for file names.
void SetSimInfo(const GGSTSimInfo &simInfo)
Set the simulation info object to be saved on output files.
UInt_t seed2
Second random generator seed.
Definition: GGSTSimInfo.h:32
UInt_t seed1
First random generator seed.
Definition: GGSTSimInfo.h:31
TString dataCard
The data card file used for the simulation.
Definition: GGSTSimInfo.h:28
A class to store simulation informations.
Definition: GGSTSimInfo.h:21
G4VUserPhysicsList * LoadPhysicsListPlugin(const std::string &libName)
Loads a physics list plugin library.
void ReadInput(std::string fileName, int *argc, std::string *argv)
Reads configuration file.
static GGSUserActionsManager * GetInstance()
Get the singleton instance.
Physics list based on CRMC for high-energy hadron-hadron interactions.
TString GGSVersion
GGS version (as defined by GGSVERSION in Version.h)
Definition: GGSTSimInfo.h:24
A run manager for GGS simulations.
Definition: GGSRunManager.h:23