ATLAS Offline Software
Loading...
Searching...
No Matches
xAOD::TEvent Class Reference

Tool for accessing xAOD files outside of Athena. More...

#include <TEvent.h>

Inheritance diagram for xAOD::TEvent:
Collaboration diagram for xAOD::TEvent:

Public Types

enum  EAuxMode { kBranchAccess = 0 , kClassAccess = 1 , kAthenaAccess = 2 }
 Auxiliary store "mode". More...
using sgkey_t = SG::sgkey_t

Public Member Functions

 TEvent (EAuxMode mode=kClassAccess)
 Default constructor.
 TEvent (::TFile *file, EAuxMode mode=kClassAccess)
 Constructor connecting the object to an input TFile.
 TEvent (::TTree *tree, EAuxMode mode=kClassAccess)
 Constructor connecting the objects to an input TTree/TChain.
virtual ~TEvent ()
 Destructor.
void setOtherMetaDataTreeNamePattern (const std::string &pattern)
 Change the pattern used for collecting information from other MetaData trees NB: Additional MetaData trees are only expected for augmented files This function also allows user to redefine MetaData tree pattern to skip trees that would not be proper MetaData ones i.e.
EAuxMode auxMode () const
 Get what auxiliary access mode the object was constructed with.
template<typename T>
bool retrieve (const T *&obj, sgkey_t key=DEFAULT_KEY, bool silent=false)
 Function retrieving an object from the event (constant version)
template<typename T>
bool retrieve (const T *&obj, const std::string &key, bool silent=false)
 Function retrieving an object from the event (constant version)
void setLevel (MSG::Level lvl)
 Change the current logging level.
Event data accessor/modifier functions
SG::IAuxStorerecordAux (const std::string &key, SG::IAuxStoreHolder::AuxStoreType type=SG::IAuxStoreHolder::AST_ContainerStore)
 Add an auxiliary store object to the output.
template<typename T>
StatusCode record (T *obj, const std::string &key)
 Add an output object to the event.
template<typename T>
StatusCode record (std::unique_ptr< T > obj, const std::string &key)
 Add an output object to the event, explicitly taking ownership of it.
Persistent data accessor/modifier functions
::Long64_t getEntries () const
 Get how many entries are available from the current input file(s)
::Int_t getEntry (::Long64_t entry, ::Int_t getall=0)
 Function loading a given entry of the input TTree.
::Long64_t getFiles () const
 Get how many files are available on the currently defined input.
::Int_t getFile (::Long64_t file, ::Int_t getall=0)
 Load the first event for a given file from the input TChain.
::Int_t fill ()
 Function filling one event into the output tree.
Setup functions
void setActive () const
 Set this event object as the currently active one.
void setAuxItemList (const std::string &containerKey, const std::string &itemList)
 Configure which dynamic variables to write out for a given store.
StatusCode addListener (TVirtualIncidentListener *listener)
 Register an incident listener object.
StatusCode removeListener (TVirtualIncidentListener *listener)
 Remove an incident listener object.
void clearListeners ()
 Remove all listeners from the object.
StatusCode addNameRemap (const std::string &onfile, const std::string &newName)
 Add a name re-mapping rule.
void clearNameRemap ()
 Clear the current name re-mapping.
void printNameRemap () const
 Print the current name re-mapping rules.
void printProxyWarnings (bool value=true)
 Enable warnings associated with broken element links.
Persistent data accessor/modifier functions
const EventFormatinputEventFormat () const
 Get information about the input objects.
const EventFormatoutputEventFormat () const
 Get information about the output objects.
Event data accessor/modifier functions
std::string dump ()
 Function creating a user-readable dump of the current input.
void printIOStats () const
 Function printing the I/O statistics of the current process.
template<typename T>
bool contains (const std::string &key)
 Function checking if an object is available from the store.
template<typename T>
bool transientContains (const std::string &key) const
 Function checking if an object is already in memory.
template<typename T>
StatusCode keys (std::vector< std::string > &vkeys, bool metadata) const
 Provide a list of all data object keys associated with a specific type.
template<typename T>
StatusCode retrieve (const T *&obj, const std::string &key)
 Retrieve either an input or an output object from the event.
template<typename T>
StatusCode retrieve (T *&obj, const std::string &key)
 Retrieve an output object from the event.
StatusCode copy (const std::string &pattern=".*")
 Copy an object directly from the input to the output.
Metadata accessor/modifier functions
template<typename T>
bool containsMeta (const std::string &key)
 Function checking if a meta-object is available from the store.
template<typename T>
bool transientContainsMeta (const std::string &key) const
 Function checking if a meta-object is already in memory.
template<typename T>
StatusCode metaKeys (std::vector< std::string > &vkeys) const
 Provide a list of all metadata object keys associated with a specific type.
template<typename T>
StatusCode retrieveMetaInput (const T *&obj, const std::string &key)
 Retrieve an input metadata object.
template<typename T>
StatusCode retrieveMetaOutput (const T *&obj, const std::string &key)
 Retrieve an output metadata object.
template<typename T>
StatusCode retrieveMetaOutput (T *&obj, const std::string &key)
 Retrieve an output metadata object.
template<typename T>
StatusCode recordMeta (T *obj, const std::string &key)
 Add an object to the output file's metadata.
template<typename T>
StatusCode recordMeta (std::unique_ptr< T > obj, const std::string &key)
 Add an object to the output file's metadata, explicitly taking ownership of it.
Functions providing the same interface as AthMessaging
bool msgLvl (const MSG::Level lvl) const
 Test the output level of the object.
MsgStream & msg () const
 The standard message stream.
MsgStream & msg (const MSG::Level lvl) const
 The standard message stream.

Static Public Attributes

static constexpr sgkey_t DEFAULT_KEY = ~static_cast<sgkey_t>(0)
 Key for retrieving the "default" object of a given type.
static constexpr sgkey_t KEY_MASK = DEFAULT_KEY >> 2
 Mask for the keys, used mostly internally.

Protected Types

using Object_t
 Definition of the internal data structure type.

Protected Member Functions

StatusCode initStats ()
 Function to initialise the statistics for all Tree content.
StatusCode record (std::unique_ptr< TAuxStore > store, const std::string &key)
 Internal function for adding an auxiliary store object to the output.
StatusCode setUpDynamicStore (TObjectManager &mgr, ::TTree *tree)
 Function adding dynamic variable reading capabilities to an auxiliary store object.
StatusCode putAux (::TTree &outTree, TVirtualManager &mgr, bool metadata)
 Function saving the dynamically created auxiliary properties.
StatusCode recordAux (TAuxStore *store, const std::string &key)
 Function setting up an existing auxiliary store for writing.
bool contains (const std::string &key, const std::type_info &ti, bool metadata)
 Internal function checking if an object is in the input.
bool transientContains (const std::string &key, const std::type_info &ti, bool metadata) const
 Internal function checking if an object is already in memory.
void * getOutputObject (const std::string &key, const std::type_info &ti, bool metadata) const
 Function for retrieving an output object in a non-template way.
const void * getInputObject (const std::string &key, const std::type_info &ti, bool silent, bool metadata)
 Function for retrieving an input object in a non-template way.
StatusCode recordTypeless (void *obj, const std::string &typeName, const std::string &key, bool overwrite=false, bool metadata=true, bool isOwner=true)
 Internal function for recording an object into the output.
Functions implemented from @c xAOD::Event
bool hasInput () const override
 Check if an input file is connected to the object.
bool hasOutput () const override
 Check if an output file is connected to the object.
StatusCode getNames (const std::string &targetClassName, std::vector< std::string > &vkeys, bool metadata) const override
 Function determining the list keys associated with a type name.
StatusCode connectObject (const std::string &key, bool silent) override
 Function setting up access to a particular object.
StatusCode connectMetaObject (const std::string &key, bool silent) override
 Function setting up access to a particular metadata object.
StatusCode connectAux (const std::string &prefix, bool standalone) override
 Function setting up access to a set of auxiliary branches.
StatusCode connectMetaAux (const std::string &prefix, bool standalone) override
 Function setting up access to a set of auxiliary branches for a metadata object.
StatusCode setAuxStore (const std::string &key, Details::IObjectManager &mgr, bool metadata) override
 Function connecting a DV object to its auxiliary store.
StatusCode record (void *obj, const std::string &typeName, const std::string &key, bool overwrite, bool metadata, bool isOwner) override
 Record an object into a connected output file.
StatusCode recordAux (TVirtualManager &mgr, const std::string &key, bool metadata) override
 Record an auxiliary store into a connected output file.
Functions implementing the IProxyDict interface
SG::DataProxyproxy (const void *const pTransient) const override
 get proxy for a given data object address in memory
SG::DataProxyproxy (const CLID &id, const std::string &key) const override
 get proxy with given id and key. Returns 0 to flag failure
SG::DataProxyproxy_exact (SG::sgkey_t sgkey) const override
 Get proxy given a hashed key+clid.
StatusCode addToStore (CLID id, SG::DataProxy *proxy) override
 Add a new proxy to the store.
std::vector< const SG::DataProxy * > proxies () const override
 return the list of all current proxies in store
SG::sgkey_t stringToKey (const std::string &str, CLID clid) override
 Find the string corresponding to a given key.
const std::string * keyToString (SG::sgkey_t key) const override
 Find the string corresponding to a given key.
const std::string * keyToString (SG::sgkey_t key, CLID &clid) const override
 Find the string and CLID corresponding to a given key.
void registerKey (SG::sgkey_t key, const std::string &str, CLID clid) override
 Remember an additional mapping from key to string/CLID.
SG::DataProxyrecordObject (SG::DataObjectSharedPtr< DataObject > obj, const std::string &key, bool allowMods, bool returnExisting) override
 Record an object in the store.
const std::string & name () const override
 Get the name of the instance.
Helper functions for the IProxyDict interface
const xAOD::EventFormatElementgetEventFormatElement (SG::sgkey_t sgkey) const
 Get the metadata object for a given "SG key".
const BranchInfogetBranchInfo (SG::sgkey_t sgkey) const
 Get the object describing one object/branch.

Protected Attributes

EAuxMode m_auxMode
 The auxiliary access mode.
::TTree * m_inTree = nullptr
 The main tree that we are reading from.
bool m_inTreeMissing = false
 Internal status flag showing that an input file is open, but it doesn't contain an event tree.
::TChain * m_inChain = nullptr
 The (optional) chain provided as input.
std::unique_ptr< TChainStateTrackerm_inChainTracker
 Optional object for tracking the state changes of an input TChain.
::Int_t m_inTreeNumber = -1
 The number of the currently open tree in the input chain.
::TTree * m_inMetaTree = nullptr
 Pointer to the metadata tree in the input file.
::Long64_t m_entry = -1
 The entry to look at from the input tree.
std::unique_ptr<::TTree > m_outTree
 The tree that we are writing to.
std::regex m_otherMetaDataTreeNamePattern
Object_t m_inputObjects
 Collection of all the managed input objects.
std::set< std::string > m_inputMissingObjects
 Objects that have been asked for, but were found to be missing in the current input.
Object_t m_outputObjects
 Collection of all the managed output object.
Object_t m_inputMetaObjects
 Collection of all the managed input meta-objects.
Object_t m_outputMetaObjects
 Collection of all the managed output meta-objects.
EventFormat m_inputEventFormat
 Format of the current input file.
EventFormatm_outputEventFormat = nullptr
 Format of the current output file.
std::unordered_map< std::string, std::set< std::string > > m_auxItemList
 Rules for selecting which auxiliary branches to write.
std::vector< TVirtualIncidentListener * > m_listeners
 Listeners who should be notified when certain incidents happen.
std::unordered_map< std::string, std::string > m_nameRemapping
 Container name re-mapping rules.
bool m_printEventProxyWarnings = false
 Option to silence common warnings that seem to be harmless.

Private Member Functions

friend::TTree * MakeTransientTree (TEvent &, const char *)
void initMessaging () const
 Initialize our message level and MessageSvc.

Private Attributes

std::string m_nm
 Message source name.
boost::thread_specific_ptr< MsgStream > m_msg_tls
 MsgStream instance (a std::cout like with print-out levels)
std::atomic< IMessageSvc * > m_imsg { nullptr }
 MessageSvc pointer.
std::atomic< MSG::Level > m_lvl { MSG::NIL }
 Current logging level.

Friends

class ::xAODTEventBranch
class ::xAODTMetaBranch
class xAOD::TFileMerger
class xAOD::TTreeMgr
class CP::xAODWriterAlg

Setup functions

static const char *const EVENT_TREE_NAME = "CollectionTree"
 Default name of the event tree.
StatusCode readFrom (::TFile *file, bool useTreeCache=true, std::string_view treeName=EVENT_TREE_NAME)
 Connect the object to a new input file.
StatusCode readFrom (::TTree *tree, bool useTreeCache=true)
 Connect the object to a new input tree/chain.
StatusCode writeTo (::TFile *file, int autoFlush=200, std::string_view treeName=EVENT_TREE_NAME)
 Connect the object to an output file.
StatusCode finishWritingTo (::TFile *file)
 Finish writing to an output file.

Variable(s) used in the @c IProxyDict implementation

upgrade_mutex_t m_branchesMutex
 Mutex for multithread synchronization.
SG::SGKeyMap< BranchInfo > m_branches ATLAS_THREAD_SAFE
 Map from hashed sgkey to BranchInfo.
using upgrade_mutex_t = AthContainers_detail::upgrade_mutex
 Mutex type for multithread synchronization.
using upgrading_lock_t
 Lock type for multithread synchronization.

Functions implementing the @c xAOD::TVirtualEvent interface

SG::sgkey_t getHash (const std::string &key) const override
 Function returning the hash describing an object name.
SG::sgkey_t getKey (const void *obj) const override
 Function returning the hash describing a known object.
const std::string & getName (const void *obj) const override
 Function returning the key describing a known object.
const std::string & getName (SG::sgkey_t hash) const override
 Function returning the key describing a known object.
void * getOutputObject (SG::sgkey_t key, const std::type_info &ti) override
 Function for retrieving an output object in a non-template way.
const void * getInputObject (SG::sgkey_t key, const std::type_info &ti, bool silent) override
 Function for retrieving an input object in a non-template way.

Detailed Description

Tool for accessing xAOD files outside of Athena.

Proper access to xAOD files in ROOT (outside of Athena) needs to be done through such an object. It takes care of reading and writing xAOD files together with their file format metadata, setting up smart pointers correctly, etc.

For a detailed description of the usage of this class, see: <Link to be added here...>

Author
Attila Krasznahorkay Attil.nosp@m.a.Kr.nosp@m.aszna.nosp@m.hork.nosp@m.ay@ce.nosp@m.rn.c.nosp@m.h

Definition at line 59 of file Control/xAODRootAccess/xAODRootAccess/TEvent.h.

Member Typedef Documentation

◆ Object_t

using xAOD::Event::Object_t
protectedinherited
Initial value:
std::unordered_map<std::string, std::unique_ptr<TVirtualManager>>

Definition of the internal data structure type.

Definition at line 304 of file Event.h.

◆ sgkey_t

Definition at line 29 of file TVirtualEvent.h.

◆ upgrade_mutex_t

using xAOD::Event::upgrade_mutex_t = AthContainers_detail::upgrade_mutex
protectedinherited

Mutex type for multithread synchronization.

Definition at line 349 of file Event.h.

◆ upgrading_lock_t

using xAOD::Event::upgrading_lock_t
protectedinherited
Initial value:

Lock type for multithread synchronization.

Definition at line 351 of file Event.h.

Member Enumeration Documentation

◆ EAuxMode

Auxiliary store "mode".

Enumerator
kBranchAccess 

Access auxiliary data branch-by-branch.

kClassAccess 

Access auxiliary data using the aux containers.

kAthenaAccess 

Access containers/objects like Athena does.

Definition at line 71 of file Control/xAODRootAccess/xAODRootAccess/TEvent.h.

71 {
72 kBranchAccess = 0,
73 kClassAccess = 1,
74 kAthenaAccess = 2
75 };
@ kAthenaAccess
Access containers/objects like Athena does.
@ kClassAccess
Access auxiliary data using the aux containers.
@ kBranchAccess
Access auxiliary data branch-by-branch.

Constructor & Destructor Documentation

◆ TEvent() [1/3]

xAOD::TEvent::TEvent ( EAuxMode mode = kClassAccess)

Default constructor.

Definition at line 77 of file Control/xAODRootAccess/Root/TEvent.cxx.

77: Event("xAOD::TEvent"), m_auxMode(mode) {}
Event(std::string_view name)
Constructor with a name.
Definition EventCore.cxx:27
EAuxMode m_auxMode
The auxiliary access mode.

◆ TEvent() [2/3]

xAOD::TEvent::TEvent ( ::TFile * file,
EAuxMode mode = kClassAccess )

Constructor connecting the object to an input TFile.

Definition at line 79 of file Control/xAODRootAccess/Root/TEvent.cxx.

79 : TEvent(mode) {
80
81 // Let the initialisation function deal with setting up the object.
82 readFrom(file).ignore();
83}
StatusCode readFrom(::TFile *file, bool useTreeCache=true, std::string_view treeName=EVENT_TREE_NAME)
Connect the object to a new input file.
TEvent(EAuxMode mode=kClassAccess)
Default constructor.
TFile * file

◆ TEvent() [3/3]

xAOD::TEvent::TEvent ( ::TTree * tree,
EAuxMode mode = kClassAccess )

Constructor connecting the objects to an input TTree/TChain.

Definition at line 85 of file Control/xAODRootAccess/Root/TEvent.cxx.

85 : TEvent(mode) {
86
87 // Let the initialisation function deal with setting up the object.
88 readFrom(tree).ignore();
89}
TChain * tree

◆ ~TEvent()

xAOD::TEvent::~TEvent ( )
virtual

Destructor.

Definition at line 91 of file Control/xAODRootAccess/Root/TEvent.cxx.

91 {
92
93 // Check that the user didn't forget to call finishWritingTo().
94 if (m_outTree) {
96 "Did not call finishWritingTo() before destroying the TEvent object!");
97 }
98
99 // Clear the input and output objects before the input/output files would be
100 // closed. Otherwise we can be left with "TTree related" objects pointing
101 // nowhere.
102 m_inputObjects.clear();
103 m_outputObjects.clear();
104}
#define ATH_MSG_ERROR(x)
Object_t m_inputObjects
Collection of all the managed input objects.
Definition Event.h:308
Object_t m_outputObjects
Collection of all the managed output object.
Definition Event.h:313
std::unique_ptr<::TTree > m_outTree
The tree that we are writing to.

Member Function Documentation

◆ addListener()

StatusCode Event::addListener ( TVirtualIncidentListener * listener)
inherited

Register an incident listener object.

This function works pretty much like IIncidentSvc::addListener does in Athena.

It tells the TEvent object that when certain "interesting incidents" happen, a given object should be notified about it.

Parameters
listenerPointer to the object that should be notified
Returns
The usual StatusCode types

Definition at line 97 of file EventCore.cxx.

97 {
98
99 // Check that we received a valid pointer:
100 if (listener == nullptr) {
101 ATH_MSG_ERROR("Received a null pointer for the listener");
102 return StatusCode::FAILURE;
103 }
104
105 // Check whether we already have this listener.
106 auto itr = std::find(m_listeners.begin(), m_listeners.end(), listener);
107 if (itr != m_listeners.end()) {
108 ATH_MSG_WARNING("Listener " << static_cast<void*>(listener)
109 << " is already registered");
110 return StatusCode::SUCCESS;
111 }
112
113 // Add the listener.
114 m_listeners.push_back(listener);
115
116 // Return gracefully:
117 return StatusCode::SUCCESS;
118}
#define ATH_MSG_WARNING(x)
std::vector< TVirtualIncidentListener * > m_listeners
Listeners who should be notified when certain incidents happen.
Definition Event.h:329

◆ addNameRemap()

StatusCode Event::addNameRemap ( const std::string & onfile,
const std::string & newName )
inherited

Add a name re-mapping rule.

The names of containers can change during the lifetime of the experiment.

One such change happened after the DC14 exercise, when many containers got a new name. (Like "ElectronCollection" became simply "Electrons".)

This function allows us to create aliases with which certain containers should be accessible. So that the analyser would be able to access older files, while using the latest container name(s).

Parameters
onfileThe name of the container as it was saved into the input file
newNameThe alias with which the object/container should be accessible
Returns
The usual StatusCode types

Save the new name association:

Definition at line 162 of file EventCore.cxx.

163 {
164
165 // Check if this name is known on the input or output already. As that's
166 // not good.
167 if (m_inputEventFormat.exists(newName)) {
168 ATH_MSG_ERROR("Can't use \"" << newName << "\" as the target name in the \""
169 << onfile << "\" -> \"" << newName
170 << "\" remapping");
171 return StatusCode::FAILURE;
172 }
173
174 // Check if this name was remapped to something already.
175 auto itr = m_nameRemapping.find(newName);
176 if (itr != m_nameRemapping.end()) {
177 ATH_MSG_WARNING("Overriding existing name remapping \""
178 << itr->second << "\" -> \"" << itr->first << "\" with: \""
179 << onfile << "\" -> \"" << newName << "\"");
180 }
181
183 m_nameRemapping[newName] = onfile;
184
185 // Return gracefully:
186 return StatusCode::SUCCESS;
187}
EventFormat m_inputEventFormat
Format of the current input file.
Definition Event.h:321
std::unordered_map< std::string, std::string > m_nameRemapping
Container name re-mapping rules.
Definition Event.h:332

