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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/// 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) {
info("++ Executing configure command:%s",c.c_str());
mgr->ApplyCommand(c.c_str());
}
}
/// 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) {
info("++ Executing initialization command:%s",c.c_str());
mgr->ApplyCommand(c.c_str());
}
}
/// 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) {
info("++ Executing finalization command:%s",c.c_str());
mgr->ApplyCommand(c.c_str());
}
}
/// 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());
mgr->ApplyCommand(command.c_str());
return;
}
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) {
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) {
info("++ Executing post-run statement:%s",c.c_str());
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);