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