◆ addToStore()

StatusCode Event::addToStore ( CLID clid,
SG::DataProxy * proxy )
overrideprotectedinherited

Add a new proxy to the store.

Smart pointers to objects that don't exist in the input event, can end up calling this function.

In this case warn the user that something fishy is happening, and take posession of the received proxy.

Parameters
clidThe CLID of the type. Not taken into account.
proxyThe proxy to take posession of. Not used for anything useful.

Definition at line 251 of file EventIProxyDict.cxx.

251 {
252
254
255 // Warn the user that the function got called:
256 static std::atomic_flag warningPrinted ATLAS_THREAD_SAFE = ATOMIC_FLAG_INIT;
257 if (!warningPrinted.test_and_set() && m_printEventProxyWarnings) {
259 "Function should only be called through an invalid ElementLink");
260 }
261
262 // Hold on to the proxy with some non-existent, hopefully unique key:
263 const ::TString uniqueKey =
264 ::TString::Format("NonExistentKey_%lu", m_branches.size());
265 BranchInfo bi;
266 bi.m_proxy.reset(proxy);
267 lock.upgrade();
268 m_branches.insert(
269 std::make_pair(stringToKey(uniqueKey.Data(), clid), std::move(bi)));
270
271 // Return gracefully:
272 return StatusCode::SUCCESS;
273}
SG::sgkey_t stringToKey(const std::string &str, CLID clid) override
Find the string corresponding to a given key.
upgrade_mutex_t m_branchesMutex
Mutex for multithread synchronization.
Definition Event.h:354
AthContainers_detail::upgrading_lock< upgrade_mutex_t > upgrading_lock_t
Lock type for multithread synchronization.
Definition Event.h:351
bool m_printEventProxyWarnings
Option to silence common warnings that seem to be harmless.
Definition Event.h:335
SG::SGKeyMap< BranchInfo > m_branches ATLAS_THREAD_SAFE
Map from hashed sgkey to BranchInfo.
Definition Event.h:358
SG::DataProxy * proxy(const void *const pTransient) const override
get proxy for a given data object address in memory
Helper struct used by the IProxyDict code.
Definition Event.h:341
std::unique_ptr< SG::DataProxy > m_proxy
Data proxy describing this branch/object.
Definition Event.h:343

◆ auxMode()

TEvent::EAuxMode xAOD::TEvent::auxMode ( ) const

Get what auxiliary access mode the object was constructed with.

Returns
The auxiliary data access mode currently in use

Definition at line 108 of file Control/xAODRootAccess/Root/TEvent.cxx.

108{ return m_auxMode; }

◆ clearListeners()

void Event::clearListeners ( )
inherited

Remove all listeners from the object.

This function can be used to remove all the listeners from the internal list.

Should not be necessary under regular circumstances.

Definition at line 143 of file EventCore.cxx.

143 {
144
145 m_listeners.clear();
146}

◆ clearNameRemap()

void Event::clearNameRemap ( )
inherited

Clear the current name re-mapping.

This function simply clears out any existing name remapping declarations.

In case the remapping rules need to be changed in the code in some complicated way.

Definition at line 193 of file EventCore.cxx.

193 {
194
195 m_nameRemapping.clear();
196}

◆ connectAux()

StatusCode xAOD::TEvent::connectAux ( const std::string & prefix,
bool standalone )
overrideprotectedvirtual

Function setting up access to a set of auxiliary branches.

This function is used internally to connect an auxiliary object to the input.

Based on the configuration of the object it will either use TAuxStore, or the EDM object that was used to write the auxiliary information in Athena.

Parameters
prefixThe prefix (main branch name) of the auxiliary data
standaloneType of the auxiliary store that should be created
Returns
The usual StatusCode types

Implements xAOD::Event.

Definition at line 1331 of file Control/xAODRootAccess/Root/TEvent.cxx.

1331 {
1332
1333 // A simple test...
1334 if (hasInput() == false) {
1335 ATH_MSG_ERROR("No input tree is available");
1336 return StatusCode::FAILURE;
1337 }
1338
1339 // Check if we know anything about this auxiliary object:
1340 if ((!m_inTree->GetBranch(prefix.c_str())) &&
1342 // If not, then let's just return right away. Not having
1343 // an auxiliary object with this name is not an error per se.
1344 return StatusCode::SUCCESS;
1345 }
1346
1347 // Check if the branch is already connected.
1348 if (m_inputObjects.contains(prefix)) {
1349 return StatusCode::SUCCESS;
1350 }
1351
1352 // Do different things based on the "auxiliary mode" we are in.
1353 if ((m_auxMode == kClassAccess) || (m_auxMode == kAthenaAccess)) {
1354
1355 // In "class" and "athena" access modes just connect the concrete auxiliary
1356 // object to the input.
1357 static constexpr bool SILENT = false;
1358 ATH_CHECK(connectObject(prefix, SILENT));
1359
1360 // Return gracefully.
1361 return StatusCode::SUCCESS;
1362
1363 } else if (m_auxMode == kBranchAccess) {
1364
1365 // In "branch access mode" let's create a TAuxStore object, and let
1366 // that take care of the auxiliary store access.
1367 static constexpr bool TOP_STORE = true;
1368 auto store = std::make_unique<TAuxStore>(
1369 prefix, TOP_STORE,
1372
1373 // Connect it to the input tree.
1374 ATH_CHECK(store->readFrom(*m_inTree));
1375
1376 // We're using this object to read from the input, it needs to be
1377 // locked:
1378 store->lock();
1379
1380 // Finally, set up an appropriate manager for it.
1381 static constexpr bool IS_OWNER = true;
1383 std::make_unique<TAuxManager>(store.release(), IS_OWNER);
1384
1385 // Return gracefully:
1386 return StatusCode::SUCCESS;
1387 }
1388
1389 // There was some problem:
1390 ATH_MSG_ERROR("Unknown auxiliary access mode set (" << m_auxMode << ")");
1391 return StatusCode::FAILURE;
1392}
#define ATH_CHECK
Evaluate an expression and check for errors.
StatusCode connectObject(const std::string &key, bool silent) override
Function setting up access to a particular object.
bool hasInput() const override
Check if an input file is connected to the object.
::TTree * m_inTree
The main tree that we are reading from.
@ kObjectStore
The object describes a single object.
@ kContainerStore
The object describes an entire container.
@ SILENT
don't print anything and return success
TestStore store
Definition TestStore.cxx:23

◆ connectMetaAux()

StatusCode xAOD::TEvent::connectMetaAux ( const std::string & prefix,
bool standalone )
overrideprotectedvirtual

Function setting up access to a set of auxiliary branches for a metadata object.

This function is used internally to connect an auxiliary metadata object to the input.

Based on the configuration of the object it will either use TAuxStore, or the EDM object that was used to write the auxiliary information in Athena.

Parameters
prefixThe prefix (main branch name) of the auxiliary data
standaloneType of the auxiliary store that should be created
Returns
The usual StatusCode types

Implements xAOD::Event.

Definition at line 1403 of file Control/xAODRootAccess/Root/TEvent.cxx.

1403 {
1404
1405 // Check if the branch is already connected:
1406 if (m_inputMetaObjects.contains(prefix)) {
1407 return StatusCode::SUCCESS;
1408 }
1409
1410 // A sanity check:
1411 if (!m_inMetaTree) {
1412 ATH_MSG_FATAL("Internal logic error detected");
1413 return StatusCode::FAILURE;
1414 }
1415
1416 // Do different things based on the "auxiliary mode" we are in:
1418
1419 // In "class" and "athena" access modes just connect the concrete auxiliary
1420 // object to the input.
1421 static constexpr bool SILENT = false;
1422 ATH_CHECK(connectMetaObject(prefix, SILENT));
1423
1424 // Return gracefully:
1425 return StatusCode::SUCCESS;
1426
1427 } else if (m_auxMode == kBranchAccess) {
1428
1429 // In "branch access mode" let's create a TAuxStore object, and let
1430 // that take care of the auxiliary store access.
1431 static constexpr bool TOP_STORE = true;
1432 auto store = std::make_unique<TAuxStore>(
1433 prefix, TOP_STORE,
1436
1437 // Connect it to the input tree.
1438 ATH_CHECK(store->readFrom(*m_inMetaTree));
1439
1440 // We're using this object to read from the input, it needs to be
1441 // locked:
1442 store->lock();
1443
1444 // Finally, set up an appropriate manager for it.
1445 static constexpr bool IS_OWNER = true;
1447 std::make_unique<TAuxManager>(store.release(), IS_OWNER);
1448
1449 // Return gracefully.
1450 return StatusCode::SUCCESS;
1451 }
1452
1453 // There was some problem:
1454 ATH_MSG_ERROR("Unknown auxiliary access mode set (" << m_auxMode << ")");
1455 return StatusCode::FAILURE;
1456}
#define ATH_MSG_FATAL(x)
Object_t m_inputMetaObjects
Collection of all the managed input meta-objects.
Definition Event.h:316
::TTree * m_inMetaTree
Pointer to the metadata tree in the input file.
StatusCode connectMetaObject(const std::string &key, bool silent) override
Function setting up access to a particular metadata object.

◆ connectMetaObject()

StatusCode xAOD::TEvent::connectMetaObject ( const std::string & key,
bool silent )
overrideprotectedvirtual

Function setting up access to a particular metadata object.

This is the function doing the heavy lifting with creating metadata objects in memory out of the payload of the input file.

Parameters
keyThe key (branch name) of the metadata object to retrieve
silentSet to kTRUE to make the code fail silently in case the branch can't be connected to
Returns
The usual StatusCode types

Implements xAOD::Event.

Definition at line 1230 of file Control/xAODRootAccess/Root/TEvent.cxx.

1230 {
1231
1232 // A little sanity check:
1233 if (!m_inMetaTree) {
1234 ATH_MSG_ERROR("Function called on un-initialised object");
1235 return StatusCode::FAILURE;
1236 }
1237
1238 // Check if the branch is already connected:
1239 if (m_inputMetaObjects.contains(key)) {
1240 return StatusCode::SUCCESS;
1241 }
1242
1243 // Check if the branch exists in our metadata tree:
1244 ::TBranch *br = m_inMetaTree->GetBranch(key.c_str());
1245 if (br == nullptr) {
1246 if (silent == false) {
1247 ATH_MSG_WARNING("Metadata branch \"" << key
1248 << "\" not available on input");
1249 }
1250 return StatusCode::RECOVERABLE;
1251 }
1252
1253 // Check that we have an entry in the branch:
1254 if (br->GetEntries() == 0) {
1255 if (silent == false) {
1256 ATH_MSG_WARNING("Metadata branch \"" << key
1257 << "\" doesn't hold any data");
1258 }
1259 return StatusCode::RECOVERABLE;
1260 }
1261
1262 // Make sure that it's not in "MakeClass mode":
1263 br->SetMakeClass(0);
1264
1265 // Extract the type of the branch:
1266 ::TClass *cl = 0;
1267 ::EDataType dt = kOther_t;
1268 if (br->GetExpectedType(cl, dt) || (!cl)) {
1269 ATH_MSG_ERROR("Couldn't get the type for metadata branch \"" << key
1270 << "\"");
1271 return StatusCode::FAILURE;
1272 }
1273
1274 // Create the object, and all of the managers around it:
1275 void *ptr = cl->New();
1276 const bool renewOnRead = (m_auxMode == kAthenaAccess);
1277 auto mgr = std::make_unique<TObjectManager>(
1278 nullptr, std::make_unique<THolder>(ptr, cl), renewOnRead);
1279
1280 // Now try to connect to the branch:
1281 const ::Int_t status = m_inMetaTree->SetBranchAddress(
1282 key.c_str(), mgr->holder()->getPtr(), mgr->branchPtr(), cl, dt, kTRUE);
1283 if (status < 0) {
1284 ATH_MSG_ERROR("Couldn't connect variable of type \""
1285 << cl->GetName() << "\" to input branch \"" << key
1286 << "\". Return code: " << status);
1287 // Clean up:
1288 *(mgr->holder()->getPtr()) = 0;
1289 m_inputMetaObjects.erase(key);
1290 return StatusCode::FAILURE;
1291 }
1292
1293 // Store the manager.
1294 TObjectManager *mgrPtr = mgr.get();
1295 m_inputMetaObjects[key] = std::move(mgr);
1296
1297 // Read in the object:
1298 if (mgrPtr->getEntry() < 0) {
1299 ATH_MSG_ERROR("Couldn't read in metadata object with key \"" << key
1300 << "\"");
1301 return StatusCode::FAILURE;
1302 }
1303
1304 // If it's an auxiliary store object, set it up correctly:
1305 if (Details::isAuxStore(*(mgrPtr->holder()->getClass()))) {
1307 }
1308
1309 // If there may be an auxiliary object connected to this one,
1310 // connect that as well.
1311 if (Details::hasAuxStore(*(mgrPtr->holder()->getClass()))) {
1313 key + "Aux.", Details::isStandalone(*(mgrPtr->holder()->getClass()))));
1314 static constexpr bool METADATA = true;
1315 ATH_CHECK(setAuxStore(key, *mgrPtr, METADATA));
1316 }
1317
1318 // We succeeded:
1319 return StatusCode::SUCCESS;
1320}
StatusCode connectMetaAux(const std::string &prefix, bool standalone) override
Function setting up access to a set of auxiliary branches for a metadata object.
StatusCode setAuxStore(const std::string &key, Details::IObjectManager &mgr, bool metadata) override
Function connecting a DV object to its auxiliary store.
StatusCode setUpDynamicStore(TObjectManager &mgr, ::TTree *tree)
Function adding dynamic variable reading capabilities to an auxiliary store object.
void * ptr(T *p)
Definition SGImplSvc.cxx:74
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
status
Definition merge.py:16
bool hasAuxStore(const TClass &cl)
Helper function deciding if a given type "has an auxiliary store".
Definition IOUtils.cxx:40
bool isAuxStore(const TClass &cl)
Helper function deciding if a given type "is an auxiliary store".
Definition IOUtils.cxx:53
bool isStandalone(const TClass &cl)
Helper function deciding if a given type "is a standalone object".
Definition IOUtils.cxx:65

◆ connectObject()

StatusCode xAOD::TEvent::connectObject ( const std::string & key,
bool silent )
overrideprotectedvirtual

Function setting up access to a particular object.

This is one of the more important functions of the class.

It connects the event object to a given branch of the input TTree.

The type that is read in to memory is not actually determined by the type written to the tree itself, but from the xAOD::EventFormat object. Which is there to make it possible to possibly use ROOT read rules in the future to read a different type than what's on disk.

Everything else is fairly basic ROOT stuff, the code just has to make sure that the memory management is set up correctly for the created object.

Parameters
keyThe name of the branch to connect to
silentSet to true to make the code fail silently in case the branch can't be connected to
Returns
The usual StatusCode types

Implements xAOD::Event.

Definition at line 1061 of file Control/xAODRootAccess/Root/TEvent.cxx.

1061 {
1062
1063 // A little sanity check:
1064 if (hasInput() == false) {
1065 ATH_MSG_ERROR("Function called on un-initialised object");
1066 return StatusCode::FAILURE;
1067 }
1068
1069 // Increment the access counter on this container:
1071
1072 // Check if the branch is already connected:
1073 if (m_inputObjects.contains(key)) {
1074 return StatusCode::SUCCESS;
1075 }
1076 // Check if it was already found to be missing.
1077 if (m_inputMissingObjects.contains(key)) {
1078 if (silent == false) {
1079 ATH_MSG_WARNING("Branch \"" << key << "\" not available on input");
1080 }
1081 return StatusCode::RECOVERABLE;
1082 }
1083
1084 // Check if we have metadata about this branch:
1085 const xAOD::EventFormatElement *ef = nullptr;
1086 if (m_inputEventFormat.exists(key) == false) {
1087 if (silent == false) {
1088 ATH_MSG_WARNING("No metadata available for branch: " << key);
1089 }
1090 } else {
1091 ef = m_inputEventFormat.get(key);
1092 }
1093
1094 // Check if the branch exists in our input tree:
1095 ::TBranch *br = m_inTree->GetBranch(key.c_str());
1096 if (br == nullptr) {
1097 if (!silent) {
1098 ATH_MSG_WARNING("Branch \"" << key << "\" not available on input");
1099 }
1100 m_inputMissingObjects.insert(key);
1101 return StatusCode::RECOVERABLE;
1102 }
1103
1104 // Make sure that it's not in "MakeClass mode":
1105 br->SetMakeClass(0);
1106
1107 // Decide about the type that we need to use for the reading of this
1108 // branch:
1109 std::string className = br->GetClassName();
1110 if (className == "") {
1111 if (ef) {
1112 // This is a fairly weird situation, but let's fall back to taking
1113 // the class name from the metadata object in this case.
1114 className = ef->className();
1115 } else {
1117 "Couldn't find an appropriate type with a dictionary for branch \""
1118 << key << "\"");
1119 return StatusCode::FAILURE;
1120 }
1121 }
1122 ::TClass *realClass = ::TClass::GetClass(className.c_str());
1123 if (((!realClass) || (!realClass->IsLoaded())) && ef) {
1124 // We may need to do an actual schema evolution here, in which
1125 // case let's fall back on the class name coming from the metadata
1126 // object.
1127 className = ef->className();
1128 realClass = ::TClass::GetClass(className.c_str());
1129 }
1130 if ((!realClass) || (!realClass->IsLoaded())) {
1131 // Now we're in trouble...
1133 "Couldn't find an appropriate type with a dictionary for branch \""
1134 << key << "\"");
1135 return StatusCode::FAILURE;
1136 }
1137
1138 // Make sure that the current object is the "active event":
1139 setActive();
1140
1141 // The data type is always "other" for us:
1142 static const ::EDataType dataType = kOther_t;
1143
1144 // Check if the output already has this object. If it does, let's
1145 // assume that we have been copying the object to the output. Which
1146 // means that we need to resume filling the same memory address that
1147 // the output holder points to.
1148 void *ptr = nullptr;
1149 Object_t::const_iterator out_itr = m_outputObjects.find(key);
1150 if (out_itr != m_outputObjects.end()) {
1151 // It needs to be an object manager...
1152 TObjectManager *mgr = dynamic_cast<TObjectManager *>(out_itr->second.get());
1153 if (mgr == nullptr) {
1154 ATH_MSG_ERROR("Couldn't access output manager for: " << key);
1155 return StatusCode::FAILURE;
1156 }
1157 // Get the pointer out of it:
1158 ptr = mgr->holder()->get();
1159 }
1160
1161 // If there is no output object, then let's create one ourselves.
1162 // This is the only way in which we can have the memory management of
1163 // THolder do the right thing with this object.
1164 if (ptr == nullptr) {
1165 ptr = realClass->New();
1166 }
1167
1168 // Create the new manager object that will hold this EDM object:
1169 const bool renewOnRead = (m_auxMode == kAthenaAccess);
1170 auto mgr = std::make_unique<TObjectManager>(
1171 nullptr, std::make_unique<THolder>(ptr, realClass), renewOnRead);
1172
1173 // One final check. If it's not an auxiliary store, then it must have
1174 // a split level of 0. Otherwise read rules may not work on it. Causing
1175 // *very* serious silent corruption in the data read, if we don't use
1176 // the "Athena read mode".
1177 if ((m_auxMode != kAthenaAccess) && (br->GetSplitLevel() != 0) &&
1178 (Details::isAuxStore(*(mgr->holder()->getClass())) == false)) {
1179 ATH_MSG_ERROR("Split level for branch \""
1180 << key << "\" is " << br->GetSplitLevel()
1181 << ". This can only be read in kAthenaAccess mode.");
1182 // Clean up:
1183 *(mgr->holder()->getPtr()) = nullptr;
1184 m_inputObjects.erase(key);
1185 return StatusCode::FAILURE;
1186 }
1187
1188 // Now try to connect to the branch:
1189 const ::Int_t status =
1190 m_inTree->SetBranchAddress(key.c_str(), mgr->holder()->getPtr(),
1191 mgr->branchPtr(), realClass, dataType, kTRUE);
1192 if (status < 0) {
1193 ATH_MSG_ERROR("Couldn't connect variable of type \""
1194 << className << "\" to input branch \"" << key
1195 << "\". Return code: " << status);
1196 // Clean up:
1197 *(mgr->holder()->getPtr()) = 0;
1198 m_inputObjects.erase(key);
1199 return StatusCode::FAILURE;
1200 }
1201
1202 // At this point we have successfully connected the branch.
1203 TObjectManager *mgrPtr = mgr.get();
1204 m_inputObjects[key] = std::move(mgr);
1205
1206 // If it's an auxiliary store object, set it up correctly:
1207 if (Details::isAuxStore(*(mgrPtr->holder()->getClass()))) {
1209 }
1210
1211 // If there may be an auxiliary object connected to this one,
1212 // connect that as well:
1213 if (Details::hasAuxStore(*(mgrPtr->holder()->getClass()))) {
1215 key + "Aux.", Details::isStandalone(*(mgrPtr->holder()->getClass()))));
1216 }
1217
1218 // Return gracefully.
1219 return StatusCode::SUCCESS;
1220}
std::set< std::string > m_inputMissingObjects
Objects that have been asked for, but were found to be missing in the current input.
Definition Event.h:311
void setActive() const
Set this event object as the currently active one.
Definition EventCore.cxx:54
ReadStats & stats()
Access the object belonging to the current thread.
Definition IOStats.cxx:17
static IOStats & instance()
Singleton object accessor.
Definition IOStats.cxx:11
void readContainer(const std::string &name)
Function incrementing the read counter on a specific container.
StatusCode connectAux(const std::string &prefix, bool standalone) override
Function setting up access to a set of auxiliary branches.

