12 #include <boost/program_options.hpp>
13 #include <boost/regex.hpp>
21 #include <TBranchElement.h>
26 #include "GaudiKernel/StatusCode.h"
27 #include "GaudiKernel/Bootstrap.h"
28 #include "GaudiKernel/IMessageSvc.h"
29 #include "GaudiKernel/ISvcLocator.h"
34 #include "../CodeGenerator_v2.h"
35 #include "../RootObjectMetadata.h"
38 static const char*
const PROGRAM_DESC =
39 "This application can be used to generate D3PDReader classes\n"
40 "based on an existing D3PD file and some additional command\n"
44 static const char*
const PROGRAM_GREETING =
45 "*******************************************************************\n"
47 "* D3PDReader standalone code generator *\n"
49 "*******************************************************************";
62 template<
typename T >
65 typename std::vector< T >::const_iterator itr =
vec.begin();
66 typename std::vector< T >::const_iterator
end =
vec.end();
67 for( ; itr !=
end; ++itr ) {
80 const std::vector< std::string >&
patterns,
87 namespace po = boost::program_options;
95 SmartIF<IMessageSvc> msvc{Gaudi::svcLocator()->service(
"MessageSvc")};
98 <<
"Couldn't set up the Gaudi message service";
106 po::options_description
desc( PROGRAM_DESC );
108 (
"help,h",
"Give some help with the program usage" )
109 (
"classname,n", po::value< std::string >()->default_value(
"D3PDReader" ),
110 "Generated class name" )
111 (
"d3pd-files,f",
po::value< std::vector< std::string > >()->multitoken(),
112 "Input D3PD file(s)" )
113 (
"tree,t", po::value< std::string >()->default_value(
"" ),
"Name of the D3PD tree" )
114 (
"variables,v",
po::value< std::vector< std::string > >()->multitoken(),
115 "Variable names to consider (regular expression(s))" )
116 (
"prefixes,p",
po::value< std::vector< std::string > >()->multitoken(),
117 "Variable name prefix(es)" )
118 (
"container,c",
"Option specifying that a proxy class should be created" )
119 (
"output,o", po::value< std::string >()->default_value(
"." ),
120 "Output directory for the generated source files" );
125 po::variables_map vm;
131 <<
"There was a problem with interpreting the command line options.";
133 <<
"Message: " << ex.what();
140 if( vm.count(
"help" ) ) {
141 std::cout <<
desc << std::endl;
149 std::cout << PROGRAM_GREETING << std::endl;
150 std::cout <<
"Program will be executed with the options:" << std::endl;
153 std::string
class_name = vm[
"classname" ].as< std::string >();
154 std::cout <<
" Generating class with name: \"D3PDReader::" <<
class_name <<
"\""
158 if( ! vm.count(
"d3pd-files" ) ) {
160 <<
"You have to specify at least one D3PD file!";
163 const std::vector< std::string > file_names =
164 vm[
"d3pd-files" ].as< std::vector< std::string > >();
165 std::cout <<
" D3PD file(s): " << file_names << std::endl;
168 const std::string d3pd_tree_name = vm[
"tree" ].as< std::string >();
169 if( d3pd_tree_name !=
"" ) {
170 std::cout <<
" Using D3PD tree: " << d3pd_tree_name << std::endl;
172 std::cout <<
" Trying to find D3PD tree automatically" << std::endl;
176 std::vector< std::string > var_names;
177 if( vm.count(
"variables" ) ) {
178 var_names = vm[
"variables" ].as< std::vector< std::string > >();
179 std::cout <<
" Only considering variables with names: " << var_names << std::endl;
181 std::cout <<
" Considering all variables from the input file" << std::endl;
185 if( ( ( vm.count(
"prefixes" ) != vm.count(
"variables" ) ) &&
186 ( vm.count(
"prefixes" ) != 1 ) ) ||
187 ( vm.count(
"prefixes" ) == 0 ) ) {
189 <<
"You have to either specify just one prefix, or the same number as "
190 <<
"how many variable regular expressions you gave";
193 const std::vector< std::string > prefixes =
194 vm[
"prefixes" ].as< std::vector< std::string > >();
195 std::cout <<
" Common variable prefix(es): " << prefixes << std::endl;
198 const bool is_container = vm.count(
"container" );
199 std::cout <<
" Proxy class will " << ( is_container ?
"" :
"NOT " ) <<
"be created"
203 const std::string
output = vm[
"output" ].as< std::string >();
204 std::cout <<
" Output directory: " <<
output << std::endl;
209 std::map< std::string, D3PD::RootObjectMetadata >
metadata;
210 std::vector< std::string >::const_iterator prefix_itr = prefixes.begin();
211 std::vector< std::string >::const_iterator prefix_end = prefixes.end();
212 for( ; prefix_itr != prefix_end; ++prefix_itr ) {
214 metadata[ *prefix_itr ].setPrefix( *prefix_itr );
215 metadata[ *prefix_itr ].setContainer( is_container );
221 std::vector< std::string >::const_iterator file_itr = file_names.begin();
222 std::vector< std::string >::const_iterator file_end = file_names.end();
223 for( ; file_itr != file_end; ++file_itr ) {
225 if( prefixes.size() > 1 ) {
227 for(
size_t i = 0;
i < prefixes.size(); ++
i ) {
229 metadata[ prefixes[
i ] ] ).isFailure() ) {
231 <<
"Couldn't extract the variable descriptions from file: "
240 metadata[ prefixes[ 0 ] ] ).isFailure() ) {
242 <<
"Couldn't extract the variable descriptions from file: "
258 prefix_itr = prefixes.begin();
259 prefix_end = prefixes.end();
260 for( ; prefix_itr != prefix_end; ++prefix_itr ) {
261 summed_meta +=
metadata[ *prefix_itr ];
269 <<
"Couldn't create the D3PDObjectBase class source";
278 <<
"Couldn't create the VarHandle class source";
288 <<
"Couldn't create the VarProxy class source";
298 <<
"Couldn't create the UserD3PDObject class source";
307 <<
"Couldn't create the D3PDReadStats class source";
316 <<
"Couldn't create the D3PDPerfStats class source";
325 <<
"Couldn't create the Utils source";
334 <<
"Couldn't generate the D3PDReader class header";
343 <<
"Couldn't generate the D3PDReader class source";
362 const std::vector< std::string >&
patterns,
369 if( ( !
file ) ||
file->IsZombie() ) {
371 <<
"Failed to open D3PD file: " <<
file_name;
372 return StatusCode::FAILURE;
379 if( tree_name !=
"" ) {
383 tree =
dynamic_cast< TTree*
>(
file->Get( tree_name.c_str() ) );
386 <<
"Couldn't find tree \"" << tree_name <<
"\" in file: " <<
file_name;
387 return StatusCode::FAILURE;
395 std::string
name =
"";
396 const TList*
keys =
file->GetListOfKeys();
397 for( Int_t
i = 0;
i <
keys->GetSize(); ++
i ) {
398 const TKey*
key =
dynamic_cast< TKey*
>(
keys->At(
i ) );
400 std::string key_name =
key->GetName();
401 if( ( key_name.find(
"CollectionTree" ) == key_name.npos ) &&
402 (
key->GetClassName() == std::string(
"TTree" ) ) ) {
404 std::cout <<
"Assuming that the D3PD tree is called: " <<
name
411 <<
"Couldn't find the name for the D3PD tree!";
412 return StatusCode::FAILURE;
414 tree =
dynamic_cast< TTree*
>(
file->Get(
name.c_str() ) );
417 <<
"Couldn't find tree \"" << tree_name <<
"\" in file: "
419 return StatusCode::FAILURE;
433 std::vector< std::string >::const_iterator itr =
patterns.begin();
434 std::vector< std::string >::const_iterator
end =
patterns.end();
435 for( ; itr !=
end; ++itr ) {
436 if( boost::regex_search(
branches->At(
i )->GetName(),
437 boost::basic_regex< char >( itr->c_str() ) ) ) {
442 if( ! pass )
continue;
448 const std::string branch_type(
branches->At(
i )->IsA()->GetName() );
449 if( branch_type ==
"TBranch" ) {
458 <<
"Could not cast object into a TBranch!";
459 return StatusCode::FAILURE;
461 TObjArray* leaves =
branch->GetListOfLeaves();
462 bool leaf_found =
false;
463 for( Int_t j = 0; j < leaves->GetSize(); ++j ) {
464 TLeaf* leaf =
dynamic_cast< TLeaf*
>( leaves->At( 0 ) );
468 branch->GetTitle() ).isFailure() ) {
470 <<
"Failed adding variable: " <<
branch->GetName();
471 return StatusCode::FAILURE;
479 <<
"Couldn't find the TLeaf describing a primitive type!";
480 return StatusCode::FAILURE;
483 }
else if( branch_type ==
"TBranchElement" ) {
491 TBranchElement*
branch =
dynamic_cast< TBranchElement*
>(
branches->At(
i ) );
494 <<
"Could not cast object into a TBranchElement!";
495 return StatusCode::FAILURE;
499 branch->GetTitle() ).isFailure() ) {
501 <<
"Failed adding variable: " <<
branch->GetName();
502 return StatusCode::FAILURE;
509 return StatusCode::SUCCESS;