14#include <boost/program_options.hpp>
20#include <TDirectory.h>
22#include <TObjString.h>
26#include "GaudiKernel/StatusCode.h"
27#include "GaudiKernel/Bootstrap.h"
28#include "GaudiKernel/IMessageSvc.h"
29#include "GaudiKernel/ISvcLocator.h"
43 "This application can be used to create all the D3PDReader classes\n"
44 "from a D3PD file that stores the metadata of the D3PDObjects that\n"
45 "were used to create it";
49 "*******************************************************************\n"
51 "* D3PDReader standalone code generator *\n"
53 "*******************************************************************";
67std::ostream&
operator<<( std::ostream& out,
const std::vector< T >&
vec ) {
69 typename std::vector< T >::const_iterator itr =
vec.begin();
70 typename std::vector< T >::const_iterator end =
vec.end();
71 for( ; itr != end; ++itr ) {
84 std::set< D3PD::ObjectMetadata >& objects );
86std::vector< D3PD::ObjectMetadata >
87mergeObjects(
const std::set< D3PD::ObjectMetadata >& objects );
90namespace po = boost::program_options;
94 gErrorIgnoreLevel = kError;
98 SmartIF<IMessageSvc> msvc{Gaudi::svcLocator()->service(
"MessageSvc")};
101 <<
"Couldn't set up the Gaudi message service";
111 (
"help,h",
"Give some help with the program usage" )
112 (
"d3pd-files,f", po::value< std::vector< std::string > >()->multitoken(),
113 "Input D3PD file(s)" )
114 (
"event-class-name,n", po::value< std::string >()->default_value(
"Event" ),
115 "Name for the D3PDReader event class" )
116 (
"output,o", po::value< std::string >()->default_value(
"." ),
117 "Output directory for the generated source files" )
118 (
"verbosity,v", po::value< int >()->default_value( 3 ),
119 "Verbosity level of the application. (1:VERBOSE, 2:DEBUG, 3:INFO, ...)" );
124 po::variables_map vm;
126 po::store( po::parse_command_line( argc, argv, desc ), vm );
128 }
catch(
const std::exception& ex ) {
130 <<
"There was a problem with interpreting the command line options.";
132 <<
"Message: " << ex.what();
139 if( vm.count(
"help" ) ) {
140 std::cout << desc << std::endl;
147 msvc->setOutputLevel( vm[
"verbosity" ].as< int >() );
156 if( ! vm.count(
"d3pd-files" ) ) {
158 <<
"You have to specify at least one D3PD file!";
161 const std::vector< std::string > file_names =
162 vm[
"d3pd-files" ].as< std::vector< std::string > >();
163 std::cout <<
" D3PD file(s): " << file_names << std::endl;
166 const std::string event_name = vm[
"event-class-name" ].as< std::string >();
167 std::cout <<
" Event class name: " << event_name << std::endl;
170 const std::string output = vm[
"output" ].as< std::string >();
171 std::cout <<
" Output directory: " << output << std::endl;
176 std::set< D3PD::ObjectMetadata > objects;
181 std::vector< std::string >::const_iterator file_itr = file_names.begin();
182 std::vector< std::string >::const_iterator file_end = file_names.end();
183 for( ; file_itr != file_end; ++file_itr ) {
187 <<
"Reading file: " << *file_itr;
188 TFile* ifile = TFile::Open( file_itr->c_str(),
"READ" );
189 if( ( ! ifile ) || ifile->IsZombie() ) {
191 <<
"Failed to open D3PD file: " << *file_itr;
196 std::vector< std::string > metaDirectories;
197 const TList* keys = ifile->GetListOfKeys();
198 for( Int_t i = 0; i < keys->GetSize(); ++i ) {
199 const TKey* key =
dynamic_cast< TKey*
>( keys->At( i ) );
201 std::string key_name = key->GetName();
202 if( ( key_name.find(
"Meta" ) != key_name.npos ) &&
203 ( key->GetClassName() == std::string(
"TDirectoryFile" ) ) ) {
204 metaDirectories.push_back( std::move(key_name) );
209 std::vector< std::string >::const_iterator dir_itr = metaDirectories.begin();
210 std::vector< std::string >::const_iterator dir_end = metaDirectories.end();
211 for( ; dir_itr != dir_end; ++dir_itr ) {
213 TDirectory* dir = ifile->GetDirectory( dir_itr->c_str() );
216 <<
"Failed to access directory: " << *dir_itr;
222 <<
"Failed to collect variable definitions from metadata directory: "
236 std::vector< D3PD::ObjectMetadata > merged_objects =
mergeObjects( objects );
237 if( ! merged_objects.size() ) {
239 <<
"Didn't find any metadata about the D3PD variables in the "
240 <<
"specified file(s)!";
249 <<
"Couldn't create the D3PDObjectBase class source";
258 <<
"Couldn't create the VarHandle class source";
267 <<
"Couldn't create the VarProxy class source";
276 <<
"Couldn't create the UserD3PDObject class source";
285 <<
"Couldn't create the D3PDReadStats class source";
294 <<
"Couldn't create the D3PDPerfStats class source";
303 <<
"Couldn't create the Utils source";
310 std::vector< D3PD::ObjectMetadata >::const_iterator obj_itr = merged_objects.begin();
311 std::vector< D3PD::ObjectMetadata >::const_iterator obj_end = merged_objects.end();
312 for( ; obj_itr != obj_end; ++obj_itr ) {
318 *obj_itr ).isFailure() ) {
320 <<
"Couldn't generate the D3PDReader class header";
328 *obj_itr ).isFailure() ) {
330 <<
"Couldn't generate the D3PDReader class source";
339 objects ).isFailure() ) {
341 <<
"Couldn't generate the D3PDReader event class header";
345 objects ).isFailure() ) {
347 <<
"Couldn't generate the D3PDReader event class source";
364 std::set< D3PD::ObjectMetadata >& objects ) {
367 const TList* keys = dir->GetListOfKeys();
368 for( Int_t i = 0; i < keys->GetSize(); ++i ) {
371 const TKey* key =
dynamic_cast< TKey*
>( keys->At( i ) );
373 if( key->GetClassName() != std::string(
"TObjString" ) )
continue;
384 <<
"Reading object '" << objName <<
"'";
387 TObjString* ostring =
388 dynamic_cast< TObjString*
>( dir->Get( TString( key->GetName() ) +
";" +
389 TString::Format(
"%hi", key->GetCycle() ) ) );
392 <<
"Couldn't access object: " << key->GetName() <<
";"
394 return StatusCode::FAILURE;
399 metadata.setName( objName );
400 if( metadata.read( ostring->GetString().Data() ).isFailure() ) {
402 <<
"Couldn't collect variables from object: " << key->GetName();
403 return StatusCode::FAILURE;
407 if( metadata.checkPrefixes().isFailure() ) {
409 <<
"Couldn't fix prefixes in metadata object with name: "
411 return StatusCode::FAILURE;
415 std::pair< std::set< D3PD::ObjectMetadata >::iterator,
bool > ret =
416 objects.insert( metadata );
420 <<
"Merging objects with name '" << objName <<
"'";
422 merged.
merge( metadata );
423 objects.erase( ret.first );
424 objects.insert( merged );
427 <<
"Added object with name '" << objName <<
"'";
432 return StatusCode::SUCCESS;
443std::vector< D3PD::ObjectMetadata >
447 std::map< std::string, D3PD::ObjectMetadata > tmp_result;
450 std::set< D3PD::ObjectMetadata >::const_iterator set_itr = objects.begin();
451 std::set< D3PD::ObjectMetadata >::const_iterator set_end = objects.end();
452 for( ; set_itr != set_end; ++set_itr ) {
453 tmp_result[ set_itr->name() ].setName( set_itr->name() );
454 tmp_result[ set_itr->name() ].setPrefix( set_itr->prefix() );
455 tmp_result[ set_itr->name() ].setContainer( set_itr->container() );
456 tmp_result[ set_itr->name() ].merge( *set_itr );
460 std::vector< D3PD::ObjectMetadata >
result;
461 std::map< std::string, D3PD::ObjectMetadata >::const_iterator map_itr =
463 std::map< std::string, D3PD::ObjectMetadata >::const_iterator map_end =
465 for( ; map_itr != map_end; ++map_itr ) {
466 result.push_back( map_itr->second );
std::vector< size_t > vec
Helpers for checking error return status codes and reporting errors.
#define REPORT_MESSAGE_WITH_CONTEXT(LVL, CONTEXT_NAME)
Report a message, with an explicitly specified context name.
int main(int, char **)
Main class for all the CppUnit test classes.
Define macros for attributes used to control the static checker.
#define ATLAS_NOT_THREAD_SAFE
getNoisyStrip() Find noisy strips from hitmaps and write out into xml/db formats
static const char *const PROGRAM_GREETING
A greeting text that's printed when the application starts up.
static const char *const PROGRAM_DESC
The program description that's printed with the available parameters.
std::ostream & operator<<(std::ostream &out, const std::vector< T > &vec)
Formatted printing for vector objects.
std::vector< D3PD::ObjectMetadata > mergeObjects(const std::set< D3PD::ObjectMetadata > &objects)
Function mergint the objects of the same type.
StatusCode collectObjects(TDirectory *dir, std::set< D3PD::ObjectMetadata > &objects)
Function collecting the objects from a specific directory in a file.
StatusCode writeUtils(const std::string &dir)
This function can be used to create source files containing some utility functions.
StatusCode writeHeader(const std::string &classname, const std::string &dir, const ObjectMetadata &metadata)
This function is used to create the header of the class describing a set of D3PD variables.
StatusCode writeEventSource(const std::string &classname, const std::string &dir, const std::set< ObjectMetadata > &metadata)
Write the source of the main event class describing a D3PD tree.
StatusCode writeD3PDReadStats(const std::string &dir)
This function can be used to create the D3PDReader::D3PDReadStats class's source files.
StatusCode writeSource(const std::string &classname, const std::string &dir, const ObjectMetadata &metadata)
This function is used to generate the source file of a D3PDReader class.
StatusCode writeVarHandle(const std::string &dir)
This function can be used to create the D3PDReader::VarHandle class's source files.
StatusCode writeVarProxy(const std::string &dir)
This function can be used to create the D3PDReader::VarProxy class's source files.
StatusCode writeEventHeader(const std::string &classname, const std::string &dir, const std::set< ObjectMetadata > &metadata)
Write the header of the main event class describing a D3PD tree.
StatusCode writeD3PDObjectBase(const std::string &dir)
This function can be used to create the D3PDReader::D3PDObjectBase class's source files.
StatusCode writeUserD3PDObject(const std::string &dir)
This function can be used to create the D3PDReader::UserD3PDObject class's source files.
StatusCode writeD3PDPerfStats(const std::string &dir)
This function can be used to create the D3PDReader::D3PDPerfStats class's source files.