File indexing completed on 2026-05-15 07:41:49
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <cstdlib>
0011 #include <cstring>
0012 #include <ctime>
0013 #include <iostream>
0014 #include <string>
0015
0016 #include "FTFP_BERT.hh"
0017 #include "G4OpticalPhysics.hh"
0018 #include "G4VModularPhysicsList.hh"
0019
0020 #include "G4UIExecutive.hh"
0021 #include "G4UImanager.hh"
0022 #include "G4VisExecutive.hh"
0023
0024 #include "G4RunManager.hh"
0025 #include "G4RunManagerFactory.hh"
0026 #include "G4VUserActionInitialization.hh"
0027
0028 #include "async_gpu_std.h"
0029 #include "sysrap/OPTICKS_LOG.hh"
0030
0031 struct ActionInitialization : public G4VUserActionInitialization
0032 {
0033 G4App* fG4App;
0034 ActionInitialization(G4App* app) :
0035 fG4App(app)
0036 {
0037 }
0038
0039 void BuildForMaster() const override
0040 {
0041 SetUserAction(fG4App->run_act_);
0042 }
0043
0044 void Build() const override
0045 {
0046 SetUserAction(fG4App->prim_gen_);
0047 SetUserAction(fG4App->run_act_);
0048 SetUserAction(fG4App->event_act_);
0049 SetUserAction(fG4App->tracking_);
0050 SetUserAction(fG4App->stepping_);
0051 }
0052 };
0053
0054 static void usage(const char* prog)
0055 {
0056 std::cerr << "Usage: " << prog
0057 << " [options]\n"
0058 " -g, --gdml PATH GDML file (default: apex.gdml)\n"
0059 " -m, --macro PATH Geant4 macro (default: run.mac)\n"
0060 " -s, --seed N random seed (default: time())\n"
0061 " -i, --interactive open interactive viewer\n"
0062 " --async double-buffered async GPU (default)\n"
0063 " --sync end-of-run GPU simulation\n"
0064 " -h, --help show this message\n";
0065 }
0066
0067 int main(int argc, char** argv)
0068 {
0069 OPTICKS_LOG(argc, argv);
0070
0071 std::string gdml_file = "apex.gdml";
0072 std::string macro_name = "run.mac";
0073 long seed = static_cast<long>(std::time(nullptr));
0074 bool seed_set = false;
0075 bool interactive = false;
0076 bool sync_mode = false;
0077
0078 for (int i = 1; i < argc; i++)
0079 {
0080 std::string a = argv[i];
0081 auto next = [&](const char* flag) -> const char* {
0082 if (i + 1 >= argc)
0083 {
0084 std::cerr << flag << " requires an argument\n";
0085 std::exit(EXIT_FAILURE);
0086 }
0087 return argv[++i];
0088 };
0089
0090 if (a == "-g" || a == "--gdml")
0091 gdml_file = next("--gdml");
0092 else if (a == "-m" || a == "--macro")
0093 macro_name = next("--macro");
0094 else if (a == "-s" || a == "--seed")
0095 {
0096 seed = std::atol(next("--seed"));
0097 seed_set = true;
0098 }
0099 else if (a == "-i" || a == "--interactive")
0100 interactive = true;
0101 else if (a == "--sync")
0102 sync_mode = true;
0103 else if (a == "--async")
0104 sync_mode = false;
0105 else if (a == "-h" || a == "--help")
0106 {
0107 usage(argv[0]);
0108 return EXIT_SUCCESS;
0109 }
0110 else
0111 {
0112 std::cerr << "unknown option: " << a << "\n";
0113 usage(argv[0]);
0114 return EXIT_FAILURE;
0115 }
0116 }
0117
0118 CLHEP::HepRandom::setTheSeed(seed);
0119 G4cout << "Random seed: " << seed << (seed_set ? " (user)" : " (time)")
0120 << G4endl;
0121
0122 bool enable_async = !sync_mode;
0123 G4cout << "Mode: " << (enable_async ? "ASYNC (std)" : "SYNC") << G4endl;
0124
0125 G4VModularPhysicsList* physics = new FTFP_BERT;
0126 physics->RegisterPhysics(new G4OpticalPhysics);
0127
0128 auto* run_mgr = G4RunManagerFactory::CreateRunManager();
0129 run_mgr->SetUserInitialization(physics);
0130
0131 G4App* g4app = new G4App(gdml_file, enable_async);
0132
0133 auto* actionInit = new ActionInitialization(g4app);
0134 run_mgr->SetUserInitialization(actionInit);
0135 run_mgr->SetUserInitialization(g4app->det_cons_);
0136
0137 G4UIExecutive* uix = nullptr;
0138 G4VisManager* vis = nullptr;
0139 if (interactive)
0140 {
0141 uix = new G4UIExecutive(argc, argv);
0142 vis = new G4VisExecutive;
0143 vis->Initialize();
0144 }
0145
0146 G4UImanager* ui = G4UImanager::GetUIpointer();
0147 ui->ApplyCommand("/control/execute " + macro_name);
0148
0149 if (interactive)
0150 uix->SessionStart();
0151
0152 delete uix;
0153 return EXIT_SUCCESS;
0154 }