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