17 #include "G4PhysListFactory.hh"
18 #include "G4UImanager.hh"
19 #include "G4Version.hh"
20 #include "Randomize.hh"
23 #include "G4VisExecutive.hh"
27 #include "G4UIExecutive.hh"
31 #include "GGSVersion.h"
44 #include "montecarlo/physicslists/GGSCRMCPhysicsList.h"
50 std::cout <<
"Usage: GGSPenny [options] \n";
51 std::cout <<
"This is the GGS main MonteCarlo program\n\n";
53 std::cout <<
"Run type selection\n";
54 std::cout <<
"------------------\n";
55 std::cout <<
" -X, --interactive interactive mode [default: false]\n\n";
57 std::cout <<
" -d, --data-card FILE data card filename [default: not set]\n\n";
59 std::cout <<
"If only -d is specified the program will run in batch mode.\n";
60 std::cout <<
"If both options are specified, the datacard will be processed before entering the interactive mode.\n\n";
62 std::cout <<
"Configuration options\n";
63 std::cout <<
"---------------------\n";
64 std::cout <<
" -g, --geometry FILE full path and name of the geometry; can be a .so or a .gdml.\n";
65 std::cout <<
" -gd, --geo-data-card FILE data card filename for geometry configuration [default: not set]\n\n";
66 std::cout <<
" -pl, --physics-list NAME physics list (standard list name or full path of physics list .so library) [default: QGSP_BERT]\n\n";
67 std::cout <<
" -pd, --physlist-data-card FILE data card filename for physics list configuration [default: not set]\n\n";
68 std::cout <<
" -ap, --action-plugin FILE full path and name of the plugin user and generator action library\n";
69 std::cout <<
" May be repeated to load many libraries: -ap libUserAction.so -ap libGeneratorAction.so\n\n";
70 std::cout <<
" -st, --single-threaded Force single-threaded run mode for multi-threaded build\n\n";
71 std::cout <<
" -nt, --n-threads Set the number of threads for multi-threaded run [default: 2]\n\n";
72 std::cout <<
" -ro, --root-output-file FILE default ROOT output filename (may be overridden in datacard for each action)\n\n";
73 std::cout <<
" -os, --output-suffix SUFFIX output file suffix [default: ]\n\n";
74 std::cout <<
" --seed1 INT first random seed [default: 1]\n\n";
75 std::cout <<
" --seed2 INT second random seed [default: 2]\n\n";
76 std::cout <<
" -s, --input-seed-file FILE file containing input random seeds [default: not set]\n\n";
77 std::cout <<
"Configuration options can either be given as command line parameters or placed in an input file.\n";
78 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";
79 std::cout <<
" -i, --input-file FILE file containing input arguments [default: not set]\n\n";
81 std::cout <<
"Miscellaneous\n";
82 std::cout <<
"-------------\n";
83 std::cout <<
" -v, --verbose be verbose [default: false]\n\n";
84 std::cout <<
" -V, --version displays software version and exit\n\n";
85 std::cout <<
" -h, --help display this help and exit\n\n";
87 std::cout <<
"\nTo run GGSPenny either the -d (data card) or the -X (interactive) option MUST be set!\n";
88 std::cout <<
"Report bugs to: https://baltig.infn.it/mori/GGSSoftware/-/issues \n";
92 void GGSPennyVersion() {
93 std::cout <<
"GGSPenny simulation software";
94 #ifdef GGSMULTITHREADED
95 std::cout <<
" (MT build)\n";
97 std::cout <<
" (ST build)\n";
99 std::cout <<
"Using GGS " << GGSVERSION << std::endl;
104 G4String rootOutputFile =
"";
105 G4String outputSuffix =
"";
106 G4String dataCard =
"";
107 G4String geoDataCard =
"";
108 G4String physListDataCard =
"";
109 G4String inputSeedFile =
"";
110 G4String geometry =
"";
111 G4String physicsListName =
"FTFP_BERT";
112 std::vector<G4String> actionPluginFiles;
113 G4bool interactiveMode =
false;
114 #ifdef GGSMULTITHREADED
115 G4bool multiThreadedMode =
true;
118 G4bool multiThreadedMode =
false;
124 using namespace GGSPenny;
127 std::cout <<
"==============> MonteCarlo globals used for this run <===============\n";
128 std::cout <<
"dataCard : " << dataCard.c_str() <<
"\n";
129 std::cout <<
"geometry : " << geometry.c_str() <<
"\n";
130 std::cout <<
"geoDataCard : " << geoDataCard.c_str() <<
"\n";
131 std::cout <<
"physicsListName : " << physicsListName.c_str() <<
"\n";
132 std::cout <<
"physListDataCard : " << physListDataCard.c_str() <<
"\n";
133 std::cout <<
"rootOutputFile : " << rootOutputFile.c_str() <<
"\n";
134 std::cout <<
"outputSuffix : " << outputSuffix.c_str() <<
"\n";
135 std::cout <<
"inputSeedFile : " << inputSeedFile.c_str() <<
"\n";
136 std::cout <<
"seed1 : " << seed1 <<
"\n";
137 std::cout <<
"seed2 : " << seed2 <<
"\n";
138 std::cout <<
"interactiveMode : " << interactiveMode <<
"\n";
139 std::cout <<
"multiThreadedMode : " << multiThreadedMode <<
"\n";
140 if (multiThreadedMode) {
141 std::cout <<
"nThreads : " << nThreads <<
"\n";
143 std::cout <<
"======================================================================" << std::endl;
146 int HandleInputPar(
int argc,
char **argv) {
147 static const std::string routineName(
"HandleInputPar");
149 GGSSmartLog::verboseLevel = GGSSmartLog::WARNING;
150 int vLevel = GGSSmartLog::INFO;
154 if (!strcmp(argv[i],
"-h") || !strcmp(argv[i],
"--help")) {
159 if (!strcmp(argv[i],
"-V") || !strcmp(argv[i],
"--version")) {
164 if (!strcmp(argv[i],
"--")) {
168 else if (!strcmp(argv[i],
"-d") || !strcmp(argv[i],
"--data-card")) {
176 else if (!strcmp(argv[i],
"-gd") || !strcmp(argv[i],
"--geo-data-card")) {
181 geoDataCard = argv[i];
184 else if (!strcmp(argv[i],
"-g") || !strcmp(argv[i],
"--geometry")) {
192 else if (!strcmp(argv[i],
"-pl") || !strcmp(argv[i],
"--physics-list")) {
197 physicsListName = argv[i];
200 else if (!strcmp(argv[i],
"-pd") || !strcmp(argv[i],
"--physlist-data-card")) {
205 physListDataCard = argv[i];
208 else if (!strcmp(argv[i],
"-ap") || !strcmp(argv[i],
"--action-plugin")) {
213 actionPluginFiles.push_back(G4String(argv[i]));
216 else if (!strcmp(argv[i],
"-st") || !strcmp(argv[i],
"--single-threaded")) {
217 multiThreadedMode =
false;
220 else if (!strcmp(argv[i],
"-nt") || !strcmp(argv[i],
"--n-threads")) {
225 nThreads = std::stoi(argv[i]);
228 else if (!strcmp(argv[i],
"-X") || !strcmp(argv[i],
"--interactive")) {
229 interactiveMode =
true;
232 else if (!strcmp(argv[i],
"-ro") || !strcmp(argv[i],
"--root-output-file")) {
237 rootOutputFile = argv[i];
240 else if (!strcmp(argv[i],
"-os") || !strcmp(argv[i],
"--output-suffix")) {
245 outputSuffix = argv[i];
248 else if (!strcmp(argv[i],
"-s") || !strcmp(argv[i],
"--input-seed-file")) {
253 inputSeedFile = argv[i];
256 else if (!strcmp(argv[i],
"--seed1")) {
261 seed1 = std::stol(argv[i]);
264 else if (!strcmp(argv[i],
"--seed2")) {
269 seed2 = std::stol(argv[i]);
272 else if (!strcmp(argv[i],
"-v") || !strcmp(argv[i],
"--verbose")) {
273 std::string vLevStr(argv[++i]);
274 if (vLevStr ==
"error")
275 vLevel = GGSSmartLog::ERROR;
276 else if (vLevStr ==
"warning")
277 vLevel = GGSSmartLog::WARNING;
278 else if (vLevStr ==
"normal" || vLevStr ==
"info")
279 vLevel = GGSSmartLog::INFO;
280 else if (vLevStr ==
"debug")
281 vLevel = GGSSmartLog::DEBUG;
282 else if (vLevStr ==
"deepdeb")
283 vLevel = GGSSmartLog::DEEPDEB;
285 GGSCOUT(WARNING) <<
"Unrecognized verbosity level: " << vLevStr <<
". Ignoring." <<
GGSENDL;
290 GGSCOUT(WARNING) <<
"Unidentified input argument \"" << argv[i] <<
"\". Ignoring." << std::endl;
298 GGSSmartLog::verboseLevel = vLevel;
302 int main(
int argc,
char **argv) {
304 static const std::string routineName(
"GGSPenny");
306 if (HandleInputPar(argc, argv))
311 if (!strcmp(dataCard.c_str(),
"") && !interactiveMode) {
316 if (geometry ==
"") {
317 GGSCOUT(ERROR) <<
"No geometry provided. Exit." <<
GGSENDL;
324 if (dataCard !=
"" && stat(dataCard.c_str(), &st) != 0) {
325 GGSCOUT(ERROR) <<
"Datacard " << dataCard <<
" not found." <<
GGSENDL;
328 if (geoDataCard !=
"" && stat(geoDataCard.c_str(), &st) != 0) {
329 GGSCOUT(ERROR) <<
"Geometry datacard " << geoDataCard <<
" not found." <<
GGSENDL;
332 if (physListDataCard !=
"" && stat(physListDataCard.c_str(), &st) != 0) {
333 GGSCOUT(ERROR) <<
"Physics list datacard " << physListDataCard <<
" not found." <<
GGSENDL;
341 if (multiThreadedMode) {
342 ROOT::EnableThreadSafety();
345 GGSCOUT(DEBUG) <<
"Initialize random generator." <<
GGSENDL;
347 CLHEP::MixMaxRng rndmEngine;
348 G4Random::setTheEngine(&rndmEngine);
349 G4long seeds[2] = {seed1, seed2};
350 G4Random::setTheSeeds(seeds, 0);
351 G4Random::showEngineStatus();
355 GGSCOUT(DEBUG) <<
"Create the run manager." <<
GGSENDL;
356 G4RunManager *runManager =
nullptr;
357 if (multiThreadedMode) {
359 static_cast<GGSMTRunManager *
>(runManager)->SetNumberOfThreads(nThreads);
364 GGSCOUT(DEBUG) <<
"Create the detector." <<
GGSENDL;
366 if (geometry.length() > 4 && geometry.substr(geometry.length() - 5) ==
".gdml") {
369 #ifdef GGS_USE_DD4HEP
370 else if (geometry.length() > 3 && geometry.substr(geometry.length() - 4) ==
".xml") {
377 runManager->SetUserInitialization(detector);
379 G4VUserPhysicsList *physicsList =
nullptr;
381 G4PhysListFactory *physListFactory =
new G4PhysListFactory;
382 if (physListFactory->IsReferencePhysList(physicsListName)) {
383 physicsList = physListFactory->GetReferencePhysList(physicsListName);
386 if (physicsList ==
nullptr) {
388 if (physicsListName ==
"GGSCRMC") {
394 if (physicsList ==
nullptr) {
397 if (physicsList ==
nullptr) {
398 GGSCOUT(WARNING) <<
"User physics list has NOT been loaded. Fall back to standard list." <<
GGSENDL;
402 if (physicsList ==
nullptr) {
403 GGSCOUT(INFO) <<
"Load standard physics list: FTFP_BERT." <<
GGSENDL;
404 physicsListName =
"FTFP_BERT";
405 physicsList = physListFactory->GetReferencePhysList(physicsListName);
409 G4UImanager *UImanager = G4UImanager::GetUIpointer();
412 if (physListDataCard !=
"") {
413 GGSCOUT(DEBUG) <<
"Execute physics list data card" <<
GGSENDL;
414 G4String command =
"/control/execute ";
415 if (UImanager->ApplyCommand(command + physListDataCard) != 0) {
416 GGSCOUT(ERROR) <<
"Error in executing physics list datacard " << physListDataCard <<
GGSENDL;
421 runManager->SetUserInitialization(physicsList);
425 for (
unsigned int i = 0; i < actionPluginFiles.size(); i++)
429 if (multiThreadedMode) {
430 GGSCOUT(DEBUG) <<
"Set the user action initialization." <<
GGSENDL;
433 GGSCOUT(DEBUG) <<
"Set the user action." <<
GGSENDL;
435 runManager->SetUserAction((G4UserSteppingAction *)muAction);
436 runManager->SetUserAction((G4UserTrackingAction *)muAction);
437 runManager->SetUserAction((G4UserEventAction *)muAction);
438 runManager->SetUserAction((G4UserRunAction *)muAction);
439 runManager->SetUserAction((G4UserStackingAction *)muAction);
443 GGSCOUT(DEBUG) <<
"Initialize output." <<
GGSENDL;
444 if (rootOutputFile !=
"")
449 simInfo.SetName(
"GGSSimInfo");
456 simInfo.
seed1 = seed1;
457 simInfo.
seed2 = seed2;
460 if (multiThreadedMode) {
466 GGSCOUT(DEBUG) <<
"Initialize run manager." <<
GGSENDL;
468 runManager->Initialize();
469 }
catch (std::runtime_error &exc) {
470 GGSCOUT(ERROR) <<
"Error while building the geometry: " << exc.what() <<
GGSENDL;
472 delete physListFactory;
475 GGSCOUT(ERROR) <<
"Impossible to set up the geometry due to an unknown exception. Exit." <<
GGSENDL;
477 delete physListFactory;
485 gROOT->GetInterpreter();
488 G4VisManager *visManager =
new G4VisExecutive;
489 visManager->Initialize();
492 if (dataCard !=
"") {
493 if (!interactiveMode) {
494 GGSCOUT(DEBUG) <<
"Start batch mode." <<
GGSENDL;
496 G4String command =
"/control/execute ";
497 if (UImanager->ApplyCommand(command + dataCard) != 0) {
498 GGSCOUT(ERROR) <<
"Error in executing datacard " << dataCard <<
GGSENDL;
502 if (interactiveMode) {
503 if (dataCard !=
"") {
504 GGSCOUT(DEBUG) <<
"Start configured interactive mode." <<
GGSENDL;
506 GGSCOUT(DEBUG) <<
"Start interactive mode." <<
GGSENDL;
510 G4UIExecutive *ui =
new G4UIExecutive(argc, argv);
513 if (stat(
"vis.mac", &st) == 0) {
514 if (UImanager->ApplyCommand(
"/control/execute vis.mac") != 0) {
515 GGSCOUT(ERROR) <<
"Error in executing vis.mac visualization macro." <<
GGSENDL;
521 if (stat(
"visTutor/gui.mac", &st) == 0) {
522 if (UImanager->ApplyCommand(
"/control/execute visTutor/gui.mac") != 0) {
523 GGSCOUT(ERROR) <<
"Error in executing visTutor/gui.mac visualization macro." <<
GGSENDL;
533 GGSCOUT(DEBUG) <<
"Job termination." <<
GGSENDL;
540 delete physListFactory;
TString geometry
The geometry used for the simulation.
void SetDefaultFileBase(const std::filesystem::path &newFileBase)
Sets the default file name.
static GGSMCPluginManager & GetInstance()
Get the singleton instance.
User worker initialization class for GGS.
Class for GGS detector construction.
User action initialization class for GGS.
TString G4Version
Geant 4 version (as defined in G4Version.hh)
bool LoadPlugin(const std::string &libName)
Loads a plugin library.
A multiplexer container for user actions.
TString physicsList
The physics list used for the simulation.
TString geoDataCard
The data card file used for geometry configuration.
A multi-threaded run manager for GGS simulations.
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.
UInt_t seed1
First random generator seed.
TString dataCard
The data card file used for the simulation.
A class to store simulation informations.
G4VUserPhysicsList * LoadPhysicsListPlugin(const std::string &libName)
Loads a physics list plugin library.
User worker thread initialization class for GGS.
Physics list based on CRMC for high-energy hadron-hadron interactions.
TString GGSVersion
GGS version (as defined by GGSVERSION in Version.h)
A run manager for GGS simulations.