Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-24 08:23:16

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 
0014 /// Framework include files
0015 #include <DDG4/Geant4UIManager.h>
0016 #include <DDG4/Geant4Kernel.h>
0017 #include <DDG4/Geant4UIMessenger.h>
0018 #include <DD4hep/Primitives.h>
0019 
0020 /// Geant4 include files
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 /// C/C++ include files
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 /// Initializing constructor
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 /// Default destructor
0065 Geant4UIManager::~Geant4UIManager()   {
0066 }
0067 
0068 /// Configure the object
0069 void Geant4UIManager::configure()   {
0070   /// Get the pointer to the User Interface manager
0071   G4UImanager* mgr = G4UImanager::GetUIpointer();
0072   /// Start UI instance
0073   if ( m_haveUI ) {
0074     m_ui = startUI();
0075   }
0076   /// Execute the chained command statements
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 /// Initialize the object
0087 void Geant4UIManager::initialize()   {
0088   /// Get the pointer to the User Interface manager
0089   G4UImanager* mgr = G4UImanager::GetUIpointer();
0090   /// Execute the chained command statements
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 /// Callback on terminate
0101 void Geant4UIManager::terminate() {
0102   /// Get the pointer to the User Interface manager
0103   G4UImanager* mgr = G4UImanager::GetUIpointer();
0104   /// Execute the chained command statements
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 /// Apply single command
0115 void Geant4UIManager::applyCommand(const std::string& command)   {
0116   /// Get the pointer to the User Interface manager
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 /// Apply DD4hep plugin call from Geant4 prompt
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 /// Install command control messenger to write GDML file from command prompt.
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 /// Force exiting this process without calling atexit handlers
0183 void Geant4UIManager::forceExit()   {
0184   std::_Exit(0);
0185 }
0186 
0187 /// Regularly exiting this process without calling atexit handlers
0188 void Geant4UIManager::regularExit()   {
0189   info("++ End of processing requested.");
0190   context()->kernel().terminate();
0191   forceExit();
0192 }
0193 
0194 /// Start visualization
0195 G4VisManager* Geant4UIManager::startVis()  {
0196   /// Initialize visualization
0197   info("+++ Starting G4VisExecutive ....");
0198   G4VisManager* vis = new G4VisExecutive();
0199   vis->Initialize();
0200   return vis;
0201 }
0202 
0203 /// Start UI
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 /// Run UI
0220 void Geant4UIManager::operator()(void* )   {
0221   start();
0222   stop();
0223 }
0224 
0225 /// Start manager & session
0226 void Geant4UIManager::start() {
0227   /// Get the pointer to the User Interface manager
0228   G4UImanager* mgr = G4UImanager::GetUIpointer();
0229   bool executed_statements = false;
0230 
0231   /// Start visualization
0232   if ( m_haveVis || !m_visSetup.empty() ) {
0233     m_vis = startVis();
0234     m_haveVis = true;   /// If graphics setup, vis is always true
0235     m_haveUI = true;    /// No graphics without UI!
0236   }
0237   /// Configure visualization instance
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   /// Configure UI instance
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   /// Execute the chained macro files
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   /// Execute the chained pre-run command statements
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   /// Start UI session if present
0264   if ( m_haveUI && m_ui )   {
0265     m_ui->SessionStart();
0266     /// Execute the chained post-run command statements
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     /// Execute the chained post-run command statements
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   /// No UI. Pure batch mode: Simply execute requested number of events
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 /// Stop and release resources
0307 void Geant4UIManager::stop() {
0308   detail::deletePtr(m_vis);
0309   detail::deletePtr(m_ui);
0310 }