◆ contains() [1/2]

template<typename T>
bool xAOD::Event::contains ( const std::string & key)
inherited

Function checking if an object is available from the store.

◆ contains() [2/2]

bool xAOD::Event::contains ( const std::string & key,
const std::type_info & ti,
bool metadata )
protectedinherited

Internal function checking if an object is in the input.

◆ containsMeta()

template<typename T>
bool xAOD::Event::containsMeta ( const std::string & key)
inherited

Function checking if a meta-object is available from the store.

◆ copy()

StatusCode Event::copy ( const std::string & pattern = ".*")
inherited

Copy an object directly from the input to the output.

This function can be used to easily copy a given (set of) object/container(s) to the output, without modifying the contents of it/them.

It only needs to be called on the interface object/container(s), the copying of the auxiliary data is done automatically, and is steered by the xAOD::Event::setAuxItemList function.

Parameters
patternRegular expression for the key(s)/name(s) of the object(s)/container(s) to copy

Definition at line 28 of file EventIO.cxx.

28 {
29
30 // Tell the user what's happening.
31 ATH_MSG_DEBUG("Copying objects matching pattern \"" << pattern
32 << "\" to the output");
33
34 // Collect a list of keys to copy.
35 std::set<std::string> keys;
36
37 // The regular expression to use.
38 std::regex re{pattern};
39
40 // Loop over the known input containers.
41 for (const auto& [key, efe] : m_inputEventFormat) {
42
43 // Tell the user what's happening.
44 ATH_MSG_VERBOSE("Considering input object with key \"" << key << "\"");
45
46 // Check if the class in question matches the requested pattern.
47 if (std::regex_match(key, re) == false) {
48 continue;
49 }
50 // Skip all branches ending in "Aux.":
51 if (key.ends_with("Aux.")) {
52 continue;
53 }
54 // Also skip dynamic branches:
55 if (efe.parentName() != "") {
56 continue;
57 }
58 // Ignore objects that don't exist on the input.
59 static const bool SILENT = true;
60 if (connectObject(key, SILENT).isSuccess() == false) {
61 continue;
62 }
63 // Add the key to the list.
64 ATH_MSG_VERBOSE("Matched key \"" << key << "\"");
65 keys.insert(key);
66 }
67
68 // Check if the pattern matches any of the name remapping rules.
69 for (const auto& [newname, onfile] : m_nameRemapping) {
70
71 // Tell the user what's happening.
72 ATH_MSG_VERBOSE("Considering remapped key \"" << newname << "\"");
73
74 // Check if the remapped name matches the pattern.
75 if (std::regex_match(newname, re) == false) {
76 continue;
77 }
78 // Ignore objects that don't exist on the input.
79 static const bool SILENT = true;
80 if (connectObject(onfile, SILENT).isSuccess() == false) {
81 continue;
82 }
83 // Add the remapped name to the list.
84 ATH_MSG_VERBOSE("Matched remapped key \"" << newname << "\"");
85 keys.insert(newname);
86 }
87
88 // Now loop over all of the found keys.
89 for (const std::string& key : keys) {
90
91 // Check if a name re-mapping should be applied or not.
92 std::string keyToUse = key;
93 auto remap_itr = m_nameRemapping.find(key);
94 if ((remap_itr != m_nameRemapping.end()) &&
95 (!m_inputEventFormat.exists(key)) &&
96 m_inputEventFormat.exists(remap_itr->second)) {
97 keyToUse = remap_itr->second;
98 }
99
100 // Make sure that the input object got connected to.
101 static const bool SILENT = false;
102 ATH_CHECK(connectObject(keyToUse, SILENT));
103
104 // Make sure that the input object is properly updated.
105 Object_t::const_iterator vobjMgr = m_inputObjects.find(keyToUse);
106 if (vobjMgr == m_inputObjects.end()) {
107 ATH_MSG_FATAL("Internal logic error detected");
108 return StatusCode::FAILURE;
109 }
110 Details::IObjectManager* objMgr =
111 dynamic_cast<Details::IObjectManager*>(vobjMgr->second.get());
112 if (objMgr == nullptr) {
113 ATH_MSG_FATAL("Internal logic error detected");
114 return StatusCode::FAILURE;
115 }
116 static const bool METADATA = false;
117 if (getInputObject(keyToUse, *(objMgr->holder()->getClass()->GetTypeInfo()),
118 SILENT, METADATA) == nullptr) {
119 ATH_MSG_FATAL("Internal logic error detected");
120 return StatusCode::FAILURE;
121 }
122
123 // Put the interface object into the output.
124 static const bool OVERWRITE = true;
125 static const bool IS_OWNER = true;
126 ATH_CHECK(record(objMgr->object(), objMgr->holder()->getClass()->GetName(),
127 key, OVERWRITE, METADATA, IS_OWNER));
128
129 // If there is also an auxiliary store for this object/container, copy that
130 // as well.
131 const std::string auxKey = keyToUse + "Aux.";
132 if (m_inputObjects.contains(auxKey)) {
133 ATH_CHECK(
134 recordAux(*(m_inputObjects.at(auxKey)), key + "Aux.", METADATA));
135 }
136 }
137
138 // Return gracefully:
139 return StatusCode::SUCCESS;
140}
const boost::regex re(r_e)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
virtual StatusCode recordAux(TVirtualManager &mgr, const std::string &key, bool metadata)=0
Record an auxiliary store into a connected output file.
const void * getInputObject(SG::sgkey_t key, const std::type_info &ti, bool silent) override
Function for retrieving an input object in a non-template way.
virtual StatusCode connectObject(const std::string &key, bool silent)=0
Function setting up access to a particular object.
StatusCode record(T *obj, const std::string &key)
Add an output object to the event.
StatusCode keys(std::vector< std::string > &vkeys, bool metadata) const
Provide a list of all data object keys associated with a specific type.
@ OVERWRITE
create the directory as is, removing existing directories if needed

◆ dump()

std::string Event::dump ( )
inherited

Function creating a user-readable dump of the current input.

This function behaves exactly like StoreGateSvc::dump().

It doesn't actually print anything to the screen, it just returns a user readable dump of the contents of the current input file/chain.

It is a pretty dumb implementation for the moment. Should be made nicer later on.

Returns
The user-readable contents of the current input file/chain

Definition at line 250 of file EventCore.cxx.

250 {
251
252 // The internal stream object.
253 std::ostringstream ost;
254 ost << "<<<<<<<<<<<<<<<<<<<< xAOD::TEvent Dump >>>>>>>>>>>>>>>>>>>>\n";
255
256 // Loop over the input EventFormat object.
257 for (const auto& [key, element] : m_inputEventFormat) {
258
259 // Get the type.
260 ::TClass* cl = ::TClass::GetClass(element.className().c_str());
261 const std::type_info* ti = (cl ? cl->GetTypeInfo() : nullptr);
262 if ((cl == nullptr) || (cl->IsLoaded() == false) || (ti == nullptr)) {
263 ATH_MSG_WARNING("Unknown type (" << element.className()
264 << ") found in the event format");
265 continue;
266 }
267
268 // Skip containers that are not available anyway.
269 static const bool METADATA = false;
270 if (!contains(element.branchName(), *ti, METADATA)) {
271 continue;
272 }
273
274 // Do the printout.
275 ost << " Hash: 0x" << std::setw(8) << std::setfill('0') << std::hex
276 << element.hash() << " Key: \"" << element.branchName() << "\"\n";
277
278 ost << " type: " << element.className() << "\n";
279 const bool isNonConst =
280 transientContains(element.branchName(), *ti, METADATA);
281 ost << " isConst: " << (isNonConst ? "No" : "Yes") << "\n";
282 static const bool SILENT = false;
283 ost << " Data: "
284 << (isNonConst
285 ? getOutputObject(element.branchName(), *ti, METADATA)
286 : getInputObject(element.branchName(), *ti, SILENT, METADATA))
287 << "\n";
288 }
289
290 // Finish with the construction:
291 ost << "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>";
292 return ost.str();
293}
bool transientContains(const std::string &key) const
Function checking if an object is already in memory.
bool contains(const std::string &key)
Function checking if an object is available from the store.
void * getOutputObject(SG::sgkey_t key, const std::type_info &ti) override
Function for retrieving an output object in a non-template way.

◆ fill()

Int_t xAOD::TEvent::fill ( )

Function filling one event into the output tree.

This function needs to be called by the user at the end of processing each event that is meant to be written out.

Returns
The number of bytes written if successful, a negative number if not

Definition at line 819 of file Control/xAODRootAccess/Root/TEvent.cxx.

819 {
820
821 // A little sanity check:
822 if (!m_outTree) {
823 ATH_MSG_ERROR("Object not connected to an output file!");
824 return 0;
825 }
826
827 // Make sure that all objects have been read in. The 99 as the value
828 // has a special meaning for TAuxStore. With this value it doesn't
829 // delete its transient (decoration) variables. Otherwise it does.
830 // (As it's supposed to, when moving to a new event.)
831 Int_t readBytes = 0;
832 if (m_inChain != nullptr) {
833 readBytes = getEntry(m_inChain->GetReadEntry(), 99);
834 } else if (m_inTree != nullptr) {
835 readBytes = getEntry(m_entry, 99);
836 }
837 if (readBytes < 0) {
838 ATH_MSG_ERROR("getEntry failed!");
839 return readBytes;
840 }
841
842 // Prepare the objects for writing. Note that we need to iterate over a
843 // copy of the m_outputObjects container. Since the putAux(...) function
844 // called inside the loop may itself add elements to the m_outputObject
845 // container.
846 std::string unsetObjects;
847 std::vector<std::pair<std::string, TVirtualManager *>> outputObjectsCopy;
848 outputObjectsCopy.reserve(m_outputObjects.size());
849 for (const auto &[key, mgr] : m_outputObjects) {
850 outputObjectsCopy.emplace_back(key, mgr.get());
851 }
852 for (auto &[key, mgr] : outputObjectsCopy) {
853 // Check that a new object was provided in the event:
854 if (!mgr->create()) {
855 // We are now going to fail. But let's collect the names of
856 // all the unset objects:
857 if (unsetObjects.size()) {
858 unsetObjects += ", ";
859 }
860 unsetObjects.append("\"" + key + "\"");
861 continue;
862 }
863 // Make sure that any dynamic auxiliary variables that
864 // were added to the object after it was put into the event,
865 // get added to the output:
866 static constexpr bool METADATA = false;
867 if (putAux(*m_outTree, *mgr, METADATA).isFailure()) {
868 ATH_MSG_ERROR("Failed to put dynamic auxiliary variables "
869 "in the output for object \""
870 << key << "\"");
871 return 0;
872 }
873 }
874
875 // Check if there were any unset objects:
876 if (unsetObjects.size()) {
877 ATH_MSG_ERROR("The following objects were not set in the current event: "
878 << unsetObjects);
879 return 0;
880 }
881
882 // Write the entry, and check the return value:
883 const ::Int_t ret = m_outTree->Fill();
884 if (ret <= 0) {
885 ATH_MSG_ERROR("Output tree filling failed with return value: " << ret);
886 }
887
888 // Reset the object managers.
889 for (auto &[key, mgr] : m_outputObjects) {
890 mgr->reset();
891 }
892
893 // Return the value:
894 return ret;
895}
::Long64_t m_entry
The entry to look at from the input tree.
::TChain * m_inChain
The (optional) chain provided as input.
StatusCode putAux(::TTree &outTree, TVirtualManager &mgr, bool metadata)
Function saving the dynamically created auxiliary properties.
::Int_t getEntry(::Long64_t entry, ::Int_t getall=0)
Function loading a given entry of the input TTree.

◆ finishWritingTo()

StatusCode xAOD::TEvent::finishWritingTo ( ::TFile * file)

Finish writing to an output file.

This function needs to be called when the user is done writing events to a file, before (s)he would close the file itself.

Parameters
fileThe file that the event data is written to
Returns
The usual StatusCode tyoes

Definition at line 452 of file Control/xAODRootAccess/Root/TEvent.cxx.

452 {
453
454 // A small sanity check:
455 if (!m_outTree) {
456 ATH_MSG_ERROR("The object doesn't seem to be connected to an output file!");
457 return StatusCode::FAILURE;
458 }
459
460 // Make sure we return to the current directory:
461 TDirectoryReset dr;
462
463 // Notify the listeners that they should write out their metadata, if they
464 // have any.
465 const TIncident incident(IncidentType::MetaDataStop);
466 for (auto &listener : m_listeners) {
467 listener->handle(incident);
468 }
469
470 // Write out the event tree, and delete it:
471 m_outTree->AutoSave("FlushBaskets");
472 m_outTree->SetDirectory(0);
473 m_outTree.reset();
474
475 // Now go to the output file:
476 file->cd();
477
478 // Check if there's already a metadata tree in the output:
479 if (file->Get(METADATA_TREE_NAME)) {
480 // Let's assume that the metadata is complete in the file already.
481 return StatusCode::SUCCESS;
482 }
483
484 // Create the metadata tree.
485 auto metatree =
486 std::make_unique<TTree>(METADATA_TREE_NAME, "xAOD metadata tree");
487 metatree->SetAutoSave(10000);
488 metatree->SetAutoFlush(-30000000);
489 metatree->SetDirectory(file);
490
491 // Create the xAOD::EventFormat branch in it.
492 try {
493 metatree->Branch(
494 "EventFormat",
497 } catch (const CxxUtils::ClassName::ExcBadClassName &e) {
498 ::Error("xAOD::TEvent::finishWritingTo",
499 XAOD_MESSAGE("Class name parsing fails for %s ! "), e.what());
500 return StatusCode::FAILURE;
501 }
502
503 // Create a copy of the m_outputMetaObjects variable. This is necessary
504 // because the putAux(...) function will modify this variable while we
505 // loop over it.
506 std::vector<std::pair<std::string, TObjectManager *>> outputMetaObjects;
507 outputMetaObjects.reserve(m_outputMetaObjects.size());
508 for (const auto &[key, mgr] : m_outputMetaObjects) {
509 TObjectManager *objMgr = dynamic_cast<TObjectManager *>(mgr.get());
510 if (objMgr == nullptr) {
511 ATH_MSG_FATAL("Internal logic error detected");
512 return StatusCode::FAILURE;
513 }
514 outputMetaObjects.emplace_back(key, objMgr);
515 }
516
517 // Now loop over all the metadata objects that need to be put into the
518 // output file:
519 for (auto &[key, mgr] : outputMetaObjects) {
520
521 // Select a split level depending on whether this is an interface or an
522 // auxiliary object:
523 const ::Int_t splitLevel = (key.ends_with("Aux.") ? 1 : 0);
524 // Create the new branch:
525 *(mgr->branchPtr()) =
526 metatree->Branch(key.c_str(), mgr->holder()->getClass()->GetName(),
527 mgr->holder()->getPtr(), 32000, splitLevel);
528 if (!mgr->branch()) {
529 ATH_MSG_ERROR("Failed to create metadata branch \""
530 << mgr->holder()->getClass()->GetName() << "/" << key
531 << "\"");
532 return StatusCode::FAILURE;
533 }
534 // Set up the saving of all the dynamic auxiliary properties
535 // of the object if it has any:
536 static constexpr bool METADATA = true;
537 ATH_CHECK(putAux(*metatree, *mgr, METADATA));
538 }
539
540 // Write the metadata objects:
541 if (metatree->Fill() <= 0) {
542 ATH_MSG_ERROR("Failed to write event format metadata into the output");
543 metatree->SetDirectory(nullptr);
544 return StatusCode::FAILURE;
545 }
546
547 // Now clean up:
548 metatree->Write();
549 metatree->SetDirectory(nullptr);
550 m_outputEventFormat = nullptr;
551 m_outputObjects.clear();
552 m_outputMetaObjects.clear();
553
554 // Return gracefully:
555 return StatusCode::SUCCESS;
556}
#define XAOD_MESSAGE(MESSAGE)
Simple macro for printing error/verbose messages.
EventFormat * m_outputEventFormat
Format of the current output file.
Definition Event.h:323
Object_t m_outputMetaObjects
Collection of all the managed output meta-objects.
Definition Event.h:318
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...
static const ::Int_t MetaDataStop
The metadata for the output file should be written out.
Definition TIncident.h:31
EventFormat_v1 EventFormat
Definition of the current event format version.
Definition EventFormat.h:16
static const char *const METADATA_TREE_NAME
Name of the metadata tree.

◆ getBranchInfo()

const Event::BranchInfo * Event::getBranchInfo ( SG::sgkey_t sgkey) const
protectedinherited

Get the object describing one object/branch.

Definition at line 347 of file EventIProxyDict.cxx.

347 {
348
349 {
350 // We can only hold the lock (even though it's a shared lock) for
351 // this limited scope because the call to getInputObject below
352 // leads to a recursion and dead-lock if not released immediately.
354
355 // If the object already exists, return it:
356 auto it = m_branches.find(sgkey);
357 if (it != m_branches.end()) {
358 return &(it->second);
359 }
360 }
361
362 // If not, construct it now:
363 BranchInfo bi;
364 const xAOD::EventFormatElement* efe = getEventFormatElement(sgkey);
365 if (!efe) {
366 // Apparently this key is not known:
367 return nullptr;
368 }
369
370 // Helper variable(s).
371 static const bool SILENT = true;
372 static const bool METADATA = false;
373
374 // The name of the requested object.
375 const std::string& name = getName(sgkey);
376 // This is a bit perverse... In order to let the "base class" figure
377 // out the exact type of this object, we ask for it with an "Event
378 // pointer". I use that type because I need something that has a
379 // dictionary, and which should always be available when this code
380 // runs. In the end it doesn't matter that the object can't be
381 // retrieved as that type (of course...), it only matters that it gets
382 // "set up" following these calls.
383 Event* nc_this = const_cast<Event*>(this);
384 static const std::type_info& dummy = typeid(Event);
385 nc_this->getInputObject(name, dummy, SILENT, METADATA);
386 auto itr = m_outputObjects.find(name);
387 if (itr == m_outputObjects.end()) {
388 itr = m_inputObjects.find(name);
389 if (itr == m_inputObjects.end()) {
390 // We didn't find this object in the store...
391 return nullptr;
392 }
393 }
394 const Details::IObjectManager* mgr =
395 dynamic_cast<const Details::IObjectManager*>(itr->second.get());
396 if (!mgr) {
397 ATH_MSG_ERROR("Internal logic error found");
398 return nullptr;
399 }
400 bi.m_class = mgr->holder()->getClass();
401 // There's no need to check whether this is a "proper" dictionary
402 // at this point, since if TEvent is holding on to it, the type
403 // must have a proper compiled dictionary.
404
405#ifndef XAOD_STANDALONE
406 // Create a proper proxy for the input branch:
407 auto taddr = std::make_unique<SG::TransientAddress>(
408 CLID_NULL, efe->branchName(), new GenericAddress());
409 taddr->setSGKey(sgkey);
411 *nc_this, getName(sgkey), *bi.m_class->GetTypeInfo());
412 bi.m_proxy = std::make_unique<SG::DataProxy>(std::move(taddr), loader);
413 loader->setProxy(*bi.m_proxy.get());
414#endif // not XAOD_STANDALONE
415
416 // Add the branch info to our list:
418 lock.upgrade();
419 auto ret = m_branches.insert(std::make_pair(sgkey, std::move(bi)));
420
421 // Return a pointer to the branch info:
422 return &(ret.first->second);
423}
void setProxy(SG::DataProxy &proxy)
const std::string & branchName() const
Get the branch/key name.
const std::string & name() const override
Get the name of the instance.
const std::string & getName(const void *obj) const override
Function returning the key describing a known object.
friend class xAODPrivate::Loader
Definition Event.h:63
const xAOD::EventFormatElement * getEventFormatElement(SG::sgkey_t sgkey) const
Get the metadata object for a given "SG key".

◆ getEntries()

Long64_t xAOD::TEvent::getEntries ( ) const

Get how many entries are available from the current input file(s)

Returns
The number of events in the input file(s)

Definition at line 626 of file Control/xAODRootAccess/Root/TEvent.cxx.

626 {
627
628 if (m_inChain) {
629 return m_inChain->GetEntries();
630 } else if (m_inTree) {
631 return m_inTree->GetEntries();
632 } else if (m_inTreeMissing) {
633 // The input file is empty:
634 return 0;
635 } else {
636 ATH_MSG_ERROR("Function called on an uninitialised object");
637 return 0;
638 }
639}
bool m_inTreeMissing
Internal status flag showing that an input file is open, but it doesn't contain an event tree.

◆ getEntry()

Int_t xAOD::TEvent::getEntry ( ::Long64_t entry,
::Int_t getall = 0 )

Function loading a given entry of the input TTree.

This function is used to move to looking at a new entry from the input tree.

It doesn't do any I/O operation at this point, it just remembers which entry the objects should be loaded from later on.

