Newer
Older
Markus Frank
committed
//==========================================================================
// AIDA Detector description implementation for LCD
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
//
//==========================================================================
// Framework include files
#include "DD4hep/LCDD.h"
Markus Frank
committed
#include "DD4hep/Printout.h"
// C/C++ include files
#include <iostream>
#include <cstdlib>
#include <vector>
#include <cerrno>
#include <string>
using namespace std;
using namespace DD4hep::Geometry;
//______________________________________________________________________________
#include "TRint.h"
//______________________________________________________________________________
namespace {
LCDD& dd4hep_instance(const char* /* name */ ="") {
v.p = ::DD4hep::PluginService::Create<void*>("LCDD_constructor",name);
Markus Frank
committed
return *v.l;
}
throw runtime_error("Failed to locate plugin to create LCDD instance");
}
catch(const exception& e) {
cout << "Exception:" << e.what() << endl;
throw runtime_error("Exception:\""+string(e.what()));
}
catch(...) {
cout << "UNKNOWN Exception while creating LCDD instance." << endl;
throw runtime_error("UNKNOWN Exception while creating LCDD instance.");
#endif
return LCDD::getInstance();
Markus Frank
committed
long run_plugin(LCDD& lcdd, const char* name, int argc, char** argv) {
try {
lcdd.apply(name,argc,argv);
return 0;
}
catch(const exception& e) {
cout << e.what() << endl;
Markus Frank
committed
return EINVAL;
}
catch(...) {
cout << "UNKNOWN Exception" << endl;
Markus Frank
committed
return EINVAL;
std::ostream& print_default_args() {
cout <<
" -build_type <number/string> Specify the build type \n"
" [OPTIONAL] MUST come immediately after the -compact input.\n"
" Default for each file is: BUILD_DEFAULT [=1] \n"
" Allowed: BUILD_SIMU [=1], BUILD_RECO [=2], \n"
" BUILD_DISPLAY [=3] or BUILD_ENVELOPE [=4] \n"
Markus Frank
committed
" -destroy [OPTIONAL] Force destruction of the LCDD instance \n"
" before exiting the application \n"
" -volmgr [OPTIONAL] Load and populate phys.volume manager to \n"
" check the volume ids for duplicates etc. \n"
" -print <number/string> Specify output level. Default: INFO(=3) \n"
" [OPTIONAL] Allowed values: VERBOSE(=1), DEBUG(=2), \n"
" INFO(=3), WARNING(=4), ERROR(=5), FATAL(=6) \n"
" The lower the level, the more printout... \n"
" -plugin <name> <args> Execute plugin <name> after loading geometry. \n"
" All arguments following until the next '-' \n"
" are considered as arguments to the plugin. \n"
" ";
return cout;
}
void usage_default(const char* name) {
cout << " " << name << " -opt [-opt] \n"
" -compact <file> Specify the compact geometry file \n"
" [REQUIRED] At least one compact geo file is required! \n";
print_default_args() <<
" -load_only [OPTIONAL] Dry-run to only load geometry without \n"
" starting the dispay. \n"
Markus Frank
committed
<< endl;
bool volmgr, dry_run, destroy, interpreter;
Markus Frank
committed
int print;
std::vector<const char*> geo_files, build_types;
std::vector<std::vector<const char*> > plugins;
Args() {
volmgr = false;
dry_run = false;
destroy = false;
Markus Frank
committed
print = DD4hep::INFO;
}
int handle(int& i, int argc, char** argv) {
Markus Frank
committed
if ( strncmp(argv[i],"-compact",5)==0 || strncmp(argv[i],"-input",4)==0 ) {
Markus Frank
committed
geo_files.push_back(argv[++i]);
if ( argc>i+2 && strncmp(argv[i+1],"-build_type",6)==0 ) {
build_types.push_back(argv[i+2]);
i += 2;
}
else {
build_types.push_back("BUILD_DEFAULT");
}
Markus Frank
committed
else if ( strncmp(argv[i],"-load_only",5)==0 )
Markus Frank
committed
dry_run = true;
Markus Frank
committed
else if ( strncmp(argv[i],"-print",4)==0 )
Markus Frank
committed
DD4hep::setPrintLevel(DD4hep::PrintLevel(print = decodePrintLevel(argv[++i])));
Markus Frank
committed
else if ( strncmp(argv[i],"-destroy",5)==0 )
Markus Frank
committed
destroy = true;
else if ( strncmp(argv[i],"-no-destroy",8)==0 )
destroy = false;
Markus Frank
committed
else if ( strncmp(argv[i],"-volmgr",4)==0 )
Markus Frank
committed
volmgr = true;
else if ( strncmp(argv[i],"-no-volmgr",7)==0 )
volmgr = false;
else if ( strncmp(argv[i],"-interpreter",6)==0 )
interpreter = true;
else if ( strncmp(argv[i],"-no-interpreter",7)==0 )
interpreter = false;
else if ( strncmp(argv[i],"-plugin",5)==0 ) {
// Need to interprete plugin args here locally.....
plugins.push_back(std::vector<const char*>());
plugins.back().push_back(argv[++i]);
for( ++i; i < argc; ++i ) {
if ( argv[i][0]=='-' ) { --i; break; }
plugins.back().push_back(argv[i]);
}
plugins.back().push_back(0);
Markus Frank
committed
return 0;
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
long run(LCDD& lcdd, const char* name) {
pair<int, char**> a(0,0);
long result;
for(size_t i=0; i<plugins.size(); ++i) {
std::vector<const char*>& plug=plugins[i];
result = run_plugin(lcdd,plug[0],plug.size()-1,(char**)(plug.size()>1 ? &plug[1] : 0));
if ( result == EINVAL ) {
cout << "FAILED to execute DD4hep plugin: '" << plug[0]
<< "' with args (" << (plug.size()-1) << ") :[ ";
for(size_t j=1; j<plug.size(); ++j) {
cout << plug[j] << " ";
}
cout << "]" << endl;
usage_default(name);
}
cout << "Executed DD4hep plugin: '" << plug[0]
<< "' with args (" << (plug.size()-1) << ") :[ ";
for(size_t j=1; j<plug.size(); ++j) {
cout << plug[j] << " ";
}
cout << "]" << endl;
}
result = run_plugin(lcdd,name,a.first,a.second);
return result;
}
Markus Frank
committed
int decodePrintLevel(const std::string& val) {
switch(::toupper(val[0])) {
case '1':
case 'V':
Markus Frank
committed
return DD4hep::VERBOSE;
Markus Frank
committed
case '2':
case 'D':
Markus Frank
committed
return DD4hep::DEBUG;
Markus Frank
committed
case '3':
case 'I':
Markus Frank
committed
return DD4hep::INFO;
Markus Frank
committed
case '4':
case 'W':
Markus Frank
committed
return DD4hep::WARNING;
Markus Frank
committed
case '5':
case 'E':
Markus Frank
committed
return DD4hep::ERROR;
Markus Frank
committed
case '6':
case 'F':
Markus Frank
committed
return DD4hep::FATAL;
Markus Frank
committed
case '7':
case 'A':
Markus Frank
committed
return DD4hep::FATAL;
Markus Frank
committed
default:
Markus Frank
committed
cout << "Unknown print level supplied:'" << val << "'. Argument ignored." << endl;
throw std::runtime_error("Invalid printLevel:"+val);
Markus Frank
committed
}
}
};
void load_compact(LCDD& lcdd, Args& args) {
// Load all compact files
for(size_t i=0; i<args.geo_files.size(); ++i) {
const char* argv[] = {args.geo_files[i], args.build_types[i], 0};
run_plugin(lcdd,"DD4hepCompactLoader",2,(char**)argv);
}
}
//______________________________________________________________________________
int main_default(const char* name, int argc,char** argv) {
for(int i=1; i<argc;++i) {
if ( argv[i][0]=='-' ) {
Markus Frank
committed
if ( args.handle(i,argc,argv) )
continue;
else
usage_default(name);
Markus Frank
committed
args.geo_files.push_back(argv[i]);
args.build_types.push_back("BUILD_DEFAULT");
if ( args.geo_files.empty() )
usage_default(name);
LCDD& lcdd = dd4hep_instance();
// Load all compact files
load_compact(lcdd, args);
// Create volume manager and populate it required
if ( args.volmgr ) run_plugin(lcdd,"DD4hepVolumeManager",0,0);
// Create an interactive ROOT application
if ( !args.dry_run ) {
pair<int, char**> a(0,0);
if ( args.interpreter ) {
TRint app(name, &a.first, a.second);
result = args.run(lcdd,name);
if ( result != EINVAL ) app.Run();
}
else
result = args.run(lcdd,name);
Markus Frank
committed
if ( result == EINVAL ) usage_default(name);
}
else {
cout << "The geometry was loaded. Application now exiting." << endl;
}
if ( args.destroy ) delete &lcdd;
return 0;
}
}