ATLAS Offline Software
Functions
d3pdReadersFromFile.cxx File Reference
#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <boost/program_options.hpp>
#include <boost/algorithm/string.hpp>
#include <TFile.h>
#include <TList.h>
#include <TKey.h>
#include <TDirectory.h>
#include <TString.h>
#include <TObjString.h>
#include <TError.h>
#include "GaudiKernel/StatusCode.h"
#include "GaudiKernel/Bootstrap.h"
#include "GaudiKernel/IMessageSvc.h"
#include "GaudiKernel/ISvcLocator.h"
#include "AthenaKernel/errorcheck.h"
#include "CxxUtils/checker_macros.h"
#include "D3PDMakerUtils/ObjectMetadata.h"
#include "../Variable.h"
#include "../CodeGenerator_v2.h"
#include "../RootObjectMetadata.h"

Go to the source code of this file.

Functions

template<typename T >
std::ostream & operator<< (std::ostream &out, const std::vector< T > &vec)
 Formatted printing for vector objects. More...
 
StatusCode collectObjects (TDirectory *dir, std::set< D3PD::ObjectMetadata > &objects)
 Function collecting the objects from a specific directory in a file. More...
 
std::vector< D3PD::ObjectMetadatamergeObjects (const std::set< D3PD::ObjectMetadata > &objects)
 Function mergint the objects of the same type. More...
 
int main ATLAS_NOT_THREAD_SAFE (int argc, char *argv[])
 A convenience declaration to save myself some typeing. More...
 

Function Documentation

◆ ATLAS_NOT_THREAD_SAFE()

int main ATLAS_NOT_THREAD_SAFE ( int  argc,
char *  argv[] 
)

A convenience declaration to save myself some typeing.

Definition at line 93 of file d3pdReadersFromFile.cxx.