Unless one calls the function with getall==1. In that case all input is force-read. This is necessary when writing out an event that was processed in a load-on-request manner.

Parameters
entryThe entry from the input tree to load
getallParameter deciding if partial reading should be used or not.
Returns
The number of bytes read, or a negative number in case of an error

Definition at line 655 of file Control/xAODRootAccess/Root/TEvent.cxx.

655 {
656
657 // A little sanity check:
658 if ((!m_inTree) && (!m_inChain)) {
659 ATH_MSG_ERROR("Function called on an uninitialised object");
660 return -1;
661 }
662
663 // If we have a chain as input:
664 if (m_inChain) {
665 // Make sure that the correct tree is loaded:
666 const ::Long64_t fileEntry = m_inChain->LoadTree(entry);
667 if (fileEntry < 0) {
668 ATH_MSG_ERROR("Failure in loading entry " << entry
669 << " from the input chain");
670 return -1;
671 }
672 // Check if a new file was loaded:
673 if ((m_inTreeNumber != m_inChain->GetTreeNumber()) ||
674 m_inChainTracker->internalStateChanged()) {
675 // Reset the tracker:
676 m_inChainTracker->reset();
677 // Connect to this new file:
678 m_inTreeNumber = m_inChain->GetTreeNumber();
679 ::TFile *file = m_inChain->GetFile();
680 // The useTreeCache parameter is set to false, since the cache
681 // is anyway set up through the TChain. It shouldn't be modified
682 // on the file level.
683 static constexpr bool USE_TREE_CACHE = false;
684 if (readFrom(file, USE_TREE_CACHE, m_inChain->GetName()).isFailure()) {
685 ATH_MSG_ERROR("Couldn't connect to input file #"
686 << m_inTreeNumber << " of the input chain");
687 return -1;
688 }
689 }
690 // Restore the previously received entry number.
691 m_entry = fileEntry;
692 }
693 // If we have a regular file/tree as input:
694 else {
695 m_entry = entry;
696 }
697
698 // In order to make the reading of branches+tree cache work
699 // NB: TTree::LoadTree() only set the entry that should be read for each
700 // branch but no reading of the branch content is performed when calling that
701 // function. The entry set that can be retrieved with
702 // branch->GetTree()->GetReadEntry()
703 // For friend trees, if an index was built, then the entry which is set for
704 // the related branches is found by the LoadTree function by matching the the
705 // major and minor values of the main tree and friend tree
706 if (m_inTree && m_inTree->LoadTree(m_entry) < 0) {
707 ATH_MSG_ERROR("Failure in loading entry " << m_entry
708 << " from the input file");
709 return -1;
710 }
711
712 // Stats counter needs to know it's the next event:
714
715 // The final number of bytes read.
716 ::Int_t result = 0;
717
718 // Check if objects need to be read in.
719 if (getall) {
720 if (m_auxMode == kAthenaAccess) {
721 // In kAthenaAccess mode we need to use getInputObject(...) to load
722 // all the input objects correctly.
723 for (auto &[key, mgr] : m_inputObjects) {
724 static const std::string dynStorePostfix = "Aux.Dynamic";
725 if (key.ends_with(dynStorePostfix)) {
726 // Ignore the dynamic store objects. They get loaded through
727 // their parents.
728 } else {
729 // Load the objects and their auxiliary stores through the
730 // getInputObject(...) function, which takes care of correctly
731 // setting them up. The type is irrelevant here. We don't
732 // really care about the exact type of the objects.
733 static constexpr bool SILENT = true;
734 static constexpr bool METADATA = false;
735 getInputObject(key, typeid(int), SILENT, METADATA);
736 }
737 }
738 } else {
739 // In a "reasonable" access mode, we do something very simple:
740 for (auto &[key, mgr] : m_inputObjects) {
741 result += mgr->getEntry(getall);
742 }
743 }
744 }
745
746 // Notify the listeners that a new event was loaded:
747 const TIncident incident(IncidentType::BeginEvent);
748 for (auto &listener : m_listeners) {
749 listener->handle(incident);
750 }
751
752 // Return the number of bytes read:
753 return result;
754}
void nextEvent()
Function incrementing the processed event counter.
std::unique_ptr< TChainStateTracker > m_inChainTracker
Optional object for tracking the state changes of an input TChain.
::Int_t m_inTreeNumber
The number of the currently open tree in the input chain.
static const ::Int_t BeginEvent
A new event was just loaded.
Definition TIncident.h:29

◆ getEventFormatElement()

const xAOD::EventFormatElement * Event::getEventFormatElement ( SG::sgkey_t sgkey) const
protectedinherited

Get the metadata object for a given "SG key".

Definition at line 321 of file EventIProxyDict.cxx.

322 {
323
324 const xAOD::EventFormatElement* efe = nullptr;
325 static const bool QUIET = true;
327 efe = m_outputEventFormat->get(sgkey, QUIET);
328 }
329 if (!efe) {
330 efe = m_inputEventFormat.get(sgkey, QUIET);
331 }
332 if (!efe) {
333 static SG::SGKeySet missingSGKeys ATLAS_THREAD_SAFE;
334 static mutex_t mutex;
335 guard_t lock(mutex);
336 if (missingSGKeys.emplace(sgkey).second) {
339 "Can't find EventFormatElement for hashed SG key: " << sgkey);
340 }
341 return 0;
342 }
343 }
344 return efe;
345}
AthContainers_detail::mutex mutex_t
Mutex type for multithread synchronization.
AthContainers_detail::lock_guard< mutex_t > guard_t
Guard type for multithreaded synchronisation.
std::unordered_set< sgkey_t > SGKeySet
A set of sgkey_t values.
Definition sgkey_t.h:97

◆ getFile()

Int_t xAOD::TEvent::getFile ( ::Long64_t file,
::Int_t getall = 0 )

Load the first event for a given file from the input TChain.

This function can be used to iterate over the input files specified for the object.

It should be most useful for collecting metadata about a set of input files, if there's no regular event loop done to process them.

Parameters
fileThe file number to load
getallIf set to 1, all connected branches are loaded
Returns
The number of read bytes on success, or a negative number on failure

Definition at line 785 of file Control/xAODRootAccess/Root/TEvent.cxx.

785 {
786
787 // Check if the file number is valid:
788 if ((file < 0) || (file >= getFiles())) {
789 ATH_MSG_ERROR("Function called with invalid file number (" << file << ")");
790 return -1;
791 }
792
793 // If we are not reading a TChain, return at this point. As the one and
794 // only file is open already...
795 if (!m_inChain) {
796 return 0;
797 }
798
799 // Trigger the "scanning" of the input files, so the TChain would know
800 // how many entries are in the various files.
801 getEntries();
802
803 // Calculate which entry/event we need to load:
804 ::Long64_t entry = 0;
805 for (::Long64_t i = 0; i < file; ++i) {
806 entry += m_inChain->GetTreeOffset()[i];
807 }
808
809 // Load this entry using the regular event opening function:
810 return getEntry(entry, getall);
811}
::Long64_t getEntries() const
Get how many entries are available from the current input file(s)
::Long64_t getFiles() const
Get how many files are available on the currently defined input.

◆ getFiles()

Long64_t xAOD::TEvent::getFiles ( ) const

Get how many files are available on the currently defined input.

This function can be used to get the number of input files that the object currently knows about.

This is meant to be used to collect the metadata from each of the input files, or to access the metadata using a transient tree. (xAOD::TMetaTree)

Returns
The number of input files when reading from a TChain, 1 when reading from a TFile, and 0 if the object is not connected to any input

Definition at line 765 of file Control/xAODRootAccess/Root/TEvent.cxx.

765 {
766
767 if (m_inChain) {
768 return m_inChain->GetListOfFiles()->GetEntries();
769 } else if (m_inTree || m_inTreeMissing) {
770 return 1;
771 } else {
772 return 0;
773 }
774}

◆ getHash()

SG::sgkey_t Event::getHash ( const std::string & key) const
overridevirtualinherited

Function returning the hash describing an object name.

This helper function is mostly needed by the smart pointers of the xAOD EDM.

Right now it very simply just calculates the hash just based on the key given to the function. But later on it might be good to do some tests here, checking if the event format knows about the specified key or not. This is why it's not made to be a static function

Parameters
keyString key to turn into a hash
Returns
A hash corresponding to the specified string key

Implements xAOD::TVirtualEvent.

Definition at line 27 of file EventTVirtualEvent.cxx.

27 {
28
29 // For empty keys let's finish quickly.
30 if (key == "") {
31 return 0;
32 }
33
34 // If the key is used in the input file, let's use the same hash for
35 // the output file as well.
36 if (m_inputEventFormat.exists(key)) {
37 return m_inputEventFormat.get(key)->hash();
38 }
39
40 // If it's a new key, make a new hash for it from scratch:
41 return Utils::hash(key);
42}
SG::sgkey_t hash(const std::string &name)
This function provides a hashed version of the key (branch) names used in the xAOD file,...

◆ getInputObject() [1/2]

const void * Event::getInputObject ( const std::string & key,
const std::type_info & ti,
bool silent,
bool metadata )
protectedinherited

Function for retrieving an input object in a non-template way.

This is the function doing the heavy lifting to retrieve objects from the input file.

Parameters
keyThe key (branch name) of the object to retrieve
tiThe type as which the object is to be retrieved
silentSet to kTRUE to make the code fail silently in case the object can't be retrieved
metadataFlag deciding whether we're looking for a metadata or event data object
Returns
A pointer to the input object if successful, or a null pointer if not

Definition at line 218 of file EventIO.cxx.

220 {
221
222 // Check if a name remapping should be applied or not:
223 std::string keyToUse = key;
224 auto remap_itr = m_nameRemapping.find(key);
225 if ((remap_itr != m_nameRemapping.end()) &&
226 (!m_inputEventFormat.exists(key)) &&
227 m_inputEventFormat.exists(remap_itr->second)) {
228 keyToUse = remap_itr->second;
229 }
230
231 // The following catches the cases when we ask for a transient
232 // ConstDataVector object to be returned as "const DataVector".
233 TStore* store = TActiveStore::store();
234 if (store && store->contains(keyToUse, ti) && store->isConst(keyToUse, ti)) {
235 const void* result = store->getConstObject(keyToUse, ti);
236 return result;
237 }
238
239 // A sanity check before checking for an object from the input file.
240 if (hasInput() == false) {
241 if (silent == false) {
242 ATH_MSG_WARNING("No input file connected to the Event object");
243 }
244 return nullptr;
245 }
246
247 // Make sure that the requested input is connected to.
248 const StatusCode sc = (metadata ? connectMetaObject(keyToUse, silent)
249 : connectObject(keyToUse, silent));
250 if (sc.isSuccess() == false) {
251 return nullptr;
252 }
253
254 // Select which object container to use:
255 Object_t& objects = (metadata ? m_inputMetaObjects : m_inputObjects);
256
257 // Access the object's manager:
258 auto itr = objects.find(keyToUse);
259 if (itr == objects.end()) {
260 ATH_MSG_FATAL("There is an internal logic error in the code...");
261 return nullptr;
262 }
263
264 // This has to be an ObjectManager object:
265 Details::IObjectManager* mgr =
266 dynamic_cast<Details::IObjectManager*>(itr->second.get());
267 if (mgr == nullptr) {
268 if (key == keyToUse) {
269 ATH_MSG_ERROR("Object of wrong type found for key \"" << key << "\"");
270 } else {
271 ATH_MSG_ERROR("Object of wrong type found for key \""
272 << key << "\"/\"" << keyToUse << "\"");
273 }
274 return nullptr;
275 }
276
277 // Make sure that the current entry is loaded for event data objects.
278 if (metadata == false) {
279 const Int_t readBytes = mgr->getEntry();
280 if (readBytes > 0) {
281 // Connect the auxiliary store to objects needing it. This call also
282 // takes care of updating the dynamic store of auxiliary containers,
283 // when they are getting accessed directly.
284 static const bool IS_METADATA = false;
285 if (setAuxStore(key, *mgr, IS_METADATA).isSuccess() == false) {
286 ATH_MSG_ERROR("Failed to set the auxiliary store for "
287 << mgr->holder()->getClass()->GetName() << "/"
288 << keyToUse);
289 return nullptr;
290 }
291 } else if (readBytes < 0) {
292 ATH_MSG_ERROR("Failed to load current entry for object "
293 << mgr->holder()->getClass()->GetName() << "/" << keyToUse);
294 return nullptr;
295 }
296 }
297
298 // Ask the holder object for the object of this type:
299 const void* result = mgr->holder()->getAsConst(ti, silent);
300 if (result == nullptr) {
301 if (!silent) {
302 ATH_MSG_WARNING("Could not retrieve object with key \""
303 << keyToUse << "\" as \""
304 << SG::normalizedTypeinfoName(ti) << "\"");
305 }
306 return nullptr;
307 }
308
309 // We succeeded:
310 return result;
311}
static Double_t sc
if(febId1==febId2)
virtual bool hasInput() const =0
Check if an input file is connected to the object.
std::unordered_map< std::string, std::unique_ptr< TVirtualManager > > Object_t
Definition of the internal data structure type.
Definition Event.h:304
virtual StatusCode connectMetaObject(const std::string &key, bool silent)=0
Function setting up access to a particular metadata object.
virtual StatusCode setAuxStore(const std::string &key, Details::IObjectManager &mgr, bool metadata)=0
Function connecting a DV object to its auxiliary store.
static TStore * store()
Access the currently active TStore object.
::StatusCode StatusCode
StatusCode definition for legacy code.
silent(func)
Redirect stdout/err to /dev/null Useful wrapper to get rid of ROOT verbosity... N....

◆ getInputObject() [2/2]

const void * Event::getInputObject ( SG::sgkey_t key,
const std::type_info & ti,
bool silent )
overrideprotectedvirtualinherited

Function for retrieving an input object in a non-template way.

This function is used by the TVirtualEvent interface to access an input object with a given hashed key.

The function looks up the string key belonging to the hash, and then calls the other GetInputObject(...) function in the class with that parameter.

Parameters
keyThe hashed key of the input object
tiThe type description of the object requested
silentSwitch for being silent about failures or not
Returns
A pointer to the requested object, or a null pointer in case of failure

Implements xAOD::TVirtualEvent.

Definition at line 162 of file EventTVirtualEvent.cxx.

163 {
164
165 // Get a string name for this key:
166 const std::string& name = getName(key);
167 if (name.empty() && (silent == false)) {
168 ATH_MSG_WARNING("Key 0x" << std::hex << key << " unknown");
169 return nullptr;
170 }
171
172 // Forward the call to the function using an std::string key:
173 static const bool METADATA = false;
174 return getInputObject(name, ti, silent, METADATA);
175}

◆ getKey()

SG::sgkey_t Event::getKey ( const void * obj) const
overridevirtualinherited

Function returning the hash describing a known object.

This function is used by the smart pointer code to find the identifier of an object that's already in the event in some way.

Parameters
objPointer to the object that we want to look up
Returns
The hashed identifier of the object, or 0 if the object was not found in the event

Implements xAOD::TVirtualEvent.

Definition at line 51 of file EventTVirtualEvent.cxx.

51 {
52
53 // Make use of the getName function.
54 return getHash(getName(obj));
55}
SG::sgkey_t getHash(const std::string &key) const override
Function returning the hash describing an object name.

◆ getName() [1/2]

const std::string & Event::getName ( const void * obj) const
overridevirtualinherited

Function returning the key describing a known object.

This function is used by the smart pointer code to find the identifier of an object that's already in the event in some way.

Parameters
objPointer to the object that we want to look up
Returns
The name of the object, or an empty string if the object was not found in the event

Implements xAOD::TVirtualEvent.

Definition at line 64 of file EventTVirtualEvent.cxx.

64 {
65
66 // First look among the output objects.
67 for (const auto& [key, manager] : m_outputObjects) {
68 // Check if this is our object.
69 if (manager->object() == obj) {
70 // If it is, let's return right away.
71 return key;
72 }
73 }
74
75 // Now look among the input objects.
76 for (const auto& [key, manager] : m_inputObjects) {
77 // Check if this is our object.
78 if (manager->object() == obj) {
79 // If it is, let's return.
80 return key;
81 }
82 }
83
84 // If it's not there either, check if it's in an active TStore object:
85 const TStore* store = TActiveStore::store();
86 if (store && store->contains(obj)) {
87 // Get the name from the store then:
88 return store->getName(obj);
89 }
90
91 // We didn't find the object in the event...
92 ATH_MSG_WARNING("Didn't find object with pointer \"" << obj
93 << "\" in the event");
94 static const std::string dummy;
95 return dummy;
96}

◆ getName() [2/2]

const std::string & Event::getName ( SG::sgkey_t hash) const
overridevirtualinherited

Function returning the key describing a known object.

This function is used primarily when getting the string key of a smart pointer that we read in from a file, or access it in memory.

Parameters
hashThe hashed key for the container/object
Returns
The name of the object, or an empty string if the object was not found in the event

Implements xAOD::TVirtualEvent.

Definition at line 105 of file EventTVirtualEvent.cxx.

105 {
106
107 // If the branch is known from the input:
108 if (m_inputEventFormat.exists(hash)) {
109 return m_inputEventFormat.get(hash)->branchName();
110 }
111
112 // If the branch is known on the output:
113 if (m_outputEventFormat && m_outputEventFormat->exists(hash)) {
114 return m_outputEventFormat->get(hash)->branchName();
115 }
116
117 // If this is an object in the active store:
118 const TStore* store = TActiveStore::store();
119 if (store && store->contains(hash)) {
120 return store->getName(hash);
121 }
122
123 // If it is unknown:
124 static const std::string dummy;
125 return dummy;
126}

◆ getNames()

StatusCode xAOD::TEvent::getNames ( const std::string & targetClassName,
std::vector< std::string > & vkeys,
bool metadata ) const
overrideprotectedvirtual

Function determining the list keys associated with a type name.

Implements xAOD::Event.

Definition at line 904 of file Control/xAODRootAccess/Root/TEvent.cxx.

906 {
907 // The results go in here
908 std::set<std::string> keys;
909
910 // Get list of branches from
911 // the input metadata tree or input tree
912 std::vector<TObjArray *> fullListOfBranches = {};
913 if (metadata) {
914 if (m_inMetaTree) {
915 // No friend tree expected for metadata tree
916 // Only add the list of branches of the metadata tree
917 ATH_MSG_DEBUG("Scanning for input metadata objects");
918 fullListOfBranches.push_back(m_inMetaTree->GetListOfBranches());
919 }
920 } else {
921 if (m_inTree) {
922 ATH_MSG_DEBUG("Scanning for input data objects");
923 // Add the list of branches of the main tree
924 fullListOfBranches.push_back(m_inTree->GetListOfBranches());
925 // If the input tree has friend trees
926 // add as well the list of friend tree branches
927 if (m_inTree->GetListOfFriends()) {
928 // Get the list of friends
929 TList *fList = m_inTree->GetListOfFriends();
930 // Loop over friend elements
931 for (TObject *feObj : *fList) {
932 if (feObj) {
933 // Get corresponding friend tree
934 auto *pElement = dynamic_cast<TFriendElement *>(feObj);
935 if (pElement == nullptr) {
936 continue;
937 }
938 TTree *friendTree = pElement->GetTree();
939 // Add list of branches of the friend tree
940 fullListOfBranches.push_back(friendTree->GetListOfBranches());
941 }
942 }
943 }
944 }
945 }
946
947 // Loop over all list of branches (if any)
948 for (const TObjArray *in : fullListOfBranches) {
949 // Loop over all branches inside the current list of branches
950 for (const TObject *obj : *in) {
951
952 if (obj == nullptr) {
953 continue;
954 }
955 const TBranch *element = dynamic_cast<const TBranch *>(obj);
956 if (!element) {
957 ATH_MSG_ERROR("Failure inspecting input data objects");
958 return StatusCode::FAILURE;
959 }
960 const std::string objClassName = element->GetClassName();
961 std::string key = obj->GetName();
962 ATH_MSG_VERBOSE("Inspecting \"" << objClassName << "\" / \"" << key
963 << "\"");
964 if (objClassName == targetClassName) {
965 ATH_MSG_DEBUG("Matched \"" << targetClassName << "\" to key \"" << key
966 << "\"");
967 keys.insert(std::move(key));
968 }
969 }
970 }
971
973
974 ATH_MSG_DEBUG("Scanning input objects for \"" << targetClassName << "\"");
975 for (const auto &[key, vmgr] : inAux) {
976 // All (metadata) objects should be held by TObjectManager objects.
977 const TObjectManager *mgr =
978 dynamic_cast<const TObjectManager *>(vmgr.get());
979 if (mgr == nullptr) {
980 continue;
981 }
982 const std::string &objClassName = mgr->holder()->getClass()->GetName();
983 ATH_MSG_VERBOSE("Inspecting \"" << objClassName << "\" / \"" << key
984 << "\"");
985 if (objClassName == targetClassName) {
986 ATH_MSG_DEBUG("Matched \"" << targetClassName << "\" to key \"" << key
987 << "\"");
988 keys.insert(key);
989 }
990 }
991
992 // Check for output objects.
993 if ((metadata == false) && m_outTree) {
994 const TObjArray *out = m_outTree->GetListOfBranches();
995 ATH_MSG_DEBUG("Scanning for output data objects");
996
997 for (const TObject *obj : *out) {
998 if (obj == nullptr) {
999 continue;
1000 }
1001 const TBranch *element = dynamic_cast<const TBranch *>(obj);
1002 if (element == nullptr) {
1003 ATH_MSG_ERROR("Failure inspecting output objects");
1004 return StatusCode::FAILURE;
1005 }
1006 const std::string objClassName = element->GetClassName();
1007 std::string key = obj->GetName();
1008 ATH_MSG_VERBOSE("Inspecting \"" << objClassName << "\" / \"" << key
1009 << "\"");
1010 if (objClassName == targetClassName) {
1011 ATH_MSG_DEBUG("Matched \"" << targetClassName << "\" to key \"" << key
1012 << "\"");
1013 keys.insert(std::move(key));
1014 }
1015 }
1016 }
1017
1019
1020 // Search though the in-memory output objects.
1021 ATH_MSG_DEBUG("Scanning output objects for \"" << targetClassName << "\"");
1022 for (const auto &[key, vmgr] : outAux) {
1023 // All (metadata) objects should be held by TObjectManager objects.
1024 TObjectManager *mgr = dynamic_cast<TObjectManager *>(vmgr.get());
1025 if (mgr == nullptr) {
1026 continue;
1027 }
1028 const std::string &objClassName = mgr->holder()->getClass()->GetName();
1029 ATH_MSG_VERBOSE("Inspecting \"" << objClassName << "\" / \"" << key
1030 << "\"");
1031 if (objClassName == targetClassName) {
1032 ATH_MSG_DEBUG("Matched \"" << targetClassName << "\" to key \"" << key
1033 << "\"");
1034 keys.insert(key);
1035 }
1036 }
1037
1038 vkeys.insert(vkeys.end(), keys.begin(), keys.end());
1039
1040 // Return gracefully.
1041 return StatusCode::SUCCESS;
1042}

