File indexing completed on 2026-09-24 08:23:16
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <DDG4/Geant4UIManager.h>
0016 #include <DDG4/Geant4Kernel.h>
0017 #include <DDG4/Geant4UIMessenger.h>
0018 #include <DD4hep/Primitives.h>
0019
0020
0021 #include <G4Version.hh>
0022 #include <G4VisExecutive.hh>
0023 #include <G4UImanager.hh>
0024 #include <G4UIsession.hh>
0025 #include <G4VisExecutive.hh>
0026 #include <G4UIExecutive.hh>
0027 #include <G4RunManager.hh>
0028
0029
0030 #include <cstdlib>
0031 #include <functional>
0032
0033 using namespace dd4hep::sim;
0034
0035 namespace {
0036 std::string make_cmd(const std::string& cmd) {
0037 return std::string( "/control/execute "+cmd);
0038 }
0039 }
0040
0041
0042 Geant4UIManager::Geant4UIManager(Geant4Context* ctxt, const std::string& nam)
0043 : Geant4Action(ctxt,nam), m_vis(0), m_ui(0)
0044 {
0045 declareProperty("SetupUI", m_uiSetup="");
0046 declareProperty("SetupVIS", m_visSetup="");
0047 declareProperty("SessionType", m_sessionType="tcsh");
0048 declareProperty("Macros", m_macros);
0049 declareProperty("ConfigureCommands", m_configureCommands);
0050 declareProperty("InitializeCommands", m_initializeCommands);
0051 declareProperty("TerminateCommands", m_terminateCommands);
0052 declareProperty("Commands", m_preRunCommands);
0053 declareProperty("PreRunCommands", m_preRunCommands);
0054 declareProperty("PostRunCommands", m_postRunCommands);
0055 declareProperty("HaveVIS", m_haveVis=false);
0056 declareProperty("HaveUI", m_haveUI=true);
0057 declareProperty("Prompt", m_prompt);
0058 context()->kernel().register_configure(std::bind(&Geant4UIManager::configure,this));
0059 context()->kernel().register_initialize(std::bind(&Geant4UIManager::initialize,this));
0060 context()->kernel().register_terminate(std::bind(&Geant4UIManager::terminate,this));
0061 enableUI();
0062 }
0063
0064
0065 Geant4UIManager::~Geant4UIManager() {
0066 }
0067
0068
0069 void Geant4UIManager::configure() {
0070
0071 G4UImanager* mgr = G4UImanager::GetUIpointer();
0072
0073 if ( m_haveUI ) {
0074 m_ui = startUI();
0075 }
0076
0077 for(const auto& c : m_configureCommands) {
0078 info("++ Executing configure command: %s",c.c_str());
0079 G4int ret = mgr->ApplyCommand(c.c_str());
0080 if ( ret != 0 ) {
0081 except("Failed to execute command: %s",c.c_str());
0082 }
0083 }
0084 }
0085
0086
0087 void Geant4UIManager::initialize() {
0088
0089 G4UImanager* mgr = G4UImanager::GetUIpointer();
0090
0091 for(const auto& c : m_initializeCommands) {
0092 info("++ Executing initialization command: %s",c.c_str());
0093 G4int ret = mgr->ApplyCommand(c.c_str());
0094 if ( ret != 0 ) {
0095 except("Failed to execute command: %s",c.c_str());
0096 }
0097 }
0098 }
0099
0100
0101 void Geant4UIManager::terminate() {
0102
0103 G4UImanager* mgr = G4UImanager::GetUIpointer();
0104
0105 for(const auto& c : m_terminateCommands) {
0106 info("++ Executing finalization command: %s",c.c_str());
0107 G4int ret = mgr->ApplyCommand(c.c_str());
0108 if ( ret != 0 ) {
0109 except("Failed to execute command: %s",c.c_str());
0110 }
0111 }
0112 }
0113
0114
0115 void Geant4UIManager::applyCommand(const std::string& command) {
0116
0117 G4UImanager* mgr = G4UImanager::GetUIpointer();
0118 if ( mgr ) {
0119 info("++ Executing G4 command: %s",command.c_str());
0120 G4int ret = mgr->ApplyCommand(command.c_str());
0121 if ( ret == 0 ) {
0122 return;
0123 }
0124 except("Failed to execute command: %s",command.c_str());
0125 }
0126 except("No UI reference present. Too early to interact with Geant4!");
0127 }
0128
0129
0130 long Geant4UIManager::runPlugin(const char* value) {
0131 Geant4Kernel& kernel = this->context()->kernel();
0132 std::string plugin_name_args = value;
0133 std::string val;
0134 std::size_t idx;
0135
0136 idx = plugin_name_args.find('(');
0137 if( idx != std::string::npos ) {
0138 std::size_t idq = plugin_name_args.find( idx+1, ')' );
0139 std::string plugin = plugin_name_args.substr( 0, idx );
0140 std::string args = plugin_name_args.substr( idx, idq-idx );
0141 std::vector<std::string> argv;
0142 int start = 0;
0143 for( const char* c = value; *c; ++c ) {
0144 if( *c == '"' && start == 0 ) {
0145 start = 1;
0146 val = "";
0147 continue;
0148 }
0149 if( *c == '"' && start == 1 ) {
0150 error("New plugin argument: '%s'", val.c_str());
0151 argv.push_back(val);
0152 start = 0;
0153 val = "";
0154 continue;
0155 }
0156 if( start == 1 ) {
0157 val += *c;
0158 }
0159 }
0160 always("Calling dd4hep plugin %s with arguments: %s",
0161 plugin.c_str(), args.c_str());
0162 return kernel.runPlugin( plugin.c_str(), argv );
0163 }
0164 error("Invalid arguments to call a dd4hep plugin: '%s'",
0165 plugin_name_args.c_str());
0166 error("Did you use the correct calling style: "
0167 "> /ddg4/UI/run_plugin <plugin-name>(\"arg1\", \"arg2\", \"arg3\",....)");
0168 return -1;
0169 }
0170
0171
0172 void Geant4UIManager::installCommandMessenger() {
0173 m_control->addCall("exit", "Force exiting this process",
0174 Callback( this ).make( &Geant4UIManager::forceExit ), 0);
0175 m_control->addCall("terminate", "Regular exit this process",
0176 Callback( this ).make( &Geant4UIManager::regularExit ), 0);
0177 m_control->addCall("run_plugin", "Execute DD4hep plugin of the form "
0178 "<plugin-name>(\"arg1\", \"arg2\", \"arg3\",....)",
0179 Callback( this ).make( &Geant4UIManager::runPlugin ), 1);
0180 }
0181
0182
0183 void Geant4UIManager::forceExit() {
0184 std::_Exit(0);
0185 }
0186
0187
0188 void Geant4UIManager::regularExit() {
0189 info("++ End of processing requested.");
0190 context()->kernel().terminate();
0191 forceExit();
0192 }
0193
0194
0195 G4VisManager* Geant4UIManager::startVis() {
0196
0197 info("+++ Starting G4VisExecutive ....");
0198 G4VisManager* vis = new G4VisExecutive();
0199 vis->Initialize();
0200 return vis;
0201 }
0202
0203
0204 G4UIExecutive* Geant4UIManager::startUI() {
0205 G4UIExecutive* ui = 0;
0206 const char* args[] = {"DDG4","",""};
0207 info("+++ Starting G4UIExecutive '%s' of type %s....", args[0], m_sessionType.c_str());
0208 #if (G4VERSION_NUMBER >= 960)
0209 ui = new G4UIExecutive(1,(char**)args,m_sessionType.c_str());
0210 #else
0211 ui = new G4UIExecutive(1,(char**)args );
0212 #endif
0213 if ( !m_prompt.empty() ) {
0214 ui->SetPrompt(m_prompt);
0215 }
0216 return ui;
0217 }
0218
0219
0220 void Geant4UIManager::operator()(void* ) {
0221 start();
0222 stop();
0223 }
0224
0225
0226 void Geant4UIManager::start() {
0227
0228 G4UImanager* mgr = G4UImanager::GetUIpointer();
0229 bool executed_statements = false;
0230
0231
0232 if ( m_haveVis || !m_visSetup.empty() ) {
0233 m_vis = startVis();
0234 m_haveVis = true;
0235 m_haveUI = true;
0236 }
0237
0238 if ( !m_visSetup.empty() ) {
0239 info("++ Executing visualization setup: %s",m_visSetup.c_str());
0240 mgr->ApplyCommand(make_cmd(m_visSetup).c_str());
0241 }
0242
0243 if ( !m_uiSetup.empty() ) {
0244 info("++ Executing UI setup: %s",m_uiSetup.c_str());
0245 mgr->ApplyCommand(make_cmd(m_uiSetup).c_str());
0246 executed_statements = true;
0247 }
0248
0249 for(const auto& m : m_macros) {
0250 info("++ Executing Macro file: %s",m.c_str());
0251 mgr->ApplyCommand(make_cmd(m.c_str()));
0252 executed_statements = true;
0253 }
0254
0255 for(const auto& c : m_preRunCommands) {
0256 info("++ Executing pre-run statement: %s",c.c_str());
0257 G4int ret = mgr->ApplyCommand(c.c_str());
0258 if ( ret != 0 ) {
0259 except("Failed to execute command: %s",c.c_str());
0260 }
0261 executed_statements = true;
0262 }
0263
0264 if ( m_haveUI && m_ui ) {
0265 m_ui->SessionStart();
0266
0267 for(const auto& c : m_postRunCommands) {
0268 info("++ Executing post-run statement: %s",c.c_str());
0269 G4int ret = mgr->ApplyCommand(c.c_str());
0270 if ( ret != 0 ) {
0271 except("Failed to execute command: %s",c.c_str());
0272 }
0273 executed_statements = true;
0274 }
0275 return;
0276 }
0277 else if ( m_haveUI ) {
0278 warning("++ No UI manager found. Exit.");
0279 return;
0280 }
0281 else if ( executed_statements ) {
0282
0283 for(const auto& c : m_postRunCommands) {
0284 info("++ Executing post-run statement: %s",c.c_str());
0285 G4int ret = mgr->ApplyCommand(c.c_str());
0286 if ( ret != 0 ) {
0287 except("Failed to execute command: %s",c.c_str());
0288 }
0289 }
0290 return;
0291 }
0292
0293
0294 long numEvent = context()->kernel().property("NumEvents").value<long>();
0295 if(numEvent < 0) numEvent = std::numeric_limits<int>::max();
0296 info("++ Start run with %d events.",numEvent);
0297 try {
0298 context()->kernel().runManager().BeamOn(numEvent);
0299 }
0300 catch (DD4hep_End_Of_File& e) {
0301 info("++ End of file reached, ending run...");
0302 context()->kernel().runManager().RunTermination();
0303 }
0304 }
0305
0306
0307 void Geant4UIManager::stop() {
0308 detail::deletePtr(m_vis);
0309 detail::deletePtr(m_ui);
0310 }