93  {
94  // Let's disable the ROOT warnings:
96 
97  // Force the Gaudi MessageSvc into existence. This gets rid of the
98  // warnings from getMessageSvc().
99  SmartIF<IMessageSvc> msvc{Gaudi::svcLocator()->service("MessageSvc")};
100  if( !msvc ) {
101  REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR, "d3pdReadersFromFile" )
102  << "Couldn't set up the Gaudi message service";
103  return 255;
104  }
105 
106  //
107  // Construct the object describing all the command line parameters of the
108  // application:
109  //
110  po::options_description desc( PROGRAM_DESC );
111  desc.add_options()
112  ( "help,h", "Give some help with the program usage" )
113  ( "d3pd-files,f", po::value< std::vector< std::string > >()->multitoken(),
114  "Input D3PD file(s)" )
115  ( "event-class-name,n", po::value< std::string >()->default_value( "Event" ),
116  "Name for the D3PDReader event class" )
117  ( "output,o", po::value< std::string >()->default_value( "." ),
118  "Output directory for the generated source files" )
119  ( "verbosity,v", po::value< int >()->default_value( 3 ),
120  "Verbosity level of the application. (1:VERBOSE, 2:DEBUG, 3:INFO, ...)" );
121 
122  //
123  // Interpret the command line options provided by the user:
124  //
125  po::variables_map vm;
126  try {
127  po::store( po::parse_command_line( argc, argv, desc ), vm );
128  po::notify( vm );
129  } catch( const std::exception& ex ) {
130  REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR, "d3pdReadersFromFile" )
131  << "There was a problem with interpreting the command line options.";
132  REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR, "d3pdReadersFromFile" )
133  << "Message: " << ex.what();
134  return 255;
135  }
136 
137  //
138  // If the user asked for some help, let's print it:
139  //
140  if( vm.count( "help" ) ) {
141  std::cout << desc << std::endl;
142  return 0;
143  }
144 
145  //
146  // Set the verbosity level of the application:
147  //
148  msvc->setOutputLevel( vm[ "verbosity" ].as< int >() );
149 
150  //
151  // Greet the user, and print all the parameters that the application
152  // received:
153  //
154  std::cout << PROGRAM_GREETING << std::endl;
155 
156  // Extract the file name(s) from the command line arguments:
157  if( ! vm.count( "d3pd-files" ) ) {
158  REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR, "d3pdReadersFromFile" )
159  << "You have to specify at least one D3PD file!";
160  return 255;
161  }
162  const std::vector< std::string > file_names =
163  vm[ "d3pd-files" ].as< std::vector< std::string > >();
164  std::cout << " D3PD file(s): " << file_names << std::endl;
165 
166  // Get the event class name:
167  const std::string event_name = vm[ "event-class-name" ].as< std::string >();
168  std::cout << " Event class name: " << event_name << std::endl;
169 
170  // Get the output directory:
171  const std::string output = vm[ "output" ].as< std::string >();
172  std::cout << " Output directory: " << output << std::endl;
173 
174  //
175  // A list of all the objects collected from all the files:
176  //
177  std::set< D3PD::ObjectMetadata > objects;
178 
179  //
180  // Loop over the specified files:
181  //
182  std::vector< std::string >::const_iterator file_itr = file_names.begin();
183  std::vector< std::string >::const_iterator file_end = file_names.end();
184  for( ; file_itr != file_end; ++file_itr ) {
185 
186  // Try to open the D3PD file:
187  REPORT_MESSAGE_WITH_CONTEXT( MSG::INFO, "d3pdReadersFromFile" )
188  << "Reading file: " << *file_itr;
189  TFile* ifile = TFile::Open( file_itr->c_str(), "READ" );
190  if( ( ! ifile ) || ifile->IsZombie() ) {
191  REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR, "d3pdReadersFromFile" )
192  << "Failed to open D3PD file: " << *file_itr;
193  return 255;
194  }
195 
196  // Search for the metadata directories:
197  std::vector< std::string > metaDirectories;
198  const TList* keys = ifile->GetListOfKeys();
199  for( Int_t i = 0; i < keys->GetSize(); ++i ) {
200  const TKey* key = dynamic_cast< TKey* >( keys->At( i ) );
201  if (!key) continue;
202  std::string key_name = key->GetName();
203  if( ( key_name.find( "Meta" ) != key_name.npos ) &&
204  ( key->GetClassName() == std::string( "TDirectoryFile" ) ) ) {
205  metaDirectories.push_back( key_name );
206  }
207  }
208 
209  // Collect the objects from each of these directories:
210  std::vector< std::string >::const_iterator dir_itr = metaDirectories.begin();
211  std::vector< std::string >::const_iterator dir_end = metaDirectories.end();
212  for( ; dir_itr != dir_end; ++dir_itr ) {
213  // Try to access the directory:
214  TDirectory* dir = ifile->GetDirectory( dir_itr->c_str() );
215  if( ! dir ) {
216  REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR, "d3pdReadersFromFile" )
217  << "Failed to access directory: " << *dir_itr;
218  return 255;
219  }
220  // Collect the metadata from this directory:
221  if( collectObjects( dir, objects ).isFailure() ) {
222  REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR, "d3pdReadersFromFile" )
223  << "Failed to collect variable definitions from metadata directory: "
224  << *dir_itr;
225  return 255;
226  }
227  }
228 
229  // Close the input file:
230  ifile->Close();
231  delete ifile;
232  }
233 
234  //
235  // Merge the objects of the same type:
236  //
237  std::vector< D3PD::ObjectMetadata > merged_objects = mergeObjects( objects );
238  if( ! merged_objects.size() ) {
239  REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR, "d3pdReadersFromFile" )
240  << "Didn't find any metadata about the D3PD variables in the "
241  << "specified file(s)!";
242  return 255;
243  }
244 
245  //
246  // Generate the D3PDObjectBase class's source:
247  //
248  if( D3PD::Version2::writeD3PDObjectBase( output ).isFailure() ) {
249  REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR, "d3pdReadersFromFile" )
250  << "Couldn't create the D3PDObjectBase class source";
251  return 255;
252  }
253 
254  //
255  // Generate the VarHandle class's source:
256  //
257  if( D3PD::Version2::writeVarHandle( output ).isFailure() ) {
258  REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR, "d3pdReadersFromFile" )
259  << "Couldn't create the VarHandle class source";
260  return 255;
261  }
262 
263  //
264  // Generate the VarProxy class's source if needed:
265  //
266  if( D3PD::Version2::writeVarProxy( output ).isFailure() ) {
267  REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR, "d3pdReadersFromFile" )
268  << "Couldn't create the VarProxy class source";
269  return 255;
270  }
271 
272  //
273  // Generate the UserD3PDObject class's source:
274  //
275  if( D3PD::Version2::writeUserD3PDObject( output ).isFailure() ) {
276  REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR, "d3pdReadersFromFile" )
277  << "Couldn't create the UserD3PDObject class source";
278  return 255;
279  }
280 
281  //
282  // Generate the D3PDReadStats class's source:
283  //
284  if( D3PD::Version2::writeD3PDReadStats( output ).isFailure() ) {
285  REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR, "d3pdReadersFromFile" )
286  << "Couldn't create the D3PDReadStats class source";
287  return 255;
288  }
289 
290  //
291  // Generate the D3PDPerfStats class's source:
292  //
293  if( D3PD::Version2::writeD3PDPerfStats( output ).isFailure() ) {
294  REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR, "d3pdReadersFromFile" )
295  << "Couldn't create the D3PDPerfStats class source";
296  return 255;
297  }
298 
299  //
300  // Generate the Utils source:
301  //
302  if( D3PD::Version2::writeUtils( output ).isFailure() ) {
303  REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR, "d3pdReadersFromFile" )
304  << "Couldn't create the Utils source";
305  return 255;
306  }
307 
308  //
309  // Generate the sources for each object:
310  //
311  std::vector< D3PD::ObjectMetadata >::const_iterator obj_itr = merged_objects.begin();
312  std::vector< D3PD::ObjectMetadata >::const_iterator obj_end = merged_objects.end();
313  for( ; obj_itr != obj_end; ++obj_itr ) {
314 
315  //
316  // Generate the header of the D3PDReader class:
317  //
318  if( D3PD::Version2::writeHeader( obj_itr->name(), output,
319  *obj_itr ).isFailure() ) {
320  REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR, "d3pdReadersFromFile" )
321  << "Couldn't generate the D3PDReader class header";
322  return 255;
323  }
324 
325  //
326  // Generate the source of the D3PDReader class:
327  //
328  if( D3PD::Version2::writeSource( obj_itr->name(), output,
329  *obj_itr ).isFailure() ) {
330  REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR, "d3pdReadersFromFile" )
331  << "Couldn't generate the D3PDReader class source";
332  return 255;
333  }
334  }
335 
336  //
337  // Generate the "event class":
338  //
339  if( D3PD::Version2::writeEventHeader( event_name, output,
340  objects ).isFailure() ) {
341  REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR, "d3pdReadersFromFile" )
342  << "Couldn't generate the D3PDReader event class header";
343  return 255;
344  }
345  if( D3PD::Version2::writeEventSource( event_name, output,
346  objects ).isFailure() ) {
347  REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR, "d3pdReadersFromFile" )
348  << "Couldn't generate the D3PDReader event class source";
349  return 255;
350  }
351 
352  return 0;
353 }