◆ getOutputObject() [1/2]

void * Event::getOutputObject ( const std::string & key,
const std::type_info & ti,
bool metadata ) const
protectedinherited

Function for retrieving an output object in a non-template way.

This function does the heavy lifting of retrieving object from the list of output objects.

While it returns a typeless pointer, that pointer can be cast directly to the type described by the second parameter in the caller code.

Parameters
keyThe key (branch name) of the object to retrieve
tiThe type as which the object is to be retrieved
metadataFlag deciding whether we're looking for a metadata or event data object
Returns
A pointer to the output object if successful, or a null pointer if not

Definition at line 154 of file EventIO.cxx.

155 {
156
157 // Select which object container to use:
159
160 // Check if the object can be found:
161 auto itr = objects.find(key);
162 if (itr == objects.end()) {
163 // Do the following only for event data:
164 if (!metadata) {
165 // It's not in the event. Let's check if we find it in an active
166 // TStore object...
167 TStore* store = TActiveStore::store();
168 if ((!store) || (!store->contains(key, ti)) || store->isConst(key, ti)) {
169 // Nope, not there either...
170 return nullptr;
171 }
172 // Let's return the object from the TStore:
173 void* result = store->getObject(key, ti);
174 return result;
175 } else {
176 // For metadata we don't use external resources.
177 return nullptr;
178 }
179 }
180
181 // If the object is not set in this event yet, we can't continue:
182 if (itr->second->isSet() == false) {
183 return nullptr;
184 }
185
186 // If it does exist, check if it's the right kind of object:
187 Details::IObjectManager* mgr =
188 dynamic_cast<Details::IObjectManager*>(itr->second.get());
189 if (mgr == nullptr) {
190 ATH_MSG_ERROR("Object of wrong type found for key \"" << key << "\"");
191 return nullptr;
192 }
193
194 // Ask the holder object for the object of this type:
195 void* result = mgr->holder()->getAs(ti);
196 if (result == nullptr) {
197 ATH_MSG_WARNING("Couldn't retrieve object as \""
198 << SG::normalizedTypeinfoName(ti) << "\"");
199 return nullptr;
200 }
201
202 // Return the object:
203 return result;
204}

◆ getOutputObject() [2/2]

void * Event::getOutputObject ( SG::sgkey_t key,
const std::type_info & ti )
overrideprotectedvirtualinherited

Function for retrieving an output object in a non-template way.

This function is used by the TVirtualEvent interface to access an output object with a given hashed key.

The function looks up the string key belonging to the hash, and then calls the other GetOutputObject(...) function in the class with that parameter.

Parameters
keyThe hashed key of the output object
tiThe type description of the object requested
Returns
A pointer to the requested object, or a null pointer in case of failure

Implements xAOD::TVirtualEvent.

Definition at line 138 of file EventTVirtualEvent.cxx.

138 {
139
140 // Get a string name for this key.
141 const std::string& name = getName(key);
142 if (name.empty()) {
143 return nullptr;
144 }
145
146 // Forward the call to the function using an std::string key.
147 static const bool METADATA = false;
148 return getOutputObject(name, ti, METADATA);
149}

◆ hasInput()

bool xAOD::TEvent::hasInput ( ) const
overrideprotectedvirtual

Check if an input file is connected to the object.

Implements xAOD::Event.

Definition at line 897 of file Control/xAODRootAccess/Root/TEvent.cxx.

897 {
898
899 return ((m_inTree != nullptr) || (m_inChain != nullptr));
900}

◆ hasOutput()

bool xAOD::TEvent::hasOutput ( ) const
overrideprotectedvirtual

Check if an output file is connected to the object.

Implements xAOD::Event.

Definition at line 902 of file Control/xAODRootAccess/Root/TEvent.cxx.

902{ return (m_outTree.get() != nullptr); }

◆ initMessaging()

void AthMessaging::initMessaging ( ) const
privateinherited

Initialize our message level and MessageSvc.

This method should only be called once.

Definition at line 39 of file AthMessaging.cxx.

40{
42 // If user did not set an explicit level, set a default
43 if (m_lvl == MSG::NIL) {
44 m_lvl = m_imsg ?
45 static_cast<MSG::Level>( m_imsg.load()->outputLevel(m_nm) ) :
46 MSG::INFO;
47 }
48}
std::string m_nm
Message source name.
std::atomic< IMessageSvc * > m_imsg
MessageSvc pointer.
std::atomic< MSG::Level > m_lvl
Current logging level.
IMessageSvc * getMessageSvc(bool quiet=false)

◆ initStats()

StatusCode xAOD::TEvent::initStats ( )
protected

Function to initialise the statistics for all Tree content.

This function is used internally to initialise the reading of an input file.

It prepares the "monitoring information" in memory that gets filled while the code is running, with information about xAOD I/O.

Returns
The usual StatusCode tyoes

Definition at line 1811 of file Control/xAODRootAccess/Root/TEvent.cxx.

1811 {
1812
1813 // If we're dealing with an empty input file, stop here:
1814 if (m_inTreeMissing) {
1815 return StatusCode::SUCCESS;
1816 }
1817
1818 // A little sanity check:
1819 if (!m_inTree) {
1820 ATH_MSG_ERROR("Function called on an uninitialised object");
1821 return StatusCode::FAILURE;
1822 }
1823
1824 // Reset the number of input branches information:
1826
1827 // Loop over the EventFormat information
1830 for (; itr != end; ++itr) {
1831
1832 // Get the name of the branch in question:
1833 const std::string &branchName = itr->second.branchName();
1834
1835 // If it's an auxiliary container, scan it using TAuxStore:
1836 if (branchName.find("Aux.") != std::string::npos) {
1837
1838 // But first decide whether it describes a container, or just
1839 // a single object. Since the file may have been written in
1840 // kBranchAccess mode, it's not necessarily a good idea to check
1841 // the type of the auxiliary class. So let's check the interface
1842 // class instead.
1843 //
1844 // Get the name of the interface object/container:
1845 const std::string intName = branchName.substr(0, branchName.size() - 4);
1846 if (!m_inputEventFormat.exists(intName)) {
1847 // When this happens, it may still be that both the interface and
1848 // the auxiliary container is missing from the file. As we didn't
1849 // check yet whether the auxiliary container is in place or not.
1850 // So, before printing a warning, let's check for this.
1851 // Unfortunately the check is pretty expensive, but this should
1852 // not be performance critical code after all...
1853 ::Bool_t auxFound = kFALSE;
1854 const std::string dynName = Utils::dynBranchPrefix(branchName);
1855
1856 std::vector<TObjArray *> fullListOfBranches = {};
1857 // Add the list of branches of the main tree
1858 fullListOfBranches.push_back(m_inTree->GetListOfBranches());
1859 // If input tree has friend trees
1860 // add as well the list of friend tree branches
1861 if (m_inTree->GetListOfFriends()) {
1862 // Get the list of friends
1863 TList *fList = m_inTree->GetListOfFriends();
1864 // Loop over friend elements
1865 for (TObject *feObj : *fList) {
1866 if (feObj) {
1867 // Get corresponding friend tree
1868 auto *pElement = dynamic_cast<TFriendElement *>(feObj);
1869 if (not pElement)
1870 continue;
1871 TTree *friendTree = pElement->GetTree();
1872 // Add list of branches of the friend tree
1873 fullListOfBranches.push_back(friendTree->GetListOfBranches());
1874 }
1875 }
1876 }
1877
1878 for (TObjArray *branches : fullListOfBranches) {
1879 for (Int_t i = 0; i < branches->GetEntriesFast(); ++i) {
1880 if (!branches->At(i))
1881 continue;
1882
1883 const TString name(branches->At(i)->GetName());
1884 if (name.BeginsWith(branchName) || name.BeginsWith(dynName)) {
1885 auxFound = kTRUE;
1886 break;
1887 }
1888 }
1889 }
1890 if (auxFound) {
1891 ATH_MSG_WARNING("Couldn't find interface object/container \""
1892 << intName << "\" belonging to branch \""
1893 << branchName << "\"");
1894 }
1895 continue;
1896 }
1897
1898 // Get the type of the interface:
1899 const EventFormatElement *el = m_inputEventFormat.get(intName);
1900 ::TClass *cl = ::TClass::GetClass(el->className().c_str());
1901 if ((!cl) || (!cl->IsLoaded())) {
1902 ATH_MSG_WARNING("Couldn't find dictionary for type \""
1903 << el->className() << "\"");
1904 continue;
1905 }
1906
1907 // Get the dictionary for the DataVector base class:
1908 static const std::type_info &baseTi = typeid(SG::AuxVectorBase);
1909 static const std::string baseName = SG::normalizedTypeinfoName(baseTi);
1910 static ::TClass *const baseCl = ::TClass::GetClass(baseName.c_str());
1911 if (!baseCl) {
1912 ATH_MSG_ERROR("Couldn't get dictionary for type \"" << baseName
1913 << "\"");
1914 return StatusCode::FAILURE;
1915 }
1916
1917 // The type of the auxiliary store is finally deduced from the
1918 // inheritance of the interface container.
1920 (cl->InheritsFrom(baseCl) ? TAuxStore::EStructMode::kContainerStore
1922
1923 // Scan the branches using a temporary TAuxStore instance:
1924 static constexpr bool TOP_STORE = true;
1925 TAuxStore temp(branchName, TOP_STORE, mode);
1926 static constexpr bool PRINT_WARNINGS = false;
1927 ATH_CHECK(temp.readFrom(*m_inTree, PRINT_WARNINGS));
1928
1929 // Conveninence variable:
1930 ReadStats &stats = IOStats::instance().stats();
1931
1932 // Teach the cache about all the branches:
1933 for (SG::auxid_t id : temp.getAuxIDs()) {
1934 stats.branch(branchName, id);
1935 }
1936
1937 // Increment the number of known branches:
1938 stats.setBranchNum(stats.branchNum() + temp.getAuxIDs().size());
1939 }
1940 // If it's an interface container:
1941 else {
1942 // Try to access the branch:
1943 const ::TBranch *container = m_inTree->GetBranch(branchName.c_str());
1944 // If it exists, let's remember it:
1945 if (container) {
1946 IOStats::instance().stats().container(branchName);
1947 }
1948 }
1949 }
1950
1951 // Return gracefully:
1952 return StatusCode::SUCCESS;
1953}
KeyedData_t::const_iterator const_iterator
Iterator for looping over the elements of the object.
BranchStats * container(const std::string &name)
Access the description of a container. Creating it if necessary.
void setBranchNum(::Int_t num)
Set the total number of branches on the input.
EStructMode
"Structural" modes of the object
size_t auxid_t
Identifier for a particular aux data item.
Definition AuxTypes.h:27
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...

◆ inputEventFormat()

const EventFormat * Event::inputEventFormat ( ) const
inherited

Get information about the input objects.

Definition at line 228 of file EventCore.cxx.

228 {
229
230 if (hasInput()) {
231 return &m_inputEventFormat;
232 }
233 return nullptr;
234}

◆ keys()

template<typename T>
StatusCode xAOD::Event::keys ( std::vector< std::string > & vkeys,
bool metadata ) const
inherited

Provide a list of all data object keys associated with a specific type.

◆ keyToString() [1/2]

const std::string * Event::keyToString ( SG::sgkey_t key) const
overrideprotectedinherited

Find the string corresponding to a given key.

Definition at line 294 of file EventIProxyDict.cxx.

294 {
295
296 return &(getName(key));
297}

◆ keyToString() [2/2]

const std::string * Event::keyToString ( SG::sgkey_t key,
CLID & clid ) const
overrideprotectedinherited

Find the string and CLID corresponding to a given key.

Definition at line 299 of file EventIProxyDict.cxx.

299 {
300
301 return &(getName(key));
302}

◆ MakeTransientTree()

friend::TTree * xAOD::TEvent::MakeTransientTree ( TEvent & ,
const char *  )
private

◆ metaKeys()

template<typename T>
StatusCode xAOD::Event::metaKeys ( std::vector< std::string > & vkeys) const
inherited

Provide a list of all metadata object keys associated with a specific type.

◆ msg() [1/2]

MsgStream & asg::AsgMessaging::msg ( ) const
inherited

The standard message stream.

Returns
A reference to the default message stream of this object.

Definition at line 49 of file AsgMessaging.cxx.

49 {
50#ifndef XAOD_STANDALONE
51 return ::AthMessaging::msg();
52#else // not XAOD_STANDALONE
53 return m_msg;
54#endif // not XAOD_STANDALONE
55 }

◆ msg() [2/2]

MsgStream & asg::AsgMessaging::msg ( const MSG::Level lvl) const
inherited

The standard message stream.

Parameters
lvlThe message level to set the stream to
Returns
A reference to the default message stream, set to level "lvl"

Definition at line 57 of file AsgMessaging.cxx.

57 {
58#ifndef XAOD_STANDALONE
59 return ::AthMessaging::msg( lvl );
60#else // not XAOD_STANDALONE
61 m_msg << lvl;
62 return m_msg;
63#endif // not XAOD_STANDALONE
64 }

◆ msgLvl()

bool asg::AsgMessaging::msgLvl ( const MSG::Level lvl) const
inherited

Test the output level of the object.

Parameters
lvlThe message level to test against
Returns
boolean Indicting if messages at given level will be printed
true If messages at level "lvl" will be printed

Definition at line 41 of file AsgMessaging.cxx.

41 {
42#ifndef XAOD_STANDALONE
43 return ::AthMessaging::msgLvl( lvl );
44#else // not XAOD_STANDALONE
45 return m_msg.msgLevel( lvl );
46#endif // not XAOD_STANDALONE
47 }

◆ name()

const std::string & Event::name ( ) const
overrideprotectedinherited

Get the name of the instance.

Definition at line 315 of file EventIProxyDict.cxx.

315 {
316
317 static const std::string result{"xAOD::Event"};
318 return result;
319}

◆ outputEventFormat()

const EventFormat * Event::outputEventFormat ( ) const
inherited

Get information about the output objects.

Definition at line 236 of file EventCore.cxx.

236 {
237
238 return m_outputEventFormat;
239}

◆ printIOStats()

void Event::printIOStats ( ) const
inherited

Function printing the I/O statistics of the current process.

This is a convenience function for printing basic I/O information about the current job.

It can be called at the end of a job to get an overview of what the job did exactly I/O-wise.

Definition at line 298 of file EventCore.cxx.

298 {
299
300 // Simply do this via the xAODCore code:
301 IOStats::instance().stats().Print("Summary");
302}
void Print(::Option_t *option="") const
Print information about the collected statistics.

◆ printNameRemap()

void Event::printNameRemap ( ) const
inherited

Print the current name re-mapping rules.

This function can be used for debugging, to check what container/object name remapping rules are in place for the current TEvent object.

Definition at line 201 of file EventCore.cxx.

201 {
202
203 // Print a header.
204 ATH_MSG_INFO("Name remapping rules:");
205
206 // In case no remapping rules have been set.
207 if (m_nameRemapping.empty()) {
208 ATH_MSG_INFO(" NONE");
209 return;
210 }
211
212 // Otherwise.
213 for (const auto& [newName, onfile] : m_nameRemapping) {
214 ATH_MSG_INFO(" \"" << newName << "\" -> \"" << onfile << "\"");
215 }
216}
#define ATH_MSG_INFO(x)

◆ printProxyWarnings()

void Event::printProxyWarnings ( bool value = true)
inherited

Enable warnings associated with broken element links.

These appear harmless so long as you don't actually try to access the links.

Which will cause other errors anyway.

Parameters
valueThe new value for the option

Definition at line 223 of file EventCore.cxx.

223 {
224
226}

◆ proxies()

std::vector< const SG::DataProxy * > Event::proxies ( ) const
overrideprotectedinherited

return the list of all current proxies in store

Definition at line 275 of file EventIProxyDict.cxx.

275 {
276
278
279 std::vector<const SG::DataProxy*> ret;
280 for (const auto& p : m_branches) {
281 const SG::DataProxy* proxy = p.second.m_proxy.get();
282 if (proxy) {
283 ret.push_back(proxy);
284 }
285 }
286 return ret;
287}

◆ proxy() [1/2]

SG::DataProxy * Event::proxy ( const CLID & id,
const std::string & key ) const
overrideprotectedinherited

get proxy with given id and key. Returns 0 to flag failure

Definition at line 213 of file EventIProxyDict.cxx.

213 {
214
215 const SG::sgkey_t sgkey = getHash(key);
216 if (!sgkey) {
217 return 0;
218 }
219 return proxy_exact(sgkey);
220}
SG::DataProxy * proxy_exact(SG::sgkey_t sgkey) const override
Get proxy given a hashed key+clid.
uint32_t sgkey_t
Type used for hashed StoreGate key+CLID pairs.
Definition sgkey_t.h:32
sgkey(tool)
Definition common.py:1027

◆ proxy() [2/2]

SG::DataProxy * Event::proxy ( const void *const pTransient) const
overrideprotectedinherited

get proxy for a given data object address in memory

Definition at line 185 of file EventIProxyDict.cxx.

185 {
186
187 // Look up the name of this object
188 std::string name = getName(pTransient);
189 if (name.empty()) {
190 // Apparently the object is not known...
191 return nullptr;
192 }
193
194 // Get the metadata object for it:
195 const xAOD::EventFormatElement* efe = 0;
196 static const bool QUIET = true;
198 efe = m_outputEventFormat->get(name, QUIET);
199 }
200 if (!efe) {
201 efe = m_inputEventFormat.get(name, QUIET);
202 }
203 if (!efe) {
204 // No metadata found...
205 return nullptr;
206 }
207
208 // Return the proxy:
209 const BranchInfo* bi = getBranchInfo(efe->hash());
210 return bi->m_proxy.get();
211}
sgkey_t hash() const
Get the hash belonging to this branch/key.
const BranchInfo * getBranchInfo(SG::sgkey_t sgkey) const
Get the object describing one object/branch.

◆ proxy_exact()

SG::DataProxy * Event::proxy_exact ( SG::sgkey_t sgkey) const
overrideprotectedinherited

Get proxy given a hashed key+clid.

Definition at line 222 of file EventIProxyDict.cxx.

222 {
223
224 // Get the object describing this branch/object:
225 const BranchInfo* bi = getBranchInfo(sgkey);
226 if (!bi) {
227 static SG::SGKeySet missingSGKeys ATLAS_THREAD_SAFE;
228 static mutex_t mutex;
229 guard_t lock(mutex);
230 if (missingSGKeys.emplace(sgkey).second && m_printEventProxyWarnings) {
231 ATH_MSG_WARNING("Can't find BranchInfo for: " << sgkey);
232 }
233 return 0;
234 }
235
236 // Access its data proxy:
237 SG::DataProxy* proxy = bi->m_proxy.get();
238
239 // Return the proxy:
240 return proxy;
241}

◆ putAux()

StatusCode xAOD::TEvent::putAux ( ::TTree & outTree,
TVirtualManager & vmgr,
bool metadata )
protected

Function saving the dynamically created auxiliary properties.

This function is used internally to set up the writing of the auxiliary store variables that were dynamically created on an object.

(And not statically defined to be part of that object.)

Parameters
outTreeThe TTree to put the auxiliary branches into
mgrThe object manager of the output object
metadataFlag specifying whether the info written is metadata or not
Returns
The usual StatusCode types

Definition at line 2130 of file Control/xAODRootAccess/Root/TEvent.cxx.

