ATLAS Offline Software
Control/xAODRootAccess/Root/TEvent.cxx
Go to the documentation of this file.
1 // Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
2 
3 // System include(s):
4 #include <cassert>
5 #include <sstream>
6 #include <iomanip>
7 #include <cstring>
8 
9 // ROOT include(s):
10 #include <TFile.h>
11 #include <TTree.h>
12 #include <TKey.h>
13 #include <TChain.h>
14 #include <TFriendElement.h>
15 #include <TChainElement.h>
16 #include <TBranch.h>
17 #include <TError.h>
18 #include <TMethodCall.h>
19 #include <TSystem.h>
20 
21 // Gaudi/Athena include(s):
28 #ifndef XAOD_STANDALONE
30 #endif // not XAOD_STANDALONE
32 
33 // Interface include(s):
35 
36 // xAOD include(s):
37 #include "xAODCore/tools/IOStats.h"
40 
41 // Local include(s):
42 #include "xAODRootAccess/TEvent.h"
45 #include "xAODRootAccess/TStore.h"
60 
61 namespace {
62 
68  void removeVersionNames( std::string& name ) {
69 
70  size_t pos = 0;
71  while( ( pos = name.find( "_v1" ) ) != name.npos ) {
72  name.erase( pos, 3 );
73  }
74  while( ( pos = name.find( "_v2" ) ) != name.npos ) {
75  name.erase( pos, 3 );
76  }
77  while( ( pos = name.find( "_v3" ) ) != name.npos ) {
78  name.erase( pos, 3 );
79  }
80  while( ( pos = name.find( "_v4" ) ) != name.npos ) {
81  name.erase( pos, 3 );
82  }
83  while( ( pos = name.find( "_v5" ) ) != name.npos ) {
84  name.erase( pos, 3 );
85  }
86  while( ( pos = name.find( "_v6" ) ) != name.npos ) {
87  name.erase( pos, 3 );
88  }
89  while( ( pos = name.find( "_v7" ) ) != name.npos ) {
90  name.erase( pos, 3 );
91  }
92  while( ( pos = name.find( "_v8" ) ) != name.npos ) {
93  name.erase( pos, 3 );
94  }
95 
96  return;
97  }
98 
101  class ForceTrackIndices : public SG::AuxVectorBase {
102  public:
104  }; // class ForceTrackIndices
105 
107  void forceTrackIndices NO_SANITIZE_UNDEFINED ( SG::AuxVectorBase& vec ) {
108  // Treat the received object like it would be of type @c ForceTrackIndices
109  ForceTrackIndices& xvec = static_cast< ForceTrackIndices& >( vec );
110  xvec.initAuxVectorBase< DataVector< SG::IAuxElement > >( SG::OWN_ELEMENTS,
112  return;
113  }
114 
115 } // private namespace
116 
117 namespace xAOD {
118 
119  //
120  // Initialise the static data:
121  //
122  const ::Int_t TEvent::CACHE_SIZE = -1;
123  const char* const TEvent::EVENT_TREE_NAME = "CollectionTree";
124  const char* const TEvent::METADATA_TREE_NAME = "MetaData";
125 
127  static const TEvent::EAuxMode DEFAULT_ACCESS_MODE = TEvent::kClassAccess;
129  static const TEvent::EAuxMode UNIT_TEST_ACCESS_MODE = TEvent::kAthenaAccess;
130 
132  : m_auxMode( mode ),
133  m_inTree( nullptr ), m_inTreeMissing( kFALSE ),
134  m_inChain( nullptr ), m_inChainTracker( nullptr ),
135  m_inTreeNumber( -1 ), m_inMetaTree( nullptr ),
136  m_entry( -1 ), m_outTree( nullptr ),
137  m_inputObjects(), m_inputMissingObjects(), m_outputObjects(),
138  m_inputMetaObjects(), m_outputMetaObjects(),
139  m_inputEventFormat(), m_outputEventFormat( nullptr ),
140  m_auxItemList(), m_listeners(), m_nameRemapping() {
141 
142  // Make sure that the I/O monitoring is active:
144 
145  // Make this the active event:
146  setActive();
147 
148  // If the user didn't ask for one particular access type, chose one
149  // based on the running environment:
150  if( m_auxMode == kUndefinedAccess ) {
151  if( gSystem->Getenv( "ROOTCORE_AUTO_UT" ) ||
152  gSystem->Getenv( "ROOTCORE_FAST_UT" ) ||
153  gSystem->Getenv( "ROOTCORE_SLOW_UT" ) ) {
154  ::Info( "xAOD::TEvent::TEvent",
155  "Using access mode \"%i\" for the unit test",
156  static_cast< int >( UNIT_TEST_ACCESS_MODE ) );
157  m_auxMode = UNIT_TEST_ACCESS_MODE;
158  } else {
159  m_auxMode = DEFAULT_ACCESS_MODE;
160  }
161  }
162  }
163 
165  : m_auxMode( mode ),
166  m_inTree( nullptr ), m_inTreeMissing( kFALSE ),
167  m_inChain( nullptr ), m_inChainTracker( nullptr ),
168  m_inTreeNumber( -1 ), m_inMetaTree( nullptr ),
169  m_entry( -1 ), m_outTree( nullptr ),
170  m_inputObjects(), m_inputMissingObjects(), m_outputObjects(),
171  m_inputMetaObjects(), m_outputMetaObjects(),
172  m_inputEventFormat(), m_outputEventFormat( nullptr ),
173  m_auxItemList(), m_listeners(), m_nameRemapping() {
174 
175  // Make sure that the I/O monitoring is active:
177 
178  // Make this the active event:
179  setActive();
180 
181  // If the user didn't ask for one particular access type, chose one
182  // based on the running environment:
183  if( m_auxMode == kUndefinedAccess ) {
184  if( gSystem->Getenv( "ROOTCORE_AUTO_UT" ) ||
185  gSystem->Getenv( "ROOTCORE_FAST_UT" ) ||
186  gSystem->Getenv( "ROOTCORE_SLOW_UT" ) ) {
187  ::Info( "xAOD::TEvent::TEvent",
188  "Using access mode \"%i\" for the unit test",
189  static_cast< int >( UNIT_TEST_ACCESS_MODE ) );
190  m_auxMode = UNIT_TEST_ACCESS_MODE;
191  } else {
192  m_auxMode = DEFAULT_ACCESS_MODE;
193  }
194  }
195 
196  // Let the initialisation function deal with setting up the object:
197  readFrom( file ).ignore();
198  }
199 
201  : m_auxMode( mode ),
202  m_inTree( nullptr ), m_inTreeMissing( kFALSE ),
203  m_inChain( nullptr ), m_inChainTracker( nullptr ),
204  m_inTreeNumber( -1 ), m_inMetaTree( nullptr ),
205  m_entry( -1 ), m_outTree( nullptr ),
206  m_inputObjects(), m_inputMissingObjects(), m_outputObjects(),
207  m_inputMetaObjects(), m_outputMetaObjects(),
208  m_inputEventFormat(), m_outputEventFormat( nullptr ),
209  m_auxItemList(), m_listeners(), m_nameRemapping() {
210 
211  // Make sure that the I/O monitoring is active:
213 
214  // Make this the active event:
215  setActive();
216 
217  // If the user didn't ask for one particular access type, chose one
218  // based on the running environment:
219  if( m_auxMode == kUndefinedAccess ) {
220  if( gSystem->Getenv( "ROOTCORE_AUTO_UT" ) ||
221  gSystem->Getenv( "ROOTCORE_FAST_UT" ) ||
222  gSystem->Getenv( "ROOTCORE_SLOW_UT" ) ) {
223  ::Info( "xAOD::TEvent::TEvent",
224  "Using access mode \"%i\" for the unit test",
225  static_cast< int >( UNIT_TEST_ACCESS_MODE ) );
226  m_auxMode = UNIT_TEST_ACCESS_MODE;
227  } else {
228  m_auxMode = DEFAULT_ACCESS_MODE;
229  }
230  }
231 
232  // Let the initialisation function deal with setting up the object:
233  readFrom( tree ).ignore();
234  }
235 
237 
238  Object_t::iterator itr = m_inputObjects.begin();
240  for( ; itr != end; ++itr ) {
241  delete itr->second;
242  }
243  itr = m_outputObjects.begin();
244  end = m_outputObjects.end();
245  for( ; itr != end; ++itr ) {
246  delete itr->second;
247  }
248  itr = m_inputMetaObjects.begin();
249  end = m_inputMetaObjects.end();
250  for( ; itr != end; ++itr ) {
251  delete itr->second;
252  }
253  itr = m_outputMetaObjects.begin();
254  end = m_outputMetaObjects.end();
255  for( ; itr != end; ++itr ) {
256  delete itr->second;
257  }
258 
259  if( m_inChainTracker ) {
260  delete m_inChainTracker;
261  }
262 
263  // If this is set up as the active event at the moment, notify
264  // the active event object that this object will no longer be
265  // available.
266  if( TActiveEvent::event() == this ) {
267  TActiveEvent::setEvent( nullptr );
268  }
269 #ifndef XAOD_STANDALONE
270  if( SG::CurrentEventStore::store() == this ) {
272  }
273 #endif // not XAOD_STANDALONE
274  }
275 
279 
280  return m_auxMode;
281  }
282 
292  std::string TEvent::dump() {
293 
294  // The internal stream object:
295  std::ostringstream ost;
296  ost << "<<<<<<<<<<<<<<<<<<<< xAOD::TEvent Dump >>>>>>>>>>>>>>>>>>>>\n";
297 
298  // Loop over the EventFormat object:
301  for( ; ef_itr != ef_end; ++ef_itr ) {
302 
303  // Construct the type name:
304  std::string typeName = ef_itr->second.className();
305  removeVersionNames( typeName );
306 
307  // Get the type:
308  ::TClass* cl =
309  ::TClass::GetClass( ef_itr->second.className().c_str() );
310  const std::type_info* ti = ( cl ? cl->GetTypeInfo() : nullptr );
311  if( ( ! cl ) || ( ! cl->IsLoaded() ) || ( ! ti ) ) {
312  Warning( "xAOD::TEvent::dump",
313  "Unknown type (%s) found in the event format",
314  ef_itr->second.className().c_str() );
315  continue;
316  }
317 
318  // Skip containers that are not available anyway:
319  if( ! contains( ef_itr->second.branchName(), *ti ) ) {
320  continue;
321  }
322 
323  // Do the printout:
324  ost << " Hash: 0x" << std::setw( 8 ) << std::setfill( '0' )
325  << std::hex << ef_itr->second.hash()
326  << " Key: \"" << ef_itr->second.branchName() << "\"\n";
327 
328  ost << " type: " << typeName << "\n";
329  const bool isNonConst = transientContains( ef_itr->second.branchName(),
330  *ti );
331  ost << " isConst: " << ( isNonConst ? "No" : "Yes" ) << "\n";
332  ost << " Data: "
333  << ( isNonConst ? getOutputObject( ef_itr->second.branchName(),
334  *ti ) :
335  getInputObject( ef_itr->second.branchName(), *ti ) ) << "\n";
336  }
337 
338  // Finish with the construction:
339  ost << "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>";
340  return ost.str();
341  }
342 
347  void TEvent::printIOStats() const {
348 
349  // Simply do this via the xAODCore code:
350  IOStats::instance().stats().Print( "Summary" );
351 
352  return;
353  }
354 
364  StatusCode TEvent::readFrom( ::TFile* file, Bool_t useTreeCache,
365  const char* treeName ) {
366 
367  // If no file was specified, return gracefully:
368  if( ! file ) return StatusCode::SUCCESS;
369 
370  // Clear the cached input objects:
371  Object_t::iterator itr = m_inputObjects.begin();
373  for( ; itr != end; ++itr ) {
374  delete itr->second;
375  }
376  m_inputObjects.clear();
377  m_inputMissingObjects.clear();
378  {
380  lock.upgrade();
381  m_branches.clear();
382  }
383 
384  // Clear the cached input meta-objects:
385  itr = m_inputMetaObjects.begin();
386  end = m_inputMetaObjects.end();
387  for( ; itr != end; ++itr ) {
388  delete itr->second;
389  }
390  m_inputMetaObjects.clear();
391 
392  // Reset the internal flags:
393  m_inTreeMissing = kFALSE;
394  m_entry = -1;
395 
396  // Make sure we return to the current directory:
398 
399  // Set up the file access tracer:
400  static TFileAccessTracer tracer ATLAS_THREAD_SAFE;
401  tracer.add( *file );
402 
403  // Look for the metadata tree:
404  m_inMetaTree =
405  dynamic_cast< ::TTree* >( file->Get( METADATA_TREE_NAME ) );
406  if( ! m_inMetaTree ) {
407  ::Error( "xAOD::TEvent::readFrom",
408  XAOD_MESSAGE( "Couldn't find metadata tree on input. Object "
409  "unusable!" ) );
410  return StatusCode::FAILURE;
411  }
412 
413  // Set metadata entry to be read
414  // NB: no reading is done calling LoadTree
415  if ( m_inMetaTree->LoadTree(0) < 0 ){
416  ::Error( "xAOD::TEvent::readFrom",
417  XAOD_MESSAGE( "Failed to load entry for metadata tree=%s" ),
418  m_inMetaTree->GetName() );
419  return StatusCode::FAILURE;
420  }
421 
422  // A sanity check:
423  if( m_inMetaTree->GetEntries() != 1 ) {
424  ::Info( "xAOD::TEvent::readFrom",
425  "Was expecting a metadata tree with size 1, instead of %i.",
426  static_cast< int >( m_inMetaTree->GetEntries() ) );
427  ::Info( "xAOD::TEvent::readFrom",
428  "File most probably produced by hadd..." );
429  }
430 
431  // Make sure that the xAOD::EventFormat dictonary is loaded.
432  // This may not be the case if streamer information reading is turned
433  // off.
434  static const std::string eventFormatTypeName =
435  Utils::getTypeName( typeid( EventFormat ) );
436  ::TClass* cl = ::TClass::GetClass( eventFormatTypeName.c_str() );
437  if( ! cl ) {
438  ::Warning( "xAOD::TEvent::readFrom",
439  "Couldn't load the EventFormat dictionary" );
440  }
441 
442  // Check if the EventFormat branch is available:
443  const std::string eventFormatBranchName =
444  Utils::getFirstBranchMatch( m_inMetaTree, "EventFormat");
445  if( ! m_inMetaTree->GetBranch( eventFormatBranchName.c_str() ) ) {
446  // This can happen when the file was produced by an Athena job that
447  // didn't have any input events itself. This means that the file
448  // doesn't actually have any useful metadata.
449  ::Info( "xAOD::TEvent::readFrom", "Input file provides no event or "
450  "metadata" );
451  m_inTree = 0;
452  m_inTreeMissing = kTRUE;
453  return StatusCode::SUCCESS;
454  }
455 
456  // Read in the event format object:
457  EventFormat* format = 0; ::TBranch* br = 0;
458  const Int_t status =
459  m_inMetaTree->SetBranchAddress( eventFormatBranchName.c_str(),
460  &format, &br );
461  if( status < 0 ) {
462  ::Error( "xAOD::TEvent::readFrom",
463  XAOD_MESSAGE( "Failed to connect to EventFormat object" ) );
464  return StatusCode::FAILURE;
465  }
466 
467  // Read in the object to our private member:
468  br->GetEntry( 0 );
470 
471  // This is a strange place. The object has to be deleted, as it is the
472  // responsibility of the user code to do so. But if I also explicitly
473  // tell the branch to forget about the address of the pointer, then
474  // all hell breaks loose...
475  delete format;
476 
477 
478  // List all the other Metadata trees in the input file
479  // Having several metatrees can happen for augmented files for instance
480  // as one metadata tree per stream is produced
481  std::set<std::string> lOtherMetaTreeNames = {};
482  TList *lKeys = file->GetListOfKeys();
483 
484  if (lKeys){
485  for (int iKey = 0; iKey < lKeys->GetEntries() ; iKey++){
486  // iterate over keys and add
487  std::string keyName = lKeys->At(iKey)->GetName();
488  // Make sure the key corresponds to a metadata tree but
489  // do not add the current metadata tree in the list of other trees
490  // and do not add the metadata tree handlers to the list
491  if ( (keyName != METADATA_TREE_NAME)
492  && (keyName.find("MetaData") != std::string::npos)
493  && !(keyName.find("MetaDataHdr") != std::string::npos)){
494  // Make sure key corresponds to a tree
495  const char *className = ((::TKey*)lKeys->At(iKey))->GetClassName();
496  static constexpr Bool_t LOAD = kFALSE;
497  static constexpr Bool_t SILENT = kTRUE;
498  ::TClass* cl = ::TClass::GetClass(className, LOAD, SILENT);
499  if ((cl != nullptr) && cl->InheritsFrom(::TTree::Class())){
500  // key is corresponding to a metadata tree
501  lOtherMetaTreeNames.insert(keyName);
502  }
503  }
504  }
505  }
506 
507  // Loop over the other metadata trees found (if any)
508  for (const std::string & metaTreeName : lOtherMetaTreeNames){
509  TTree *tmpMetaTree = dynamic_cast< ::TTree* >( file->Get( metaTreeName.c_str() ) );
510 
511  if (!tmpMetaTree){
512  // Skip tree if could not read it
513  ::Warning( "xAOD::TEvent::readFrom", "Could not read metadata tree=%s",metaTreeName.c_str());
514  continue;
515  }
516 
517  // Set metadata entry to be read
518  // NB: no reading is done calling LoadTree
519  if ( tmpMetaTree->LoadTree(0) < 0 ){
520  ::Error( "xAOD::TEvent::readFrom",
521  XAOD_MESSAGE( "Failed to load entry for metadata tree=%s" ),
522  tmpMetaTree->GetName() );
523  return StatusCode::FAILURE;
524  }
525 
526  // Check if the EventFormat branch is available:
527  const std::string tmpEventFormatBranchName =
528  Utils::getFirstBranchMatch( tmpMetaTree, "EventFormat");
529  if( ! tmpMetaTree->GetBranch( tmpEventFormatBranchName.c_str() ) ) {
530  // skip the additionnal metadata tree
531  ::Warning( "xAOD::TEvent::readFrom", "No EventFormat branch found in metadata tree=%s",tmpMetaTree->GetName() );
532  continue ;
533  }
534  // Read in the event format object:
535  EventFormat* tmpFormat = 0; ::TBranch* tmpBr = 0;
536  const Int_t status =
537  tmpMetaTree->SetBranchAddress( tmpEventFormatBranchName.c_str(),
538  &tmpFormat, &tmpBr );
539  if( status < 0 ) {
540  ::Error( "xAOD::TEvent::readFrom",
541  XAOD_MESSAGE( "Failed to connect to EventFormat object for metadata tree = %s"), tmpMetaTree->GetName() );
542  return StatusCode::FAILURE;
543  }
544  // Read in the object
545  tmpBr->GetEntry( 0 );
546  // read all objects contained in the event format
547  for (const std::pair<const std::string, xAOD::EventFormatElement> &evtElem : *tmpFormat){
548  // if element is not existing
549  // then add it to the private event format member
550  if (!m_inputEventFormat.exists(evtElem.first)){
551  m_inputEventFormat.add(evtElem.second);
552  }
553  }
554  delete tmpFormat;
555  }
556 
557  // Look for the event tree in the input file:
558  m_inTree = dynamic_cast< ::TTree* >( file->Get( treeName ) );
559  if( ! m_inTree ) {
560  // This is no longer an error condition. As it can happen for DxAODs
561  // that don't have any events in them. But they still have metadata
562  // that needs to be collected.
563  m_inTreeMissing = kTRUE;
564  }
565 
566  // Turn on the cache if requested:
567  if( m_inTree && useTreeCache && ( ! m_inTree->GetCacheSize() ) ) {
568  m_inTree->SetCacheSize( CACHE_SIZE );
569  m_inTree->SetCacheLearnEntries( 10 );
570  }
571 
572  // Init the statistics collection:
573  RETURN_CHECK( "xAOD::TEvent::readFrom", initStats() );
574  // Update the event counter in the statistics object:
576  if( m_inTree ) {
577  stats.setNEvents( stats.nEvents() + m_inTree->GetEntries() );
578  }
579 
580  // Notify the listeners that a new file was opened:
581  const TIncident beginIncident( IncidentType::BeginInputFile );
582  for( TVirtualIncidentListener* listener : m_listeners ) {
583  listener->handle( beginIncident );
584  }
585  // For now implement a very simple scheme in which we claim already
586  // at the start that the entire file was processed. Since we have no way
587  // of ensuring that the user indeed does this. And we can't delay calling
588  // this function, as the user may likely close his/her output file before
589  // closing the last opened input file.
590  const TIncident endIncident( IncidentType::EndInputFile );
591  for( TVirtualIncidentListener* listener : m_listeners ) {
592  listener->handle( endIncident );
593  }
594 
595  // The initialisation was successful:
596  return StatusCode::SUCCESS;
597  }
598 
607  StatusCode TEvent::readFrom( ::TTree* tree, Bool_t useTreeCache ) {
608 
609  // Remember the info:
610  m_inTree = 0;
611  m_inTreeMissing = kFALSE;
612  m_inChain = dynamic_cast< ::TChain* >( tree );
613  m_inMetaTree = 0;
614 
615  if( m_inChain ) {
616 
617  // Set up the caching on the chain level. The individual trees of the
618  // input files will get a cache set up automatically after this.
619  if( useTreeCache && ( ! m_inChain->GetCacheSize() ) ) {
620  m_inChain->SetCacheSize( CACHE_SIZE );
621  m_inChain->SetCacheLearnEntries( 10 );
622  }
623 
624  // Explicitly open the first file of the chain. To correctly auto-load
625  // the dictionaries necessary. This doesn't happen automatically with
626  // some ROOT versions...
627  const TObjArray* files = m_inChain->GetListOfFiles();
628  if( ! files ) {
629  ::Error( "xAOD::TEvent::readFrom",
630  XAOD_MESSAGE( "Couldn't get the list of files from the "
631  "input TChain" ) );
632  return StatusCode::FAILURE;
633  }
634  if( ! files->GetEntries() ) {
635  ::Error( "xAOD::TEvent::readFrom",
636  XAOD_MESSAGE( "No files are present in the received "
637  "TChain" ) );
638  return StatusCode::FAILURE;
639  }
640  const ::TChainElement* chEl =
641  dynamic_cast< const ::TChainElement* >( files->At( 0 ) );
642  if( ! chEl ) {
643  ::Error( "xAOD::TEvent::readFrom",
644  XAOD_MESSAGE( "Couldn't cast object to TChainElement" ) );
645  return StatusCode::FAILURE;
646  }
647  ::TFile* dummyFile = ::TFile::Open( chEl->GetTitle() );
648  if( ! dummyFile ) {
649  ::Error( "xAOD::TEvent::readFrom",
650  XAOD_MESSAGE( "Couldn't open file %s" ),
651  chEl->GetTitle() );
652  return StatusCode::FAILURE;
653  }
654  delete dummyFile;
655 
656  // Set up a tracker for the chain:
657  if( ! m_inChainTracker ) {
659  }
661  tree->SetNotify( m_inChainTracker );
662 
663  // Stop at this point. The first file will be opened when the user
664  // asks for the first event. Otherwise we open the first file of the
665  // chain multiple times.
666  m_inTreeNumber = -1;
667  return StatusCode::SUCCESS;
668 
669  } else {
670 
671  // If it's a simple TTree, then let's fully initialise the object
672  // using its file:
673  m_inTreeNumber = -1;
674  if( m_inChainTracker ) {
675  delete m_inChainTracker;
676  m_inChainTracker = 0;
677  }
678  ::TFile* file = tree->GetCurrentFile();
679  return readFrom( file, useTreeCache, tree->GetName() );
680 
681  }
682  }
683 
692  StatusCode TEvent::writeTo( ::TFile* file, Int_t autoFlush,
693  const char* treeName ) {
694 
695  // Just a simple security check:
696  if( ! file ) {
697  ::Error( "xAOD::TEvent::writeTo",
698  XAOD_MESSAGE( "Null pointer given to the function!" ) );
699  return StatusCode::FAILURE;
700  }
701 
702  // Check that the object is in the "right state":
703  if( m_outTree ) {
704  ::Error( "xAOD::TEvent::writeTo",
705  XAOD_MESSAGE( "Object already writing to a file. Close that "
706  "file first!" ) );
707  return StatusCode::FAILURE;
708  }
709 
710  // Make sure we return to the current directory:
712 
713  // Create the output TTree:
714  file->cd();
715  m_outTree = new ::TTree( treeName, "xAOD event tree" );
716  m_outTree->SetDirectory( file );
717  m_outTree->SetAutoSave( 1000000 );
718  m_outTree->SetAutoFlush( autoFlush );
719 
720  // Access the EventFormat object associated with this file:
723 
724  // Return gracefully:
725  return StatusCode::SUCCESS;
726  }
727 
735 
736  // A small sanity check:
737  if( ! m_outTree ) {
738  ::Error( "xAOD::TEvent::finishWritingTo",
739  XAOD_MESSAGE( "The object doesn't seem to be connected to an "
740  "output file!" ) );
741  return StatusCode::FAILURE;
742  }
743 
744  // Make sure we return to the current directory:
746 
747  // Notify the listeners that they should write out their metadata, if they
748  // have any.
749  const TIncident incident( IncidentType::MetaDataStop );
750  Listener_t::iterator l_itr = m_listeners.begin();
751  Listener_t::iterator l_end = m_listeners.end();
752  for( ; l_itr != l_end; ++l_itr ) {
753  ( *l_itr )->handle( incident );
754  }
755 
756  // Write out the event tree, and delete it:
757  m_outTree->AutoSave( "FlushBaskets" );
758  m_outTree->SetDirectory( 0 );
759  delete m_outTree;
760  m_outTree = 0;
761 
762  // Now go to the output file:
763  file->cd();
764 
765  // Check if there's already a metadata tree in the output:
766  if( file->Get( METADATA_TREE_NAME ) ) {
767  // Let's assume that the metadata is complete in the file already.
768  return StatusCode::SUCCESS;
769  }
770 
771  // Create the metadata tree:
772  ::TTree* metatree =
773  new ::TTree( METADATA_TREE_NAME, "xAOD metadata tree" );
774  metatree->SetAutoSave( 10000 );
775  metatree->SetAutoFlush( -30000000 );
776  metatree->SetDirectory( file );
777 
778  // Create the only branch in it:
779  metatree->Branch( "EventFormat",
780  SG::normalizedTypeinfoName( typeid( xAOD::EventFormat ) ).c_str(),
782 
783  // Create a copy of the m_outputMetaObjects variable. This is necessary
784  // because the putAux(...) function will modify this variable while we
785  // loop over it.
786  Object_t outputMetaObjects = m_outputMetaObjects;
787 
788  // Now loop over all the metadata objects that need to be put into the
789  // output file:
790  for( auto& object : outputMetaObjects ) {
791  // All metadata objects should be held by TObjectManager objects.
792  // Anything else is an error.
793  TObjectManager* mgr = dynamic_cast< TObjectManager* >( object.second );
794  if( ! mgr ) {
795  ::Error( "xAOD::TEvent::finishWritingTo",
796  XAOD_MESSAGE( "Internal logic error detected" ) );
797  return StatusCode::FAILURE;
798  }
799  // Select a split level depending on whether this is an interface or an
800  // auxiliary object:
801  const ::Int_t splitLevel = ( object.first.find( "Aux." ) ==
802  ( object.first.size() - 4 ) ? 1 : 0 );
803  // Create the new branch:
804  *( mgr->branchPtr() ) =
805  metatree->Branch( object.first.c_str(),
806  mgr->holder()->getClass()->GetName(),
807  mgr->holder()->getPtr(), 32000, splitLevel );
808  if( ! mgr->branch() ) {
809  ::Error( "xAOD::TEvent::finishWritingTo",
810  XAOD_MESSAGE( "Failed to create metadata branch "
811  "\"%s/%s\"" ),
812  mgr->holder()->getClass()->GetName(),
813  object.first.c_str() );
814  return StatusCode::FAILURE;
815  }
816  // Set up the saving of all the dynamic auxiliary properties
817  // of the object if it has any:
818  RETURN_CHECK( "xAOD::TEvent::finishWritingTo",
819  putAux( *metatree, *( object.second ), 32000, 0,
820  kTRUE ) );
821  }
822 
823  // Write the metadata objects:
824  if( metatree->Fill() <= 0 ) {
825  ::Error( "xAOD::TEvent::finishWritingTo",
826  XAOD_MESSAGE( "Failed to write event format metadata into "
827  "the output" ) );
828  metatree->SetDirectory( 0 );
829  delete metatree;
830  return StatusCode::FAILURE;
831  }
832 
833  // Now clean up:
834  metatree->Write();
835  metatree->SetDirectory( 0 );
836  delete metatree;
838  Object_t::iterator obj_itr = m_outputObjects.begin();
839  Object_t::iterator obj_end = m_outputObjects.end();
840  for( ; obj_itr != obj_end; ++obj_itr ) {
841  delete obj_itr->second;
842  }
843  m_outputObjects.clear();
844  obj_itr = m_outputMetaObjects.begin();
845  obj_end = m_outputMetaObjects.end();
846  for( ; obj_itr != obj_end; ++obj_itr ) {
847  delete obj_itr->second;
848  }
849  m_outputMetaObjects.clear();
850 
851  // Return gracefully:
852  return StatusCode::SUCCESS;
853  }
854 
860  void TEvent::setActive() const {
861 
862  // The active event and current store are thread-local globals:
863  TEvent* nc_this ATLAS_THREAD_SAFE = const_cast<TEvent*>(this);
864 
865  TActiveEvent::setEvent( static_cast<TVirtualEvent*>( nc_this ) );
866 
867 #ifndef XAOD_STANDALONE
869 #endif // not XAOD_STANDALONE
870 
871  // Return gracefully:
872  return;
873  }
874 
882  void TEvent::setAuxItemList( const std::string& containerKey,
883  const std::string& itemList ) {
884 
885  // Decoded attributes:
886  std::set< std::string > attributes;
887 
888  // Split up the received string using "." as the separator:
889  if( itemList.size() ) {
890  std::stringstream ss( itemList );
891  std::string attr;
892  while( std::getline( ss, attr, '.' ) ) {
893  attributes.insert( attr );
894  }
895  }
896 
897  // Remember the setting:
898  m_auxItemList[ containerKey ] = attributes;
899 
900  return;
901  }
902 
911 
912  // Check that we received a valid pointer:
913  if( ! listener ) {
914  ::Error( "xAOD::TEvent::addListener",
915  XAOD_MESSAGE( "Received a null pointer for the listener" ) );
916  return StatusCode::FAILURE;
917  }
918 
919  // Check if this listener is already in our list:
920  bool listenerKnown = false;
922  if( l == listener ) {
923  ::Warning( "xAOD::TEvent::addListener",
924  "Listener %p was added previously already",
925  static_cast< void* >( listener ) );
926  listenerKnown = true;
927  break;
928  }
929  }
930 
931  // If we don't know it yet, let's add it now:
932  if( ! listenerKnown ) {
933  m_listeners.push_back( listener );
934  }
935 
936  // Return gracefully:
937  return StatusCode::SUCCESS;
938  }
939 
947 
948  // Find the pointer if we can...
950  m_listeners.end(), listener );
951 
952  // If we didn't find it:
953  if( itr == m_listeners.end() ) {
954  ::Error( "xAOD::TEvent::removeListener",
955  XAOD_MESSAGE( "Listener %p not known" ),
956  static_cast< void* >( listener ) );
957  return StatusCode::FAILURE;
958  }
959 
960  // Remove it:
961  m_listeners.erase( itr );
962 
963  // Return gracefully:
964  return StatusCode::SUCCESS;
965  }
966 
971 
972  m_listeners.clear();
973  return;
974  }
975 
990  StatusCode TEvent::addNameRemap( const std::string& onfile,
991  const std::string& newName ) {
992 
993  // Check if this name is known on the input or output already. As that's
994  // not good.
996  ::Error( "xAOD::TEvent::addNameRemap",
997  XAOD_MESSAGE( "Can't use \"%s\" as the target name in the"
998  "\"%s\" -> \"%s\" remapping" ),
999  newName.c_str(), onfile.c_str(), newName.c_str() );
1000  return StatusCode::FAILURE;
1001  }
1002 
1003  // Check if this name was remapped to something already:
1004  auto itr = m_nameRemapping.find( newName );
1005  if( itr != m_nameRemapping.end() ) {
1006  ::Warning( "xAOD::TEvent::addNameRemap",
1007  "Overriding existing name remapping \"%s\" -> \"%s\"",
1008  itr->second.c_str(), itr->first.c_str() );
1009  ::Warning( "xAOD::TEvent::addNameRemap", " with: \"%s\" -> \"%s\"",
1010  onfile.c_str(), newName.c_str() );
1011  }
1012 
1014  m_nameRemapping[ newName ] = onfile;
1015 
1016  // Return gracefully:
1017  return StatusCode::SUCCESS;
1018  }
1019 
1025 
1026  m_nameRemapping.clear();
1027  return;
1028  }
1029 
1033  void TEvent::printNameRemap() const {
1034 
1035  // Print a header:
1036  ::Info( "xAOD::TEvent::printNameRemap", "Name remapping rules:" );
1037 
1038  // In case no remapping rules have been set:
1039  if( ! m_nameRemapping.size() ) {
1040  ::Info( "xAOD::TEvent::printNameRemap", " NONE" );
1041  return;
1042  }
1043 
1044  // Otherwise:
1045  for( auto itr = m_nameRemapping.begin(); itr != m_nameRemapping.end();
1046  ++itr ) {
1047  ::Info( "xAOD::TEvent::printNameRemap", " \"%s\" -> \"%s\"",
1048  itr->second.c_str(), itr->first.c_str() );
1049  }
1050 
1051  // Return gracefully:
1052  return;
1053  }
1054 
1066  SG::IAuxStore* TEvent::recordAux( const std::string& key,
1068  ::Int_t basketSize, ::Int_t splitLevel ) {
1069 
1070  // A sanity check:
1071  if( ! m_outTree ) {
1072  ::Error( "xAOD::TEvent::recordAux",
1073  XAOD_MESSAGE( "No output tree given to the object" ) );
1074  return 0;
1075  }
1076 
1077  // Check for an object with this name in the output list:
1078  Object_t::iterator itr = m_outputObjects.find( key );
1079  if( itr == m_outputObjects.end() ) {
1080  // Create one if if it doesn't exist yet...
1081  // Translate the store type:
1083  switch( type ) {
1086  break;
1089  break;
1090  default:
1091  ::Error( "xAOD::TEvent::recordAux",
1092  XAOD_MESSAGE( "Unknown store type (%i) requested" ),
1093  static_cast< int >( type ) );
1094  return 0;
1095  }
1096  // Create and record the object:
1097  TAuxStore* store = new TAuxStore( key.c_str(), kTRUE, mode,
1098  basketSize, splitLevel );
1099  if( record( store, key, basketSize, splitLevel, kTRUE ).isFailure() ) {
1100  ::Error( "xAOD::TEvent::recordAux",
1101  XAOD_MESSAGE( "Couldn't connect TAuxStore object to the "
1102  "output" ) );
1103  delete store;
1104  return 0;
1105  }
1106  // Update the iterator:
1107  itr = m_outputObjects.find( key );
1108  }
1109 
1110  // A security check:
1111  if( itr == m_outputObjects.end() ) {
1112  ::Error( "xAOD::TEvent::recordAux",
1113  XAOD_MESSAGE( "Internal logic error detected" ) );
1114  return 0;
1115  }
1116 
1117  // Check that it is of the right type:
1118  TAuxManager* mgr = dynamic_cast< TAuxManager* >( itr->second );
1119  if( ! mgr ) {
1120  ::Error( "xAOD::TEvent::recordAux",
1121  XAOD_MESSAGE( "Object of non-TAuxStore type registered "
1122  "with key \"%s\"" ), key.c_str() );
1123  return 0;
1124  }
1125 
1126  // Extract the pointer out of it:
1127  TAuxStore* store = mgr->getStore();
1128 
1129  // Give it to the user:
1130  return store;
1131  }
1132 
1143  StatusCode TEvent::copy( const std::string& key,
1144  ::Int_t basketSize, ::Int_t splitLevel ) {
1145 
1146  // Check if a name re-mapping should be applied or not:
1147  std::string keyToUse = key;
1148  auto remap_itr = m_nameRemapping.find( key );
1149  if( ( remap_itr != m_nameRemapping.end() ) &&
1150  ( ! m_inputEventFormat.exists( key ) ) &&
1151  m_inputEventFormat.exists( remap_itr->second ) ) {
1152  keyToUse = remap_itr->second;
1153  }
1154 
1155  // Make sure that the branch got connected to:
1156  RETURN_CHECK( "xAOD::TEvent::copy", connectBranch( keyToUse ) );
1157 
1158  // Make sure that the input object is properly updated:
1159  Object_t::const_iterator vobjMgr = m_inputObjects.find( keyToUse );
1160  if( vobjMgr == m_inputObjects.end() ) {
1161  ::Error( "xAOD::TEvent::copy",
1162  XAOD_MESSAGE( "Internal logic error detected" ) );
1163  return StatusCode::FAILURE;
1164  }
1165  TObjectManager* objMgr =
1166  dynamic_cast< TObjectManager* >( vobjMgr->second );
1167  if( ! objMgr ) {
1168  ::Error( "xAOD::TEvent::copy",
1169  XAOD_MESSAGE( "Internal logic error detected" ) );
1170  return StatusCode::FAILURE;
1171  }
1172  if( ! getInputObject( key,
1173  *( objMgr->holder()->getClass()->GetTypeInfo() ) ) ) {
1174  ::Error( "xAOD::TEvent::copy",
1175  XAOD_MESSAGE( "Internal logic error detected" ) );
1176  return StatusCode::FAILURE;
1177  }
1178 
1179  // Put the interface object into the output:
1180  RETURN_CHECK( "xAOD::TEvent::copy",
1181  record( objMgr->object(),
1182  objMgr->holder()->getClass()->GetName(),
1183  key, basketSize, splitLevel, kTRUE ) );
1184 
1185  // Check if we have a filtering rule for the store:
1186  const std::set< std::string >* filter = 0;
1187  auto fitr = m_auxItemList.find( key + "Aux." );
1188  if( fitr != m_auxItemList.end() ) {
1189  filter = &( fitr->second );
1190  }
1191 
1192  // Put the auxiliary store object into the output:
1193  Object_t::const_iterator vauxMgr = m_inputObjects.find( keyToUse +
1194  "Aux." );
1195  if( vauxMgr == m_inputObjects.end() ) {
1196  // If there is no auxiliary store for this object/container, we're
1197  // done already:
1198  return StatusCode::SUCCESS;
1199  }
1200  // Check what type of auxiliary store this is:
1202  TObjectManager* auxMgr =
1203  dynamic_cast< TObjectManager* >( vauxMgr->second );
1204  if( ! auxMgr ) {
1205  ::Error( "xAOD::TEvent::copy",
1206  XAOD_MESSAGE( "Internal logic error detected" ) );
1207  return StatusCode::FAILURE;
1208  }
1209  RETURN_CHECK( "xAOD::TEvent::copy",
1210  record( auxMgr->object(),
1211  auxMgr->holder()->getClass()->GetName(),
1212  key + "Aux.", basketSize, splitLevel, kTRUE ) );
1213  } else if( m_auxMode == kBranchAccess ) {
1214  TAuxManager* auxMgr =
1215  dynamic_cast< TAuxManager* >( vauxMgr->second );
1216  if( ! auxMgr ) {
1217  ::Error( "xAOD::TEvent::copy",
1218  XAOD_MESSAGE( "Internal logic error detected" ) );
1219  return StatusCode::FAILURE;
1220  }
1221  // Set up the filtering:
1222  if( filter ) {
1223  auxMgr->getStore()->selectAux( *filter );
1224  }
1225  RETURN_CHECK( "xAOD::TEvent::copy",
1226  record( auxMgr->getStore(),
1227  key + "Aux.", basketSize, splitLevel ) );
1228  } else {
1229  ::Fatal( "xAOD::TEvent::copy",
1230  XAOD_MESSAGE( "Internal logic error detected" ) );
1231  }
1232 
1233  // Return gracefully:
1234  return StatusCode::SUCCESS;
1235  }
1236 
1246  StatusCode TEvent::copy( ::Int_t basketSize, ::Int_t splitLevel ) {
1247 
1248  // Make sure that an input TTree is available:
1249  if( ! m_inTree ) {
1250  ::Error( "xAOD::TEvent::copy",
1251  XAOD_MESSAGE( "No input TTree is open" ) );
1252  return StatusCode::FAILURE;
1253  }
1254 
1255  // Loop over the known input containers:
1258  for( ; itr != end; ++itr ) {
1259 
1260  // Convenience reference:
1261  const EventFormatElement& efe = itr->second;
1262 
1263  // Ignore objects that don't exist on the input:
1264  if( ! m_inTree->GetBranch( efe.branchName().c_str() ) ) {
1265  continue;
1266  }
1267  // Skip all branches ending in "Aux.":
1268  if( efe.branchName().find( "Aux." ) ==
1269  ( efe.branchName().size() - 4 ) ) {
1270  continue;
1271  }
1272  // Also skip dynamic branches:
1273  if( efe.parentName() != "" ) {
1274  continue;
1275  }
1276  // Check if the class in question is known:
1277  ::TClass* cl = ::TClass::GetClass( efe.className().c_str() );
1278  if( ( ! cl ) || ( ! cl->IsLoaded() ) ) {
1279  continue;
1280  }
1281 
1282  // Make the copy then...
1283  RETURN_CHECK( "xAOD::TEvent::copy",
1284  this->copy( efe.branchName(), basketSize, splitLevel ) );
1285  }
1286 
1287  // Return gracefully:
1288  return StatusCode::SUCCESS;
1289  }
1290 
1293  ::Long64_t TEvent::getEntries() const {
1294 
1295  if( m_inChain ) {
1296  return m_inChain->GetEntries();
1297  } else if( m_inTree ) {
1298  return m_inTree->GetEntries();
1299  } else if( m_inTreeMissing ) {
1300  // The input file is empty:
1301  return 0;
1302  } else {
1303  ::Error( "xAOD::TEvent::getEntries",
1304  XAOD_MESSAGE( "Function called on an uninitialised "
1305  "object" ) );
1306  return 0;
1307  }
1308  }
1309 
1324  ::Int_t TEvent::getEntry( ::Long64_t entry, ::Int_t getall ) {
1325 
1326  // A little sanity check:
1327  if( ( ! m_inTree ) && ( ! m_inChain ) ) {
1328  ::Error( "xAOD::TEvent::getEntry",
1329  XAOD_MESSAGE( "Function called on an uninitialised "
1330  "object" ) );
1331  return -1;
1332  }
1333 
1334  // If we have a chain as input:
1335  if( m_inChain ) {
1336  // Make sure that the correct tree is loaded:
1337  const ::Long64_t fileEntry = m_inChain->LoadTree( entry );
1338  if( fileEntry < 0 ) {
1339  ::Error( "xAOD::TEvent::getEntry",
1340  XAOD_MESSAGE( "Failure in loading entry %i from the "
1341  "input chain" ),
1342  static_cast< int >( entry ) );
1343  return -1;
1344  }
1345  // Check if a new file was loaded:
1346  if( ( m_inTreeNumber != m_inChain->GetTreeNumber() ) ||
1348  // Reset the tracker:
1350  // Connect to this new file:
1351  m_inTreeNumber = m_inChain->GetTreeNumber();
1352  ::TFile* file = m_inChain->GetFile();
1353  // The useTreeCache parameter is set to false, since the cache
1354  // is anyway set up through the TChain. It shouldn't be modified
1355  // on the file level.
1356  if( ! readFrom( file, kFALSE, m_inChain->GetName() ) ) {
1357  ::Error( "xAOD::TEvent::getEntry",
1358  XAOD_MESSAGE( "Couldn't connect to input file #%i "
1359  "of the input chain" ), m_inTreeNumber );
1360  return -1;
1361  }
1362  }
1363  // Restore the previously received entry number.
1364  m_entry = fileEntry;
1365  }
1366  // If we have a regular file/tree as input:
1367  else {
1368  m_entry = entry;
1369  }
1370 
1371  // In order to make the reading of branches+tree cache work
1372  // NB: TTree::LoadTree() only set the entry that should be read for each branch
1373  // but no reading of the branch content is performed when calling that function.
1374  // The entry set that can be retrieved with
1375  // branch->GetTree()->GetReadEntry()
1376  // For friend trees, if an index was built, then the entry which is set for the related branches
1377  // is found by the LoadTree function by matching
1378  // the the major and minor values of the main tree and friend tree
1379  if( m_inTree && m_inTree->LoadTree( m_entry ) < 0 ) {
1380  ::Error( "xAOD::TEvent::getEntry",
1381  XAOD_MESSAGE( "Failure in loading entry %i from the input "
1382  "file" ), static_cast< int >( m_entry ) );
1383  return -1;
1384  }
1385 
1386  // Stats counter needs to know it's the next event:
1388 
1389  // If force-reading is not requested, we're done:
1390  if( ! getall ) {
1391 
1392  // Notify the listeners that a new event was loaded:
1393  const TIncident incident( IncidentType::BeginEvent );
1394  Listener_t::iterator l_itr = m_listeners.begin();
1395  Listener_t::iterator l_end = m_listeners.end();
1396  for( ; l_itr != l_end; ++l_itr ) {
1397  ( *l_itr )->handle( incident );
1398  }
1399 
1400  // No real reading was done:
1401  return 0;
1402  }
1403 
1404  // Loop over all input object managers, and force them to load their
1405  // content:
1406  ::Int_t result = 0;
1407  if( m_auxMode == kAthenaAccess ) {
1408  // In kAthenaAccess mode we need to use getInputObject(...) to load
1409  // all the input objects correctly.
1410  for( auto& inObj : m_inputObjects ) {
1411  static const std::string dynStorePostfix = "Aux.Dynamic";
1412  if( inObj.first.find( dynStorePostfix ) ==
1413  ( inObj.first.size() - dynStorePostfix.size() ) ) {
1414  // Ignore the dynamic store objects. They get loaded through
1415  // their parents.
1416  } else {
1417  // Load the objects and their auxiliary stores through the
1418  // getInputObject(...) function, which takes care of correctly
1419  // setting them up. The type is irrelevant here. We don't
1420  // really care about the exact type of the objects.
1421  getInputObject( inObj.first, typeid( int ), kTRUE, kFALSE );
1422  }
1423  }
1424  } else {
1425  // In a "reasonable" access mode, we do something very simple:
1426  for( auto& inObj : m_inputObjects ) {
1427  result += inObj.second->getEntry( getall );
1428  }
1429  }
1430 
1431  // Notify the listeners that a new event was loaded:
1432  const TIncident incident( IncidentType::BeginEvent );
1433  Listener_t::iterator l_itr = m_listeners.begin();
1434  Listener_t::iterator l_end = m_listeners.end();
1435  for( ; l_itr != l_end; ++l_itr ) {
1436  ( *l_itr )->handle( incident );
1437  }
1438 
1439  // Return the number of bytes read:
1440  return result;
1441  }
1442 
1452  ::Long64_t TEvent::getFiles() const {
1453 
1454  if( m_inChain ) {
1455  return m_inChain->GetListOfFiles()->GetEntries();
1456  } else if( m_inTree || m_inTreeMissing ) {
1457  return 1;
1458  } else {
1459  return 0;
1460  }
1461  }
1462 
1472  ::Int_t TEvent::getFile( ::Long64_t file, ::Int_t getall ) {
1473 
1474  // Check if the file number is valid:
1475  if( ( file < 0 ) || ( file >= getFiles() ) ) {
1476  ::Error( "xAOD::TEvent::getFile",
1477  XAOD_MESSAGE( "Function called with invalid file number "
1478  "(%i)" ), static_cast< int >( file ) );
1479  return -1;
1480  }
1481 
1482  // If we are not reading a TChain, return at this point. As the one and
1483  // only file is open already...
1484  if( ! m_inChain ) {
1485  return 0;
1486  }
1487 
1488  // Trigger the "scanning" of the input files, so the TChain would know
1489  // how many entries are in the various files.
1490  getEntries();
1491 
1492  // Calculate which entry/event we need to load:
1493  ::Long64_t entry = 0;
1494  for( ::Long64_t i = 0; i < file; ++i ) {
1495  entry += m_inChain->GetTreeOffset()[ i ];
1496  }
1497 
1498  // Load this entry using the regular event opening function:
1499  return getEntry( entry, getall );
1500  }
1501 
1508  ::Int_t TEvent::fill() {
1509 
1510  // A little sanity check:
1511  if( ! m_outTree ) {
1512  ::Error( "xAOD::TEvent::fill",
1513  XAOD_MESSAGE( "Object not connected to an output file!" ) );
1514  return 0;
1515  }
1516 
1517  // Make sure that all objects have been read in. The 99 as the value
1518  // has a special meaning for TAuxStore. With this value it doesn't
1519  // delete its transient (decoration) variables. Otherwise it does.
1520  // (As it's supposed to, when moving to a new event.)
1521  if( m_inChain ) {
1522  if (getEntry( m_inChain->GetReadEntry(), 99 ) < 0) {
1523  ::Error( "xAOD::TEvent::fill",
1524  XAOD_MESSAGE( "getEntry failed!" ) );
1525  return 0;
1526  }
1527  } else if( m_inTree ) {
1528  if (getEntry( m_entry, 99 ) < 0) {
1529  ::Error( "xAOD::TEvent::fill",
1530  XAOD_MESSAGE( "getEntry failed!" ) );
1531  return 0;
1532  }
1533  }
1534 
1535  // Prepare the objects for writing. Note that we need to iterate over a
1536  // copy of the m_outputObjects container. Since the putAux(...) function
1537  // called inside the loop may itself add elements to the m_outputObject
1538  // container.
1539  std::string unsetObjects;
1540  Object_t outputObjectsCopy = m_outputObjects;
1541  for( auto& itr : outputObjectsCopy ) {
1542  // Check that a new object was provided in the event:
1543  if( ! itr.second->create() ) {
1544  // We are now going to fail. But let's collect the names of
1545  // all the unset objects:
1546  if( unsetObjects.size() ) {
1547  unsetObjects.append( ", \"" + itr.first + "\"" );
1548  } else {
1549  unsetObjects.append( "\"" + itr.first + "\"" );
1550  }
1551  continue;
1552  }
1553  // Make sure that any dynamic auxiliary variables that
1554  // were added to the object after it was put into the event,
1555  // get added to the output:
1556  if( ! putAux( *m_outTree, *( itr.second ) ) ) {
1557  ::Error( "xAOD::TEvent::fill",
1558  XAOD_MESSAGE( "Failed to put dynamic auxiliary variables "
1559  "in the output for object \"%s\"" ),
1560  itr.first.c_str() );
1561  return 0;
1562  }
1563  }
1564 
1565  // Check if there were any unset objects:
1566  if( unsetObjects.size() ) {
1567  ::Error( "xAOD::TEvent::fill",
1568  XAOD_MESSAGE( "The following objects were not set in the "
1569  "current event: %s" ), unsetObjects.c_str() );
1570  return 0;
1571  }
1572 
1573  // Write the entry, and check the return value:
1574  const ::Int_t ret = m_outTree->Fill();
1575  if( ret <= 0 ) {
1576  ::Error( "xAOD::TEvent::fill",
1577  XAOD_MESSAGE( "Output tree filling failed with return "
1578  "value: %i" ), ret );
1579  }
1580 
1581  // Reset the object managers:
1582  Object_t::iterator ncitr = m_outputObjects.begin();
1583  Object_t::iterator ncend = m_outputObjects.end();
1584  for( ; ncitr != ncend; ++ncitr ) {
1585  ncitr->second->reset();
1586  }
1587 
1588  // Return the value:
1589  return ret;
1590  }
1591 
1604 
1605  // If we *are* reading an input file:
1606  if( m_inTree || m_inTreeMissing ) {
1607  return &m_inputEventFormat;
1608  }
1609 
1610  // If not, let's complain:
1611  ::Warning( "xAOD::TEvent::inputEventFormat",
1612  "No input file is connected at the moment" );
1613  return 0;
1614  }
1615 
1627 
1628  // If we *are* reading an input file:
1629  if( m_outTree ) {
1630  return m_outputEventFormat;
1631  }
1632 
1633  // If not, let's complain:
1634  ::Warning( "xAOD::TEvent::outputEventFormat",
1635  "No output file is connected at the moment" );
1636  return 0;
1637  }
1638 
1649  SG::sgkey_t TEvent::getHash( const std::string& key ) const {
1650 
1651  // For empty keys let's finish quickly:
1652  if( key == "" ) return 0;
1653 
1654  // If the key is used in the input file, let's use the same hash for
1655  // the output file as well:
1656  if( m_inputEventFormat.exists( key ) ) {
1657  return m_inputEventFormat.get( key )->hash();
1658  }
1659 
1660  // If it's a new key, make a new hash for it from scratch:
1661  return Utils::hash( key );
1662  }
1663 
1671  SG::sgkey_t TEvent::getKey( const void* obj ) const {
1672 
1673  // Make use of the getName function:
1674  return getHash( getName( obj ) );
1675  }
1676 
1684  const std::string& TEvent::getName( const void* obj ) const {
1685 
1686  // First look among the output objects:
1687  Object_t::const_iterator obj_itr = m_outputObjects.begin();
1688  Object_t::const_iterator obj_end = m_outputObjects.end();
1689  for( ; obj_itr != obj_end; ++obj_itr ) {
1690 
1691  // Check if this is our object:
1692  if( obj_itr->second->object() != obj ) continue;
1693 
1694  // If it is, let's return right away:
1695  return obj_itr->first;
1696  }
1697 
1698  // Now look among the input objects:
1699  obj_itr = m_inputObjects.begin();
1700  obj_end = m_inputObjects.end();
1701  for( ; obj_itr != obj_end; ++obj_itr ) {
1702 
1703  // Check if this is our object:
1704  if( obj_itr->second->object() != obj ) continue;
1705 
1706  // If it is, let's return:
1707  return obj_itr->first;
1708  }
1709 
1710  // If it's not there either, check if it's in an active TStore object:
1711  const TStore* store = TActiveStore::store();
1712  if( store && store->contains( obj ) ) {
1713  // Get the name from the store then:
1714  return store->getName( obj );
1715  }
1716 
1717  // We didn't find the object in the event...
1718  ::Warning( "xAOD::TEvent::getName",
1719  "Didn't find object with pointer %p in the event",
1720  obj );
1721  static const std::string dummy;
1722  return dummy;
1723  }
1724 
1725  void TEvent::getNames(const std::string& targetClassName,
1726  std::vector<std::string>& vkeys,
1727  bool metadata) const {
1728  // The results go in here
1729  std::set<std::string> keys;
1730 
1731  // Get list of branches from
1732  // the input metadata tree or input tree
1733  std::vector<TObjArray*> fullListOfBranches = {};
1734  if (metadata){
1735  if (m_inMetaTree){
1736  // No friend tree expected for metadata tree
1737  // Only add the list of branches of the metadata tree
1738  ::Info("xAOD::TEvent::getNames", "scanning input objects");
1739  fullListOfBranches.push_back(m_inMetaTree->GetListOfBranches());
1740  }
1741  }
1742  else {
1743  if (m_inTree){
1744  ::Info("xAOD::TEvent::getNames", "scanning input objects");
1745  // Add the list of branches of the main tree
1746  fullListOfBranches.push_back(m_inTree->GetListOfBranches());
1747  // If input tree has friend trees
1748  // add as well the list of friend tree branches
1749  if (m_inTree->GetListOfFriends()){
1750  // Get the list of friends
1751  TList *fList = m_inTree->GetListOfFriends();
1752  // Loop over friend elements
1753  for (TObject * feObj : *fList){
1754  if (feObj){
1755  // Get corresponding friend tree
1756  TTree *friendTree = dynamic_cast<TFriendElement*>(feObj)->GetTree();
1757  // Add list of branches of the friend tree
1758  fullListOfBranches.push_back(friendTree->GetListOfBranches());
1759  }
1760  }
1761  }
1762  }
1763  }
1764 
1765  // Loop over all list of branches (if any)
1766  for (const TObjArray * in : fullListOfBranches){
1767  // Loop over all branches inside the current list of branches
1768  for ( Int_t index = 0; index < in->GetEntriesFast(); ++index ) {
1769  const TObject * obj = in->At(index);
1770  if ( ! obj ) continue;
1771  const TBranch * element = dynamic_cast<const TBranch*>(obj);
1772  if (!element) {
1773  ::Error("xAOD::TEvent::getNames", "Failure inspecting input objects");
1774  break;
1775  }
1776  std::string objClassName = element->GetClassName();
1777  std::string key = obj->GetName();
1778  ::Info("xAOD::TEvent::getNames",
1779  "Inspecting %s / %s",
1780  objClassName.c_str(), key.c_str());
1781  if (objClassName == targetClassName) {
1782  ::Info("xAOD::TEvent::getNames",
1783  "Matched %s to key %s",
1784  targetClassName.c_str(), key.c_str());
1785  keys.insert(key);
1786  }
1787  }
1788  }
1789 
1790  const Object_t& inAux = ( metadata ?
1792 
1793  ::Info("xAOD::TEvent::getNames",
1794  "scanning input Aux objects for %s", targetClassName.c_str());
1795  for( const auto& object : inAux ) {
1796  // All metadata objects should be held by TObjectManager objects.
1797  // Anything else is an error.
1798  TObjectManager* mgr = dynamic_cast< TObjectManager* >( object.second );
1799  if ( ! mgr ) continue;
1800  const std::string& objClassName = mgr->holder()->getClass()->GetName();
1801  const std::string& key = object.first;
1802  ::Info("xAOD::TEvent::getNames",
1803  "Inspecting %s / %s",
1804  objClassName.c_str(), key.c_str());
1805  if (objClassName == targetClassName) {
1806  ::Info("xAOD::TEvent::getNames",
1807  "Matched %s to key %s",
1808  targetClassName.c_str(), key.c_str());
1809  keys.insert(key);
1810  }
1811  }
1812 
1813 
1814  // check output objects
1815  TTree *tree = ( metadata ? nullptr : m_outTree );
1816  if (tree) {
1817  const TObjArray * out = tree->GetListOfBranches();
1818  ::Info("xAOD::TEvent::getNames", "scanning output objects");
1819 
1820  for ( Int_t index = 0; index < out->GetEntriesFast(); ++index ) {
1821  const TObject * obj = out->At(index);
1822  if ( ! obj ) continue;
1823  const TBranch * element = dynamic_cast<const TBranch*>(obj);
1824  if (!element) {
1825  ::Error("xAOD::TEvent::getNames", "Failure inspecting input objects");
1826  break;
1827  }
1828  std::string objClassName = element->GetClassName();
1829  std::string key = obj->GetName();
1830  ::Info("xAOD::TEvent::getNames",
1831  "Inspecting %s / %s",
1832  objClassName.c_str(), key.c_str());
1833  if (objClassName == targetClassName) {
1834  ::Info("xAOD::TEvent::getNames",
1835  "Matched %s to key %s",
1836  targetClassName.c_str(), key.c_str());
1837  keys.insert(key);
1838  }
1839  }
1840  } else {
1841  ::Info("xAOD::TEvent::getNames", "no output tree connected");
1842  }
1843 
1844 
1845  const Object_t& outAux = ( metadata ?
1847 
1848  // Search though EventFormat for entries where class matches the provided
1849  // typeName
1850  ::Info("xAOD::TEvent::getNames",
1851  "scanning output Aux objects for %s", targetClassName.c_str());
1852  for( const auto& object : outAux ) {
1853  // All metadata objects should be held by TObjectManager objects.
1854  // Anything else is an error.
1855  TObjectManager* mgr = dynamic_cast< TObjectManager* >( object.second );
1856  if ( ! mgr ) continue;
1857  const std::string& objClassName = mgr->holder()->getClass()->GetName();
1858  const std::string& key = object.first;
1859  ::Info("xAOD::TEvent::getNames",
1860  "Inspecting %s / %s",
1861  objClassName.c_str(), key.c_str());
1862  if (objClassName == targetClassName) {
1863  ::Info("xAOD::TEvent::getNames",
1864  "Matched %s to key %s",
1865  targetClassName.c_str(), key.c_str());
1866  keys.insert(key);
1867  }
1868  }
1869 
1870  vkeys.insert(vkeys.end(), keys.begin(), keys.end());
1871  }
1872 
1880  const std::string& TEvent::getName( SG::sgkey_t hash ) const {
1881 
1882  // If the branch is known from the input:
1883  if( m_inputEventFormat.exists( hash ) ) {
1884  return m_inputEventFormat.get( hash )->branchName();
1885  }
1886 
1887  // If the branch is known on the output:
1888  if( m_outputEventFormat &&
1890  return m_outputEventFormat->get( hash )->branchName();
1891  }
1892 
1893  // If this is an object in the active store:
1894  const TStore* store = TActiveStore::store();
1895  if( store && store->contains( hash ) ) {
1896  return store->getName( hash );
1897  }
1898 
1899  // If it is unknown:
1900  static const std::string dummy;
1901  return dummy;
1902  }
1903 
1915  const std::type_info& ti ) {
1916 
1917  // Get a string name for this key:
1918  const std::string& name = getName( key );
1919  if( ! name.length() ) {
1920  return 0;
1921  }
1922 
1923  // Forward the call to the function using an std::string key:
1924  return getOutputObject( name, ti );
1925  }
1926 
1939  const std::type_info& ti,
1940  bool silent ) {
1941 
1942  // Get a string name for this key:
1943  const std::string& name = getName( key );
1944  if( ( ! name.length() ) && ( ! silent ) ) {
1945  Warning( "xAOD::TEvent::getInputObject",
1946  "Key 0x%08x unknown", key );
1947  return 0;
1948  }
1949 
1950  // Forward the call to the function using an std::string key:
1951  return getInputObject( name, ti, silent );
1952  }
1953 
1962 
1963  // If we're dealing with an empty input file, stop here:
1964  if( m_inTreeMissing ) {
1965  return StatusCode::SUCCESS;
1966  }
1967 
1968  // A little sanity check:
1969  if( ! m_inTree ) {
1970  ::Error( "xAOD::TEvent::initStats",
1971  XAOD_MESSAGE( "Function called on an uninitialised "
1972  "object" ) );
1973  return StatusCode::FAILURE;
1974  }
1975 
1976  // Reset the number of input branches information:
1978 
1979  // Loop over the EventFormat information
1982  for( ; itr != end; ++itr ) {
1983 
1984  // Get the name of the branch in question:
1985  const std::string& branchName = itr->second.branchName();
1986 
1987  // If it's an auxiliary container, scan it using TAuxStore:
1988  if( branchName.find( "Aux." ) != std::string::npos ) {
1989 
1990  // But first decide whether it describes a container, or just
1991  // a single object. Since the file may have been written in
1992  // kBranchAccess mode, it's not necessarily a good idea to check
1993  // the type of the auxiliary class. So let's check the interface
1994  // class instead.
1995  //
1996  // Get the name of the interface object/container:
1997  const std::string intName =
1998  branchName.substr( 0, branchName.size() - 4 );
1999  if( ! m_inputEventFormat.exists( intName ) ) {
2000  // When this happens, it may still be that both the interface and
2001  // the auxiliary container is missing from the file. As we didn't
2002  // check yet whether the auxiliary container is in place or not.
2003  // So, before printing a warning, let's check for this.
2004  // Unfortunately the check is pretty expensive, but this should
2005  // not be performance critical code after all...
2006  ::Bool_t auxFound = kFALSE;
2007  const std::string dynName = Utils::dynBranchPrefix( branchName );
2008 
2009  std::vector<TObjArray*> fullListOfBranches = {};
2010  // Add the list of branches of the main tree
2011  fullListOfBranches.push_back(m_inTree->GetListOfBranches());
2012  // If input tree has friend trees
2013  // add as well the list of friend tree branches
2014  if (m_inTree->GetListOfFriends()){
2015  // Get the list of friends
2016  TList *fList = m_inTree->GetListOfFriends();
2017  // Loop over friend elements
2018  for (TObject * feObj : *fList){
2019  if (feObj){
2020  // Get corresponding friend tree
2021  TTree *friendTree = dynamic_cast<TFriendElement*>(feObj)->GetTree();
2022  // Add list of branches of the friend tree
2023  fullListOfBranches.push_back(friendTree->GetListOfBranches());
2024  }
2025  }
2026  }
2027 
2028  for (TObjArray* branches : fullListOfBranches){
2029  for( Int_t i = 0; i < branches->GetEntriesFast(); ++i ){
2030  if (!branches->At( i )) continue ;
2031 
2032  const TString name( branches->At( i )->GetName() );
2033  if( name.BeginsWith( branchName ) ||
2034  name.BeginsWith( dynName ) ) {
2035  auxFound = kTRUE;
2036  break;
2037  }
2038  }
2039  }
2040  if( auxFound ) {
2041  ::Warning( "xAOD::TEvent::initStats",
2042  "Couldn't find interface object/container "
2043  "\"%s\" belonging to branch \"%s\"",
2044  intName.c_str(), branchName.c_str() );
2045  }
2046  continue;
2047  }
2048 
2049  // Get the type of the interface:
2050  const EventFormatElement* el = m_inputEventFormat.get( intName );
2051  ::TClass* cl = ::TClass::GetClass( el->className().c_str() );
2052  if( ( ! cl ) || ( ! cl->IsLoaded() ) ) {
2053  ::Warning( "xAOD::TEvent::initStats",
2054  "Couldn't find dictionary for type \"%s\"",
2055  el->className().c_str() );
2056  continue;
2057  }
2058 
2059  // Get the dictionary for the DataVector base class:
2060  static const std::type_info& baseTi = typeid( SG::AuxVectorBase );
2061  static const std::string baseName =
2062  SG::normalizedTypeinfoName( baseTi );
2063  static ::TClass* const baseCl = ::TClass::GetClass( baseName.c_str() );
2064  if( ! baseCl ) {
2065  ::Error( "xAOD::TEvent::initStats",
2066  XAOD_MESSAGE( "Couldn't get dictionary for type "
2067  "\"%s\"" ), baseName.c_str() );
2068  return StatusCode::FAILURE;
2069  }
2070 
2071  // The type of the auxiliary store is finally deduced from the
2072  // inheritance of the interface container.
2074  ( cl->InheritsFrom( baseCl ) ? TAuxStore::kContainerStore :
2076 
2077  // Scan the branches using a temporary TAuxStore instance:
2078  TAuxStore temp( branchName.c_str(), kTRUE, mode );
2079  RETURN_CHECK( "xAOD::TEvent::initStats",
2080  temp.initStats( m_inTree ) );
2081  }
2082  // If it's an interface container:
2083  else {
2084  // Try to access the branch:
2085  const ::TBranch* container =
2086  m_inTree->GetBranch( branchName.c_str() );
2087  // If it exists, let's remember it:
2088  if( container ) {
2089  IOStats::instance().stats().container( branchName );
2090  }
2091  }
2092  }
2093 
2094  // Return gracefully:
2095  return StatusCode::SUCCESS;
2096  }
2097 
2110  void* TEvent::getOutputObject( const std::string& key,
2111  const std::type_info& ti,
2112  ::Bool_t metadata ) const {
2113 
2114  // Select which object container to use:
2115  const Object_t& objects = ( metadata ?
2117 
2118  // Check if the object can be found:
2119  Object_t::const_iterator itr = objects.find( key );
2120  if( itr == objects.end() ) {
2121  // Do the following only for event data:
2122  if( ! metadata ) {
2123  // It's not in the event. Let's check if we find it in an active
2124  // TStore object...
2126  if( ( ! store ) || ( ! store->contains( key, ti ) ) ||
2127  store->isConst( key, ti ) ) {
2128  // Nope, not there either...
2129  return 0;
2130  }
2131  // Let's return the object from the TStore:
2132  void* result = store->getObject( key, ti );
2133  return result;
2134  } else {
2135  // For metadata we don't use external resources.
2136  return 0;
2137  }
2138  }
2139 
2140  // If the object is not set in this event yet, we can't continue:
2141  if( ! itr->second->isSet() ) {
2142  return 0;
2143  }
2144 
2145  // If it does exist, check if it's the right kind of object:
2146  TObjectManager* mgr =
2147  dynamic_cast< TObjectManager* >( itr->second );
2148  if( ! mgr ) {
2149  ::Error( "xAOD::TEvent::getOutputObject",
2150  XAOD_MESSAGE( "Object of wrong type found for key \"%s\"" ),
2151  key.c_str() );
2152  return 0;
2153  }
2154 
2155  // Ask the holder object for the object of this type:
2156  void* result = mgr->holder()->getAs( ti );
2157  if( ! result ) {
2158  ::Warning( "xAOD::TEvent::getOutputObject",
2159  "Couldn't retrieve object as \"%s\"",
2160  Utils::getTypeName( ti ).c_str() );
2161  return 0;
2162  }
2163 
2164  // Return the object:
2165  return result;
2166  }
2167 
2180  const void* TEvent::getInputObject( const std::string& key,
2181  const std::type_info& ti,
2182  ::Bool_t silent,
2183  ::Bool_t metadata ) {
2184 
2185  // Check if a name remapping should be applied or not:
2186  std::string keyToUse = key;
2187  auto remap_itr = m_nameRemapping.find( key );
2188  if( ( remap_itr != m_nameRemapping.end() ) &&
2189  ( ! m_inputEventFormat.exists( key ) ) &&
2190  m_inputEventFormat.exists( remap_itr->second ) ) {
2191  keyToUse = remap_itr->second;
2192  }
2193 
2194  // The following catches the cases when we ask for a transient
2195  // ConstDataVector object to be returned as "const DataVector".
2197  if( store && store->contains( keyToUse, ti ) &&
2198  store->isConst( keyToUse, ti ) ) {
2199  const void* result = store->getConstObject( keyToUse, ti );
2200  return result;
2201  }
2202 
2203  // A sanity check before checking for an object from the input file:
2204  if( ( ( ! m_inTree ) || ( m_entry < 0 ) ) &&
2205  ( ! metadata ) ) {
2206  return 0;
2207  }
2208  if( ( ! m_inMetaTree ) && metadata ) {
2209  return 0;
2210  }
2211 
2212  // Make sure that the requested branch is connected to:
2213  if( metadata ) {
2214  if( ! connectMetaBranch( keyToUse, silent ).isSuccess() ) {
2215  return 0;
2216  }
2217  } else {
2218  if( ! connectBranch( keyToUse, silent ).isSuccess() ) {
2219  return 0;
2220  }
2221  }
2222 
2223  // Select which object container to use:
2224  Object_t& objects = ( metadata ?
2226 
2227  // Access the object's manager:
2228  Object_t::iterator itr = objects.find( keyToUse );
2229  if( itr == objects.end() ) {
2230  ::Fatal( "xAOD::TEvent::getInputObject",
2231  XAOD_MESSAGE( "There is an internal logic error in the "
2232  "code..." ) );
2233  return 0;
2234  }
2235 
2236  // This has to be an ObjectManager object:
2237  TObjectManager* mgr =
2238  dynamic_cast< TObjectManager* >( itr->second );
2239  if( ! mgr ) {
2240  if( key == keyToUse ) {
2241  ::Error( "xAOD::TEvent::getInputObject",
2242  XAOD_MESSAGE( "Object of wrong type found for key "
2243  "\"%s\"" ),
2244  key.c_str() );
2245  } else {
2246  ::Error( "xAOD::TEvent::getInputObject",
2247  XAOD_MESSAGE( "Object of wrong type found for key "
2248  "\"%s\"/\"%s\"" ), key.c_str(),
2249  keyToUse.c_str() );
2250  }
2251  return 0;
2252  }
2253 
2254  // Make sure that the current entry is loaded for event data objects:
2255  if( ! metadata ) {
2256  if( mgr->getEntry() ) {
2257  // Connect the auxiliary store to objects needing it. This call also
2258  // takes care of updating the dynamic store of auxiliary containers,
2259  // when they are getting accessed directly.
2260  if( ! setAuxStore( *mgr ).isSuccess() ) {
2261  ::Error( "xAOD::TEvent::getInputObject",
2262  XAOD_MESSAGE( "Failed to set the auxiliary store for "
2263  "%s/%s" ),
2264  mgr->holder()->getClass()->GetName(),
2265  keyToUse.c_str() );
2266  return 0;
2267  }
2268  }
2269  }
2270 
2271  // Ask the holder object for the object of this type:
2272  const void* result = mgr->holder()->getAsConst( ti, silent );
2273  if( ! result ) {
2274  if( ! silent ) {
2275  ::Warning( "xAOD::TEvent::getInputObject",
2276  "Could not retrieve object with key \"%s\" "
2277  "as \"%s\"", keyToUse.c_str(),
2278  Utils::getTypeName( ti ).c_str() );
2279  }
2280  return 0;
2281  }
2282 
2283  // We succeeded:
2284  return result;
2285  }
2286 
2305  StatusCode TEvent::record( void* obj, const std::string& typeName,
2306  const std::string& key,
2307  ::Int_t basketSize, ::Int_t splitLevel,
2308  ::Bool_t overwrite, ::Bool_t metadata,
2309  ::Bool_t isOwner ) {
2310 
2311  // Check if we have an output tree:
2312  if( ! m_outTree ) {
2313  ::Error( "xAOD::TEvent::record",
2314  XAOD_MESSAGE( "No output tree defined. Did you forget to "
2315  "call writeTo(...)?" ) );
2316  return StatusCode::FAILURE;
2317  }
2318  assert( m_outputEventFormat != 0 );
2319 
2320  // If this is metadata, just take ownership of it. The object will only
2321  // be recorded into the output file when calling finishWritingTo(...).
2322  if( metadata ) {
2323  // Check whether we already have such an object:
2324  if( ( ! overwrite ) &&
2325  ( m_outputMetaObjects.find( key ) !=
2326  m_outputMetaObjects.end() ) ) {
2327  ::Error( "xAOD::TEvent::record",
2328  XAOD_MESSAGE( "Meta-object %s/%s already recorded" ),
2329  typeName.c_str(), key.c_str() );
2330  return StatusCode::FAILURE;
2331  }
2332  // Check if we have a dictionary for this object:
2333  TClass* cl = TClass::GetClass( typeName.c_str() );
2334  if( ! cl ) {
2335  ::Error( "xAOD::TEvent::record",
2336  XAOD_MESSAGE( "Didn't find dictionary for type: %s" ),
2337  typeName.c_str() );
2338  return StatusCode::FAILURE;
2339  }
2340  // Let's create a holder for the object:
2341  THolder* hldr = new THolder( obj, cl, isOwner );
2342  TObjectManager* mgr =
2343  new TObjectManager( 0, hldr, m_auxMode == kAthenaAccess );
2345  // We're done. The rest will be done later on.
2346  return StatusCode::SUCCESS;
2347  }
2348 
2349  // Check if we accessed this object on the input. If yes, then this
2350  // key may not be used for recording.
2351  if( ( ! overwrite ) &&
2352  ( m_inputObjects.find( key ) != m_inputObjects.end() ) ) {
2353  ::Error( "xAOD::TEvent::record",
2354  XAOD_MESSAGE( "Object %s/%s already accessed from the input, "
2355  "can't be overwritten in memory" ),
2356  typeName.c_str(), key.c_str() );
2357  return StatusCode::FAILURE;
2358  }
2359 
2360  // Override the default 0 split level with a split level of 1 for
2361  // auxiliary container objects.
2362  if( ( splitLevel == 0 ) &&
2363  ( key.find( "Aux." ) == ( key.size() - 4 ) ) ) {
2364  splitLevel = 1;
2365  }
2366 
2367  // Check if we need to add it to the event record:
2368  Object_t::iterator vitr = m_outputObjects.find( key );
2369  if( vitr == m_outputObjects.end() ) {
2370 
2371  // Check if we have a dictionary for this object:
2372  TClass* cl = TClass::GetClass( typeName.c_str() );
2373  if( ! cl ) {
2374  ::Error( "xAOD::TEvent::record",
2375  XAOD_MESSAGE( "Didn't find dictionary for type: %s" ),
2376  typeName.c_str() );
2377  return StatusCode::FAILURE;
2378  }
2379 
2380  // Check if this is a new object "type" or not:
2381  if( ! m_outputEventFormat->exists( key ) ) {
2383  "", getHash( key ) ) );
2384  }
2385 
2386  // Let's create a holder for the object:
2387  THolder* hldr = new THolder( obj, cl, isOwner );
2388  TObjectManager* mgr =
2389  new TObjectManager( 0, hldr, m_auxMode == kAthenaAccess );
2390  m_outputObjects[ key ] = mgr;
2391 
2392  // ... and let's add it to the output TTree:
2393  *( mgr->branchPtr() ) =
2394  m_outTree->Branch( key.c_str(), cl->GetName(),
2395  hldr->getPtr(), basketSize, splitLevel );
2396  if( ! mgr->branch() ) {
2397  ::Error( "xAOD::TEvent::record",
2398  XAOD_MESSAGE( "Failed to create branch \"%s\" out of "
2399  "type \"%s\"" ),
2400  key.c_str(), cl->GetName() );
2401  // Clean up:
2402  hldr->setOwner( kFALSE );
2403  delete mgr;
2404  return StatusCode::FAILURE;
2405  }
2406 
2407  // Set up the saving of all the dynamic auxiliary properties
2408  // of the object if it has any:
2409  RETURN_CHECK( "xAOD::TEvent::record",
2410  putAux( *m_outTree, *mgr, basketSize, splitLevel,
2411  kFALSE ) );
2412 
2413  // Return at this point, as we don't want to run the rest of
2414  // the function's code:
2415  return StatusCode::SUCCESS;
2416  }
2417 
2418  // Access the object manager:
2419  TObjectManager* omgr = dynamic_cast< TObjectManager* >( vitr->second );
2420  if( ! omgr ) {
2421  ::Error( "xAOD::TEvent::record",
2422  XAOD_MESSAGE( "Manager object of the wrong type "
2423  "encountered" ) );
2424  return StatusCode::FAILURE;
2425  }
2426 
2427  // Check that the type of the object matches that of the previous
2428  // object:
2429  if( typeName != omgr->holder()->getClass()->GetName() ) {
2430  // This may still be, when the ROOT dictionary name differs from the
2431  // "simple type name" known to C++. So let's get the ROOT name of the
2432  // new type:
2433  TClass* cl = TClass::GetClass( typeName.c_str() );
2434  if( ( ! cl ) || ::strcmp( cl->GetName(),
2435  omgr->holder()->getClass()->GetName() ) ) {
2436  ::Error( "xAOD::TEvent::record",
2437  XAOD_MESSAGE( "For output key \"%s\" the previous type "
2438  "was \"%s\", the newly requested type is "
2439  "\"%s\"" ),
2440  key.c_str(), omgr->holder()->getClass()->GetName(),
2441  typeName.c_str() );
2442  return StatusCode::FAILURE;
2443  }
2444  }
2445 
2446  // Replace the managed object:
2447  omgr->setObject( obj );
2448 
2449  // Replace the auxiliary objects:
2450  return putAux( *m_outTree, *omgr, basketSize, splitLevel, kFALSE );
2451  }
2452 
2469  ::Int_t /*basketSize*/, ::Int_t /*splitLevel*/,
2470  ::Bool_t ownsStore ) {
2471 
2472  // Check if we have an output tree:
2473  if( ! m_outTree ) {
2474  ::Error( "xAOD::TEvent::record",
2475  XAOD_MESSAGE( "No output tree defined. Did you forget to "
2476  "call writeTo(...)?" ) );
2477  return StatusCode::FAILURE;
2478  }
2479 
2480  // Check if we have a filtering rule for this key:
2481  const std::set< std::string >* filter = 0;
2482  auto filter_itr = m_auxItemList.find( key );
2483  if( filter_itr != m_auxItemList.end() ) {
2484  filter = &( filter_itr->second );
2485  }
2486 
2487  // Check if we need to add it to the event record:
2488  Object_t::iterator vitr = m_outputObjects.find( key );
2489  if( vitr == m_outputObjects.end() ) {
2490 
2491  // Configure the object for variable filtering:
2492  if( filter ) {
2493  store->selectAux( *filter );
2494  }
2495  // Tell the object where to write its contents:
2496  RETURN_CHECK( "xAOD::TEvent::record", store->writeTo( m_outTree ) );
2497  // Record it to the output list:
2498  TAuxManager* mgr = new TAuxManager( store, ownsStore );
2499  m_outputObjects[ key ] = mgr;
2500 
2501  // We're done:
2502  return StatusCode::SUCCESS;
2503  }
2504 
2505  // Check if the output has the right store:
2506  if( vitr->second->object() == store ) {
2507  // We're done already:
2508  return StatusCode::SUCCESS;
2509  }
2510 
2511  // If not, update the output manager. This can happen when we copy
2512  // objects from the input to the output files, and we process
2513  // multiple input files.
2514 
2515  // Check if the output manager is of the right type:
2516  TAuxManager* mgr = dynamic_cast< TAuxManager* >( vitr->second );
2517  if( ! mgr ) {
2518  ::Error( "xAOD::TEvent::record",
2519  XAOD_MESSAGE( "Output object with key %s already exists, "
2520  "and is not of type TAuxStore" ),
2521  key.c_str() );
2522  return StatusCode::FAILURE;
2523  }
2524 
2525  // Configure the object for variable filtering:
2526  if( filter ) {
2527  store->selectAux( *filter );
2528  }
2529 
2530  // Connect the auxiliary store to the output tree:
2531  RETURN_CHECK( "xAOD::TEvent::record", store->writeTo( m_outTree ) );
2532 
2533  // Update the manager:
2534  mgr->setObject( store );
2535 
2536  // Return gracefully:
2537  return StatusCode::SUCCESS;
2538  }
2539 
2558  StatusCode TEvent::connectBranch( const std::string& key,
2559  ::Bool_t silent ) {
2560 
2561  // A little sanity check:
2562  if( ! m_inTree ) {
2563  ::Error( "xAOD::TEvent::connectBranch",
2564  XAOD_MESSAGE( "Function called on un-initialised object" ) );
2565  return StatusCode::FAILURE;
2566  }
2567 
2568  // Increment the access counter on this container:
2570 
2571  // Check if the branch is already connected:
2572  if( m_inputObjects.find( key ) != m_inputObjects.end() ) {
2573  return StatusCode::SUCCESS;
2574  }
2575  // Check if it was already found to be missing.
2576  if( m_inputMissingObjects.find( key ) != m_inputMissingObjects.end() ) {
2577  if( ! silent ) {
2578  ::Warning( "xAOD::TEvent::connectBranch",
2579  "Branch \"%s\" not available on input",
2580  key.c_str() );
2581  }
2582  return StatusCode::RECOVERABLE;
2583  }
2584 
2585  // Check if we have metadata about this branch:
2586  const xAOD::EventFormatElement* ef = 0;
2587  if( ! m_inputEventFormat.exists( key ) ) {
2588  if( ! silent ) {
2589  ::Warning( "xAOD::TEvent::connectBranch",
2590  "No metadata available for branch: %s",
2591  key.c_str() );
2592  }
2593  } else {
2595  }
2596 
2597  // Check if the branch exists in our input tree:
2598  ::TBranch* br =
2599  m_inTree->GetBranch( key.c_str() );
2600  if( ! br ) {
2601  if( ! silent ) {
2602  ::Warning( "xAOD::TEvent::connectBranch",
2603  "Branch \"%s\" not available on input",
2604  key.c_str() );
2605  }
2606  m_inputMissingObjects.insert( key );
2607  return StatusCode::RECOVERABLE;
2608  }
2609 
2610  // Make sure that it's not in "MakeClass mode":
2611  br->SetMakeClass( 0 );
2612 
2613  // Decide about the type that we need to use for the reading of this
2614  // branch:
2615  std::string className = br->GetClassName();
2616  if( className == "" ) {
2617  if( ef ) {
2618  // This is a fairly weird situation, but let's fall back to taking
2619  // the class name from the metadata object in this case.
2620  className = ef->className();
2621  } else {
2622  ::Error( "xAOD::TEvent::connectBranch",
2623  XAOD_MESSAGE( "Couldn't find an appropriate type with a "
2624  "dictionary for branch \"%s\"" ),
2625  key.c_str() );
2626  return StatusCode::FAILURE;
2627  }
2628  }
2629  ::TClass* realClass = ::TClass::GetClass( className.c_str() );
2630  if( ( ( ! realClass ) || ( ! realClass->IsLoaded() ) ) && ef ) {
2631  // We may need to do an actual schema evolution here, in which
2632  // case let's fall back on the class name coming from the metadata
2633  // object.
2634  className = ef->className();
2635  realClass = ::TClass::GetClass( className.c_str() );
2636  }
2637  if( ( ! realClass ) || ( ! realClass->IsLoaded() ) ) {
2638  // Now we're in trouble...
2639  ::Error( "xAOD::TEvent::connectBranch",
2640  XAOD_MESSAGE( "Couldn't find an appropriate type with a "
2641  "dictionary for branch \"%s\"" ),
2642  key.c_str() );
2643  return StatusCode::FAILURE;
2644  }
2645 
2646  // Make sure that the current object is the "active event":
2647  setActive();
2648 
2649  // The data type is always "other" for us:
2650  static const ::EDataType dataType = kOther_t;
2651 
2652  // Check if the output already has this object. If it does, let's
2653  // assume that we have been copying the object to the output. Which
2654  // means that we need to resume filling the same memory address that
2655  // the output holder points to.
2656  void* ptr = 0;
2657  Object_t::const_iterator out_itr = m_outputObjects.find( key );
2658  if( out_itr != m_outputObjects.end() ) {
2659  // It needs to be an object manager...
2660  TObjectManager* mgr =
2661  dynamic_cast< TObjectManager* >( out_itr->second );
2662  if( ! mgr ) {
2663  ::Error( "xAOD::TEvent::connectBranch",
2664  XAOD_MESSAGE( "Couldn't access output manager for: %s" ),
2665  key.c_str() );
2666  return StatusCode::FAILURE;
2667  }
2668  // Get the pointer out of it:
2669  ptr = mgr->holder()->get();
2670  }
2671 
2672  // If there is no output object, then let's create one ourselves.
2673  // This is the only way in which we can have the memory management of
2674  // THolder do the right thing with this object.
2675  if( ! ptr ) {
2676  ptr = realClass->New();
2677  }
2678 
2679  // Create the new manager object that will hold this EDM object:
2680  THolder* hldr = new THolder( ptr, realClass );
2681  TObjectManager* mgr =
2682  new TObjectManager( 0, hldr, ( m_auxMode == kAthenaAccess ) );
2683  m_inputObjects[ key ] = mgr;
2684 
2685  // One final check. If it's not an auxiliary store, then it must have
2686  // a split level of 0. Otherwise read rules may not work on it. Causing
2687  // *very* serious silent corruption in the data read, if we don't use
2688  // the "Athena read mode".
2689  if( ( m_auxMode != kAthenaAccess ) && ( br->GetSplitLevel() != 0 ) &&
2690  ( ! isAuxStore( *mgr ) ) ) {
2691  ::Error( "xAOD::TEvent::connectBranch",
2692  XAOD_MESSAGE( "Split level for branch \"%s\" is %i. "
2693  "This can only be read in kAthenaAccess mode." ),
2694  key.c_str(), br->GetSplitLevel() );
2695  // Clean up:
2696  *( hldr->getPtr() ) = 0;
2697  delete mgr;
2698  m_inputObjects.erase( key );
2699  return StatusCode::FAILURE;
2700  }
2701 
2702  // Now try to connect to the branch:
2703  const ::Int_t status = m_inTree->SetBranchAddress( key.c_str(),
2704  hldr->getPtr(),
2705  mgr->branchPtr(),
2706  realClass, dataType,
2707  kTRUE );
2708  if( status < 0 ) {
2709  ::Error( "xAOD::TEvent::connectBranch",
2710  XAOD_MESSAGE( "Couldn't connect variable of type \"%s\" to "
2711  "input branch \"%s\". Return code: %i" ),
2712  className.c_str(), key.c_str(), status );
2713  // Clean up:
2714  *( hldr->getPtr() ) = 0;
2715  delete mgr;
2716  m_inputObjects.erase( key );
2717  return StatusCode::FAILURE;
2718  }
2719 
2720  // If it's an auxiliary store object, set it up correctly:
2721  if( isAuxStore( *mgr ) ) {
2722  RETURN_CHECK( "xAOD::TEvent::connectBranch",
2724  }
2725 
2726  // Return here if the object can't have an auxiliary store:
2727  if( ! hasAuxStore( *mgr ) ) return StatusCode::SUCCESS;
2728 
2729  // If there may be an auxiliary object connected to this one,
2730  // connect that as well:
2731  return connectAux( key + "Aux.", isStandalone( *mgr ) );
2732  }
2733 
2743  ::Bool_t silent ) {
2744 
2745  // A little sanity check:
2746  if( ! m_inMetaTree ) {
2747  ::Error( "xAOD::TEvent::connectMetaBranch",
2748  XAOD_MESSAGE( "Function called on un-initialised object" ) );
2749  return StatusCode::FAILURE;
2750  }
2751 
2752  // Check if the branch is already connected:
2753  if( m_inputMetaObjects.find( key ) != m_inputMetaObjects.end() ) {
2754  return StatusCode::SUCCESS;
2755  }
2756 
2757  // Check if the branch exists in our metadata tree:
2758  ::TBranch* br = m_inMetaTree->GetBranch( key.c_str() );
2759  if( ! br ) {
2760  if( ! silent ) {
2761  ::Warning( "xAOD::TEvent::connectMetaBranch",
2762  "Branch \"%s\" not available on input",
2763  key.c_str() );
2764  }
2765  return StatusCode::RECOVERABLE;
2766  }
2767 
2768  // Check that we have an entry in the branch:
2769  if( ! br->GetEntries() ) {
2770  if( ! silent ) {
2771  ::Warning( "xAOD::TEvent::connectMetaBranch",
2772  "Branch \"%s\" doesn't hold any data",
2773  key.c_str() );
2774  }
2775  return StatusCode::RECOVERABLE;
2776  }
2777 
2778  // Make sure that it's not in "MakeClass mode":
2779  br->SetMakeClass( 0 );
2780 
2781  // Extract the type of the branch:
2782  ::TClass* cl = 0;
2783  ::EDataType dt = kOther_t;
2784  if( br->GetExpectedType( cl, dt ) || ( ! cl ) ) {
2785  ::Error( "xAOD::TEvent::connectMetaBranch",
2786  XAOD_MESSAGE( "Couldn't get the type for metadata "
2787  "branch %s" ), key.c_str() );
2788  return StatusCode::FAILURE;
2789  }
2790 
2791  // Create the object, and all of the managers around it:
2792  void* ptr = cl->New();
2793  THolder* hldr = new THolder( ptr, cl );
2794  TObjectManager* mgr =
2795  new TObjectManager( 0, hldr, m_auxMode == kAthenaAccess );
2796  m_inputMetaObjects[ key ] = mgr;
2797 
2798  // Now try to connect to the branch:
2799  const ::Int_t status = m_inMetaTree->SetBranchAddress( key.c_str(),
2800  hldr->getPtr(),
2801  mgr->branchPtr(),
2802  cl, dt,
2803  kTRUE );
2804  if( status < 0 ) {
2805  ::Error( "xAOD::TEvent::connectMetaBranch",
2806  XAOD_MESSAGE( "Couldn't connect variable of type \"%s\" to "
2807  "input branch \"%s\". Return code: %i" ),
2808  cl->GetName(), key.c_str(), status );
2809  // Clean up:
2810  *( hldr->getPtr() ) = 0;
2811  delete mgr;
2812  m_inputMetaObjects.erase( key );
2813  return StatusCode::FAILURE;
2814  }
2815 
2816  // Read in the object:
2817  if( mgr->getEntry() < 0 ) {
2818  ::Error( "xAOD::TEvent::connectMetaBranch",
2819  XAOD_MESSAGE( "Couldn't read in metadata object with key "
2820  "\"%s\"" ), key.c_str() );
2821  return StatusCode::FAILURE;
2822  }
2823 
2824  // If it's an auxiliary store object, set it up correctly:
2825  if( isAuxStore( *mgr ) ) {
2826  RETURN_CHECK( "xAOD::TEvent::connectBranch",
2828  }
2829 
2830  // Return here if the object can't have an auxiliary store:
2831  if( ! hasAuxStore( *mgr ) ) return StatusCode::SUCCESS;
2832 
2833  // If there may be an auxiliary object connected to this one,
2834  // connect that as well:
2835  RETURN_CHECK( "xAOD::TEvent::connectMetaBranch",
2836  connectMetaAux( key + "Aux.", isStandalone( *mgr ) ) );
2837 
2838  // And now connect the first object to its auxiliary store:
2839  RETURN_CHECK( "xAOD::TEvent::connectMetaBranch",
2840  setAuxStore( *mgr, kTRUE ) );
2841 
2842  // We succeeded:
2843  return StatusCode::SUCCESS;
2844  }
2845 
2856  StatusCode TEvent::connectAux( const std::string& prefix,
2857  ::Bool_t standalone ) {
2858 
2859  // A simple test...
2860  if( ! m_inTree ) {
2861  ::Error( "xAOD::TEvent::connectAux",
2862  XAOD_MESSAGE( "No input tree is available" ) );
2863  return StatusCode::FAILURE;
2864  }
2865 
2866  // Check if we know anything about this auxiliary object:
2867  if( ( ! m_inTree->GetBranch( prefix.c_str() ) ) &&
2869  // If not, then let's just return right away. Not having
2870  // an auxiliary object with this name is not an error per se.
2871  return StatusCode::SUCCESS;
2872  }
2873 
2874  // Check if the branch is already connected:
2875  if( m_inputObjects.find( prefix ) != m_inputObjects.end() ) {
2876  return StatusCode::SUCCESS;
2877  }
2878 
2879  // Do different things based on the "auxiliary mode" we are in:
2881 
2882  // In "class access mode" let's first connect the concrete auxiliary
2883  // object to the input:
2884  RETURN_CHECK( "xAOD::TEvent::connectAux", connectBranch( prefix ) );
2885 
2886  // Access the object's manager:
2887  Object_t::const_iterator mgr_itr = m_inputObjects.find( prefix );
2888  if( mgr_itr == m_inputObjects.end() ) {
2889  ::Fatal( "xAOD::TEvent::connectAux",
2890  XAOD_MESSAGE( "There's a logic error in the code" ) );
2891  }
2892  const TObjectManager* omgr =
2893  dynamic_cast< const TObjectManager* >( mgr_itr->second );
2894  if( ! omgr ) {
2895  ::Fatal( "xAOD::TEvent::connectAux",
2896  XAOD_MESSAGE( "There's a logic error in the code" ) );
2897  return StatusCode::FAILURE;
2898  }
2899 
2900  // Check if we can switch out the internal store of this object:
2901  static const TClass* const holderClass =
2902  TClass::GetClass( typeid( SG::IAuxStoreHolder ) );
2903  if( ! omgr->holder()->getClass()->InheritsFrom( holderClass ) ) {
2904  // Nope... So let's just end the journey here.
2905  return StatusCode::SUCCESS;
2906  }
2907 
2908  // Try to get the object as an IAuxStoreHolder:
2909  SG::IAuxStoreHolder* storeHolder =
2910  reinterpret_cast< SG::IAuxStoreHolder* >(
2911  omgr->holder()->getAs( typeid( SG::IAuxStoreHolder ) ) );
2912  if( ! storeHolder ) {
2913  ::Fatal( "xAOD::TEvent::connectAux",
2914  XAOD_MESSAGE( "There's a logic error in the code" ) );
2915  }
2916 
2917  // A sanity check to see whether the store's type is in sync with the
2918  // object's type that it will be connected to:
2919  if( ( standalone && ( storeHolder->getStoreType() !=
2921  ( ( ! standalone ) &&
2922  ( storeHolder->getStoreType() !=
2924  ::Error( "xAOD::TEvent::connectAux",
2925  XAOD_MESSAGE( "Requested store types inconsistent "
2926  "for: %s" ), prefix.c_str() );
2927  ::Error( "xAOD::TEvent::connectAux",
2928  XAOD_MESSAGE( "standalone = %s, getStoreType() = %i" ),
2929  ( standalone ? "kTRUE" : "kFALSE" ),
2930  static_cast< int >( storeHolder->getStoreType() ) );
2931  return StatusCode::FAILURE;
2932  }
2933 
2934  // Return gracefully:
2935  return StatusCode::SUCCESS;
2936 
2937  } else if( m_auxMode == kBranchAccess ) {
2938 
2939  // In "branch access mode" let's create a TAuxStore object, and let
2940  // that take care of the auxiliary store access:
2941  TAuxStore* store =
2942  new TAuxStore( prefix.c_str(), kTRUE,
2943  ( standalone ? TAuxStore::kObjectStore :
2945  // We're using this object to read from the input, it needs to be
2946  // locked:
2947  store->lock();
2948  TAuxManager* mgr = new TAuxManager( store );
2949  m_inputObjects[ prefix ] = mgr;
2950 
2951  // Now connect the object to the input tree:
2952  RETURN_CHECK( "xAOD::TEvent::connectAux",
2953  store->readFrom( m_inTree ) );
2954 
2955  // Return gracefully:
2956  return StatusCode::SUCCESS;
2957  }
2958 
2959  // There was some problem:
2960  ::Error( "xAOD::TEvent::connectAux",
2961  XAOD_MESSAGE( "Unknown auxiliary access mode set (%i)" ),
2962  static_cast< int >( m_auxMode ) );
2963  return StatusCode::FAILURE;
2964  }
2965 
2976  ::Bool_t standalone ) {
2977 
2978  // Check if the branch is already connected:
2979  if( m_inputMetaObjects.find( prefix ) != m_inputMetaObjects.end() ) {
2980  return StatusCode::SUCCESS;
2981  }
2982 
2983  // A sanity check:
2984  if( ! m_inMetaTree ) {
2985  ::Fatal( "xAOD::TEvent::connectMetaAux",
2986  XAOD_MESSAGE( "Internal logic error detected" ) );
2987  return StatusCode::FAILURE;
2988  }
2989 
2990  // Do different things based on the "auxiliary mode" we are in:
2992 
2993  // In "class access mode" let's first connect the concrete auxiliary
2994  // object to the input:
2995  RETURN_CHECK( "xAOD::TEvent::connectMetaAux",
2997 
2998  // Access the object's manager:
2999  Object_t::const_iterator mgr_itr = m_inputMetaObjects.find( prefix );
3000  if( mgr_itr == m_inputMetaObjects.end() ) {
3001  ::Fatal( "xAOD::TEvent::connectMetaAux",
3002  XAOD_MESSAGE( "There's a logic error in the code" ) );
3003  }
3004  const TObjectManager* omgr =
3005  dynamic_cast< const TObjectManager* >( mgr_itr->second );
3006  if( ! omgr ) {
3007  ::Fatal( "xAOD::TEvent::connectMetaAux",
3008  XAOD_MESSAGE( "There's a logic error in the code" ) );
3009  return StatusCode::FAILURE;
3010  }
3011 
3012  // Check if we can switch out the internal store of this object:
3013  static const TClass* const holderClass =
3014  TClass::GetClass( typeid( SG::IAuxStoreHolder ) );
3015  if( ! omgr->holder()->getClass()->InheritsFrom( holderClass ) ) {
3016  // Nope... So let's just end the journey here.
3017  return StatusCode::SUCCESS;
3018  }
3019 
3020  // Try to get the object as an IAuxStoreHolder:
3021  SG::IAuxStoreHolder* storeHolder =
3022  reinterpret_cast< SG::IAuxStoreHolder* >(
3023  omgr->holder()->getAs( typeid( SG::IAuxStoreHolder ) ) );
3024  if( ! storeHolder ) {
3025  ::Fatal( "xAOD::TEvent::connectMetaAux",
3026  XAOD_MESSAGE( "There's a logic error in the code" ) );
3027  }
3028 
3029  // A sanity check to see whether the store's type is in sync with the
3030  // object's type that it will be connected to:
3031  if( ( standalone && ( storeHolder->getStoreType() !=
3033  ( ( ! standalone ) &&
3034  ( storeHolder->getStoreType() !=
3036  ::Error( "xAOD::TEvent::connectMetaAux",
3037  XAOD_MESSAGE( "Requested store types inconsistent" ) );
3038  ::Error( "xAOD::TEvent::connectMetaAux",
3039  XAOD_MESSAGE( "standalone = %s, getStoreType() = %i" ),
3040  ( standalone ? "kTRUE" : "kFALSE" ),
3041  static_cast< int >( storeHolder->getStoreType() ) );
3042  return StatusCode::FAILURE;
3043  }
3044 
3045  // Return gracefully:
3046  return StatusCode::SUCCESS;
3047 
3048  } else if( m_auxMode == kBranchAccess ) {
3049 
3050  // In "branch access mode" let's create a TAuxStore object, and let
3051  // that take care of the auxiliary store access:
3052  TAuxStore* store =
3053  new TAuxStore( prefix.c_str(), kTRUE,
3054  ( standalone ? TAuxStore::kObjectStore :
3056  // We use this object to read data from the input, it needs to be
3057  // locked:
3058  store->lock();
3059  TAuxManager* mgr = new TAuxManager( store );
3061 
3062  // Now connect the object to the input tree:
3063  RETURN_CHECK( "xAOD::TEvent::connectMetaAux",
3064  store->readFrom( m_inMetaTree ) );
3065 
3066  // Tell the auxiliary store which entry to use:
3067  store->getEntry( 0 );
3068 
3069  // Return gracefully:
3070  return StatusCode::SUCCESS;
3071  }
3072 
3073  // There was some problem:
3074  ::Error( "xAOD::TEvent::connectMetaAux",
3075  XAOD_MESSAGE( "Unknown auxiliary access mode set (%i)" ),
3076  static_cast< int >( m_auxMode ) );
3077  return StatusCode::FAILURE;
3078  }
3079 
3089 
3090  // Check if we can call setName(...) on the object:
3091  ::TMethodCall setNameCall;
3092  // Don't use this code in Athena access mode. And just accept that access
3093  // monitoring is disabled in this case...
3094  if( m_auxMode != kAthenaAccess ) {
3095  setNameCall.InitWithPrototype( mgr.holder()->getClass(),
3096  "setName", "const char*" );
3097  if( setNameCall.IsValid() ) {
3098  // Yes, there is such a function. Let's call it with the branch
3099  // name:
3100  const ::TString params =
3101  ::TString::Format( "\"%s\"", mgr.branch()->GetName() );
3102  const char* charParams = params.Data();
3103  setNameCall.Execute( mgr.holder()->get(), charParams );
3104  } else {
3105  // This is weird. What sort of auxiliary container is this? :-/
3106  ::Warning( "xAOD::TEvent::setUpDynamicStore",
3107  "Couldn't find setName(...) function for container %s "
3108  " (type: %s)",
3109  mgr.branch()->GetName(),
3110  mgr.holder()->getClass()->GetName() );
3111  }
3112  }
3113 
3114  // Check if we can switch out the internal store of this object:
3115  static const TClass* const holderClass =
3116  TClass::GetClass( typeid( SG::IAuxStoreHolder ) );
3117  if( ! mgr.holder()->getClass()->InheritsFrom( holderClass ) ) {
3118  // Nope... So let's just end the journey here.
3119  return StatusCode::SUCCESS;
3120  }
3121 
3122  // Try to get the object as an IAuxStoreHolder:
3123  SG::IAuxStoreHolder* storeHolder =
3124  reinterpret_cast< SG::IAuxStoreHolder* >(
3125  mgr.holder()->getAs( typeid( SG::IAuxStoreHolder ) ) );
3126  if( ! storeHolder ) {
3127  ::Fatal( "xAOD::TEvent::setUpDynamicStore",
3128  XAOD_MESSAGE( "There's a logic error in the code" ) );
3129  return StatusCode::FAILURE;
3130  }
3131 
3132  // Create a TAuxStore instance that will read the dynamic variables
3133  // of this container. Notice that the TAuxManager doesn't own the
3134  // TAuxStore object. It will be owned by the SG::IAuxStoreHolder
3135  // object.
3136  TAuxStore* store =
3137  new TAuxStore( mgr.branch()->GetName(), kFALSE,
3138  ( storeHolder->getStoreType() ==
3142  // This object is used to read data from the input, it needs to be
3143  // locked:
3144  store->lock();
3145  TAuxManager* amgr = new TAuxManager( store, kFALSE );
3146  m_inputObjects[ std::string( mgr.branch()->GetName() ) +
3147  "Dynamic" ] = amgr;
3148  RETURN_CHECK( "xAOD::TEvent::setUpDynamicStore",
3149  store->readFrom( tree ) );
3150  // Tell the auxiliary store which entry to use. This is essential for
3151  // metadata objects, and non-important for event data objects, which will
3152  // get a possibly different entry loaded in setAuxStore(...).
3153  store->getEntry( 0 );
3154 
3155  // Give this object to the store holder:
3156  storeHolder->setStore( store );
3157 
3158  // Return gracefully:
3159  return StatusCode::SUCCESS;
3160  }
3161 
3173  ::Bool_t metadata ) {
3174 
3175  // Check if we need to do anything:
3176  if( ( ! hasAuxStore( mgr ) ) && ( ! isAuxStore( mgr ) ) ) {
3177  return StatusCode::SUCCESS;
3178  }
3179 
3180  // Get the branch name of the object in question:
3181  const std::string key = mgr.branch()->GetName();
3182 
3183  // Select which object container to use:
3184  Object_t& objects = ( metadata ?
3186 
3187 
3188  // Look up the auxiliary object's manager:
3189  TVirtualManager* auxMgr = nullptr;
3190  std::string auxKey;
3191  if( isAuxStore( mgr ) ) {
3192  auxMgr = &mgr;
3193  auxKey = key;
3194  } else {
3195  auto itr = objects.find( key + "Aux." );
3196  if( itr == objects.end() ) {
3197  // Apparently there's no auxiliary object for this DV, so let's
3198  // give up:
3199  return StatusCode::SUCCESS;
3200  }
3201  auxMgr = itr->second;
3202  auxKey = key + "Aux.";
3203  }
3204 
3205  if( ! metadata ) {
3206  // Make sure the auxiliary object is up to date:
3207  ::Int_t readBytes = auxMgr->getEntry();
3208 
3209  // Check if there is a separate auxiliary object for the dynamic
3210  // variables:
3211  const std::string dynAuxKey = auxKey + "Dynamic";
3212  auto dynAuxMgr = objects.find( dynAuxKey );
3213 
3214  if( ( dynAuxMgr != objects.end() ) &&
3215  ( readBytes || ( m_auxMode == kAthenaAccess ) ||
3216  ( auxMgr == &mgr ) ) ) {
3217  // Do different things based on the access mode:
3218  if( m_auxMode != kAthenaAccess ) {
3219  // In "normal" access modes just tell the dynamic store object
3220  // to switch to a new event.
3221  dynAuxMgr->second->getEntry();
3222  } else {
3223  // In "Athena mode" this object has already been deleted when
3224  // the main auxiliary store object was switched to the new
3225  // event. So let's re-create it:
3226  xAOD::TObjectManager& auxMgrRef =
3227  dynamic_cast< xAOD::TObjectManager& >( *auxMgr );
3228  RETURN_CHECK( "xAOD::TEvent::setAuxStore",
3229  setUpDynamicStore( auxMgrRef,
3230  ( metadata ?
3231  m_inMetaTree :
3232  m_inTree ) ) );
3233  // Now tell the newly created dynamic store object which event
3234  // it should be looking at:
3235  auto dynAuxMgr = objects.find( dynAuxKey );
3236  if( dynAuxMgr == objects.end() ) {
3237  ::Error( "xAOD::TEvent::setAuxStore",
3238  XAOD_MESSAGE( "Internal logic error detected" ) );
3239  return StatusCode::FAILURE;
3240  }
3241  dynAuxMgr->second->getEntry();
3242  }
3243  }
3244  }
3245 
3246  // Stop here if we've set up an auxiliary store.
3247  if( auxMgr == &mgr ) {
3248  return StatusCode::SUCCESS;
3249  }
3250 
3251  // Access the auxiliary base class of the object/vector:
3252  SG::AuxVectorBase* vec = 0;
3253  SG::AuxElement* aux = 0;
3254  switch( mgr.holder()->typeKind() ) {
3255  case THolder::DATAVECTOR:
3256  {
3257  void* vvec = mgr.holder()->getAs( typeid( SG::AuxVectorBase ) );
3258  vec = reinterpret_cast< SG::AuxVectorBase* >( vvec );
3259  }
3260  break;
3261  case THolder::AUXELEMENT:
3262  {
3263  void* vaux = mgr.holder()->getAs( typeid( SG::AuxElement ) );
3264  aux = reinterpret_cast< SG::AuxElement* >( vaux );
3265  }
3266  break;
3267  default:
3268  break;
3269  }
3270 
3271  // Check whether index tracking is enabled for the type. If not, then
3272  // we need to fix it...
3273  if( vec && ( ! vec->trackIndices() ) ) {
3274  forceTrackIndices( *vec );
3275  }
3276 
3277  // Check if we were successful:
3278  if( ( ! vec ) && ( ! aux ) ) {
3279  ::Fatal( "xAOD::TEvent::setAuxStore",
3280  XAOD_MESSAGE( "Couldn't access class \"%s\" as "
3281  "SG::AuxVectorBase or SG::AuxElement" ),
3282  mgr.holder()->getClass()->GetName() );
3283  }
3284 
3285  // Get the auxiliary store object:
3286  const SG::IConstAuxStore* store = 0;
3287  if( m_auxMode == kBranchAccess ) {
3288  // Get the concrete auxiliary manager:
3289  TAuxManager* amgr = dynamic_cast< TAuxManager* >( auxMgr );
3290  if( ! amgr ) {
3291  ::Fatal( "xAOD::TEvent::setAuxStore",
3292  XAOD_MESSAGE( "Auxiliary manager for \"%s\" is not of the "
3293  "right type" ), auxKey.c_str() );
3294  return StatusCode::FAILURE;
3295  }
3296  store = amgr->getConstStore();
3297  // If the store still doesn't know its type, help it now:
3298  if( amgr->getStore()->structMode() == TAuxStore::kUndefinedStore ) {
3299  const TAuxStore::EStructMode mode = ( vec ?
3302  RETURN_CHECK( "xAOD::TEvent::setAuxStore",
3303  amgr->getStore()->setStructMode( mode ) );
3304  }
3305  } else if( m_auxMode == kClassAccess || m_auxMode == kAthenaAccess ) {
3306  // Get the concrete auxiliary manager:
3307  TObjectManager* omgr =
3308  dynamic_cast< TObjectManager* >( auxMgr );
3309  if( ! omgr ) {
3310  ::Fatal( "xAOD::TEvent::setAuxStore",
3311  XAOD_MESSAGE( "Auxiliary manager for \"%s\" is not of the "
3312  "right type" ), auxKey.c_str() );
3313  return StatusCode::FAILURE;
3314  }
3315  void* p = omgr->holder()->getAs( typeid( SG::IConstAuxStore ) );
3316  store = reinterpret_cast< const SG::IConstAuxStore* >( p );
3317  }
3318  if( ! store ) {
3319  ::Fatal( "xAOD::TEvent::setAuxStore",
3320  XAOD_MESSAGE( "Logic error detected in the code" ) );
3321  }
3322 
3323  // Connect the two:
3324  if( vec ) {
3325  vec->setStore( store );
3326  } else if( aux ) {
3327  aux->setStore( store );
3328  } else {
3329  ::Fatal( "xAOD::TEvent::setAuxStore",
3330  XAOD_MESSAGE( "Logic error detected in the code" ) );
3331  }
3332 
3333  // We succeeded:
3334  return StatusCode::SUCCESS;
3335  }
3336 
3350  StatusCode TEvent::putAux( ::TTree& outTree, TVirtualManager& vmgr,
3351  ::Int_t basketSize, ::Int_t splitLevel,
3352  ::Bool_t metadata ) {
3353 
3354  // A little sanity check:
3355  assert( m_outputEventFormat != 0 );
3356 
3357  // Do the conversion:
3358  TObjectManager* mgr = dynamic_cast< TObjectManager* >( &vmgr );
3359  if( ! mgr ) {
3360  // It's not an error any more when we don't get a TObjectManager.
3361  return StatusCode::SUCCESS;
3362  }
3363 
3364  // Check if we need to do anything here:
3365  if( ! mgr->holder()->getClass()->InheritsFrom( "SG::IAuxStoreIO" ) ) {
3366  return StatusCode::SUCCESS;
3367  }
3368 
3369  // Get a pointer to the auxiliary store I/O interface:
3370  SG::IAuxStoreIO* aux =
3371  reinterpret_cast< SG::IAuxStoreIO* >(
3372  mgr->holder()->getAs( typeid( SG::IAuxStoreIO ) ) );
3373  if( ! aux ) {
3374  ::Fatal( "xAOD::TEvent::putAux",
3375  XAOD_MESSAGE( "There is a logic error in the code!" ) );
3376  }
3377 
3378  // Check if we have rules defined for which auxiliary properties
3379  // to write out:
3381  if( ! metadata ) {
3382  auto item_itr = m_auxItemList.find( mgr->branch()->GetName() );
3383  if( item_itr != m_auxItemList.end() ) {
3384  sel.selectAux( item_itr->second );
3385  }
3386  }
3387 
3388  // Get the dynamic auxiliary variables held by this object, which
3389  // were selected to be written:
3390  const SG::auxid_set_t auxids = sel.getSelectedAuxIDs (aux->getSelectedAuxIDs());
3391 
3392  // If there are no dynamic auxiliary variables in the object, return
3393  // right away:
3394  if( auxids.empty() ) {
3395  return StatusCode::SUCCESS;
3396  }
3397 
3398  // Decide what should be the prefix of all the dynamic branches:
3399  const std::string dynNamePrefix =
3400  Utils::dynBranchPrefix( mgr->branch()->GetName() );
3401 
3402  // Select which container to add the variables to:
3404 
3405  // This iteration will determine the ordering of branches within
3406  // the tree, so sort auxids by name.
3408  typedef std::pair< std::string, SG::auxid_t > AuxVarSort_t;
3409  std::vector< AuxVarSort_t > varsort;
3410  varsort.reserve( auxids.size() );
3411  for( SG::auxid_t id : auxids ) {
3412  varsort.emplace_back( r.getName( id ), id );
3413  }
3414  std::sort( varsort.begin(), varsort.end() );
3415 
3416  // Extract all the dynamic variables from the object:
3417  for( const auto& p : varsort ) {
3418 
3419  // The auxiliary ID:
3420  const SG::auxid_t id = p.second;
3421 
3422  // Construct a name for the branch that we will write:
3423  const std::string brName = dynNamePrefix + p.first;
3424 
3425  // Try to find the branch:
3426  Object_t::iterator bmgr = objects.find( brName );
3427 
3428  // Check if we already know about this variable:
3429  if( bmgr == objects.end() ) {
3430 
3431  // Construct the full type name of the variable:
3432  const std::type_info* brType = aux->getIOType( id );
3433  if( ! brType ) {
3434  ::Error( "xAOD::TEvent::putAux",
3435  XAOD_MESSAGE( "No I/O type found for variable %s" ),
3436  brName.c_str() );
3437  return StatusCode::FAILURE;
3438  }
3439  const std::string brTypeName =
3440  Utils::getTypeName( *brType );
3441  std::string brProperTypeName = "<unknown>";
3442 
3443  // The branch that will hopefully be created:
3444  ::TBranch* br = 0;
3445 
3446  // Check if it's a primitive type or not:
3447  if( strlen( brType->name() ) == 1 ) {
3448 
3449  // Making the "proper" type name is simple in this case:
3450  brProperTypeName = brTypeName;
3451 
3452  // Get the character describing this type for ROOT:
3453  const char rootType = Utils::rootType( brType->name()[ 0 ] );
3454  if( rootType == '\0' ) {
3455  ::Error( "xAOD::TEvent::putAux",
3456  XAOD_MESSAGE( "Type not known for variable \"%s\" "
3457  "of type \"%s\"" ),
3458  brName.c_str(), brTypeName.c_str() );
3459  return StatusCode::FAILURE;
3460  }
3461 
3462  // Create the full description of the variable for ROOT:
3463  std::ostringstream leaflist;
3464  leaflist << brName << "/" << rootType;
3465 
3466  // Let's create a holder for this property:
3467  THolder* hldr = new THolder( aux->getIOData( id ),
3468  0, kFALSE );
3469  TPrimitiveAuxBranchManager* auxmgr =
3470  new TPrimitiveAuxBranchManager( id, 0, hldr );
3471  objects[ brName ] = auxmgr;
3472 
3473  // ... and let's add it to the output TTree:
3474  *( auxmgr->branchPtr() ) =
3475  outTree.Branch( brName.c_str(), hldr->get(),
3476  leaflist.str().c_str(),
3477  basketSize );
3478  if( ! auxmgr->branch() ) {
3479  ::Error( "xAOD::TEvent::putAux",
3480  XAOD_MESSAGE( "Failed to create branch \"%s\" out "
3481  "of type \"%s\"" ),
3482  brName.c_str(), brProperTypeName.c_str() );
3483  // Clean up:
3484  *( auxmgr->holder()->getPtr() ) = 0;
3485  delete auxmgr;
3486  objects.erase( brName );
3487  return StatusCode::FAILURE;
3488  }
3489  br = auxmgr->branch();
3490 
3491  } else {
3492 
3493  // Check if we have a dictionary for this type:
3494  TClass* cl = TClass::GetClass( *brType, kTRUE, kTRUE );
3495  if( ! cl ) {
3496  // The dictionary needs to be loaded now. This could be an
3497  // issue. But let's hope for the best...
3498  cl = TClass::GetClass( brTypeName.c_str() );
3499  // If still not found...
3500  if( ! cl ) {
3501  ::Error( "xAOD::TEvent::putAux",
3502  XAOD_MESSAGE( "Dictionary not available for "
3503  "variable \"%s\" of type \"%s\"" ),
3504  brName.c_str(), brTypeName.c_str() );
3505  return StatusCode::FAILURE;
3506  }
3507  }
3508 
3509  // The proper type name comes from the dictionary in this case:
3510  brProperTypeName = cl->GetName();
3511 
3512  // Let's create a holder for this property:
3513  THolder* hldr = new THolder( aux->getIOData( id ),
3514  cl, kFALSE );
3515  TAuxBranchManager* auxmgr =
3516  new TAuxBranchManager( id, 0, hldr );
3517  objects[ brName ] = auxmgr;
3518 
3519  if (!cl->CanSplit() && strncmp (cl->GetName(), "SG::PackedContainer<", 20) == 0)
3520  splitLevel = 0;
3521 
3522  // ... and let's add it to the output TTree:
3523  *( auxmgr->branchPtr() ) =
3524  outTree.Branch( brName.c_str(),
3525  cl->GetName(),
3526  hldr->getPtr(), basketSize, splitLevel );
3527  if( ! auxmgr->branch() ) {
3528  ::Error( "xAOD::TEvent::putAux",
3529  XAOD_MESSAGE( "Failed to create branch \"%s\" out "
3530  "of type \"%s\"" ),
3531  brName.c_str(), brProperTypeName.c_str() );
3532  // Clean up:
3533  *( auxmgr->holder()->getPtr() ) = 0;
3534  delete auxmgr;
3535  objects.erase( brName );
3536  return StatusCode::FAILURE;
3537  }
3538  br = auxmgr->branch();
3539 
3540  }
3541 
3542  // If this is not the first event, fill up the already filled
3543  // events with (empty) content:
3544  if( outTree.GetEntries() ) {
3545  void* ptr = br->GetAddress();
3546  br->SetAddress( 0 );
3547  for( ::Long64_t i = 0; i < outTree.GetEntries(); ++i ) {
3548  br->Fill();
3549  }
3550  br->SetAddress( ptr );
3551  }
3552 
3553  // If all went fine, let's add this branch to the event format
3554  // metadata:
3555  if( ! m_outputEventFormat->exists( brName ) ) {
3558  brProperTypeName,
3559  mgr->branch()->GetName(),
3560  getHash( brName ) ) );
3561  }
3562 
3563  // We don't need to do the rest:
3564  continue;
3565  }
3566 
3567  // Access the object manager:
3568  bmgr = objects.find( brName );
3569  if( bmgr == objects.end() ) {
3570  ::Fatal( "xAOD::TEvent::putAux",
3571  XAOD_MESSAGE( "There is an internal logic error in the "
3572  "code..." ) );
3573  }
3574 
3575  // Replace the managed object:
3576  void* nc_data ATLAS_THREAD_SAFE = // we hold non-const pointers but check on retrieve
3577  const_cast< void* >( static_cast< const void* >( aux->getIOData( id ) ) );
3578  bmgr->second->setObject( nc_data );
3579  }
3580 
3581  // Return gracefully:
3582  return StatusCode::SUCCESS;
3583  }
3584 
3594 
3595  // The classes whose children can have an auxiliary store attached
3596  // to them:
3597  static const TClass* const dvClass =
3598  ::TClass::GetClass( typeid( SG::AuxVectorBase ) );
3599  static const TClass* const aeClass =
3600  ::TClass::GetClass( typeid( SG::AuxElement ) );
3601 
3602  // Do the check:
3603  return ( mgr.holder()->getClass()->InheritsFrom( dvClass ) ||
3604  mgr.holder()->getClass()->InheritsFrom( aeClass ) );
3605  }
3606 
3615 
3616  // The classes whose children are considered auxiliary stores:
3617  static const TClass* const storeClass =
3618  ::TClass::GetClass( typeid( SG::IConstAuxStore ) );
3619  static const TClass* const storeHolderClass =
3620  ::TClass::GetClass( typeid( SG::IAuxStoreHolder ) );
3621 
3622  // Do the check:
3623  return ( mgr.holder()->getClass()->InheritsFrom( storeClass ) ||
3624  mgr.holder()->getClass()->InheritsFrom( storeHolderClass ) );
3625  }
3626 
3638 
3639  // The classes whose children can have an auxiliary store attached
3640  // to them:
3641  static const TClass* const dvClass =
3642  TClass::GetClass( typeid( SG::AuxVectorBase ) );
3643  static const TClass* const aeClass =
3644  TClass::GetClass( typeid( SG::AuxElement ) );
3645 
3646  // Do the check:
3647  if( mgr.holder()->getClass()->InheritsFrom( aeClass ) ) {
3648  return kTRUE;
3649  } else if( mgr.holder()->getClass()->InheritsFrom( dvClass ) ) {
3650  return kFALSE;
3651  }
3652 
3653  // Some logic error happened:
3654  ::Error( "xAOD::TEvent::isStandalone",
3655  XAOD_MESSAGE( "Received type (%s) that can't have an "
3656  "auxiliary store" ),
3657  mgr.holder()->getClass()->GetName() );
3658  return kFALSE;
3659  }
3660 
3671  ::Bool_t TEvent::contains( const std::string& key,
3672  const std::type_info& ti,
3673  ::Bool_t metadata ) {
3674 
3675  return ( getOutputObject( key, ti, metadata ) ||
3676  getInputObject( key, ti, kTRUE, metadata ) );
3677  }
3678 
3690  ::Bool_t TEvent::transientContains( const std::string& key,
3691  const std::type_info& ti,
3692  ::Bool_t metadata ) const {
3693 
3694  return getOutputObject( key, ti, metadata );
3695  }
3696 
3699  }
3700 
3701 } // namespace xAOD
xAOD::TEvent::m_inTreeNumber
::Int_t m_inTreeNumber
The number of the currently open tree in the input chain.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:438
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
xAOD::TEvent::m_nameRemapping
std::unordered_map< std::string, std::string > m_nameRemapping
Container name re-mapping rules.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:472
xAOD::EventFormat_v1::end
const_iterator end() const
STL-like function for getting the end of the container.
Definition: EventFormat_v1.cxx:163
xAOD::TEvent::addListener
StatusCode addListener(TVirtualIncidentListener *listener)
Register an incident listener object.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:910
xAOD::TVirtualEvent
Base interface for getting objects out of the input file.
Definition: TVirtualEvent.h:32
xAOD::TEvent::finishWritingTo
StatusCode finishWritingTo(::TFile *file)
Finish writing to an output file.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:734
xAOD::TPrimitiveAuxBranchManager::branchPtr
::TBranch ** branchPtr()
Pointer to the branch's pointer.
Definition: TPrimitiveAuxBranchManager.cxx:89
beamspotman.r
def r
Definition: beamspotman.py:676
store
StoreGateSvc * store
Definition: fbtTestBasics.cxx:69
CurrentEventStore.h
Hold a pointer to the current event store.
python.SystemOfUnits.second
int second
Definition: SystemOfUnits.py:120
xAOD::EventFormat_v1::get
const EventFormatElement * get(const std::string &key, bool quiet=false) const
Get the description of a given branch.
Definition: EventFormat_v1.cxx:91
xAOD::THolder::AUXELEMENT
@ AUXELEMENT
A type inheriting from SG::AuxElement.
Definition: THolder.h:106
RETURN_CHECK
#define RETURN_CHECK(CONTEXT, EXP)
Helper macro for checking return codes in a compact form in the code.
Definition: ReturnCheck.h:26
StoreGateSvc::contains
bool contains(const TKEY &key) const
Look up a keyed object in TDS (compare also tryRetrieve) returns false if object not available in TDS...
xAOD::TEvent::name
const std::string & name() const override
Get the name of the instance.
Definition: TEventProxyDict.cxx:462
SG::AuxVectorBase::initAuxVectorBase
void initAuxVectorBase(SG::OwnershipPolicy ownPolicy, SG::IndexTrackingPolicy indexTrackingPolicy)
Initialize index tracking mode.
xAOD::TEvent::m_auxMode
EAuxMode m_auxMode
The auxiliary access mode.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:426
xAOD::TEvent::kUndefinedAccess
@ kUndefinedAccess
Undefined, to be selected by the object.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:99
TEventFormatRegistry.h
IAuxStoreHolder.h
checkxAOD.brName
brName
Definition: Tools/PyUtils/bin/checkxAOD.py:113
python.trigbs_prescaleL1.ost
ost
Definition: trigbs_prescaleL1.py:104
get_generator_info.result
result
Definition: get_generator_info.py:21
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
SG::IAuxStoreHolder::getStoreType
virtual AuxStoreType getStoreType() const =0
Return the type of the store object.
TPrimitiveAuxBranchManager.h
PowhegControl_ttHplus_NLO.ss
ss
Definition: PowhegControl_ttHplus_NLO.py:83
LArConditions2Ntuple.objects
objects
Definition: LArConditions2Ntuple.py:56
vtune_athena.format
format
Definition: vtune_athena.py:14
xAOD::TEvent::getInputObject
const void * getInputObject(SG::sgkey_t key, const std::type_info &ti, bool silent=false) override
Function for retrieving an input object in a non-template way.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:1938
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
xAOD::IOStats::stats
ReadStats & stats()
Access the object belonging to the current thread.
Definition: IOStats.cxx:17
xAOD::TAuxManager::getStore
TAuxStore * getStore()
Get a type-specific pointer to the managed object.
Definition: TAuxManager.cxx:99
SG::AuxTypeRegistry::instance
static AuxTypeRegistry & instance()
Return the singleton registry instance.
Definition: AuxTypeRegistry.cxx:49
xAOD::TAuxBranchManager
Manager for auxiliary branches created dynamically.
Definition: TAuxBranchManager.h:34
TAuxBranchManager.h
xAOD::THolder::setOwner
void setOwner(::Bool_t state=kTRUE)
Set whether the holder should own its object.
Definition: THolder.cxx:257
xAOD::TActiveEvent::setEvent
static void setEvent(TVirtualEvent *ptr)
Set the active event pointer.
Definition: TActiveEvent.cxx:21
SG::normalizedTypeinfoName
std::string normalizedTypeinfoName(const std::type_info &info)
Convert a type_info to a normalized string representation (matching the names used in the root dictio...
Definition: normalizedTypeinfoName.cxx:120
index
Definition: index.py:1
SG::AuxElement
Base class for elements of a container that can have aux data.
Definition: AuxElement.h:446
xAOD::TEvent::getOutputObject
void * getOutputObject(SG::sgkey_t key, const std::type_info &ti) override
Function for retrieving an output object in a non-template way.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:1914
xAOD::THolder::DATAVECTOR
@ DATAVECTOR
A DataVector container.
Definition: THolder.h:105
xAOD::THolder::getAs
virtual void * getAs(const std::type_info &tid, ::Bool_t silent=kFALSE) const
Return the object as a specific pointer.
Definition: THolder.cxx:370
xAOD::THolder
This class takes care of holding EDM objects in memory.
Definition: THolder.h:35
xAOD::TEvent::kAthenaAccess
@ kAthenaAccess
Access containers/objects like Athena does.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:98
StateLessPT_NewConfig.Format
Format
Definition: StateLessPT_NewConfig.py:146
xAOD::TEvent::m_outTree
::TTree * m_outTree
The tree that we are writing to.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:445
xAOD::TEvent::getFile
::Int_t getFile(::Long64_t file, ::Int_t getall=0)
Load the first event for a given file from the input TChain.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:1472
xAOD::TEvent::m_inChain
::TChain * m_inChain
The (optional) chain provided as input.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:434
xAOD::TEvent::putAux
StatusCode putAux(::TTree &outTree, TVirtualManager &mgr, ::Int_t basketSize=32000, ::Int_t splitLevel=0, ::Bool_t metadata=kFALSE)
Function saving the dynamically created auxiliary properties.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:3350
tree
TChain * tree
Definition: tile_monitor.h:30
xAOD::TVirtualManager::getEntry
virtual ::Int_t getEntry(::Int_t getall=0)=0
Function for updating the object in memory if needed.
xAOD::ReadStats::Print
void Print(::Option_t *option="") const
Print information about the collected statistics.
xAOD::THolder::getPtr
void ** getPtr()
Return a typeless pointer to the held object's pointer.
Definition: THolder.cxx:225
xAOD::THolder::get
const void * get() const
Return a typeless const pointer to the held object.
Definition: THolder.cxx:215
SG::ALWAYS_TRACK_INDICES
@ ALWAYS_TRACK_INDICES
Always track indices, regardless of the setting of the ownership policy.
Definition: IndexTrackingPolicy.h:43
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
xAOD::TEvent::m_inputObjects
Object_t m_inputObjects
Collection of all the managed input objects.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:448
SG::CurrentEventStore::setStore
static IProxyDict * setStore(IProxyDict *store)
Set the current store.
Definition: CurrentEventStore.cxx:36
xAOD::TDirectoryReset
Helper class for making sure the current directory is preserved.
Definition: TDirectoryReset.h:28
downloadSingle.dataType
string dataType
Definition: downloadSingle.py:18
TChainStateTracker.h
NO_SANITIZE_UNDEFINED
#define NO_SANITIZE_UNDEFINED
Definition: no_sanitize_undefined.h:28
xAOD::TAuxStore::setStructMode
StatusCode setStructMode(EStructMode mode)
Set the structure mode of the object to a new value.
Definition: TAuxStore.cxx:100
xAOD::TAuxManager::getConstStore
const SG::IConstAuxStore * getConstStore() const
Get a convenience pointer to the managed object.
Definition: TAuxManager.cxx:104
xAOD::TEvent::printNameRemap
void printNameRemap() const
Print the current name re-mapping rules.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:1033
xAOD::TAuxStore
"ROOT implementation" of IAuxStore
Definition: TAuxStore.h:46
xAOD::TActiveStore::store
static TStore * store()
Access the currently active TStore object.
Definition: TActiveStore.cxx:16
xAOD::TEvent::recordAux
SG::IAuxStore * recordAux(const std::string &key, SG::IAuxStoreHolder::AuxStoreType type=SG::IAuxStoreHolder::AST_ContainerStore, Int_t basketSize=32000, Int_t splitLevel=0)
Add an auxiliary store object to the output.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:1066
xAOD
ICaloAffectedTool is abstract interface for tools checking if 4 mom is in calo affected region.
Definition: ICaloAffectedTool.h:24
SG::CurrentEventStore::store
static IProxyDict * store()
Fetch the current store.
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
xAOD::ReadStats::container
BranchStats * container(const std::string &name)
Access the description of a container. Creating it if necessary.
xAOD::EventFormatElement::parentName
const std::string & parentName() const
Get the name of the parent auxiliary object.
Definition: EventFormatElement.cxx:42
xAOD::TVirtualIncidentListener
Class providing an interface for classes listening to xAOD incidents.
Definition: TVirtualIncidentListener.h:25
xAOD::EventFormatElement
Class describing one branch of the ROOT file.
Definition: EventFormatElement.h:39
xAOD::TEvent::copy
StatusCode copy(const std::string &key, ::Int_t basketSize=32000, ::Int_t splitLevel=0)
Copy an object directly from the input to the output.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:1143
XAOD_MESSAGE
#define XAOD_MESSAGE(MESSAGE)
Simple macro for printing error/verbose messages.
Definition: Control/xAODRootAccess/xAODRootAccess/tools/Message.h:19
vec
std::vector< size_t > vec
Definition: CombinationsGeneratorTest.cxx:12
xAOD::TEvent::~TEvent
virtual ~TEvent()
Destructor.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:236
python.TurnDataReader.dr
dr
Definition: TurnDataReader.py:112
Utils.h
xAOD::TAuxStore::EStructMode
EStructMode
"Structural" modes of the object
Definition: TAuxStore.h:53
xAOD::TVirtualManager
Interface class for the "manager classes".
Definition: TVirtualManager.h:24
xAOD::TEvent::getKey
SG::sgkey_t getKey(const void *obj) const override
Function returning the hash describing a known object.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:1671
xAOD::EventFormatElement::branchName
const std::string & branchName() const
Get the branch/key name.
Definition: EventFormatElement.cxx:30
IOStats.h
xAOD::TEvent::kClassAccess
@ kClassAccess
Access auxiliary data using the aux containers.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:97
TVirtualIncidentListener.h
xAOD::TEvent::dump
std::string dump()
Function creating a user-readable dump of the current input.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:292
xAOD::TPrimitiveAuxBranchManager
Manager for primitive auxiliary branches created dynamically.
Definition: TPrimitiveAuxBranchManager.h:35
TDirectoryReset.h
SG::IAuxStoreIO::getIOType
virtual const std::type_info * getIOType(SG::auxid_t auxid) const =0
Return the type of the data to be stored for one aux data item.
xAOD::TEvent::outputEventFormat
const EventFormat * outputEventFormat() const
Get information about the output objects.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:1626
trigbs_dumpHLTContentInBS.stats
stats
Definition: trigbs_dumpHLTContentInBS.py:91
PerfStats.h
ReturnCheck.h
AuxVectorBase.h
Manage index tracking and synchronization of auxiliary data.
SG::AuxVectorBase
Manage index tracking and synchronization of auxiliary data.
Definition: AuxVectorBase.h:98
xAOD::TEvent::m_inMetaTree
::TTree * m_inMetaTree
Pointer to the metadata tree in the input file.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:440
xAOD::EventFormatElement::hash
sgkey_t hash() const
Get the hash belonging to this branch/key.
Definition: EventFormatElement.cxx:48
SG::IAuxStoreIO
Interface providing I/O for a generic auxiliary store.
Definition: IAuxStoreIO.h:44
xAOD::Utils::dynBranchPrefix
std::string dynBranchPrefix(const std::string &key)
This function is used to figure out what to name dynamic auxiliary branches coming from a container c...
Definition: Control/xAODRootAccess/Root/Utils.cxx:144
xAOD::TEvent::clearNameRemap
void clearNameRemap()
Clear the current name re-mapping.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:1024
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
xAOD::ReadStats::nextEvent
void nextEvent()
Function incrementing the processed event counter.
xAOD::THolder::getClass
const ::TClass * getClass() const
Definition: THolder.cxx:401
covarianceTool.filter
filter
Definition: covarianceTool.py:514
SG::AuxTypeRegistry
Handle mappings between names and auxid_t.
Definition: AuxTypeRegistry.h:62
xAOD::TEvent::auxMode
EAuxMode auxMode() const
Get what auxiliary access mode the object was constructed with.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:278
python.checkMetadata.metadata
metadata
Definition: checkMetadata.py:175
BchCleanup.mgr
mgr
Definition: BchCleanup.py:294
xAOD::TActiveEvent::event
static TVirtualEvent * event()
Access the currently active TVirtualEvent object.
Definition: TActiveEvent.cxx:16
CxxUtils::vec
typename vecDetail::vec_typedef< T, N >::type vec
Define a nice alias for the vectorized type.
Definition: vec.h:207
runLayerRecalibration.branches
list branches
Definition: runLayerRecalibration.py:98
JetTagCalibConfig.className
string className
Definition: JetTagCalibConfig.py:31
SG::IAuxStoreHolder::AuxStoreType
AuxStoreType
Type of the auxiliary store.
Definition: IAuxStoreHolder.h:66
SG::auxid_t
size_t auxid_t
Identifier for a particular aux data item.
Definition: AuxTypes.h:27
xAOD::TEvent::m_printEventProxyWarnings
Bool_t m_printEventProxyWarnings
Option to silence common warnings that seem to be harmless.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:475
CxxUtils::ConcurrentBitset::size
bit_t size() const
Count the number of 1 bits in the set.
TFileAccessTracer.h
xAOD::EventFormat_v1::begin
const_iterator begin() const
STL-like function for getting the beginning of the container.
Definition: EventFormat_v1.cxx:158
ReadStats.h
TAuxStore.h
xAOD::TEvent::m_inTree
::TTree * m_inTree
The main tree that we are reading from.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:429
xAOD::TAuxBranchManager::branch
::TBranch * branch()
Accessor to the branch.
Definition: TAuxBranchManager.cxx:82
xAOD::TEvent::getNames
void getNames(const std::string &targetClassName, std::vector< std::string > &vkeys, bool metadata=false) const override
Function determining the list keys associated with a type name.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:1725
xAOD::Utils::getTypeName
std::string getTypeName(const std::type_info &ti)
This function is necessary in order to create type names that ROOT can understand.
Definition: Control/xAODRootAccess/Root/Utils.cxx:285
lumiFormat.i
int i
Definition: lumiFormat.py:92
SG::OWN_ELEMENTS
@ OWN_ELEMENTS
this data object owns its elements
Definition: OwnershipPolicy.h:17
SG::AuxElement::setStore
void setStore(const SG::IConstAuxStore *store)
Set the store associated with this object.
Definition: AuxElement.cxx:221
ret
T ret(T t)
Definition: rootspy.cxx:260
xAOD::TEvent::getEntries
::Long64_t getEntries() const
Get how many entries are available from the current input file(s)
Definition: Control/xAODRootAccess/Root/TEvent.cxx:1293
IAuxStoreIO.h
Interface providing I/O for a generic auxiliary store.
xAOD::TEvent::m_auxItemList
std::unordered_map< std::string, std::set< std::string > > m_auxItemList
Rules for selecting which auxiliary branches to write.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:466
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
xAOD::TEvent::getEntry
::Int_t getEntry(::Long64_t entry, ::Int_t getall=0)
Function loading a given entry of the input TTree.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:1324
Message.h
CaloNoise_fillDB.dt
dt
Definition: CaloNoise_fillDB.py:58
xAOD::TIncident
Class describing a certain "incident" that is communicated to user code.
Definition: TIncident.h:58
xAOD::TChainStateTracker
Class helping with tracking the state of TChain objects.
Definition: TChainStateTracker.h:32
xAOD::TEvent::isStandalone
::Bool_t isStandalone(const TObjectManager &mgr)
Function checking if an object is standalone (not a container)
Definition: Control/xAODRootAccess/Root/TEvent.cxx:3637
sel
sel
Definition: SUSYToolsTester.cxx:92
xAOD::TAuxStore::kObjectStore
@ kObjectStore
The object describes a single object.
Definition: TAuxStore.h:56
SG::IAuxStoreIO::getSelectedAuxIDs
virtual SG::auxid_set_t getSelectedAuxIDs() const
Get a list of dynamic variables that need to be written out.
Definition: IAuxStoreIO.h:86
xAOD::TChainStateTracker::reset
void reset()
Reset the object.
Definition: TChainStateTracker.cxx:31
generateReferenceFile.files
files
Definition: generateReferenceFile.py:12
TEvent.h
checkCorrelInHIST.prefix
dictionary prefix
Definition: checkCorrelInHIST.py:391
file
TFile * file
Definition: tile_monitor.h:29
plotIsoValidation.el
el
Definition: plotIsoValidation.py:197
dumpFileToPlots.treeName
string treeName
Definition: dumpFileToPlots.py:20
xAOD::EventFormatElement::className
const std::string & className() const
Get the class name of this branch/key.
Definition: EventFormatElement.cxx:36
python.xAODType.dummy
dummy
Definition: xAODType.py:4
xAOD::ReadStats::setBranchNum
void setBranchNum(::Int_t num)
Set the total number of branches on the input.
Preparation.mode
mode
Definition: Preparation.py:95
xAOD::TEvent::m_inputEventFormat
EventFormat m_inputEventFormat
Format of the current input file.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:461
CxxUtils::ConcurrentBitset::empty
bool empty() const
Return true if there are no 1 bits in the set.
xAOD::TEventFormatRegistry::instance
static const TEventFormatRegistry & instance()
Access the only instance of the object in memory.
Definition: TEventFormatRegistry.cxx:14
xAOD::TEvent::contains
::Bool_t contains(const std::string &key)
Function checking if an object is available from the store.
plotmaker.keyName
keyName
Definition: plotmaker.py:145
xAOD::IOStats::instance
static IOStats & instance()
Singleton object accessor.
Definition: IOStats.cxx:11
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
xAOD::TEvent::setPrintEventProxyWarnings
void setPrintEventProxyWarnings(bool)
Function to silence warnings associated with broken element links.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:3697
xAOD::TEvent::m_listeners
Listener_t m_listeners
Listeners who should be notified when certain incidents happen.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:469
xAOD::TAuxStore::initStats
StatusCode initStats(::TTree *tree)
Function used for setting up the statistics info about the managed branches.
Definition: TAuxStore.cxx:851
normalizedTypeinfoName.h
Convert a type_info to a normalized string representation (matching the names used in the root dictio...
xAOD::TEvent::CACHE_SIZE
static const ::Int_t CACHE_SIZE
Size of a possible TTreeCache (30 MB)
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:419
xAOD::TEvent::m_outputMetaObjects
Object_t m_outputMetaObjects
Collection of all the managed output meta-objects.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:458
xAOD::TEvent::EVENT_TREE_NAME
static const char *const EVENT_TREE_NAME
Name of the event tree.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:421
xAOD::TEvent::m_outputObjects
Object_t m_outputObjects
Collection of all the managed output object.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:453
xAOD::TAuxStore::kContainerStore
@ kContainerStore
The object describes an entire container.
Definition: TAuxStore.h:55
TObjectManager.h
xAOD::TEvent::m_inputMetaObjects
Object_t m_inputMetaObjects
Collection of all the managed input meta-objects.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:456
AthContainers_detail::upgrading_lock::upgrade
void upgrade()
Convert the lock from upgrade to exclusive.
SG::IAuxStoreHolder::setStore
virtual void setStore(IAuxStore *store)=0
Give an auxiliary store object to the holder object.
GetAllXsec.entry
list entry
Definition: GetAllXsec.py:132
xAOD::TVirtualEvent::keys
void keys(std::vector< std::string > &vkeys, bool metadata=false) const
provide list of all keys associated with provided type.
xAOD::TEvent::m_branchesMutex
upgrade_mutex_t m_branchesMutex
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:491
xAOD::AuxSelection
Class helping in dealing with dynamic branch selection.
Definition: AuxSelection.h:31
TAuxManager.h
xAOD::TEvent::METADATA_TREE_NAME
static const char *const METADATA_TREE_NAME
Name of the metadata tree.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:423
xAOD::TChainStateTracker::internalStateChanged
::Bool_t internalStateChanged() const
Check whether there was an internal state change without us knowing.
Definition: TChainStateTracker.cxx:26
TActiveEvent.h
xAOD::EventFormat_v1
Event format metadata for xAOD files.
Definition: EventFormat_v1.h:38
xAOD::TEvent::record
StatusCode record(T *obj, const std::string &key, ::Int_t basketSize=32000, ::Int_t splitLevel=0)
Add an output object to the event.
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
xAOD::TEvent::TEvent
TEvent(EAuxMode mode=kUndefinedAccess)
Default constructor.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:131
xAOD::TEvent::m_inTreeMissing
::Bool_t m_inTreeMissing
Internal status flag showing that an input file is open, but it doesn't contain an event tree.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:432
xAOD::ReadStats::readContainer
void readContainer(const std::string &name)
Function incrementing the read counter on a specific container.
MakeNewFileFromOldAndSubstitution.newName
dictionary newName
Definition: ICHEP2016/MakeNewFileFromOldAndSubstitution.py:95
xAOD::TFileAccessTracer
Helper class keeping track of the files that got accessed.
Definition: TFileAccessTracer.h:46
xAOD::TEvent::initStats
StatusCode initStats()
Function to initialise the statistics for all Tree content.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:1961
xAOD::TObjectManager
Manager for EDM objects created by ROOT.
Definition: TObjectManager.h:29
SG::sgkey_t
uint32_t sgkey_t
Type used for hashed StoreGate key+CLID pairs.
Definition: CxxUtils/CxxUtils/sgkey_t.h:32
SG::IAuxStoreIO::getIOData
virtual const void * getIOData(SG::auxid_t auxid) const =0
Return a pointer to the data to be stored for one aux data item.
xAOD::TAuxManager
Manager for TAuxStore objects.
Definition: TAuxManager.h:33
xAOD::TEvent::fill
::Int_t fill()
Function filling one event into the output tree.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:1508
xAOD::PerfStats::instance
static PerfStats & instance()
Function accessing the singleton instance.
xAOD::TEventFormatRegistry::getEventFormat
EventFormat & getEventFormat(const TFile *file) const
Access the managed EventFormat object.
Definition: TEventFormatRegistry.cxx:20
xAOD::TEvent::transientContains
::Bool_t transientContains(const std::string &key) const
Function checking if an object is already in memory.
xAOD::TEvent::removeListener
StatusCode removeListener(TVirtualIncidentListener *listener)
Remove an incident listener object.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:946
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
xAOD::TEvent::isAuxStore
::Bool_t isAuxStore(const TObjectManager &mgr)
Function checking if a given object may be an auxiliary store.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:3614
xAOD::TEvent::connectAux
StatusCode connectAux(const std::string &prefix, ::Bool_t standalone)
Function setting up access to a set of auxiliary branches.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:2856
SG::IAuxStore
Interface for non-const operations on an auxiliary store.
Definition: IAuxStore.h:48
xAOD::TEvent::m_outputEventFormat
EventFormat * m_outputEventFormat
Format of the current output file.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:463
xAOD::TAuxStore::kUndefinedStore
@ kUndefinedStore
The structure mode is not defined.
Definition: TAuxStore.h:54
xAOD::TEvent::setUpDynamicStore
StatusCode setUpDynamicStore(TObjectManager &mgr, ::TTree *tree)
Function adding dynamic variable reading capabilities to an auxiliary store object.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:3088
xAOD::TAuxStore::selectAux
virtual void selectAux(const std::set< std::string > &attributes)
Select dynamic auxiliary attributes for writing.
Definition: TAuxStore.cxx:825
DeMoScan.index
string index
Definition: DeMoScan.py:362
xAOD::TEvent::EAuxMode
EAuxMode
Auxiliary store "mode".
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:95
xAOD::TEvent::getFiles
::Long64_t getFiles() const
Get how many files are available on the currently defined input.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:1452
xAOD::TStore
A relatively simple transient store for objects created in analysis.
Definition: TStore.h:44
xAOD::TEvent::addNameRemap
StatusCode addNameRemap(const std::string &onfile, const std::string &newName)
Add a name re-mapping rule.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:990
python.trfDecorators.silent
def silent(func)
Redirect stdout/err to /dev/null Useful wrapper to get rid of ROOT verbosity...
Definition: trfDecorators.py:24
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:109
xAOD::TEvent::ATLAS_THREAD_SAFE
SG::SGKeyMap< BranchInfo > m_branches ATLAS_THREAD_SAFE
Map from hashed sgkey to BranchInfo.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:494
xAOD::TEvent::hasAuxStore
::Bool_t hasAuxStore(const TObjectManager &mgr)
Function checking if a given object may have an auxiliary store.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:3593
xAOD::Utils::getFirstBranchMatch
std::string getFirstBranchMatch(TTree *tree, const std::string &pre)
Search for branches, returns search term on no result.
Definition: Control/xAODRootAccess/Root/Utils.cxx:318
xAOD::TEvent::connectBranch
StatusCode connectBranch(const std::string &key, ::Bool_t silent=kFALSE)
Function setting up access to a particular branch.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:2558
xAOD::TEvent::getHash
SG::sgkey_t getHash(const std::string &key) const override
Function returning the hash describing an object name.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:1649
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
xAOD::TObjectManager::holder
const THolder * holder() const
Accessor to the Holder object.
Definition: TObjectManager.cxx:82
xAOD::TEvent::m_entry
::Long64_t m_entry
The entry to look at from the input tree.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:442
THolder.h
Muon::print
std::string print(const MuPatSegment &)
Definition: MuonTrackSteering.cxx:28
xAOD::TAuxStore::structMode
EStructMode structMode() const
Get what structure mode the object was constructed with.
Definition: TAuxStore.cxx:88
xAOD::TEvent::inputEventFormat
const EventFormat * inputEventFormat() const
Get information about the input objects.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:1603
AuxTypeRegistry.h
Handle mappings between names and auxid_t.
xAOD::TPrimitiveAuxBranchManager::branch
::TBranch * branch()
Accessor to the branch.
Definition: TPrimitiveAuxBranchManager.cxx:84
xAOD::TAuxBranchManager::branchPtr
::TBranch ** branchPtr()
Pointer to the branch's pointer.
Definition: TAuxBranchManager.cxx:87
xAOD::TEvent::m_inChainTracker
TChainStateTracker * m_inChainTracker
Optional object for tracking the state changes of an input TChain.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:436
xAOD::TEvent::writeTo
StatusCode writeTo(::TFile *file, Int_t autoFlush=200, const char *treeName=EVENT_TREE_NAME)
Connect the object to an output file.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:692
ReadCalibFromCool.typeName
typeName
Definition: ReadCalibFromCool.py:477
collListGuids.attributes
attributes
Definition: collListGuids.py:46
xAOD::TEvent::readFrom
StatusCode readFrom(::TFile *file, Bool_t useTreeCache=kTRUE, const char *treeName=EVENT_TREE_NAME)
Connect the object to a new input file.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:364
SG::auxid_set_t
A set of aux data identifiers.
Definition: AuxTypes.h:47
AthContainers_detail::upgrading_lock
Lock object for taking out upgradable locks.
Definition: threading.h:248
xAOD::TEvent::Object_t
std::unordered_map< std::string, TVirtualManager * > Object_t
Definition of the internal data structure type.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:414
merge.status
status
Definition: merge.py:17
xAOD::EventFormat_v1::const_iterator
KeyedData_t::const_iterator const_iterator
Iterator for looping over the elements of the object.
Definition: EventFormat_v1.h:67
xAOD::TEvent::kBranchAccess
@ kBranchAccess
Access auxiliary data branch-by-branch.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:96
no_sanitize_undefined.h
Helper to disable undefined behavior sanitizer for a function.
xAOD::TEvent::setAuxItemList
void setAuxItemList(const std::string &containerKey, const std::string &itemList)
Configure which dynamic variables to write out for a given store.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:882
PowhegControl_ttFCNC_NLO.params
params
Definition: PowhegControl_ttFCNC_NLO.py:226
xAOD::EventFormat_v1::add
void add(const EventFormatElement &element, bool updatePersistent=true)
Add the description of a new branch.
Definition: EventFormat_v1.cxx:43
xAOD::TEvent::getName
const std::string & getName(const void *obj) const override
Function returning the key describing a known object.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:1684
xAOD::ReadStats
Class describing the access statistics of a collection of branches.
Definition: ReadStats.h:123
SG::IConstAuxStore
Interface for const operations on an auxiliary store.
Definition: IConstAuxStore.h:64
python.PyAthena.obj
obj
Definition: PyAthena.py:135
xAOD::TEvent::setActive
void setActive() const
Set this event object as the currently active one.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:860
SG::IAuxStoreHolder::AST_ObjectStore
@ AST_ObjectStore
The store describes a single object.
Definition: IAuxStoreHolder.h:67
SG::IAuxStoreHolder
Interface for objects taking part in direct ROOT I/O.
Definition: IAuxStoreHolder.h:36
xAOD::Utils::hash
SG::sgkey_t hash(const std::string &name)
This function provides a hashed version of the key (branch) names used in the xAOD file,...
Definition: Control/xAODRootAccess/Root/Utils.cxx:125
xAOD::TObjectManager::setObject
virtual void setObject(void *obj) override
Function replacing the object being handled.
Definition: TObjectManager.cxx:189
xAOD::TEvent::connectMetaBranch
StatusCode connectMetaBranch(const std::string &key, ::Bool_t silent=kFALSE)
Function setting up access to a branch in the metadata tree.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:2742
xAOD::TEvent::printIOStats
void printIOStats() const
Function printing the I/O statistics of the current process.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:347
TIncident.h
dq_make_web_display.cl
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
Definition: dq_make_web_display.py:26
xAOD::Utils::rootType
char rootType(char typeidType)
This function is used internally in the code when creating primitive dynamic auxiliary branches.
Definition: Control/xAODRootAccess/Root/Utils.cxx:226
xAOD::TAuxBranchManager::holder
const THolder * holder() const
Accessor to the Holder object (constant version)
Definition: TAuxBranchManager.cxx:92
TActiveStore.h
LheEventFiller_Common.ef
ef
Definition: SFGen_i/share/common/LheEventFiller_Common.py:7
TStore.h
xAOD::TEvent
Tool for accessing xAOD files outside of Athena.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:81
xAOD::TPrimitiveAuxBranchManager::holder
const THolder * holder() const
Accessor to the Holder object (constant version)
Definition: TPrimitiveAuxBranchManager.cxx:94
xAOD::TObjectManager::object
virtual const void * object() const override
Function getting a const pointer to the object being handled.
Definition: TObjectManager.cxx:175
xAOD::EventFormat_v1::exists
bool exists(const std::string &key) const
Check if a description exists about a given branch.
Definition: EventFormat_v1.cxx:65
AuxElement.h
Base class for elements of a container that can have aux data.
xAOD::TEvent::m_inputMissingObjects
std::set< std::string > m_inputMissingObjects
Objects that have been asked for, but were found to be missing in the current input.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:451
PlotCalibFromCool.br
br
Definition: PlotCalibFromCool.py:355
SG::IAuxStoreHolder::AST_ContainerStore
@ AST_ContainerStore
The store describes a container.
Definition: IAuxStoreHolder.h:68
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
xAOD::TEvent::connectMetaAux
StatusCode connectMetaAux(const std::string &prefix, ::Bool_t standalone)
Function setting up access to a set of auxiliary branches for a metadata object.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:2975
xAOD::TEvent::setAuxStore
StatusCode setAuxStore(TObjectManager &mgr, ::Bool_t metadata=kFALSE)
Function connecting a DV object to its auxiliary store.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:3172
xAOD::TEvent::clearListeners
void clearListeners()
Remove all listeners from the object.
Definition: Control/xAODRootAccess/Root/TEvent.cxx:970