◆ collectObjects()

StatusCode collectObjects ( TDirectory *  dir,
std::set< D3PD::ObjectMetadata > &  objects 
)

Function collecting the objects from a specific directory in a file.

This function is used to collect the metadata about D3PDObjects from one particular directory in one D3PD file.

Parameters
dirThe directory where metadata should be searched for
objectsThe global list of object metadata
Returns
StatusCode::SUCCESS if the operation was successful, StatusCode::FAILURE otherwise

Definition at line 364 of file d3pdReadersFromFile.cxx.

365  {
366 
367  // Find all the D3PDObject definitions in the directory:
368  const TList* keys = dir->GetListOfKeys();
369  for( Int_t i = 0; i < keys->GetSize(); ++i ) {
370 
371  // Look for D3PDObject definitions:
372  const TKey* key = dynamic_cast< TKey* >( keys->At( i ) );
373  if (!key) continue;
374  if( key->GetClassName() != std::string( "TObjString" ) ) continue;
375 
376  // Check whether it looks like object metadata:
377  if( ! D3PD::RootObjectMetadata::isObjectMetadata( key->GetName() ) ) {
378  continue;
379  }
380 
381  // The name of the D3PDObject:
382  const std::string objName = D3PD::ObjectMetadata::objectName( key->GetName() );
383 
384  REPORT_MESSAGE_WITH_CONTEXT( MSG::DEBUG, "d3pdReadersFromFile" )
385  << "Reading object '" << objName << "'";
386 
387  // Access the variable description:
388  TObjString* ostring =
389  dynamic_cast< TObjString* >( dir->Get( TString( key->GetName() ) + ";" +
390  TString::Format( "%hi", key->GetCycle() ) ) );
391  if( ! ostring ) {
392  REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR, "d3pdReadersFromFile" )
393  << "Couldn't access object: " << key->GetName() << ";"
394  << key->GetCycle();
395  return StatusCode::FAILURE;
396  }
397 
398  // Decode the metadata:
400  metadata.setName( objName );
401  if( metadata.read( ostring->GetString().Data() ).isFailure() ) {
402  REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR, "d3pdReadersFromFile" )
403  << "Couldn't collect variables from object: " << key->GetName();
404  return StatusCode::FAILURE;
405  }
406 
407  // Fix the variable names if they need fixing:
408  if( metadata.checkPrefixes().isFailure() ) {
409  REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR, "d3pdReadersFromFile" )
410  << "Couldn't fix prefixes in metadata object with name: "
411  << metadata.name();
412  return StatusCode::FAILURE;
413  }
414 
415  // Check if such an object has already been added:
417  objects.insert( metadata );
418  // If this object already existed, merge the two:
419  if( ! ret.second ) {
420  REPORT_MESSAGE_WITH_CONTEXT( MSG::DEBUG, "d3pdReadersFromFile" )
421  << "Merging objects with name '" << objName << "'";
422  D3PD::ObjectMetadata merged( *( ret.first ) );
423  merged.merge( metadata );
424  objects.erase( ret.first );
425  objects.insert( merged );
426  } else {
427  REPORT_MESSAGE_WITH_CONTEXT( MSG::DEBUG, "d3pdReadersFromFile" )
428  << "Added object with name '" << objName << "'";
429  }
430 
431  }
432 
433  return StatusCode::SUCCESS;
434 }