2131 {
2132
2133 // A little sanity check:
2134 assert(m_outputEventFormat != 0);
2135
2136 // Do the conversion:
2137 TObjectManager *mgr = dynamic_cast<TObjectManager *>(&vmgr);
2138 if (!mgr) {
2139 // It's not an error any more when we don't get a TObjectManager.
2140 return StatusCode::SUCCESS;
2141 }
2142
2143 // Check if we need to do anything here:
2144 if (!mgr->holder()->getClass()->InheritsFrom("SG::IAuxStoreIO")) {
2145 return StatusCode::SUCCESS;
2146 }
2147
2148 // Get a pointer to the auxiliary store I/O interface:
2149 SG::IAuxStoreIO *aux = reinterpret_cast<SG::IAuxStoreIO *>(
2150 mgr->holder()->getAs(typeid(SG::IAuxStoreIO)));
2151 if (!aux) {
2152 ATH_MSG_FATAL("There is a logic error in the code!");
2153 return StatusCode::FAILURE;
2154 }
2155
2156 // Check if we have rules defined for which auxiliary properties
2157 // to write out:
2158 xAOD::AuxSelection sel;
2159 if (!metadata) {
2160 auto item_itr = m_auxItemList.find(mgr->branch()->GetName());
2161 if (item_itr != m_auxItemList.end()) {
2162 sel.selectAux(item_itr->second);
2163 }
2164 }
2165
2166 // Get the dynamic auxiliary variables held by this object, which
2167 // were selected to be written:
2168 const SG::auxid_set_t auxids =
2169 sel.getSelectedAuxIDs(aux->getSelectedAuxIDs());
2170
2171 // If there are no dynamic auxiliary variables in the object, return
2172 // right away:
2173 if (auxids.empty()) {
2174 return StatusCode::SUCCESS;
2175 }
2176
2177 // Decide what should be the prefix of all the dynamic branches:
2178 const std::string dynNamePrefix =
2179 Utils::dynBranchPrefix(mgr->branch()->GetName());
2180
2181 // Select which container to add the variables to:
2183
2184 // This iteration will determine the ordering of branches within
2185 // the tree, so sort auxids by name.
2186 const SG::AuxTypeRegistry &r = SG::AuxTypeRegistry::instance();
2187 typedef std::pair<std::string, SG::auxid_t> AuxVarSort_t;
2188 std::vector<AuxVarSort_t> varsort;
2189 varsort.reserve(auxids.size());
2190 for (SG::auxid_t id : auxids) {
2191 varsort.emplace_back(r.getName(id), id);
2192 }
2193 std::sort(varsort.begin(), varsort.end());
2194
2195 // Extract all the dynamic variables from the object:
2196 for (const auto &p : varsort) {
2197
2198 // The auxiliary ID:
2199 const SG::auxid_t id = p.second;
2200
2201 // Construct a name for the branch that we will write:
2202 const std::string brName = dynNamePrefix + p.first;
2203
2204 // Try to find the branch:
2205 Object_t::iterator bmgr = objects.find(brName);
2206
2207 // Check if we already know about this variable:
2208 if (bmgr == objects.end()) {
2209
2210 // Construct the full type name of the variable:
2211 const std::type_info *brType = aux->getIOType(id);
2212 if (!brType) {
2213 ATH_MSG_ERROR("No I/O type found for variable " << brName);
2214 return StatusCode::FAILURE;
2215 }
2216 const std::string brTypeName = Utils::getTypeName(*brType);
2217 std::string brProperTypeName = "<unknown>";
2218
2219 // The branch that will hopefully be created:
2220 ::TBranch *br = 0;
2221
2222 // Check if it's a primitive type or not:
2223 if (strlen(brType->name()) == 1) {
2224
2225 // Making the "proper" type name is simple in this case:
2226 brProperTypeName = brTypeName;
2227
2228 // Get the character describing this type for ROOT:
2229 const char rootType = Utils::rootType(brType->name()[0]);
2230 if (rootType == '\0') {
2231 ATH_MSG_ERROR("Type not known for variable \""
2232 << brName << "\" of type \"" << brTypeName << "\"");
2233 return StatusCode::FAILURE;
2234 }
2235
2236 // Create the full description of the variable for ROOT:
2237 std::ostringstream leaflist;
2238 leaflist << brName << "/" << rootType;
2239
2240 // Let's create a holder for this property:
2241 static constexpr bool IS_OWNER = false;
2242 auto auxmgr = std::make_unique<TPrimitiveAuxBranchManager>(
2243 id, nullptr, new THolder(aux->getIOData(id), nullptr, IS_OWNER));
2244
2245 // ... and let's add it to the output TTree:
2246 static constexpr Int_t BASKET_SIZE = 32000;
2247 *(auxmgr->branchPtr()) =
2248 outTree.Branch(brName.c_str(), auxmgr->holder()->get(),
2249 leaflist.str().c_str(), BASKET_SIZE);
2250 if (!auxmgr->branch()) {
2251 ATH_MSG_ERROR("Failed to create branch \""
2252 << brName << "\" out of type \"" << brProperTypeName
2253 << "\"");
2254 // Clean up:
2255 *(auxmgr->holder()->getPtr()) = 0;
2256 return StatusCode::FAILURE;
2257 }
2258 br = auxmgr->branch();
2259
2260 // Store it in the output list.
2261 objects[brName] = std::move(auxmgr);
2262
2263 } else {
2264
2265 // Check if we have a dictionary for this type:
2266 static constexpr Bool_t LOAD_IF_NOT_FOUND = kTRUE;
2267 static constexpr Bool_t SILENT = kTRUE;
2268 TClass *cl = TClass::GetClass(*brType, LOAD_IF_NOT_FOUND, SILENT);
2269 if (cl == nullptr) {
2270 // The dictionary needs to be loaded now. This could be an
2271 // issue. But let's hope for the best...
2272 cl = TClass::GetClass(brTypeName.c_str());
2273 // If still not found...
2274 if (cl == nullptr) {
2275 ATH_MSG_ERROR("Dictionary not available for variable \""
2276 << brName << "\" of type \"" << brTypeName << "\"");
2277 return StatusCode::FAILURE;
2278 }
2279 }
2280
2281 // The proper type name comes from the dictionary in this case:
2282 brProperTypeName = cl->GetName();
2283
2284 // Let's create a holder for this property:
2285 static constexpr bool IS_OWNER = false;
2286 auto auxmgr = std::make_unique<TAuxBranchManager>(
2287 id, nullptr, new THolder(aux->getIOData(id), cl, IS_OWNER));
2288
2289 // ... and let's add it to the output TTree.
2290 static constexpr Int_t BASKET_SIZE = 32000;
2291 static constexpr Int_t SPLIT_LEVEL = 0;
2292 *(auxmgr->branchPtr()) = outTree.Branch(brName.c_str(), cl->GetName(),
2293 auxmgr->holder()->getPtr(),
2294 BASKET_SIZE, SPLIT_LEVEL);
2295 if (!auxmgr->branch()) {
2296 ATH_MSG_ERROR("Failed to create branch \""
2297 << brName << "\" out of type \"" << brProperTypeName
2298 << "\"");
2299 // Clean up:
2300 *(auxmgr->holder()->getPtr()) = 0;
2301 return StatusCode::FAILURE;
2302 }
2303 br = auxmgr->branch();
2304
2305 // Store it in the output list.
2306 objects[brName] = std::move(auxmgr);
2307 }
2308
2309 // If this is not the first event, fill up the already filled
2310 // events with (empty) content:
2311 if (outTree.GetEntries()) {
2312 void *ptr = br->GetAddress();
2313 br->SetAddress(0);
2314 for (::Long64_t i = 0; i < outTree.GetEntries(); ++i) {
2315 br->Fill();
2316 }
2317 br->SetAddress(ptr);
2318 }
2319
2320 // If all went fine, let's add this branch to the event format
2321 // metadata:
2322 if (!m_outputEventFormat->exists(brName)) {
2323 m_outputEventFormat->add(EventFormatElement(brName, brProperTypeName,
2324 mgr->branch()->GetName(),
2325 getHash(brName)));
2326 }
2327
2328 // We don't need to do the rest:
2329 continue;
2330 }
2331
2332 // Access the object manager:
2333 bmgr = objects.find(brName);
2334 if (bmgr == objects.end()) {
2335 ATH_MSG_FATAL("There is an internal logic error in the code...");
2336 return StatusCode::FAILURE;
2337 }
2338
2339 // Replace the managed object:
2340 void *nc_data ATLAS_THREAD_SAFE = // we hold non-const pointers but check
2341 // on retrieve
2342 const_cast<void *>(static_cast<const void *>(aux->getIOData(id)));
2343 bmgr->second->setObject(nc_data);
2344 }
2345
2346 // Return gracefully:
2347 return StatusCode::SUCCESS;
2348}
std::atomic_flag m_initialized ATLAS_THREAD_SAFE
Messaging initialized (initMessaging)
bit_t size() const
Count the number of 1 bits in the set.
bool empty() const
Return true if there are no 1 bits in the set.
static AuxTypeRegistry & instance()
Return the singleton registry instance.
virtual SG::auxid_set_t getSelectedAuxIDs() const
Get a list of dynamic variables that need to be written out.
Definition IAuxStoreIO.h:86
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.
virtual const void * getIOData(SG::auxid_t auxid) const =0
Return a pointer to the data to be stored for one aux data item.
std::unordered_map< std::string, std::set< std::string > > m_auxItemList
Rules for selecting which auxiliary branches to write.
Definition Event.h:326
int r
Definition globals.cxx:22
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
char rootType(char typeidType)
This function is used internally in the code when creating primitive dynamic auxiliary branches.
std::string getTypeName(const std::type_info &ti)
This function is necessary in order to create type names that ROOT can understand.

◆ readFrom() [1/2]

StatusCode xAOD::TEvent::readFrom ( ::TFile * file,
bool useTreeCache = true,
std::string_view treeName = EVENT_TREE_NAME )

Connect the object to a new input file.

This function takes care of connecting the event object to a new input file.

It reads in the metadata of the input file needed for reading the file.

Parameters
filePointer to the file being read
useTreeCacheFlag for turning on/off the usage of TTreeCache
treeNameName of the input tree
Returns
The usual StatusCode tyoes

Definition at line 127 of file Control/xAODRootAccess/Root/TEvent.cxx.

128 {
129
130 // If no file was specified, return gracefully.
131 if (file == nullptr) {
132 ATH_MSG_DEBUG("No input file specified for readFrom(...)");
133 return StatusCode::SUCCESS;
134 }
135
136 // Clear the cached input objects.
137 m_inputObjects.clear();
138 m_inputMissingObjects.clear();
139 m_inputMetaObjects.clear();
140 {
142 lock.upgrade();
143 m_branches.clear();
144 }
145
146 // Reset the internal flags.
147 m_inTreeMissing = kFALSE;
148 m_entry = -1;
149
150 // Make sure we return to the current directory:
151 TDirectoryReset dr;
152
153 // Set up the file access tracer.
154 static TFileAccessTracer tracer ATLAS_THREAD_SAFE;
155 tracer.add(*file);
156
157 // Look for the metadata tree:
158 m_inMetaTree = file->Get<TTree>(METADATA_TREE_NAME);
159 if (m_inMetaTree == nullptr) {
160 ATH_MSG_ERROR("Couldn't find metadata tree on input. Object is unusable!");
161 return StatusCode::FAILURE;
162 }
163
164 // Set metadata entry to be read
165 // NB: no reading is done calling LoadTree
166 if (m_inMetaTree->LoadTree(0) < 0) {
167 ATH_MSG_ERROR("Failed to load entry 0 for metadata tree");
168 return StatusCode::FAILURE;
169 }
170
171 // A sanity check.
172 if (m_inMetaTree->GetEntries() != 1) {
173 ATH_MSG_WARNING("Was expecting a metadata tree with size 1, instead of "
174 << m_inMetaTree->GetEntries() << ".");
175 ATH_MSG_WARNING("The input file was most probably produced by hadd...");
176 }
177
178 // Make sure that the xAOD::EventFormat dictonary is loaded.
179 // This may not be the case if streamer information reading is turned
180 // off.
181 static const std::string eventFormatTypeName =
183 ::TClass *cl = ::TClass::GetClass(eventFormatTypeName.c_str());
184 if (cl == nullptr) {
185 ATH_MSG_WARNING("Couldn't load the xAOD::EventFormat dictionary");
186 }
187
188 // Helper lambda for collecting the event format metadata from an RNTuple
189 // with a given name.
190 auto readEventFormatMetadata =
191 [&](std::string_view thisTreeName) -> StatusCode {
192 // Look for the metadata tree:
193 TTree *metaTree = file->Get<TTree>(thisTreeName.data());
194 if (metaTree == nullptr) {
195 ATH_MSG_ERROR("Couldn't find metadata tree \"" << thisTreeName
196 << "\"on input.");
197 return StatusCode::FAILURE;
198 }
199 // Set metadata entry to be read.
200 if (metaTree->LoadTree(0) < 0) {
201 ATH_MSG_ERROR("Failed to load entry 0 for metadata tree \""
202 << thisTreeName << "\"");
203 return StatusCode::FAILURE;
204 }
205
206 // Check if the EventFormat branch is available:
207 const std::string eventFormatBranchName =
209 if (!metaTree->GetBranch(eventFormatBranchName.c_str())) {
210 // This can happen when the file was produced by an Athena job that
211 // didn't have any input events itself. This means that the file
212 // doesn't actually have any useful metadata.
213 ATH_MSG_INFO("Input file provides no event or metadata");
214 return StatusCode::RECOVERABLE;
215 }
216
217 // Read in the event format object:
218 EventFormat *format = 0;
219 ::TBranch *br = 0;
220 const Int_t status =
221 metaTree->SetBranchAddress(eventFormatBranchName.c_str(), &format, &br);
222 if (status < 0) {
223 ATH_MSG_ERROR("Failed to connect to xAOD::EventFormat object");
224 return StatusCode::FAILURE;
225 }
226
227 // Merge the object into our private member.
228 br->GetEntry(0);
229 for (const auto &[key, element] : *format) {
230 m_inputEventFormat.add(element);
231 }
232
233 // This is a strange place. The object has to be deleted, as it is the
234 // responsibility of the user code to do so. But if I also explicitly
235 // tell the branch to forget about the address of the pointer, then
236 // all hell breaks loose...
237 delete format;
238
239 // Return gracefully.
240 return StatusCode::SUCCESS;
241 };
242
243 // Read in the metadata from the "main" metadata ntuple.
245 const StatusCode sc = readEventFormatMetadata(METADATA_TREE_NAME);
246 if (sc.isRecoverable()) {
247 m_inTree = nullptr;
248 m_inTreeMissing = true;
249 return StatusCode::SUCCESS;
250 }
251 ATH_CHECK(sc);
252
253 // List all the other Metadata trees in the input file
254 // Having several metatrees can happen for augmented files for instance
255 // as one metadata tree per stream is produced
256 std::set<std::string> lOtherMetaTreeNames = {};
257 TList *lKeys = file->GetListOfKeys();
258
259 if (lKeys) {
260 for (int iKey = 0; iKey < lKeys->GetEntries(); iKey++) {
261 // iterate over keys and add
262 std::string keyName = lKeys->At(iKey)->GetName();
263 // Make sure the key corresponds to a metadata tree but
264 // do not add the current metadata tree in the list of other trees
265 // and do not add the metadata tree handlers to the list
266 if ((keyName != METADATA_TREE_NAME) &&
267 std::regex_match(keyName, m_otherMetaDataTreeNamePattern)) {
268 // Make sure key corresponds to a tree
269 const char *className = ((::TKey *)lKeys->At(iKey))->GetClassName();
270 static constexpr Bool_t LOAD = kFALSE;
271 static constexpr Bool_t SILENT = kTRUE;
272 ::TClass *cl = ::TClass::GetClass(className, LOAD, SILENT);
273 if ((cl != nullptr) && cl->InheritsFrom(::TTree::Class())) {
274 // key is corresponding to a metadata tree
275 lOtherMetaTreeNames.insert(std::move(keyName));
276 }
277 }
278 }
279 }
280
281 // Loop over the other metadata trees found (if any).
282 for (const std::string &metaTreeName : lOtherMetaTreeNames) {
283 ATH_CHECK(readEventFormatMetadata(metaTreeName));
284 }
285
286 // Look for the event tree in the input file.
287 m_inTree = file->Get<TTree>(treeName.data());
288 if (m_inTree == nullptr) {
289 // This is no longer an error condition. As it can happen for DxAODs
290 // that don't have any events in them. But they still have metadata
291 // that needs to be collected.
292 m_inTreeMissing = kTRUE;
293 }
294
295 // Turn on the cache if requested.
296 if (m_inTree && useTreeCache && (!m_inTree->GetCacheSize())) {
297 m_inTree->SetCacheSize(CACHE_SIZE);
298 m_inTree->SetCacheLearnEntries(10);
299 }
300
301 // Init the statistics collection.
303 // Update the event counter in the statistics object.
304 xAOD::ReadStats &stats = IOStats::instance().stats();
305 if (m_inTree) {
306 stats.setNEvents(stats.nEvents() + m_inTree->GetEntries());
307 }
308
309 // Notify the listeners that a new file was opened.
310 const TIncident beginIncident(IncidentType::BeginInputFile);
311 for (TVirtualIncidentListener *listener : m_listeners) {
312 listener->handle(beginIncident);
313 }
314 // For now implement a very simple scheme in which we claim already
315 // at the start that the entire file was processed. Since we have no way
316 // of ensuring that the user indeed does this. And we can't delay calling
317 // this function, as the user may likely close his/her output file before
318 // closing the last opened input file.
319 const TIncident endIncident(IncidentType::EndInputFile);
320 for (TVirtualIncidentListener *listener : m_listeners) {
321 listener->handle(endIncident);
322 }
323
324 // The initialisation was successful.
325 return StatusCode::SUCCESS;
326}
StatusCode initStats()
Function to initialise the statistics for all Tree content.
static const ::Int_t EndInputFile
The processing of an input file has finished.
Definition TIncident.h:40
static const ::Int_t BeginInputFile
A new input file was just opened.
Definition TIncident.h:27
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.
static const ::Int_t CACHE_SIZE
Size of a possible TTreeCache.

◆ readFrom() [2/2]

StatusCode xAOD::TEvent::readFrom ( ::TTree * tree,
bool useTreeCache = true )

Connect the object to a new input tree/chain.

This version of the function sets up the object to read information from a tree/chain.

Using it with a TTree pointer makes not much sense, but using it with a TChain pointer could be a very valid usage mode.

Parameters
treeThe pointer to a TTree or a TChain
useTreeCacheFlag for switching TTreeCache usage on/off
Returns
The usual StatusCode tyoes

Definition at line 336 of file Control/xAODRootAccess/Root/TEvent.cxx.

336 {
337
338 // Remember the info:
339 m_inTree = nullptr;
340 m_inTreeMissing = false;
341 m_inChain = dynamic_cast<TChain *>(tree);
342 m_inMetaTree = nullptr;
343
344 if (m_inChain) {
345
346 // Set up the caching on the chain level. The individual trees of the
347 // input files will get a cache set up automatically after this.
348 if (useTreeCache && (!m_inChain->GetCacheSize())) {
349 m_inChain->SetCacheSize(CACHE_SIZE);
350 m_inChain->SetCacheLearnEntries(10);
351 }
352
353 // Explicitly open the first file of the chain. To correctly auto-load
354 // the dictionaries necessary. This doesn't happen automatically with
355 // some ROOT versions...
356 const TObjArray *files = m_inChain->GetListOfFiles();
357 if (!files) {
358 ATH_MSG_ERROR("Couldn't get the list of files from the input TChain");
359 return StatusCode::FAILURE;
360 }
361 if (!files->GetEntries()) {
362 ATH_MSG_ERROR("No files are present in the received TChain");
363 return StatusCode::FAILURE;
364 }
365 const ::TChainElement *chEl =
366 dynamic_cast<const ::TChainElement *>(files->At(0));
367 if (!chEl) {
368 ATH_MSG_ERROR("Couldn't cast object to TChainElement");
369 return StatusCode::FAILURE;
370 }
371 {
372 std::unique_ptr<TFile> dummyFile{TFile::Open(chEl->GetTitle())};
373 if (!dummyFile) {
374 ATH_MSG_ERROR("Couldn't open file " << chEl->GetTitle());
375 return StatusCode::FAILURE;
376 }
377 }
378
379 // Set up a tracker for the chain.
380 if (!m_inChainTracker) {
381 m_inChainTracker = std::make_unique<TChainStateTracker>();
382 }
383 m_inChainTracker->reset();
384 tree->SetNotify(m_inChainTracker.get());
385
386 // Stop at this point. The first file will be opened when the user
387 // asks for the first event. Otherwise we open the first file of the
388 // chain multiple times.
389 m_inTreeNumber = -1;
390 return StatusCode::SUCCESS;
391
392 } else {
393
394 // If it's a simple TTree, then let's fully initialise the object
395 // using its file:
396 m_inTreeNumber = -1;
397 if (m_inChainTracker) {
398 m_inChainTracker.reset();
399 }
400 ::TFile *file = tree->GetCurrentFile();
401 return readFrom(file, useTreeCache, tree->GetName());
402 }
403}
std::vector< std::string > files
file names and file pointers
Definition hcg.cxx:50

◆ record() [1/4]

template<typename T>
StatusCode xAOD::Event::record ( std::unique_ptr< T > obj,
const std::string & key )

Add an output object to the event, explicitly taking ownership of it.

