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