◆ mergeObjects()

std::vector< D3PD::ObjectMetadata > mergeObjects ( const std::set< D3PD::ObjectMetadata > &  objects)

Function mergint the objects of the same type.

This function is used to merge the objects of the same type on its input.

This practically means that objects that have the same "object name" get merged, irrespective of their prefix.

Parameters
objectsA set of independent D3PDObjects
Returns
A merged list of D3PDObjects

Definition at line 445 of file d3pdReadersFromFile.cxx.

445  {
446 
447  // Internal map for executing the merging:
448  std::map< std::string, D3PD::ObjectMetadata > tmp_result;
449 
450  // Merge the objects using the temporary map:
451  std::set< D3PD::ObjectMetadata >::const_iterator set_itr = objects.begin();
452  std::set< D3PD::ObjectMetadata >::const_iterator set_end = objects.end();
453  for( ; set_itr != set_end; ++set_itr ) {
454  tmp_result[ set_itr->name() ].setName( set_itr->name() );
455  tmp_result[ set_itr->name() ].setPrefix( set_itr->prefix() );
456  tmp_result[ set_itr->name() ].setContainer( set_itr->container() );
457  tmp_result[ set_itr->name() ].merge( *set_itr );
458  }
459 
460  // Copy the objects from the temporary map into the result vector:
461  std::vector< D3PD::ObjectMetadata > result;
462  std::map< std::string, D3PD::ObjectMetadata >::const_iterator map_itr =
463  tmp_result.begin();
464  std::map< std::string, D3PD::ObjectMetadata >::const_iterator map_end =
465  tmp_result.end();
466  for( ; map_itr != map_end; ++map_itr ) {
467  result.push_back( map_itr->second );
468  }
469 
470  return result;
471 }

◆ operator<<()

template<typename T >
std::ostream& operator<< ( std::ostream &  out,
const std::vector< T > &  vec 
)

Formatted printing for vector objects.

The code has to print a vector in at least one place. To make it easily readable in the code, I like to use such an output operator. It can be used for any kind of vector as long as the template type can also be printed with the << operator.

Parameters
outAn STL output stream
vecThe vector that should be printed
Returns
The same output stream that the operator received

Definition at line 68 of file d3pdReadersFromFile.cxx.