◆ record() [2/4]

StatusCode xAOD::TEvent::record ( std::unique_ptr< TAuxStore > store,
const std::string & key )
protected

Internal function for adding an auxiliary store object to the output.

This function is used internally when copying an object with its auxiliary store from the input file, and branch access mode is activated for the event object.

The assumption is that the store object already knows what prefix it should be using. The key parameter only specifies under what ID the object should be handled in the output object list.

Parameters
storeThe store object to connect to the output
keyThe "key" with which to record the object
Returns
The usual StatusCode tyoes

Definition at line 1967 of file Control/xAODRootAccess/Root/TEvent.cxx.

1968 {
1969
1970 // Check if we have an output tree:
1971 if (!m_outTree) {
1973 "No output tree defined. Did you forget to call writeTo(...)?");
1974 return StatusCode::FAILURE;
1975 }
1976
1977 // Check if we have a filtering rule for this key:
1978 const std::set<std::string> *filter = 0;
1979 auto filter_itr = m_auxItemList.find(key);
1980 if (filter_itr != m_auxItemList.end()) {
1981 filter = &(filter_itr->second);
1982 }
1983
1984 // Check if we need to add it to the event record:
1985 Object_t::iterator vitr = m_outputObjects.find(key);
1986 if (vitr == m_outputObjects.end()) {
1987
1988 // Configure the object for variable filtering:
1989 if (filter) {
1990 store->selectAux(*filter);
1991 }
1992 // Tell the object where to write its contents:
1993 ATH_CHECK(store->writeTo(*m_outTree));
1994 // Record it to the output list:
1995 static constexpr bool OWNS_STORE = true;
1997 std::make_unique<TAuxManager>(store.release(), OWNS_STORE);
1998
1999 // We're done:
2000 return StatusCode::SUCCESS;
2001 }
2002
2003 // Check if the output has the right store:
2004 if (vitr->second->object() == store.get()) {
2005 // We're done already:
2006 return StatusCode::SUCCESS;
2007 }
2008
2009 // If not, update the output manager. This can happen when we copy
2010 // objects from the input to the output files, and we process
2011 // multiple input files.
2012
2013 // Check if the output manager is of the right type:
2014 TAuxManager *mgr = dynamic_cast<TAuxManager *>(vitr->second.get());
2015 if (mgr == nullptr) {
2016 ATH_MSG_ERROR("Output object with key \""
2017 << key << "\" already exists, and is not of type TAuxStore");
2018 return StatusCode::FAILURE;
2019 }
2020
2021 // Configure the object for variable filtering:
2022 if (filter) {
2023 store->selectAux(*filter);
2024 }
2025
2026 // Connect the auxiliary store to the output tree:
2027 ATH_CHECK(store->writeTo(*m_outTree));
2028
2029 // Update the manager:
2030 mgr->setObject(store.release());
2031
2032 // Return gracefully:
2033 return StatusCode::SUCCESS;
2034}

◆ record() [3/4]

template<typename T>
StatusCode xAOD::Event::record ( T * obj,
const std::string & key )

Add an output object to the event.

◆ record() [4/4]

StatusCode xAOD::TEvent::record ( void * obj,
const std::string & typeName,
const std::string & key,
bool overwrite,
bool metadata,
bool isOwner )
overrideprotectedvirtual

Record an object into a connected output file.

This is the function doing the heavy lifting when recording a new object into the output tree/file.

It makes sure that the object is saved together with all of its dynamic auxiliary data if it has any.

Parameters
objA typeless pointer to the object that we want to record
typeNameThe type name of the output object
keyThe key (branch name) of the object to record
overwriteFlag selecting if it is allowed to overwrite an already existing object (used internally)
metadataFlag selecting if we are writing an event or a metadata object
isOwnerFlag selecting if we should take ownership of the object or not
Returns
The usual StatusCode tyoes

Implements xAOD::Event.

Definition at line 1640 of file Control/xAODRootAccess/Root/TEvent.cxx.

1642 {
1643
1644 // Check if we have an output tree when writing an event:
1645 if (!m_outTree && !metadata) {
1647 "No output tree defined. Did you forget to call writeTo(...)?");
1648 return StatusCode::FAILURE;
1649 }
1650 assert(m_outputEventFormat != 0);
1651
1652 // If this is metadata, just take ownership of it. The object will only
1653 // be recorded into the output file when calling finishWritingTo(...).
1654 if (metadata) {
1655 // Check whether we already have such an object:
1656 if ((!overwrite) &&
1657 (m_outputMetaObjects.find(key) != m_outputMetaObjects.end())) {
1658 ATH_MSG_ERROR("Meta-object \"" << typeName << "\"/\"" << key
1659 << "\" already recorded");
1660 return StatusCode::FAILURE;
1661 }
1662 // Check if we have a dictionary for this object:
1663 TClass *cl = TClass::GetClass(typeName.c_str());
1664 if (!cl) {
1665 ATH_MSG_ERROR("Didn't find dictionary for type: " << typeName);
1666 return StatusCode::FAILURE;
1667 }
1668 // Let's create a holder for the object:
1669 const bool renewOnRead = (m_auxMode == kAthenaAccess);
1670 m_outputMetaObjects[key] = std::make_unique<TObjectManager>(
1671 nullptr, std::make_unique<THolder>(obj, cl, isOwner), renewOnRead);
1672 // We're done. The rest will be done later on.
1673 return StatusCode::SUCCESS;
1674 }
1675
1676 // Check if we accessed this object on the input. If yes, then this
1677 // key may not be used for recording.
1678 if ((!overwrite) && (m_inputObjects.find(key) != m_inputObjects.end())) {
1679 ATH_MSG_ERROR("Object \"" << typeName << "\"/\"" << key
1680 << "\" already accessed from the input, can't be "
1681 "overwritten in memory");
1682 return StatusCode::FAILURE;
1683 }
1684
1685 // Choose a split level.
1686 const Int_t splitLevel = (key.ends_with("Aux.") ? 1 : 0);
1687
1688 // Check if we need to add it to the event record:
1689 Object_t::iterator vitr = m_outputObjects.find(key);
1690 if (vitr == m_outputObjects.end()) {
1691
1692 // Check if we have a dictionary for this object:
1693 TClass *cl = TClass::GetClass(typeName.c_str());
1694 if (cl == nullptr) {
1695 ATH_MSG_ERROR("Didn't find dictionary for type: " << typeName);
1696 return StatusCode::FAILURE;
1697 }
1698
1699 // Check if this is a new object "type" or not.
1700 if (!m_outputEventFormat->exists(key)) {
1702 EventFormatElement(key, cl->GetName(), "", getHash(key)));
1703 }
1704
1705 // Let's create a holder for the object.
1706 const bool renewOnRead = (m_auxMode == kAthenaAccess);
1707 auto mgr = std::make_unique<TObjectManager>(
1708 nullptr, std::make_unique<THolder>(obj, cl, isOwner), renewOnRead);
1709 TObjectManager *mgrPtr = mgr.get();
1710 m_outputObjects[key] = std::move(mgr);
1711
1712 // ... and let's add it to the output TTree.
1713 static constexpr Int_t basketSize = 32000;
1714 *(mgrPtr->branchPtr()) =
1715 m_outTree->Branch(key.c_str(), cl->GetName(),
1716 mgrPtr->holder()->getPtr(), basketSize, splitLevel);
1717 if (!mgrPtr->branch()) {
1718 ATH_MSG_ERROR("Failed to create branch \"" << key << "\" out of type \""
1719 << cl->GetName() << "\"");
1720 // Clean up:
1721 mgrPtr->holder()->setOwner(kFALSE);
1722 return StatusCode::FAILURE;
1723 }
1724
1725 // Set up the saving of all the dynamic auxiliary properties
1726 // of the object if it has any:
1727 static constexpr bool METADATA = false;
1728 ATH_CHECK(putAux(*m_outTree, *mgrPtr, METADATA));
1729
1730 // Return at this point, as we don't want to run the rest of
1731 // the function's code:
1732 return StatusCode::SUCCESS;
1733 }
1734
1735 // Access the object manager:
1736 TObjectManager *omgr = dynamic_cast<TObjectManager *>(vitr->second.get());
1737 if (!omgr) {
1738 ATH_MSG_ERROR("Manager object of the wrong type encountered");
1739 return StatusCode::FAILURE;
1740 }
1741
1742 // Check that the type of the object matches that of the previous
1743 // object:
1744 if (typeName != omgr->holder()->getClass()->GetName()) {
1745 // This may still be, when the ROOT dictionary name differs from the
1746 // "simple type name" known to C++. So let's get the ROOT name of the
1747 // new type:
1748 TClass *cl = TClass::GetClass(typeName.c_str());
1749 if ((!cl) ||
1750 ::strcmp(cl->GetName(), omgr->holder()->getClass()->GetName())) {
1751 ATH_MSG_ERROR("For output key \""
1752 << key << "\" the previous type was \""
1753 << omgr->holder()->getClass()->GetName()
1754 << "\", but the newly requested type is \"" << typeName
1755 << "\"");
1756 return StatusCode::FAILURE;
1757 }
1758 }
1759
1760 // Replace the managed object.
1761 omgr->setObject(obj);
1762
1763 // Replace the auxiliary objects.
1764 static constexpr bool METADATA = false;
1765 ATH_CHECK(putAux(*m_outTree, *omgr, METADATA));
1766
1767 // Return gracefully.
1768 return StatusCode::SUCCESS;
1769}

◆ recordAux() [1/3]

SG::IAuxStore * xAOD::TEvent::recordAux ( const std::string & key,
SG::IAuxStoreHolder::AuxStoreType type = SG::IAuxStoreHolder::AST_ContainerStore )

Add an auxiliary store object to the output.

This function can be used to create/retrieve a ROOT-specific auxiliary object container that can be used to write information in the output file.

Any auxiliary information written this way will however only be readable in ROOT, using the kBranchAccess option.

Parameters
keyThe name/prefix of the auxiliary store object/branches
typeThe type of the auxiliary store (object/container)
Returns
An auxiliary store object that will write to the output

Definition at line 567 of file Control/xAODRootAccess/Root/TEvent.cxx.

568 {
569
570 // A sanity check:
571 if (!m_outTree) {
572 ATH_MSG_ERROR("No output tree given to the object");
573 return nullptr;
574 }
575
576 // Check for an object with this name in the output list:
577 Object_t::iterator itr = m_outputObjects.find(key);
578 if (itr == m_outputObjects.end()) {
579 // Create one if if it doesn't exist yet...
580 // Translate the store type:
582 switch (type) {
585 break;
588 break;
589 default:
590 ATH_MSG_ERROR("Unknown store type (" << type << ") requested");
591 return nullptr;
592 }
593 // Create and record the object:
594 static constexpr bool TOP_STORE = true;
595 if (record(std::make_unique<TAuxStore>(key, TOP_STORE, mode), key)
596 .isFailure()) {
597 ATH_MSG_ERROR("Couldn't connect TAuxStore object to the output");
598 return nullptr;
599 }
600 // Update the iterator:
601 itr = m_outputObjects.find(key);
602 }
603
604 // A security check:
605 if (itr == m_outputObjects.end()) {
606 ATH_MSG_ERROR("Internal logic error detected");
607 return nullptr;
608 }
609
610 // Check that it is of the right type:
611 TAuxManager *mgr = dynamic_cast<TAuxManager *>(itr->second.get());
612 if (!mgr) {
613 ATH_MSG_ERROR("Internal logic error detected");
614 return nullptr;
615 }
616
617 // Extract the pointer out of it:
618 TAuxStore *store = mgr->getStore();
619
620 // Give it to the user:
621 return store;
622}
@ AST_ContainerStore
The store describes a container.
@ AST_ObjectStore
The store describes a single object.
StatusCode record(void *obj, const std::string &typeName, const std::string &key, bool overwrite, bool metadata, bool isOwner) override
Record an object into a connected output file.
@ kUndefinedStore
The structure mode is not defined.

◆ recordAux() [2/3]

StatusCode xAOD::TEvent::recordAux ( TAuxStore * store,
const std::string & key )
protected

Function setting up an existing auxiliary store for writing.

Definition at line 2350 of file Control/xAODRootAccess/Root/TEvent.cxx.

2350 {
2351
2352 // Check if we have an output tree:
2353 if (hasOutput() == false) {
2354 ATH_MSG_ERROR("No output tree set up.");
2355 return StatusCode::FAILURE;
2356 }
2357
2358 // Check if we have a filtering rule for this key:
2359 const std::set<std::string> *filter = 0;
2360 auto filter_itr = m_auxItemList.find(key);
2361 if (filter_itr != m_auxItemList.end()) {
2362 filter = &(filter_itr->second);
2363 }
2364
2365 // Check if we need to add it to the event record:
2366 Object_t::iterator vitr = m_outputObjects.find(key);
2367 if (vitr == m_outputObjects.end()) {
2368
2369 // Configure the object for variable filtering:
2370 if (filter) {
2371 store->selectAux(*filter);
2372 }
2373 // Tell the object where to write its contents:
2374 ATH_CHECK(store->writeTo(*m_outTree));
2375 // Record it to the output list.
2376 static constexpr bool OWNS_STORE = false;
2377 m_outputObjects[key] = std::make_unique<TAuxManager>(store, OWNS_STORE);
2378
2379 // We're done:
2380 return StatusCode::SUCCESS;
2381 }
2382
2383 // Check if the output has the right store:
2384 if (vitr->second->object() == store) {
2385 // We're done already:
2386 return StatusCode::SUCCESS;
2387 }
2388
2389 // If not, update the output manager. This can happen when we copy
2390 // objects from the input to the output files, and we process
2391 // multiple input files.
2392
2393 // Check if the output manager is of the right type:
2394 TAuxManager *mgr = dynamic_cast<TAuxManager *>(vitr->second.get());
2395 if (mgr == nullptr) {
2396 ATH_MSG_ERROR("Output object with key \""
2397 << key << "\" already exists, and is not of type TAuxStore");
2398 return StatusCode::FAILURE;
2399 }
2400
2401 // Configure the object for variable filtering:
2402 if (filter) {
2403 store->selectAux(*filter);
2404 }
2405
2406 // Connect the auxiliary store to the output tree:
2407 ATH_CHECK(store->writeTo(*m_outTree));
2408
2409 // Update the manager:
2410 mgr->setObject(store);
2411
2412 // Return gracefully:
2413 return StatusCode::SUCCESS;
2414}
bool hasOutput() const override
Check if an output file is connected to the object.

◆ recordAux() [3/3]

StatusCode xAOD::TEvent::recordAux ( TVirtualManager & mgr,
const std::string & key,
bool metadata )
overrideprotectedvirtual

Record an auxiliary store into a connected output file.

Implements xAOD::Event.

Definition at line 1771 of file Control/xAODRootAccess/Root/TEvent.cxx.

1772 {
1773
1774 // Check if the auxiliary store is a generic object.
1775 Details::IObjectManager *iomgr =
1776 dynamic_cast<Details::IObjectManager *>(&mgr);
1777 if (iomgr != nullptr) {
1778 // Record the auxiliary object using the main record function.
1779 static const bool OVERWRITE = true;
1780 static const bool IS_OWNER = true;
1781 ATH_CHECK(record(iomgr->object(), iomgr->holder()->getClass()->GetName(),
1782 key, OVERWRITE, metadata, IS_OWNER));
1783 return StatusCode::SUCCESS;
1784 }
1785
1786 // Check if it's a TAuxStore object.
1787 TAuxManager *auxmgr = dynamic_cast<TAuxManager *>(&mgr);
1788 if (auxmgr != nullptr) {
1789 // This type has to be an event object.
1790 if (metadata) {
1792 "TAuxStore auxiliary objects can only be recorded for event data");
1793 return StatusCode::FAILURE;
1794 }
1795 // Record the auxiliary object with the dedicated record function.
1796 ATH_CHECK(recordAux(auxmgr->getStore(), key));
1797 return StatusCode::SUCCESS;
1798 }
1799
1800 // Apparently we didn't recorgnize the auxiliary store type.
1801 ATH_MSG_ERROR("Unknown auxiliary store manager type encountered");
1802 return StatusCode::FAILURE;
1803}
SG::IAuxStore * recordAux(const std::string &key, SG::IAuxStoreHolder::AuxStoreType type=SG::IAuxStoreHolder::AST_ContainerStore)
Add an auxiliary store object to the output.

◆ recordMeta() [1/2]

template<typename T>
StatusCode xAOD::Event::recordMeta ( std::unique_ptr< T > obj,
const std::string & key )
inherited

Add an object to the output file's metadata, explicitly taking ownership of it.

◆ recordMeta() [2/2]

template<typename T>
StatusCode xAOD::Event::recordMeta ( T * obj,
const std::string & key )
inherited

Add an object to the output file's metadata.

◆ recordObject()

SG::DataProxy * Event::recordObject ( SG::DataObjectSharedPtr< DataObject > obj,
const std::string & key,
bool allowMods,
bool returnExisting )
overrideprotectedinherited

Record an object in the store.

Definition at line 309 of file EventIProxyDict.cxx.

310 {
311
312 throw std::runtime_error("xAOD::Event::recordObject is not implemented");
313}

◆ recordTypeless()

StatusCode xAOD::Event::recordTypeless ( void * obj,
const std::string & typeName,
const std::string & key,
bool overwrite = false,
bool metadata = true,
bool isOwner = true )
protectedinherited

Internal function for recording an object into the output.

◆ registerKey()

void Event::registerKey ( SG::sgkey_t key,
const std::string & str,
CLID clid )
overrideprotectedinherited

Remember an additional mapping from key to string/CLID.

Definition at line 304 of file EventIProxyDict.cxx.

304 {
305
306 return;
307}

◆ removeListener()

StatusCode Event::removeListener ( TVirtualIncidentListener * listener)
inherited

Remove an incident listener object.

This function allows us to remove a listener when for instance a metadata tool is deleted during a job.

Parameters
listenerPointer to the listener that should be removed
Returns
The usual StatusCode types

Definition at line 126 of file EventCore.cxx.

126 {
127
128 // Remove the listener. Or at least try to...
129 auto itr = std::find(m_listeners.begin(), m_listeners.end(), listener);
130 if (itr == m_listeners.end()) {
131 ATH_MSG_ERROR("Listener " << static_cast<void*>(listener) << " not known");
132 return StatusCode::FAILURE;
133 }
134 m_listeners.erase(itr);
135
136 // Return gracefully:
137 return StatusCode::SUCCESS;
138}

◆ retrieve() [1/4]

template<typename T>
StatusCode xAOD::Event::retrieve ( const T *& obj,
const std::string & key )
inherited

Retrieve either an input or an output object from the event.

◆ retrieve() [2/4]

template<typename T>
StatusCode xAOD::Event::retrieve ( T *& obj,
const std::string & key )
inherited

Retrieve an output object from the event.

◆ retrieve() [3/4]

template<typename T>
bool xAOD::TVirtualEvent::retrieve ( const T *& obj,
const std::string & key,
bool silent = false )
inherited

Function retrieving an object from the event (constant version)

◆ retrieve() [4/4]

template<typename T>
bool xAOD::TVirtualEvent::retrieve ( const T *& obj,
sgkey_t key = DEFAULT_KEY,
bool silent = false )
inherited

Function retrieving an object from the event (constant version)

◆ retrieveMetaInput()

template<typename T>
StatusCode xAOD::Event::retrieveMetaInput ( const T *& obj,
const std::string & key )
inherited

Retrieve an input metadata object.

◆ retrieveMetaOutput() [1/2]

template<typename T>
StatusCode xAOD::Event::retrieveMetaOutput ( const T *& obj,
const std::string & key )
inherited

Retrieve an output metadata object.

◆ retrieveMetaOutput() [2/2]

template<typename T>
StatusCode xAOD::Event::retrieveMetaOutput ( T *& obj,
const std::string & key )
inherited

Retrieve an output metadata object.

◆ setActive()

void Event::setActive ( ) const
inherited

Set this event object as the currently active one.

Definition at line 54 of file EventCore.cxx.

54 {
55
56 // The active event and current store are thread-local globals.
57 Event* nc_this ATLAS_THREAD_SAFE = const_cast<Event*>(this);
58 TActiveEvent::setEvent(static_cast<TVirtualEvent*>(nc_this));
59#ifndef XAOD_STANDALONE
61#endif // not XAOD_STANDALONE
62}
static IProxyDict * setStore(IProxyDict *store)
Set the current store.
static void setEvent(TVirtualEvent *ptr)
Set the active event pointer.

◆ setAuxItemList()

void Event::setAuxItemList ( const std::string & containerKey,
const std::string & itemList )
inherited

Configure which dynamic variables to write out for a given store.

This function receives the rules for selecting which dynamic auxiliary branches should be written for a given container, in the exact same format in which we need to set it in the Athena output ItemList.

Parameters
containerKeyThe name of the auxiliary container in question
itemListThe variable list according to the formatting rules

Definition at line 71 of file EventCore.cxx.

72 {
73
74 // Decoded attributes.
75 std::set<std::string> attributes;
76
77 // Split up the received string using "." as the separator.
78 if (itemList.size()) {
79 std::istringstream ss(itemList);
80 std::string attr;
81 while (std::getline(ss, attr, '.')) {
82 attributes.insert(attr);
83 }
84 }
85
86 // Remember the setting.
87 m_auxItemList[containerKey] = std::move(attributes);
88}
static Double_t ss

