Newer
Older
Markus Frank
committed
//==========================================================================
Markus Frank
committed
//--------------------------------------------------------------------------
// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
Markus Frank
committed
// All rights reserved.
Markus Frank
committed
// For the licensing terms see $DD4hepINSTALL/LICENSE.
// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
Markus Frank
committed
// Author : M.Frank
//
//==========================================================================
Markus Frank
committed
/// Framework include files
#include <DDG4/Geant4UIManager.h>
#include <DDG4/Geant4Kernel.h>
#include <DDG4/Geant4UIMessenger.h>
#include <DD4hep/Primitives.h>
/// Geant4 include files
#include <G4Version.hh>
#include <G4VisExecutive.hh>
#include <G4UImanager.hh>
#include <G4UIsession.hh>
#include <G4VisExecutive.hh>
#include <G4UIExecutive.hh>
#include <G4RunManager.hh>
/// C/C++ include files
#include <cstdlib>
Markus Frank
committed
#include <functional>
namespace {
string make_cmd(const string& cmd) {
return string( "/control/execute "+cmd);
}
}
Markus Frank
committed
Geant4UIManager::Geant4UIManager(Geant4Context* ctxt, const string& nam)
Markus Frank
committed
: Geant4Action(ctxt,nam), m_vis(0), m_ui(0)
Markus Frank
committed
declareProperty("SetupUI", m_uiSetup="");
declareProperty("SetupVIS", m_visSetup="");
declareProperty("SessionType", m_sessionType="tcsh");
declareProperty("Macros", m_macros);
declareProperty("ConfigureCommands", m_configureCommands);
declareProperty("InitializeCommands", m_initializeCommands);
declareProperty("TerminateCommands", m_terminateCommands);
declareProperty("Commands", m_preRunCommands);
declareProperty("PreRunCommands", m_preRunCommands);
declareProperty("PostRunCommands", m_postRunCommands);
declareProperty("HaveVIS", m_haveVis=false);
declareProperty("HaveUI", m_haveUI=true);
declareProperty("Prompt", m_prompt);
context()->kernel().register_configure(bind(&Geant4UIManager::configure,this));
context()->kernel().register_initialize(bind(&Geant4UIManager::initialize,this));
context()->kernel().register_terminate(bind(&Geant4UIManager::terminate,this));
enableUI();
}
/// Default destructor
Geant4UIManager::~Geant4UIManager() {
}
Markus Frank
committed
/// Configure the object
void Geant4UIManager::configure() {
/// Get the pointer to the User Interface manager
G4UImanager* mgr = G4UImanager::GetUIpointer();
/// Start UI instance
if ( m_haveUI ) {
m_ui = startUI();
}
/// Execute the chained command statements
for(const auto& c : m_configureCommands) {
Markus Frank
committed
info("++ Executing configure command: %s",c.c_str());
G4int ret = mgr->ApplyCommand(c.c_str());
if ( ret != 0 ) {
except("Failed to execute command: %s",c.c_str());
}
Markus Frank
committed
}
}
/// Initialize the object
void Geant4UIManager::initialize() {
/// Get the pointer to the User Interface manager
G4UImanager* mgr = G4UImanager::GetUIpointer();
/// Execute the chained command statements
for(const auto& c : m_initializeCommands) {
Markus Frank
committed
info("++ Executing initialization command: %s",c.c_str());
G4int ret = mgr->ApplyCommand(c.c_str());
if ( ret != 0 ) {
except("Failed to execute command: %s",c.c_str());
}
Markus Frank
committed
}
}
/// Callback on terminate
void Geant4UIManager::terminate() {
/// Get the pointer to the User Interface manager
G4UImanager* mgr = G4UImanager::GetUIpointer();
/// Execute the chained command statements
for(const auto& c : m_terminateCommands) {
Markus Frank
committed
info("++ Executing finalization command: %s",c.c_str());
G4int ret = mgr->ApplyCommand(c.c_str());
if ( ret != 0 ) {
except("Failed to execute command: %s",c.c_str());
}
Markus Frank
committed
}
}
/// Apply single command
void Geant4UIManager::applyCommand(const string& command) {
/// Get the pointer to the User Interface manager
G4UImanager* mgr = G4UImanager::GetUIpointer();
if ( mgr ) {
info("++ Executing G4 command: %s",command.c_str());
Markus Frank
committed
G4int ret = mgr->ApplyCommand(command.c_str());
if ( ret == 0 ) {
return;
}
except("Failed to execute command: %s",command.c_str());
Markus Frank
committed
}
except("No UI reference present. Too early to interact with Geant4!");
}
/// Install command control messenger to write GDML file from command prompt.
void Geant4UIManager::installCommandMessenger() {
m_control->addCall("exit", "Force exiting this process",
Callback(this).make(&Geant4UIManager::forceExit),0);
Markus Frank
committed
m_control->addCall("terminate", "Regular exit this process",
Callback(this).make(&Geant4UIManager::regularExit),0);
}
/// Force exiting this process without calling atexit handlers
void Geant4UIManager::forceExit() {
std::_Exit(0);
}
Markus Frank
committed
/// Regularly exiting this process without calling atexit handlers
void Geant4UIManager::regularExit() {
Markus Frank
committed
info("++ End of processing requested.");
context()->kernel().terminate();
forceExit();
Markus Frank
committed
}
/// Start visualization
G4VisManager* Geant4UIManager::startVis() {
Markus Frank
committed
/// Initialize visualization
info("+++ Starting G4VisExecutive ....");
G4VisManager* vis = new G4VisExecutive();
vis->Initialize();
return vis;
}
/// Start UI
G4UIExecutive* Geant4UIManager::startUI() {
G4UIExecutive* ui = 0;
const char* args[] = {"DDG4","",""};
Markus Frank
committed
info("+++ Starting G4UIExecutive '%s' of type %s....", args[0], m_sessionType.c_str());
#if (G4VERSION_NUMBER >= 960)
ui = new G4UIExecutive(1,(char**)args,m_sessionType.c_str());
#else
ui = new G4UIExecutive(1,(char**)args );
#endif
if ( !m_prompt.empty() ) {
ui->SetPrompt(m_prompt);
}
return ui;
}
/// Run UI
void Geant4UIManager::operator()(void* ) {
start();
stop();
}
/// Start manager & session
void Geant4UIManager::start() {
Markus Frank
committed
/// Get the pointer to the User Interface manager
bool executed_statements = false;
Markus Frank
committed
/// Start visualization
if ( m_haveVis || !m_visSetup.empty() ) {
m_vis = startVis();
Markus Frank
committed
m_haveVis = true; /// If graphics setup, vis is always true
m_haveUI = true; /// No graphics without UI!
Markus Frank
committed
/// Configure visualization instance
Markus Frank
committed
info("++ Executing visualization setup: %s",m_visSetup.c_str());
mgr->ApplyCommand(make_cmd(m_visSetup).c_str());
Markus Frank
committed
/// Configure UI instance
Markus Frank
committed
info("++ Executing UI setup: %s",m_uiSetup.c_str());
mgr->ApplyCommand(make_cmd(m_uiSetup).c_str());
executed_statements = true;
}
Markus Frank
committed
/// Execute the chained macro files
Markus Frank
committed
for(const auto& m : m_macros) {
Markus Frank
committed
info("++ Executing Macro file: %s",m.c_str());
Markus Frank
committed
mgr->ApplyCommand(make_cmd(m.c_str()));
executed_statements = true;
}
Markus Frank
committed
/// Execute the chained pre-run command statements
for(const auto& c : m_preRunCommands) {
Markus Frank
committed
info("++ Executing pre-run statement: %s",c.c_str());
Markus Frank
committed
mgr->ApplyCommand(c.c_str());
executed_statements = true;
Markus Frank
committed
/// Start UI session if present
Markus Frank
committed
/// Execute the chained post-run command statements
Markus Frank
committed
for(const auto& c : m_postRunCommands) {
Markus Frank
committed
info("++ Executing post-run statement: %s",c.c_str());
Markus Frank
committed
mgr->ApplyCommand(c.c_str());
executed_statements = true;
}
else if ( m_haveUI ) {
Markus Frank
committed
warning("++ No UI manager found. Exit.");
return;
}
else if ( executed_statements ) {
Markus Frank
committed
/// Execute the chained post-run command statements
for(const auto& c : m_postRunCommands) {
Markus Frank
committed
info("++ Executing post-run statement: %s",c.c_str());
Markus Frank
committed
mgr->ApplyCommand(c.c_str());
}
return;
}
Markus Frank
committed
/// No UI. Pure batch mode: Simply execute requested number of events
long numEvent = context()->kernel().property("NumEvents").value<long>();
Markus Frank
committed
if(numEvent < 0) numEvent = numeric_limits<int>::max();
info("++ Start run with %d events.",numEvent);
Andre Sailer
committed
try {
context()->kernel().runManager().BeamOn(numEvent);
} catch (DD4hep_End_Of_File& e) {
Markus Frank
committed
info("++ End of file reached, ending run...");
Markus Frank
committed
context()->kernel().runManager().RunTermination();
Andre Sailer
committed
}
}
/// Stop and release resources
void Geant4UIManager::stop() {
detail::deletePtr(m_vis);
detail::deletePtr(m_ui);