68  {
69  out << "[";
70  typename std::vector< T >::const_iterator itr = vec.begin();
71  typename std::vector< T >::const_iterator end = vec.end();
72  for( ; itr != end; ++itr ) {
73  out << *itr;
74  if( ++itr != end ) {
75  out << ", ";
76  }
77  --itr;
78  }
79  out << "]";
80  return out;
81 }
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
SGTest::store
TestStore store
Definition: TestStore.cxx:23
mergeObjects
std::vector< D3PD::ObjectMetadata > mergeObjects(const std::set< D3PD::ObjectMetadata > &objects)
Function mergint the objects of the same type.
Definition: d3pdReadersFromFile.cxx:445
D3PD::Version2::writeD3PDPerfStats
StatusCode writeD3PDPerfStats(const std::string &dir)
This function can be used to create the D3PDReader::D3PDPerfStats class's source files.
Definition: CodeGenerator_v2.cxx:528
D3PD::RootObjectMetadata::isObjectMetadata
static bool isObjectMetadata(const std::string &name)
Function guessing if an object with a given name is object metadata.
Definition: RootObjectMetadata.cxx:118
D3PD::Version2::writeUserD3PDObject
StatusCode writeUserD3PDObject(const std::string &dir)
This function can be used to create the D3PDReader::UserD3PDObject class's source files.
Definition: CodeGenerator_v2.cxx:411
D3PD::Version2::writeSource
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.
Definition: CodeGenerator_v2.cxx:967
get_generator_info.result
result
Definition: get_generator_info.py:21
LArConditions2Ntuple.objects
objects
Definition: LArConditions2Ntuple.py:59
D3PD::Version2::writeD3PDObjectBase
StatusCode writeD3PDObjectBase(const std::string &dir)
This function can be used to create the D3PDReader::D3PDObjectBase class's source files.
Definition: CodeGenerator_v2.cxx:265
StateLessPT_NewConfig.Format
Format
Definition: StateLessPT_NewConfig.py:146
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
athena.value
value
Definition: athena.py:124
D3PD::Version2::writeVarHandle
StatusCode writeVarHandle(const std::string &dir)
This function can be used to create the D3PDReader::VarHandle class's source files.
Definition: CodeGenerator_v2.cxx:298
vec
std::vector< size_t > vec
Definition: CombinationsGeneratorTest.cxx:12
D3PD::Version2::writeUtils
StatusCode writeUtils(const std::string &dir)
This function can be used to create source files containing some utility functions.
Definition: CodeGenerator_v2.cxx:577
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
D3PD::Version2::writeEventSource
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.
Definition: CodeGenerator_v2.cxx:2037
python.checkMetadata.metadata
metadata
Definition: checkMetadata.py:175
CaloCondBlobAlgs_fillNoiseFromASCII.desc
desc
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:54
lumiFormat.i
int i
Definition: lumiFormat.py:85
LArCellNtuple.argv
argv
Definition: LArCellNtuple.py:152
Analysis::kError
@ kError
Definition: CalibrationDataVariables.h:60
D3PD::ObjectMetadata::objectName
static std::string objectName(const std::string &metaName)
Get the D3PDObject's name from the name of the metadata object.
Definition: ObjectMetadata.cxx:213
calibdata.exception
exception
Definition: calibdata.py:496
collectObjects
StatusCode collectObjects(TDirectory *dir, std::set< D3PD::ObjectMetadata > &objects)
Function collecting the objects from a specific directory in a file.
Definition: d3pdReadersFromFile.cxx:364
DQHistogramMergeRegExp.argc
argc
Definition: DQHistogramMergeRegExp.py:20
D3PD::RootObjectMetadata
Extension of the ObjectMetadata class for reading D3PD files.
Definition: RootObjectMetadata.h:32
beamspotman.dir
string dir
Definition: beamspotman.py:623
merge.output
output
Definition: merge.py:17
REPORT_MESSAGE_WITH_CONTEXT
#define REPORT_MESSAGE_WITH_CONTEXT(LVL, CONTEXT_NAME)
Report a message, with an explicitly specified context name.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:345
D3PD::ObjectMetadata
D3PD variable metadata handling class.
Definition: ObjectMetadata.h:36
D3PD::Version2::writeD3PDReadStats
StatusCode writeD3PDReadStats(const std::string &dir)
This function can be used to create the D3PDReader::D3PDReadStats class's source files.
Definition: CodeGenerator_v2.cxx:478
gErrorIgnoreLevel
int gErrorIgnoreLevel
D3PD::Version2::writeEventHeader
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.
Definition: CodeGenerator_v2.cxx:1913
DEBUG
#define DEBUG
Definition: page_access.h:11
python.Bindings.keys
keys
Definition: Control/AthenaPython/python/Bindings.py:798
LArCellNtuple.ifile
string ifile
Definition: LArCellNtuple.py:133
D3PD::Version2::writeHeader
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.
Definition: CodeGenerator_v2.cxx:632
D3PD::Version2::writeVarProxy
StatusCode writeVarProxy(const std::string &dir)
This function can be used to create the D3PDReader::VarProxy class's source files.
Definition: CodeGenerator_v2.cxx:363
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37