◆ setAuxStore()

StatusCode xAOD::TEvent::setAuxStore ( const std::string & key,
Details::IObjectManager & mgr,
bool metadata )
overrideprotectedvirtual

Function connecting a DV object to its auxiliary store.

Every time a DataVector is read in from the input for a new TTree entry, one needs to re-connect it with its auxiliary store.

This function takes care of this.

Parameters
mgrThe manager object of the DV container
metadataFlag specifying whether we're dealing with a metadata or event data object
Returns
The usual StatusCode types

Implements xAOD::Event.

Definition at line 1467 of file Control/xAODRootAccess/Root/TEvent.cxx.

1468 {
1469
1470 // Pre-compute some values.
1471 const bool isAuxStore = Details::isAuxStore(*(mgr.holder()->getClass()));
1472
1473 // Check if we need to do anything.
1474 if ((Details::hasAuxStore(*(mgr.holder()->getClass())) == false) &&
1475 (isAuxStore == false)) {
1476 return StatusCode::SUCCESS;
1477 }
1478
1479 // Select which object container to use:
1481
1482 // Look up the auxiliary object's manager:
1483 TVirtualManager *auxMgr = nullptr;
1484 std::string auxKey;
1485 if (isAuxStore) {
1486 auxMgr = &mgr;
1487 auxKey = key;
1488 } else {
1489 auto itr = objects.find(key + "Aux.");
1490 if (itr == objects.end()) {
1491 // Apparently there's no auxiliary object for this DV, so let's
1492 // give up:
1493 return StatusCode::SUCCESS;
1494 }
1495 auxMgr = itr->second.get();
1496 auxKey = key + "Aux.";
1497 }
1498
1499 if (metadata == false) {
1500 // Make sure the auxiliary object is up to date:
1501 const ::Int_t readBytes = auxMgr->getEntry();
1502 if (readBytes < 0) {
1504 "Couldn't load current entry for auxiliary object with key \""
1505 << auxKey << "\"");
1506 return StatusCode::FAILURE;
1507 }
1508
1509 // Check if there is a separate auxiliary object for the dynamic
1510 // variables:
1511 const std::string dynAuxKey = auxKey + "Dynamic";
1512 auto dynAuxMgr = objects.find(dynAuxKey);
1513
1514 if ((dynAuxMgr != objects.end()) &&
1515 (readBytes || (m_auxMode == kAthenaAccess) || (auxMgr == &mgr))) {
1516 // Do different things based on the access mode:
1517 if (m_auxMode != kAthenaAccess) {
1518 // In "normal" access modes just tell the dynamic store object
1519 // to switch to a new event.
1520 dynAuxMgr->second->getEntry();
1521 } else {
1522 // In "Athena mode" this object has already been deleted when
1523 // the main auxiliary store object was switched to the new
1524 // event. So let's re-create it:
1525 xAOD::TObjectManager &auxMgrRef =
1526 dynamic_cast<xAOD::TObjectManager &>(*auxMgr);
1527 ATH_CHECK(
1528 setUpDynamicStore(auxMgrRef, (metadata ? m_inMetaTree : m_inTree)));
1529 // Now tell the newly created dynamic store object which event
1530 // it should be looking at:
1531 auto dynAuxMgr = objects.find(dynAuxKey);
1532 if (dynAuxMgr == objects.end()) {
1533 ATH_MSG_ERROR("Internal logic error detected");
1534 return StatusCode::FAILURE;
1535 }
1536 dynAuxMgr->second->getEntry();
1537 }
1538 }
1539 }
1540
1541 // Stop here if we've set up an auxiliary store.
1542 if (isAuxStore) {
1543 return StatusCode::SUCCESS;
1544 }
1545
1546 // Access the auxiliary base class of the object/vector:
1547 SG::AuxVectorBase *vec = 0;
1548 SG::AuxElement *aux = 0;
1549 switch (mgr.holder()->typeKind()) {
1550 case THolder::DATAVECTOR: {
1551 void *vvec = mgr.holder()->getAs(typeid(SG::AuxVectorBase));
1552 vec = reinterpret_cast<SG::AuxVectorBase *>(vvec);
1553 } break;
1554 case THolder::AUXELEMENT: {
1555 void *vaux = mgr.holder()->getAs(typeid(SG::AuxElement));
1556 aux = reinterpret_cast<SG::AuxElement *>(vaux);
1557 } break;
1558 default:
1559 break;
1560 }
1561
1562 // Check whether index tracking is enabled for the type. If not, then
1563 // we need to fix it...
1564 if (vec && (!vec->trackIndices())) {
1565 Details::forceTrackIndices(*vec);
1566 }
1567
1568 // Check if we were successful:
1569 if ((!vec) && (!aux)) {
1570 ATH_MSG_FATAL("Couldn't access class \""
1571 << mgr.holder()->getClass()->GetName()
1572 << "\" as SG::AuxVectorBase or SG::AuxElement");
1573 return StatusCode::FAILURE;
1574 }
1575
1576 // Get the auxiliary store object:
1577 const SG::IConstAuxStore *store = 0;
1578 if (m_auxMode == kBranchAccess) {
1579 // Get the concrete auxiliary manager:
1580 TAuxManager *amgr = dynamic_cast<TAuxManager *>(auxMgr);
1581 if (!amgr) {
1582 ATH_MSG_FATAL("Auxiliary manager for \""
1583 << auxKey << "\" is not of the right type");
1584 return StatusCode::FAILURE;
1585 }
1586 store = amgr->getConstStore();
1587 // If the store still doesn't know its type, help it now:
1588 if (amgr->getStore()->structMode() ==
1593 amgr->getStore()->setStructMode(mode);
1594 }
1595 } else if (m_auxMode == kClassAccess || m_auxMode == kAthenaAccess) {
1596 // Get the concrete auxiliary manager:
1597 TObjectManager *omgr = dynamic_cast<TObjectManager *>(auxMgr);
1598 if (!omgr) {
1599 ATH_MSG_FATAL("Auxiliary manager for \""
1600 << auxKey << "\" is not of the right type");
1601 return StatusCode::FAILURE;
1602 }
1603 void *p = omgr->holder()->getAs(typeid(SG::IConstAuxStore));
1604 store = reinterpret_cast<const SG::IConstAuxStore *>(p);
1605 }
1606 if (!store) {
1607 ATH_MSG_FATAL("Logic error detected in the code");
1608 return StatusCode::FAILURE;
1609 }
1610
1611 // Connect the two:
1612 if (vec) {
1613 vec->setStore(store);
1614 } else if (aux) {
1615 aux->setStore(store);
1616 } else {
1617 ATH_MSG_FATAL("Logic error detected in the code");
1618 return StatusCode::FAILURE;
1619 }
1620
1621 // We succeeded:
1622 return StatusCode::SUCCESS;
1623}
std::vector< size_t > vec
void setStore(const SG::IConstAuxStore *store)
Set the store associated with this object.
@ DATAVECTOR
A DataVector container.
Definition THolder.h:105
@ AUXELEMENT
A type inheriting from SG::AuxElement.
Definition THolder.h:106

◆ setLevel()

void AthMessaging::setLevel ( MSG::Level lvl)
inherited

Change the current logging level.

Use this rather than msg().setLevel() for proper operation with MT.

Definition at line 28 of file AthMessaging.cxx.

29{
30 m_lvl = lvl;
31}

◆ setOtherMetaDataTreeNamePattern()

void xAOD::TEvent::setOtherMetaDataTreeNamePattern ( const std::string & pattern)

Change the pattern used for collecting information from other MetaData trees NB: Additional MetaData trees are only expected for augmented files This function also allows user to redefine MetaData tree pattern to skip trees that would not be proper MetaData ones i.e.

trees not containing an EventFormat* branch

Definition at line 110 of file Control/xAODRootAccess/Root/TEvent.cxx.

110 {
111 // Only change if pattern provided is not empty
112 if (pattern.size()) {
113 // User provided a regular expression for other MetaData trees
114 m_otherMetaDataTreeNamePattern = std::regex(pattern);
115 }
116}

◆ setUpDynamicStore()

StatusCode xAOD::TEvent::setUpDynamicStore ( TObjectManager & mgr,
::TTree * tree )
protected

Function adding dynamic variable reading capabilities to an auxiliary store object.

This function is used by connectBranch(...) and connectMetaBranch(...) to set up auxiliary store type objects correctly for accessing dynamic variables from the input file.

Parameters
mgrThe object manager of the auxiliary store object
treeThe tree to read dynamic variables from
Returns
The usual StatusCode types

Definition at line 2044 of file Control/xAODRootAccess/Root/TEvent.cxx.

2044 {
2045
2046 // Check if we can call setName(...) on the object:
2047 ::TMethodCall setNameCall;
2048 // Don't use this code in Athena access mode. And just accept that access
2049 // monitoring is disabled in this case...
2050 if (m_auxMode != kAthenaAccess) {
2051 setNameCall.InitWithPrototype(mgr.holder()->getClass(), "setName",
2052 "const char*");
2053 if (setNameCall.IsValid()) {
2054 // Yes, there is such a function. Let's call it with the branch
2055 // name:
2056 const ::TString params =
2057 ::TString::Format("\"%s\"", mgr.branch()->GetName());
2058 const char *charParams = params.Data();
2059 setNameCall.Execute(mgr.holder()->get(), charParams);
2060 } else {
2061 // This is weird. What sort of auxiliary container is this? :-/
2062 ATH_MSG_WARNING("Couldn't find setName(...) function for container \""
2063 << mgr.branch()->GetName() << "\" (type: "
2064 << mgr.holder()->getClass()->GetName() << ")");
2065 }
2066 }
2067
2068 // Check if we can switch out the internal store of this object:
2069 static const TClass *const holderClass =
2070 TClass::GetClass(typeid(SG::IAuxStoreHolder));
2071 if (!mgr.holder()->getClass()->InheritsFrom(holderClass)) {
2072 // Nope... So let's just end the journey here.
2073 return StatusCode::SUCCESS;
2074 }
2075
2076 // Try to get the object as an IAuxStoreHolder:
2077 SG::IAuxStoreHolder *storeHolder = reinterpret_cast<SG::IAuxStoreHolder *>(
2078 mgr.holder()->getAs(typeid(SG::IAuxStoreHolder)));
2079 if (!storeHolder) {
2080 ATH_MSG_FATAL("There's a logic error in the code");
2081 return StatusCode::FAILURE;
2082 }
2083
2084 // Create a TAuxStore instance that will read the dynamic variables
2085 // of this container. Notice that the TAuxManager doesn't own the
2086 // TAuxStore object. It will be owned by the SG::IAuxStoreHolder
2087 // object.
2088 static constexpr bool TOP_STORE = false;
2089 auto store = std::make_unique<TAuxStore>(
2090 mgr.branch()->GetName(), TOP_STORE,
2094 // This object is used to read data from the input, it needs to be
2095 // locked:
2096 store->lock();
2097
2098 // Set it up to read from the input RNTuple.
2099 ATH_CHECK(store->readFrom(*tree));
2100
2101 // Set it up to read from the input TTree.
2102 ATH_CHECK(store->readFrom(*tree));
2103 // Tell the auxiliary store which entry to use. This is essential for
2104 // metadata objects, and non-important for event data objects, which will
2105 // get a possibly different entry loaded in setAuxStore(...).
2106 store->getEntry(0);
2107
2108 // Set up a manager for it.
2109 static constexpr bool SHARED_OWNER = false;
2110 m_inputObjects[std::string(mgr.branch()->GetName()) + "Dynamic"] =
2111 std::make_unique<TAuxManager>(store.get(), SHARED_OWNER);
2112
2113 // Give this object to the store holder:
2114 storeHolder->setStore(store.release());
2115
2116 // Return gracefully:
2117 return StatusCode::SUCCESS;
2118}
virtual AuxStoreType getStoreType() const =0
Return the type of the store object.
virtual void setStore(IAuxStore *store)=0
Give an auxiliary store object to the holder object.

◆ stringToKey()

SG::sgkey_t Event::stringToKey ( const std::string & str,
CLID clid )
overrideprotectedinherited

Find the string corresponding to a given key.

Definition at line 289 of file EventIProxyDict.cxx.

289 {
290
291 return getHash(str);
292}

◆ transientContains() [1/2]

template<typename T>
bool xAOD::Event::transientContains ( const std::string & key) const
inherited

Function checking if an object is already in memory.

◆ transientContains() [2/2]

bool xAOD::Event::transientContains ( const std::string & key,
const std::type_info & ti,
bool metadata ) const
protectedinherited

Internal function checking if an object is already in memory.

◆ transientContainsMeta()

template<typename T>
bool xAOD::Event::transientContainsMeta ( const std::string & key) const
inherited

Function checking if a meta-object is already in memory.

◆ writeTo()

StatusCode xAOD::TEvent::writeTo ( ::TFile * file,
int autoFlush = 200,
std::string_view treeName = EVENT_TREE_NAME )

Connect the object to an output file.

This function should be called on a file opened be the user, before any event processing would occur.

It sets up the output event tree.

Parameters
fileThe file that the event data should be written to
autoFlushThe auto-flush setting to use on the output TTree
treeNameName of the output event tree
Returns
The usual StatusCode tyoes

Definition at line 413 of file Control/xAODRootAccess/Root/TEvent.cxx.

414 {
415
416 // Just a simple security check.
417 if (!file) {
418 ATH_MSG_ERROR("Null pointer received!");
419 return StatusCode::FAILURE;
420 }
421
422 // Check that the object is in the "right state":
423 if (m_outTree) {
424 ATH_MSG_ERROR("Object already writing to a file. Close that file first!");
425 return StatusCode::FAILURE;
426 }
427
428 // Make sure we return to the current directory:
429 TDirectoryReset dr;
430
431 // Create the output TTree:
432 file->cd();
433 m_outTree = std::make_unique<TTree>(treeName.data(), "xAOD event tree");
434 m_outTree->SetDirectory(file);
435 m_outTree->SetAutoSave(1000000);
436 m_outTree->SetAutoFlush(autoFlush);
437
438 // Access the EventFormat object associated with this file:
441
442 // Return gracefully:
443 return StatusCode::SUCCESS;
444}
static const TEventFormatRegistry & instance()
Access the only instance of the object in memory.
EventFormat & getEventFormat(const TFile *file) const
Access the managed EventFormat object.

◆ ::xAODTEventBranch

friend class ::xAODTEventBranch
friend

◆ ::xAODTMetaBranch

friend class ::xAODTMetaBranch
friend

◆ CP::xAODWriterAlg

friend class CP::xAODWriterAlg
friend

◆ xAOD::TFileMerger

friend class xAOD::TFileMerger
friend

◆ xAOD::TTreeMgr

friend class xAOD::TTreeMgr
friend

Member Data Documentation

◆ ATLAS_THREAD_SAFE

SG::SGKeyMap<BranchInfo> m_branches xAOD::Event::ATLAS_THREAD_SAFE
mutableprotectedinherited

Map from hashed sgkey to BranchInfo.

Definition at line 358 of file Event.h.

◆ DEFAULT_KEY

sgkey_t xAOD::TVirtualEvent::DEFAULT_KEY = ~static_cast<sgkey_t>(0)
staticconstexprinherited

Key for retrieving the "default" object of a given type.

Definition at line 35 of file TVirtualEvent.h.

◆ EVENT_TREE_NAME

const char *const xAOD::TEvent::EVENT_TREE_NAME = "CollectionTree"
static

Default name of the event tree.

Name of the event tree.

Definition at line 100 of file Control/xAODRootAccess/xAODRootAccess/TEvent.h.

◆ KEY_MASK

sgkey_t xAOD::TVirtualEvent::KEY_MASK = DEFAULT_KEY >> 2
staticconstexprinherited

Mask for the keys, used mostly internally.

Definition at line 37 of file TVirtualEvent.h.

◆ m_auxItemList

std::unordered_map<std::string, std::set<std::string> > xAOD::Event::m_auxItemList
protectedinherited

Rules for selecting which auxiliary branches to write.

Definition at line 326 of file Event.h.

◆ m_auxMode

EAuxMode xAOD::TEvent::m_auxMode
protected

The auxiliary access mode.

Definition at line 199 of file Control/xAODRootAccess/xAODRootAccess/TEvent.h.

◆ m_branchesMutex

upgrade_mutex_t xAOD::Event::m_branchesMutex
mutableprotectedinherited

Mutex for multithread synchronization.

Definition at line 354 of file Event.h.

◆ m_entry

::Long64_t xAOD::TEvent::m_entry = -1
protected

The entry to look at from the input tree.

Definition at line 215 of file Control/xAODRootAccess/xAODRootAccess/TEvent.h.

◆ m_imsg

std::atomic<IMessageSvc*> AthMessaging::m_imsg { nullptr }
mutableprivateinherited

MessageSvc pointer.

Definition at line 135 of file AthMessaging.h.

135{ nullptr };

◆ m_inChain

::TChain* xAOD::TEvent::m_inChain = nullptr
protected

The (optional) chain provided as input.

Definition at line 207 of file Control/xAODRootAccess/xAODRootAccess/TEvent.h.

◆ m_inChainTracker

std::unique_ptr<TChainStateTracker> xAOD::TEvent::m_inChainTracker
protected

Optional object for tracking the state changes of an input TChain.

Definition at line 209 of file Control/xAODRootAccess/xAODRootAccess/TEvent.h.

◆ m_inMetaTree

::TTree* xAOD::TEvent::m_inMetaTree = nullptr
protected

Pointer to the metadata tree in the input file.

Definition at line 213 of file Control/xAODRootAccess/xAODRootAccess/TEvent.h.

◆ m_inputEventFormat

EventFormat xAOD::Event::m_inputEventFormat
protectedinherited

Format of the current input file.

Definition at line 321 of file Event.h.

◆ m_inputMetaObjects

Object_t xAOD::Event::m_inputMetaObjects
protectedinherited

Collection of all the managed input meta-objects.

Definition at line 316 of file Event.h.

◆ m_inputMissingObjects

std::set<std::string> xAOD::Event::m_inputMissingObjects
protectedinherited

Objects that have been asked for, but were found to be missing in the current input.

Definition at line 311 of file Event.h.

◆ m_inputObjects

Object_t xAOD::Event::m_inputObjects
protectedinherited

Collection of all the managed input objects.

Definition at line 308 of file Event.h.

◆ m_inTree

::TTree* xAOD::TEvent::m_inTree = nullptr
protected

The main tree that we are reading from.

Definition at line 202 of file Control/xAODRootAccess/xAODRootAccess/TEvent.h.

◆ m_inTreeMissing

bool xAOD::TEvent::m_inTreeMissing = false
protected

Internal status flag showing that an input file is open, but it doesn't contain an event tree.

Definition at line 205 of file Control/xAODRootAccess/xAODRootAccess/TEvent.h.

◆ m_inTreeNumber

::Int_t xAOD::TEvent::m_inTreeNumber = -1
protected

The number of the currently open tree in the input chain.

Definition at line 211 of file Control/xAODRootAccess/xAODRootAccess/TEvent.h.

◆ m_listeners

std::vector<TVirtualIncidentListener*> xAOD::Event::m_listeners
protectedinherited

Listeners who should be notified when certain incidents happen.

Definition at line 329 of file Event.h.

◆ m_lvl

std::atomic<MSG::Level> AthMessaging::m_lvl { MSG::NIL }
mutableprivateinherited

Current logging level.

Definition at line 138 of file AthMessaging.h.

138{ MSG::NIL };

◆ m_msg_tls

boost::thread_specific_ptr<MsgStream> AthMessaging::m_msg_tls
mutableprivateinherited

MsgStream instance (a std::cout like with print-out levels)

Definition at line 132 of file AthMessaging.h.

◆ m_nameRemapping

std::unordered_map<std::string, std::string> xAOD::Event::m_nameRemapping
protectedinherited

Container name re-mapping rules.

Definition at line 332 of file Event.h.

◆ m_nm

std::string AthMessaging::m_nm
privateinherited

Message source name.

Definition at line 129 of file AthMessaging.h.

◆ m_otherMetaDataTreeNamePattern

std::regex xAOD::TEvent::m_otherMetaDataTreeNamePattern
protected
Initial value:
=
std::regex("^MetaData(?!Hdr)_.*$")

Definition at line 223 of file Control/xAODRootAccess/xAODRootAccess/TEvent.h.

◆ m_outputEventFormat

EventFormat* xAOD::Event::m_outputEventFormat = nullptr
protectedinherited

Format of the current output file.

Definition at line 323 of file Event.h.

◆ m_outputMetaObjects

Object_t xAOD::Event::m_outputMetaObjects
protectedinherited

Collection of all the managed output meta-objects.

Definition at line 318 of file Event.h.

◆ m_outputObjects

Object_t xAOD::Event::m_outputObjects
protectedinherited

Collection of all the managed output object.

Definition at line 313 of file Event.h.

◆ m_outTree

std::unique_ptr<::TTree> xAOD::TEvent::m_outTree
protected

The tree that we are writing to.

Definition at line 218 of file Control/xAODRootAccess/xAODRootAccess/TEvent.h.

◆ m_printEventProxyWarnings

bool xAOD::Event::m_printEventProxyWarnings = false
protectedinherited

Option to silence common warnings that seem to be harmless.

Definition at line 335 of file Event.h.


The documentation for this class was generated from the following files: