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
//
//==========================================================================
#include <DD4hep/Printout.h>
#include <DD4hep/Primitives.h>
#include <DDG4/Geant4UIMessenger.h>
#include <G4UIcmdWithoutParameter.hh>
#include <G4UIcmdWithAString.hh>
// C/C++ include files
#include <algorithm>
namespace {
struct InstallProperties {
Geant4UIMessenger::Commands& cmds;
const std::string& path;
G4UImessenger* msg;
InstallProperties(Geant4UIMessenger::Commands& c, const std::string& p, G4UImessenger* m)
Markus Frank
committed
: cmds(c), path(p), msg(m) {
void operator()(const std::pair<std::string, dd4hep::Property>& o) {
std::string n = path + o.first;
G4UIcmdWithAString* cmd = new G4UIcmdWithAString(n.c_str(), msg);
cmd->SetParameterName(o.first.c_str(), true);
cmd->SetGuidance(("Property item of type " + o.second.type()).c_str());
cmds[cmd] = o.first;
}
};
}
Geant4UIMessenger::Geant4UIMessenger(const std::string& name, const std::string& path)
Markus Frank
committed
: G4UImessenger(), m_directory(0), m_properties(0), m_name(name), m_path(path) {
m_directory = new G4UIdirectory(path.c_str());
printout(INFO, "Geant4UI", "+++ %s> Install Geant4 control directory:%s", name.c_str(), path.c_str());
m_directory->SetGuidance(("Control hierarchy for Geant4 action:" + name).c_str());
}
/// Default destructor
Geant4UIMessenger::~Geant4UIMessenger() {
detail::destroyFirst(m_propertyCmd);
detail::destroyFirst(m_actionCmd);
}
/// Add a new callback structure
void Geant4UIMessenger::addCall(const std::string& name, const std::string& description, const Callback& cb, size_t npar) {
if ( 0 == npar ) {
G4UIcommand* cmd = new G4UIcmdWithoutParameter((m_path + name).c_str(), this);
cmd->SetGuidance(description.c_str());
m_actionCmd[cmd] = cb;
}
else if ( 1 == npar ) {
G4UIcmdWithAString* cmd = new G4UIcmdWithAString((m_path + name).c_str(), this);
cmd->SetParameterName("p1", true);
cmd->SetGuidance(description.c_str());
m_actionCmd[cmd] = cb;
}
else {
except("Geant4UIMessenger","+++ Currently only callbacks with one argument are handled! [Contact developers if more are required]");
}
}
/// Export all properties to the Geant4 UI
void Geant4UIMessenger::exportProperties(PropertyManager& mgr) {
InstallProperties installer(m_propertyCmd, m_path, this);
m_properties = &mgr;
Markus Frank
committed
addCall("show", "Show all properties of Geant4 component:" + m_name,
Callback(m_properties).make(&PropertyManager::dump));
m_properties->for_each(installer);
}
/// Pass current property value to Geant4 UI
G4String Geant4UIMessenger::GetCurrentValue(G4UIcommand * c) {
Commands::iterator i = m_propertyCmd.find(c);
if (m_properties && i != m_propertyCmd.end()) {
const std::string& n = (*i).second;
return (*m_properties)[n].str();
}
printout(INFO, "Geant4UI",
Markus Frank
committed
"+++ %s> Failed to access property value.", m_name.c_str());
return "";
}
/// Accept ne property value from Geant4 UI
void Geant4UIMessenger::SetNewValue(G4UIcommand *c, G4String v) {
Commands::iterator i = m_propertyCmd.find(c);
if (m_properties && i != m_propertyCmd.end()) {
const std::string& n = (*i).second;
Markus Frank
committed
Property& p = (*m_properties)[n];
p.str(v);
printout(INFO, "Geant4UI",
Markus Frank
committed
"+++ %s> Setting property value %s = %s native:%s.",
m_name.c_str(), n.c_str(), v.c_str(), p.str().c_str());
std::string value = (*m_properties)[n].str();
printout(INFO, "Geant4UI", "+++ %s> Unchanged property value %s = %s.",
Markus Frank
committed
m_name.c_str(), n.c_str(), value.c_str());
catch(const std::exception& e) {
printout(INFO, "Geant4UI", "+++ %s> Exception: Failed to change property %s = '%s'.",
Markus Frank
committed
m_name.c_str(), n.c_str(), v.c_str());
printout(INFO, "Geant4UI", "+++ %s> Exception: %s", m_name.c_str(), e.what());
printout(INFO, "Geant4UI", "+++ %s> UNKNOWN Exception: Failed to change property %s = '%s'.",
Markus Frank
committed
m_name.c_str(), n.c_str(), v.c_str());
else {
Actions::iterator j = m_actionCmd.find(c);
if (j != m_actionCmd.end()) {
try {
const void* args[] = {v.c_str(), 0};
(*j).second.execute(args);
catch(const std::exception& e) {
printout(INFO, "Geant4UI", "+++ %s> Exception: Failed to exec action '%s' [%s].",
Markus Frank
committed
m_name.c_str(), c->GetCommandName().c_str(), c->GetCommandPath().c_str());
printout(INFO, "Geant4UI", "+++ %s> Exception: %s",e.what());
printout(INFO, "Geant4UI", "+++ %s> UNKNOWN Exception: Failed to exec action '%s' [%s].",
Markus Frank
committed
m_name.c_str(), c->GetCommandName().c_str(), c->GetCommandPath().c_str());
printout(INFO, "Geant4UI", "+++ %s> Unknown command callback!", m_name.c_str());