ATLAS Offline Software
Loading...
Searching...
No Matches
REventClass Class Reference

Class used for the test. More...

Inheritance diagram for REventClass:
Collaboration diagram for REventClass:

Public Types

using sgkey_t = SG::sgkey_t

Public Member Functions

StatusCode loadInputObjects ()
 Function loading all interface objects of the event.
 REvent ()
 Default constructor.
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.
Setup functions
StatusCode readFrom (TFile &inFile) override
 Set up the reading of an input file from TFile This method implements the interface from Event.
StatusCode readFrom (std::string_view fileName)
 Set up the reading of an input file via a file name.
StatusCode writeTo (TFile &file) override
 Connect the object to an output file.
StatusCode finishWritingTo (TFile &file) override
 Finish writing to an output file.
Persistent data accessor/modifier functions
::Long64_t getEntries () const override
 Get how many entries are available from the current input file(s)
::Int_t getEntry (::Long64_t entry, ::Int_t getall=0) override
 Function loading a given entry of the input RNTuple.
::Int_t fill () override
 Method filling one event into 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
const EventFormat * inputEventFormat () const
 Get information about the input objects.
const EventFormat * outputEventFormat () 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

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 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

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.
EventFormat * m_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

StatusCode initStats ()
 Function to initialise the statistics for all RNTuple content.
StatusCode setUpDynamicStore (RObjectManager &mgr, ROOT::RNTupleReader &ntupleReader)
 event uses RNTupleReader:
void initMessaging () const
 Initialize our message level and MessageSvc.
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.
StatusCode putAux (TVirtualManager &mgr, ::Bool_t metadata=kFALSE)
 Method saving the dynamically created auxiliary properties.
StatusCode addField (const std::string &key, const TVirtualManager &mgr)
 Add field to RNTuple model given the StoreGate key and output object manager.

Private Attributes

std::unique_ptr< ROOT::RNTupleReader > m_eventReader
 The main event data reader.
bool m_inputNTupleIsMissing = false
 Whether the input has an event RNTuple or not.
std::unique_ptr< ROOT::RNTupleReader > m_metaReader
 The metadata reader.
::Long64_t m_entry {}
 The entry to look at from the input.
std::unique_ptr< ROOT::RNTupleModel > m_model
 The RNTuple model used for event fields.
std::unique_ptr< ROOT::RNTupleWriter > m_eventWriter
 The main event writer: RNTupleWeader.
::TFile * m_outputFile {nullptr}
 The output file for writing.
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.

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.
static const char *const EVENT_TREE_NAME = "CollectionTree"
 Default name of the event TTree.
static const char *const EVENT_RNTUPLE_NAME = "EventData"
 Name of the event RNTuple.
static const char *const METADATA_OBJECT_NAME = "MetaData"
 Name of the metadata tree or RNTuple.
static std::unique_ptr< EventcreateAndReadFrom (TFile &file)
 static method to create an Event object and readFrom a file, given by a TFile.

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.

Variable(s) used in the @c IProxyDict implementation

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

Detailed Description

Class used for the test.

Definition at line 36 of file xAODRNFileReadTest.cxx.

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 333 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 378 of file Event.h.

◆ upgrading_lock_t

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

Lock type for multithread synchronization.

Definition at line 380 of file Event.h.

Member Function Documentation

◆ addField()

StatusCode xAOD::Experimental::REvent::addField ( const std::string & key,
const TVirtualManager & mgr )
privateinherited

Add field to RNTuple model given the StoreGate key and output object manager.

Definition at line 1677 of file REvent.cxx.

1677 {
1678
1679 // Add to the RNTuple model -
1680 // This is done by either adding the field to the initial model before the first event is written, or
1681 // after the first event has been written a new field is added via an extension of the output RNTuple model.
1682 // This can occurs when an AuxStore is empty for the initial events
1683
1684 // Get field name and class name to create a RFieldBase
1685 std::string fieldName;
1686 std::string className;
1687 if (getInfoForFieldCreation( key, mgr, fieldName, className ).isFailure()) return StatusCode::FAILURE;
1688 // should have found class name
1689 if ( className.empty() ) {
1690 ATH_MSG_ERROR( "could not find className!" );
1691 return StatusCode::FAILURE;
1692 }
1693
1694 if (m_model) {
1695 // Continue to add to the initial RNTuple model
1696 m_model->AddField( ROOT::RFieldBase::Create( fieldName, className ).Unwrap());
1697 }
1698 else {
1699 if (m_eventWriter.get() == nullptr) {
1700 ATH_MSG_ERROR("Internal logic error detected - no output found");
1701 return StatusCode::FAILURE;
1702 }
1703 // After the first event, one needs to extend the output RNTuple model
1704 auto field = ROOT::RFieldBase::Create(fieldName, className).Unwrap();
1705 auto updater = m_eventWriter->CreateModelUpdater();
1706 updater->BeginUpdate();
1707 updater->AddField(std::move(field));
1708 updater->CommitUpdate();
1709 }
1710
1711 // Return gracefully:
1712 return StatusCode::SUCCESS;
1713
1714}
#define ATH_MSG_ERROR(x)
std::unique_ptr< ROOT::RNTupleWriter > m_eventWriter
The main event writer: RNTupleWeader.
Definition REvent.h:144
std::unique_ptr< ROOT::RNTupleModel > m_model
The RNTuple model used for event fields.
Definition REvent.h:141

◆ 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:358

◆ 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:350
std::unordered_map< std::string, std::string > m_nameRemapping
Container name re-mapping rules.
Definition Event.h:361

◆ 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:383
AthContainers_detail::upgrading_lock< upgrade_mutex_t > upgrading_lock_t
Lock type for multithread synchronization.
Definition Event.h:380
bool m_printEventProxyWarnings
Option to silence common warnings that seem to be harmless.
Definition Event.h:364
SG::SGKeyMap< BranchInfo > m_branches ATLAS_THREAD_SAFE
Map from hashed sgkey to BranchInfo.
Definition Event.h:387
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:370
std::unique_ptr< SG::DataProxy > m_proxy
Data proxy describing this branch/object.
Definition Event.h:372

◆ 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::Experimental::REvent::connectAux ( const std::string & prefix,
bool standalone )
overrideprivatevirtualinherited

Function setting up access to a set of auxiliary branches.

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

This uses 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
kTRUE if the connection was successful, or kFALSE if it was not

Implements xAOD::Event.

Definition at line 1072 of file REvent.cxx.

1072 {
1073
1074 // A little sanity check.
1075 if (!m_eventReader) {
1076 ATH_MSG_ERROR("Function called on un-initialised object");
1077 return StatusCode::FAILURE;
1078 }
1079
1080 // Check if the field is already connected.
1081 if (m_inputObjects.contains(prefix)) {
1082 return StatusCode::SUCCESS;
1083 }
1084
1085 // Connect to the field as we would for any other.
1086 static constexpr bool SILENT = false;
1087 ATH_CHECK(connectObject(prefix, SILENT));
1088
1089 // Access the object's manager.
1090 Object_t::const_iterator mgr_itr = m_inputObjects.find(prefix);
1091 if (mgr_itr == m_inputObjects.end()) {
1092 ATH_MSG_FATAL("There's a logic error in the code");
1093 return StatusCode::FAILURE;
1094 }
1095 const Details::IObjectManager* omgr =
1096 dynamic_cast<const RObjectManager*>(mgr_itr->second.get());
1097 if (omgr == nullptr) {
1098 ATH_MSG_FATAL("There's a logic error in the code");
1099 return StatusCode::FAILURE;
1100 }
1101
1102 // Check if we can switch out the internal store of this object.
1103 static const TClass* const holderClass = TClass::GetClass(typeid(SG::IAuxStoreHolder));
1104 if (omgr->holder()->getClass()->InheritsFrom(holderClass) == false) {
1105 // Nope... So let's just end the journey here.
1106 return StatusCode::SUCCESS;
1107 }
1108
1109 // Try to get the object as an IAuxStoreHolder.
1110 SG::IAuxStoreHolder* storeHolder = reinterpret_cast<SG::IAuxStoreHolder*>(
1111 omgr->holder()->getAs(typeid(SG::IAuxStoreHolder)));
1112 if (!storeHolder) {
1113 ATH_MSG_FATAL("There's a logic error in the code");
1114 return StatusCode::FAILURE;
1115 }
1116
1117 // A sanity check to see whether the store's type is in sync with the
1118 // object's type that it will be connected to:
1119 if ((standalone &&
1121 ((!standalone) && (storeHolder->getStoreType() !=
1123 ATH_MSG_ERROR("Requested store types inconsistent for: " << prefix);
1124 ATH_MSG_ERROR("standalone = "
1125 << standalone << ", getStoreType() = "
1126 << static_cast<int>(storeHolder->getStoreType()));
1127 return StatusCode::FAILURE;
1128 }
1129
1130 // Return gracefully.
1131 return StatusCode::SUCCESS;
1132}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
@ AST_ContainerStore
The store describes a container.
@ AST_ObjectStore
The store describes a single object.
virtual AuxStoreType getStoreType() const =0
Return the type of the store object.
Object_t m_inputObjects
Collection of all the managed input objects.
Definition Event.h:337
std::unique_ptr< ROOT::RNTupleReader > m_eventReader
The main event data reader.
Definition REvent.h:131
StatusCode connectObject(const std::string &key, bool silent) override
Function setting up access to a particular object.
Definition REvent.cxx:834
@ SILENT
don't print anything and return success

◆ connectMetaAux()

StatusCode xAOD::Experimental::REvent::connectMetaAux ( const std::string & prefix,
bool standalone )
overrideprivatevirtualinherited

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.

This uses 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 1142 of file REvent.cxx.

1143 {
1144
1145 // A little sanity check.
1146 if (!m_metaReader) {
1147 ATH_MSG_ERROR("Function called on un-initialised object");
1148 return StatusCode::FAILURE;
1149 }
1150
1151 // Check if the field is already connected.
1152 if (m_inputMetaObjects.contains(prefix)) {
1153 return StatusCode::SUCCESS;
1154 }
1155
1156 // Connect to the field as we would for any other.
1157 static constexpr bool SILENT = false;
1158 ATH_CHECK(connectMetaObject(prefix, SILENT));
1159
1160 // Access the object's manager.
1161 Object_t::const_iterator mgr_itr = m_inputMetaObjects.find(prefix);
1162 if (mgr_itr == m_inputMetaObjects.end()) {
1163 ATH_MSG_FATAL("There's a logic error in the code");
1164 return StatusCode::FAILURE;
1165 }
1166 const Details::IObjectManager* omgr =
1167 dynamic_cast<const RObjectManager*>(mgr_itr->second.get());
1168 if (omgr == nullptr) {
1169 ATH_MSG_FATAL("There's a logic error in the code");
1170 return StatusCode::FAILURE;
1171 }
1172
1173 // Check if we can switch out the internal store of this object.
1174 static const TClass* const holderClass =
1175 TClass::GetClass(typeid(SG::IAuxStoreHolder));
1176 if (omgr->holder()->getClass()->InheritsFrom(holderClass) == false) {
1177 // Nope... So let's just end the journey here.
1178 return StatusCode::SUCCESS;
1179 }
1180
1181 // Try to get the object as an IAuxStoreHolder.
1182 SG::IAuxStoreHolder* storeHolder = reinterpret_cast<SG::IAuxStoreHolder*>(
1183 omgr->holder()->getAs(typeid(SG::IAuxStoreHolder)));
1184 if (!storeHolder) {
1185 ATH_MSG_FATAL("There's a logic error in the code");
1186 return StatusCode::FAILURE;
1187 }
1188
1189 // A sanity check to see whether the store's type is in sync with the
1190 // object's type that it will be connected to:
1191 if ((standalone &&
1193 ((!standalone) && (storeHolder->getStoreType() !=
1195 ATH_MSG_ERROR("Requested store types inconsistent for: " << prefix);
1196 ATH_MSG_ERROR("standalone = "
1197 << standalone << ", getStoreType() = "
1198 << static_cast<int>(storeHolder->getStoreType()));
1199 return StatusCode::FAILURE;
1200 }
1201
1202 // Return gracefully.
1203 return StatusCode::SUCCESS;
1204}
Object_t m_inputMetaObjects
Collection of all the managed input meta-objects.
Definition Event.h:345
std::unique_ptr< ROOT::RNTupleReader > m_metaReader
The metadata reader.
Definition REvent.h:135
StatusCode connectMetaObject(const std::string &key, bool silent) override
Function setting up access to a particular metadata object.
Definition REvent.cxx:983

◆ connectMetaObject()

StatusCode xAOD::Experimental::REvent::connectMetaObject ( const std::string & key,
bool silent )
overrideprivatevirtualinherited

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 983 of file REvent.cxx.

983 {
984
985 // A little sanity check.
986 if (!m_metaReader) {
987 ATH_MSG_ERROR("Function called on un-initialised object");
988 return StatusCode::FAILURE;
989 }
990
991 // Check if the branch is already connected.
992 if (m_inputMetaObjects.contains(key)) {
993 return StatusCode::SUCCESS;
994 }
995
996 // RNTuples store fields with an "Aux:" postfix instead of "Aux.".
997 std::string fieldName = key;
998 if (key.ends_with("Aux.")) {
999 fieldName.replace(fieldName.size() - 1, 1, ":");
1000 }
1001
1002 // Check if the field exists in our input RNTuple.
1003 if (m_metaReader->GetDescriptor().FindFieldId(fieldName.c_str()) ==
1004 ROOT::kInvalidDescriptorId) {
1005 // Field doesn't exist
1006 if (!silent) {
1007 ATH_MSG_WARNING("Field \"" << fieldName << "\" not available on input");
1008 }
1009 return StatusCode::RECOVERABLE;
1010 }
1011
1012 // RDS: may need some logic here to get type from inputEventFormat rather than
1013 // the view to read in with automatic schema evolution
1014
1015 // Get class name from the field
1016 ROOT::RNTupleView<void> view =
1017 m_metaReader->GetView<void>(fieldName.c_str(), nullptr);
1018 std::string className = view.GetField().GetTypeName();
1019 if (className == "") {
1021 "Couldn't find an appropriate type with a dictionary for field \""
1022 << fieldName << "\"");
1023 return StatusCode::FAILURE;
1024 }
1025 ::TClass* realClass = ::TClass::GetClass(className.c_str());
1026 if ((!realClass) || (!realClass->IsLoaded())) {
1027 // Now we're in trouble...
1029 "Couldn't find an appropriate type with a dictionary for field \""
1030 << fieldName << "\"");
1031 return StatusCode::FAILURE;
1032 }
1033
1034 // Create the object and the manager(s) around it.
1035 void* ptr = realClass->New();
1036 static const ::Long64_t FIRST_ENTRY = 0;
1037 auto mgr = std::make_unique<RObjectManager>(
1038 m_metaReader->GetView(fieldName, ptr, className), FIRST_ENTRY,
1039 std::make_unique<THolder>(ptr, realClass));
1040 // For metadata, we must read in the first entry - entry number already set by FIRST_ENTRY in constructor
1041 mgr->getEntry();
1042 RObjectManager* mgrPtr = mgr.get();
1043 m_inputMetaObjects[key] = std::move(mgr);
1044
1045 // If it's an auxiliary store object, set it up correctly.
1046 if (Details::isAuxStore(*(mgrPtr->holder()->getClass()))) {
1047 // For reading in of the dynamic variables for metadata
1049 }
1050
1051 // If it (probably) has an associated auxiliary store, set it up as well.
1052 if (Details::hasAuxStore(*(mgrPtr->holder()->getClass()))) {
1054 key + "Aux.", Details::isStandalone(*(mgrPtr->holder()->getClass()))));
1055 static constexpr bool METADATA = true;
1056 ATH_CHECK(setAuxStore(key, *mgrPtr, METADATA));
1057 }
1058
1059 // Return gracefully.
1060 return StatusCode::SUCCESS;
1061} // connectMetaObject
StatusCode setUpDynamicStore(RObjectManager &mgr, ROOT::RNTupleReader &ntupleReader)
event uses RNTupleReader:
Definition REvent.cxx:1816
StatusCode connectMetaAux(const std::string &prefix, bool standalone) override
Function setting up access to a set of auxiliary branches for a metadata object.
Definition REvent.cxx:1142
StatusCode setAuxStore(const std::string &key, Details::IObjectManager &mgr, bool metadata) override
Function connecting a DV object to its auxiliary store.
Definition REvent.cxx:1217
void * ptr(T *p)
Definition SGImplSvc.cxx:74
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::Experimental::REvent::connectObject ( const std::string & key,
bool silent )
overrideprivatevirtualinherited

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 field of the input RNTuple.

The type that is read in to memory is not actually determined by the type written to the ntuple itself, but from the xAOD::EventFormat object. Which is there to make it possible to possibly use ROOT read rules 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 field can't be connected to
Returns
The usual StatusCode values

Implements xAOD::Event.

Definition at line 834 of file REvent.cxx.

834 {
835
836 // A little sanity check.
837 if (!m_eventReader) {
838 ATH_MSG_ERROR("Function called on un-initialised object");
839 return StatusCode::FAILURE;
840 }
841
842 // Increment the access counter on this container.
844
845 // Check if the branch is already connected.
846 if (m_inputObjects.contains(key)) {
847 return StatusCode::SUCCESS;
848 }
849 // Check if it was already found to be missing.
850 if (m_inputMissingObjects.contains(key)) {
851 if (!silent) {
852 ATH_MSG_WARNING("Field \"" << key << "\" not available on input");
853 }
854 return StatusCode::RECOVERABLE;
855 }
856
857 // Tell the user what's happening.
858 ATH_MSG_DEBUG("Connecting to field \"" << key << "\"");
859
860 // Check if we have metadata about this branch.
861 const xAOD::EventFormatElement* ef = nullptr;
862
863 // RNTuples store fields with an "Aux:" postfix instead of "Aux.".
864 std::string fieldName = key;
865 if (key.ends_with("Aux.")) {
866 fieldName.replace(fieldName.size() - 1, 1, ":");
867 }
868
869 if (m_inputEventFormat.exists(key) == false) {
870 if (!silent) {
871 ATH_MSG_WARNING("No metadata available for object: " << key);
872 }
873 } else {
874 ef = m_inputEventFormat.get(key);
875 }
876
877 // Check if the field exists in our input RNTuple.
878 if (m_eventReader->GetDescriptor().FindFieldId(fieldName.c_str()) ==
879 ROOT::kInvalidDescriptorId) {
880 // Field doesn't exist
881 if (!silent) {
882 ATH_MSG_WARNING("Field \"" << fieldName << "\" not available on input");
883 }
884 m_inputMissingObjects.insert(key);
885 return StatusCode::RECOVERABLE;
886 }
887
888 // RDS: may need some logic here to get type from inputEventFormat rather than
889 // the view to read in with automatic schema evolution
890
891 // Get class name from the field
892 ROOT::RNTupleView<void> view =
893 m_eventReader->GetView<void>(fieldName.c_str(), nullptr);
894 std::string className = view.GetField().GetTypeName();
895 if (className == "") {
896 if (ef) {
897 // This is a fairly weird situation, but let's fall back to taking
898 // the class name from the metadata object in this case.
899 className = ef->className();
900 } else {
902 "Couldn't find an appropriate type with a dictionary for field \""
903 << fieldName << "\"");
904 return StatusCode::FAILURE;
905 }
906 }
907 ::TClass* realClass = ::TClass::GetClass(className.c_str());
908 if (((!realClass) || (!realClass->IsLoaded())) && ef) {
909 // We may need to do an actual schema evolution here, in which
910 // case let's fall back on the class name coming from the metadata
911 // object.
912 className = ef->className();
913 realClass = ::TClass::GetClass(className.c_str());
914 }
915 if ((!realClass) || (!realClass->IsLoaded())) {
916 // Now we're in trouble...
918 "Couldn't find an appropriate type with a dictionary for field \""
919 << fieldName << "\"");
920 return StatusCode::FAILURE;
921 }
922
923 // Make sure that the current object is the "active event":
924 setActive();
925
926 // Check if the output already has this object. If it does, let's
927 // assume that we have been copying the object to the output. Which
928 // means that we need to resume filling the same memory address that
929 // the output holder points to.
930 void* ptr = nullptr;
931
932 // Handle the case where an output object with this key already exists.
933 Object_t::const_iterator out_itr = m_outputObjects.find( key );
934 if( out_itr != m_outputObjects.end() ) {
935 // It needs to be an object manager...
936 RObjectManager* mgr =
937 dynamic_cast< RObjectManager* >( out_itr->second.get() );
938 if( ! mgr ) {
939 ATH_MSG_ERROR("Couldn't access output manager for: " << key );
940 return StatusCode::FAILURE;
941 }
942 // Get the pointer out of it:
943 ptr = mgr->holder()->get();
944 }
945
946 // If there is no output object, then let's create one ourselves.
947 // This is the only way in which we can have the memory management of
948 // THolder do the right thing with this object.
949 if (ptr == nullptr) {
950 ptr = realClass->New();
951 }
952
953 // Create the new manager object that will hold this EDM object.
954 auto mgr = std::make_unique<RObjectManager>(
955 m_eventReader->GetView(fieldName, ptr, className), m_entry,
956 std::make_unique<THolder>(ptr, realClass));
957 RObjectManager* mgrPtr = mgr.get();
958 m_inputObjects[key] = std::move(mgr);
959
960 // If it's an auxiliary store object, set it up correctly.
961 if (Details::isAuxStore(*(mgrPtr->holder()->getClass()))) {
963 }
964
965 // If it (probably) has an associated auxiliary store, set it up as well.
966 if (Details::hasAuxStore(*(mgrPtr->holder()->getClass()))) {
968 key + "Aux.", Details::isStandalone(*(mgrPtr->holder()->getClass()))));
969 }
970
971 // Return gracefully.
972 return StatusCode::SUCCESS;
973} // connectObject
#define ATH_MSG_DEBUG(x)
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:340
void setActive() const
Set this event object as the currently active one.
Definition EventCore.cxx:54
Object_t m_outputObjects
Collection of all the managed output object.
Definition Event.h:342
::Long64_t m_entry
The entry to look at from the input.
Definition REvent.h:138
StatusCode connectAux(const std::string &prefix, bool standalone) override
Function setting up access to a set of auxiliary branches.
Definition REvent.cxx:1072
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.

◆ 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 75 of file EventIO.cxx.

75 {
76
77 // Tell the user what's happening.
78 ATH_MSG_DEBUG("Copying objects matching pattern \"" << pattern
79 << "\" to the output");
80
81 // Collect a list of keys to copy.
82 std::set<std::string> keys;
83
84 // The regular expression to use.
85 std::regex re{pattern};
86
87 // Loop over the known input containers.
88 for (const auto& [key, efe] : m_inputEventFormat) {
89
90 // Tell the user what's happening.
91 ATH_MSG_VERBOSE("Considering input object with key \"" << key << "\"");
92
93 // Check if the class in question matches the requested pattern.
94 if (std::regex_match(key, re) == false) {
95 continue;
96 }
97 // Skip all branches ending in "Aux.":
98 if (key.ends_with("Aux.")) {
99 continue;
100 }
101 // Also skip dynamic branches:
102 if (efe.parentName() != "") {
103 continue;
104 }
105 // Ignore objects that don't exist on the input.
106 static const bool SILENT = true;
107 if (connectObject(key, SILENT).isSuccess() == false) {
108 continue;
109 }
110 // Add the key to the list.
111 ATH_MSG_VERBOSE("Matched key \"" << key << "\"");
112 keys.insert(key);
113 }
114
115 // Check if the pattern matches any of the name remapping rules.
116 for (const auto& [newname, onfile] : m_nameRemapping) {
117
118 // Tell the user what's happening.
119 ATH_MSG_VERBOSE("Considering remapped key \"" << newname << "\"");
120
121 // Check if the remapped name matches the pattern.
122 if (std::regex_match(newname, re) == false) {
123 continue;
124 }
125 // Ignore objects that don't exist on the input.
126 static const bool SILENT = true;
127 if (connectObject(onfile, SILENT).isSuccess() == false) {
128 continue;
129 }
130 // Add the remapped name to the list.
131 ATH_MSG_VERBOSE("Matched remapped key \"" << newname << "\"");
132 keys.insert(newname);
133 }
134
135 // Now loop over all of the found keys.
136 for (const std::string& key : keys) {
137
138 // Check if a name re-mapping should be applied or not.
139 std::string keyToUse = key;
140 auto remap_itr = m_nameRemapping.find(key);
141 if ((remap_itr != m_nameRemapping.end()) &&
142 (!m_inputEventFormat.exists(key)) &&
143 m_inputEventFormat.exists(remap_itr->second)) {
144 keyToUse = remap_itr->second;
145 }
146
147 // Make sure that the input object got connected to.
148 static const bool SILENT = false;
149 ATH_CHECK(connectObject(keyToUse, SILENT));
150
151 // Make sure that the input object is properly updated.
152 Object_t::const_iterator vobjMgr = m_inputObjects.find(keyToUse);
153 if (vobjMgr == m_inputObjects.end()) {
154 ATH_MSG_FATAL("Internal logic error detected");
155 return StatusCode::FAILURE;
156 }
157 Details::IObjectManager* objMgr =
158 dynamic_cast<Details::IObjectManager*>(vobjMgr->second.get());
159 if (objMgr == nullptr) {
160 ATH_MSG_FATAL("Internal logic error detected");
161 return StatusCode::FAILURE;
162 }
163 static const bool METADATA = false;
164 if (getInputObject(keyToUse, *(objMgr->holder()->getClass()->GetTypeInfo()),
165 SILENT, METADATA) == nullptr) {
166 ATH_MSG_FATAL("Internal logic error detected");
167 return StatusCode::FAILURE;
168 }
169
170 // Put the interface object into the output.
171 static const bool OVERWRITE = true;
172 static const bool IS_OWNER = true;
173 ATH_CHECK(record(objMgr->object(), objMgr->holder()->getClass()->GetName(),
174 key, OVERWRITE, METADATA, IS_OWNER));
175
176 // If there is also an auxiliary store for this object/container, copy that
177 // as well.
178 const std::string auxKey = keyToUse + "Aux.";
179 if (m_inputObjects.contains(auxKey)) {
180 ATH_CHECK(
181 recordAux(*(m_inputObjects.at(auxKey)), key + "Aux.", METADATA));
182 }
183 }
184
185 // Return gracefully:
186 return StatusCode::SUCCESS;
187}
const boost::regex re(r_e)
#define ATH_MSG_VERBOSE(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

◆ createAndReadFrom()

std::unique_ptr< Event > Event::createAndReadFrom ( TFile & inFile)
staticinherited

static method to create an Event object and readFrom a file, given by a TFile.

static method to get Event object for reading either TTree (TEvent) or RNTuple (REvent).

The the reader technology, TTree read by TEvent or RNTuple read by REvent, is determined by the looking into the file, given as a TFile object.

Here we access by TFile object

Definition at line 39 of file EventIO.cxx.

39 {
40
41 // Make use of the messaging function(s) from the xAODEvent namespace.
42 using xAODEvent::msg;
43
44 if (inFile.FindKey(EVENT_RNTUPLE_NAME) != nullptr) {
45 // Create and set up an REvent object
46 auto event = std::make_unique<Experimental::REvent>();
47 if (event->readFrom(inFile).isFailure()) {
48 ANA_MSG_ERROR("Could not read RNTuple from: " << inFile.GetName());
49 return {};
50 }
51 return event;
52 } else if (inFile.FindKey(EVENT_TREE_NAME) != nullptr) {
53 // Create and set up a TEvent object
54 auto event = std::make_unique<TEvent>();
55 if (event->readFrom(inFile).isFailure()) {
56 ANA_MSG_ERROR("Could not read TTree from: " << inFile.GetName());
57 return {};
58 }
59 return event;
60 } else {
61 ANA_MSG_ERROR("Could not recognize file: " << inFile.GetName());
62 return {};
63 }
64}
#define ANA_MSG_ERROR(xmsg)
Macro printing error messages.
static const char *const EVENT_TREE_NAME
Default name of the event TTree.
Definition Event.h:76
static const char *const EVENT_RNTUPLE_NAME
Name of the event RNTuple.
Definition Event.h:77
str inFile
Definition makeTOC.py:5

◆ 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.
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]

◆ fill()

Int_t xAOD::Experimental::REvent::fill ( )
overridevirtualinherited

Method filling one event into the output.

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

Implements xAOD::Event.

Definition at line 607 of file REvent.cxx.

607 {
608
609 // Make sure that all objects have been read in. The 99 as the value
610 // has a special meaning for RAuxStore. With this value it doesn't
611 // delete its transient (decoration) variables. Otherwise it does.
612 // (As it's supposed to, when moving to a new event.)
613 if( m_eventReader ) {
614 if (getEntry( m_entry, 99 ) < 0) {
615 ATH_MSG_ERROR( "getEntry failed!" );
616 return 0;
617 }
618 }
619
620 // Prepare the objects for writing. Note that we need to iterate over a
621 // copy of the m_outputObjects container. Since the putAux(...) function
622 // called inside the loop may itself add elements to the m_outputObject
623 // container.
624 std::string unsetObjects;
625 std::vector<std::pair<std::string, TVirtualManager*>> outputObjectsCopy;
626 outputObjectsCopy.reserve(m_outputObjects.size());
627 for (const auto& [key, mgr] : m_outputObjects) {
628 TVirtualManager* objMgr = dynamic_cast<TVirtualManager*>(mgr.get());
629 if (objMgr == nullptr) {
630 ATH_MSG_ERROR("Internal logic error detected");
631 return 0;
632 }
633 outputObjectsCopy.emplace_back(key, objMgr);
634 }
635 for (auto &[key, mgr] : outputObjectsCopy) {
636
637 ATH_MSG_DEBUG("REvent::fill - checking and adding aux for " << key << ", " << mgr << " isSet " << mgr->isSet());
638
639 // Check that a new object was provided in the event - skip dynamic variables:
640 if ((key.find("AuxDyn") == std::string::npos) && !mgr->isSet()) {
641
642 ATH_MSG_DEBUG("REvent::fill - not set " << key);
643
644 // We are now going to fail. But let's collect the names of
645 // all the unset objects:
646 if (unsetObjects.size()) {
647 unsetObjects += ", ";
648 }
649 unsetObjects.append("\"" + key + "\"");
650 continue;
651 }
652
653 // Make sure that any dynamic auxiliary variables that
654 // were added to the object after it was put into the event
655 // are also added to the output.
656 if( putAux( *mgr ).isFailure() ) {
657 ATH_MSG_ERROR( "Failed to put dynamic auxiliary variables in the output for object \"" << key << "\"" );
658 return 0;
659 }
660 }
661
662 // Check if there were any unset objects:
663 if (unsetObjects.size()) {
664 ATH_MSG_ERROR("The following objects were not set in the current event: "
665 << unsetObjects);
666 return 0;
667 }
668
669 // For the first call to fill, we create an RNTupleWriter with the RNTuple model already accumulated
670 // - there may be extensions for Aux containers which are empty for the first few events
671 ATH_MSG_DEBUG( "REvent::fill - has event writer " << (m_eventWriter.get() != nullptr) );
672
673 if( m_eventWriter.get() == nullptr ) {
674
675 // Set output RNTuple name as model description
676 const char* rnTupleName = EVENT_RNTUPLE_NAME;
677
678 // Create RNTuple write with model
679 m_eventWriter = ROOT::RNTupleWriter::Append(std::move(m_model), rnTupleName, *m_outputFile);
680
681 // Reset the RNTupleModel so that subsequent additions of new fields will be done with model extensions
682 m_model.reset();
683
684 ATH_MSG_DEBUG( "REvent::fill - created writer and reset model " );
685
686 }
687
688 // Get entry for writing
689 auto rnEntry = m_eventWriter->GetModel().CreateBareEntry();
690
691 // Now loop over all object managers and bind the output object pointers
692 // to the those in the output RNTuple
693 ::Int_t nbytes = 0;
694 for (auto &[key, mgr] : m_outputObjects) {
695
696 // Get field name from the key
697 auto fieldName = getFieldNameFromKey(key);
698
699 // Check if this is a container, top-level or aux, rather than a aux variable (AuxDyn):
700 ROutObjManager* omgr = dynamic_cast< ROutObjManager* >( mgr.get() );
701 bool isContainer = (omgr != nullptr);
702
703 ATH_MSG_DEBUG("REvent::fill - bind ptr " << key << " mgr " << mgr << " is set " << mgr->isSet()
704 << ", is container " << isContainer);
705
706 // Save value, if an object has been set, otherwise save default value
707 // Dynamic attributes don't exist for empty containers, e.g. no electrons in an event
708 if (mgr->isSet()) {
709 rnEntry->BindRawPtr(fieldName, mgr->object());
710 } else {
711
712 ATH_MSG_DEBUG("REvent::fill - bind unSet ptr " << key << " mgr " << mgr << " is set " << mgr->isSet()
713 << ", is container " << isContainer);
714
715 rnEntry->EmplaceNewValue(fieldName);
716 }
717 }
718
719 ATH_MSG_DEBUG("REvent::fill - writer fill ");
720
721 // Write the entry, and check the return value:
722 const ::Int_t ret = m_eventWriter->Fill(*rnEntry);
723 if( ret <= 0 ) {
724 ATH_MSG_ERROR( "Output RNTuple filling failed with return value: " << ret );
725 }
726 nbytes += ret;
727
728 ATH_MSG_DEBUG("REvent::fill - writer filled ");
729
730 // Reset the object managers:
731 for (auto &[key, mgr] : m_outputObjects) {
732 mgr->reset();
733
734 ATH_MSG_DEBUG("REvent::fill - after reset " << key << " is set " << mgr->isSet());
735
736 }
737
738 // Return the number of bytes written:
739 return nbytes;
740}
StatusCode putAux(TVirtualManager &mgr, ::Bool_t metadata=kFALSE)
Method saving the dynamically created auxiliary properties.
Definition REvent.cxx:1497
::Int_t getEntry(::Long64_t entry, ::Int_t getall=0) override
Function loading a given entry of the input RNTuple.
Definition REvent.cxx:553
::TFile * m_outputFile
The output file for writing.
Definition REvent.h:147

◆ finishWritingTo()

StatusCode xAOD::Experimental::REvent::finishWritingTo ( TFile & file)
overridevirtualinherited

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
kTRUE if successful, kFALSE otherwise

reset writer (metaDataWriter will be reset when going out of scope)

Implements xAOD::Event.

Definition at line 372 of file REvent.cxx.

372 {
373
374 // A small sanity check for meta data writing - need output file as long as MetaData is in a rntuple:
375 if( m_outputFile != &file ) {
376 ATH_MSG_FATAL("File given to finishWritingTo does not match the file given in writeTo file!");
377 return StatusCode::FAILURE;
378 }
379
380 // Notify the listeners that they should write out their metadata, if they
381 // have any.
382 const TIncident incident( IncidentType::MetaDataStop );
383 for (auto& listener : m_listeners) {
384 listener->handle(incident);
385 }
386
387 // Now go to the output file:
388 m_outputFile->cd();
389
390 const char* outRNTupleName = METADATA_OBJECT_NAME;
391
392 // Check if there's already a metadata tree in the output, if so we can return:
393 if( m_outputFile->Get( outRNTupleName ) ) {
394
395 // Let's assume that the metadata is complete in the file already.
396 ATH_MSG_INFO( "Metadata tree already exists, returning" );
397
398 return StatusCode::SUCCESS;
399 }
400
401 // Write out meta data
402
403 // Create new model for this file
404 auto model = ROOT::RNTupleModel::Create();
405
406 // Set output RNTuple name as model description
407 model->SetDescription(outRNTupleName);
408
409
410 // Create field explicitly for EventFormat
411
412 // Check if we have a dictionary: for this object:
413 std::string typeName = SG::normalizedTypeinfoName( typeid( xAOD::EventFormat ) );
414 TClass* cl = TClass::GetClass( typeName.c_str() );
415 if( ! cl ) {
416 ATH_MSG_ERROR( "Didn't find dictionary for type: " << typeName );
417 return StatusCode::FAILURE;
418 }
419 std::string efName = cl->GetName();
420
421 ATH_MSG_DEBUG("finishWriting");
422
423 model->AddField( ROOT::RFieldBase::Create( "EventFormat", efName ).Unwrap());
424
425 // Loop over output meta data object managers and create the corresponding fields for the output model
426
427 // Make sure that any dynamic auxiliary variables that
428 // were added to the object after it was put into the event,
429 // get added to the output
430
431 // Must copy m_outputMetaObjects because it may be augmented in putAux
432 std::vector<std::pair<std::string, TVirtualManager*>> outputMetaObjects;
433 outputMetaObjects.reserve(m_outputMetaObjects.size());
434 for (const auto& [key, mgr] : m_outputMetaObjects) {
435 TVirtualManager* objMgr = dynamic_cast<TVirtualManager*>(mgr.get());
436 if (objMgr == nullptr) {
437 ATH_MSG_FATAL("Internal logic error detected");
438 return StatusCode::FAILURE;
439 }
440
441 ATH_MSG_DEBUG("finishWriting: save metadata key " << key);
442
443 outputMetaObjects.emplace_back(key, objMgr);
444 }
445
446 // Set up the saving of all the dynamic auxiliary properties
447 // of the object if it has any:
448 for( auto& itr : outputMetaObjects ) {
449 static constexpr bool IS_METADATA = true;
450 ATH_CHECK( putAux( *(itr.second), IS_METADATA ) );
451 }
452
453 // Now create fields for each output metadata object
454 for (auto &[key, mgr] : m_outputMetaObjects) {
455
456 // Get field name and class name to create a RFieldBase
457 std::string fieldName;
458 std::string className;
459 if (getInfoForFieldCreation( key, *mgr, fieldName, className ).isFailure()) return StatusCode::FAILURE;
460
461 // should have found class name
462 if ( className.empty() ) {
463 ATH_MSG_ERROR( "could not find className!" );
464 return StatusCode::FAILURE;
465 }
466
467 // Add RFieldBase to model
468 model->AddField( ROOT::RFieldBase::Create( fieldName, className ).Unwrap());
469
470 }
471
472 // Create RNTuple write for meta data with model
473 auto metaDataWriter = ROOT::RNTupleWriter::Append(std::move(model), outRNTupleName, *m_outputFile);
474
475
476 // Get entry for writing
477 auto rnEntry = metaDataWriter->GetModel().CreateBareEntry();
478
479 // Now loop over all object managers and bind the output object pointers
480 // to the those in the output metadata RNTuple
481 for (auto &[key, mgr] : m_outputMetaObjects) {
482
483 // Get field name from the key
484 auto fieldName = getFieldNameFromKey(key);
485
486 // Save value, if exist, otherwise save default value
487 if (mgr.get()) {
488 rnEntry->BindRawPtr(fieldName, mgr->object());
489 } else {
490 rnEntry->EmplaceNewValue(fieldName);
491 }
492 }
493
494 // Add EventFormat to the RNEntry
495 rnEntry->BindRawPtr( "EventFormat", m_outputEventFormat );
496
497 // Write the entry, and check the return value:
498 const ::Int_t ret = metaDataWriter->Fill(*rnEntry);
499 if( ret <= 0 ) {
500 ATH_MSG_FATAL( "Output rntuple filling failed with return value: " << ret );
501 }
502 else {
503 ATH_MSG_INFO( "Output meta data rntuple filled. nbytes = " << ret );
504 }
505
506 // Now clean up:
507
508 // reset output EventFormat
510 m_outputObjects.clear();
511 m_outputMetaObjects.clear();
512
513 rnEntry.reset();
514
516 m_eventWriter.reset();
517
518 metaDataWriter.reset();
519
520 // Return gracefully:
521 return StatusCode::SUCCESS;
522} // finishWriting
#define ATH_MSG_INFO(x)
static const char *const METADATA_OBJECT_NAME
Name of the metadata tree or RNTuple.
Definition Event.h:78
EventFormat * m_outputEventFormat
Format of the current output file.
Definition Event.h:352
Object_t m_outputMetaObjects
Collection of all the managed output meta-objects.
Definition Event.h:347
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
TFile * file

◆ 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:64
Event(std::string_view name)
Constructor with a name.
Definition EventCore.cxx:27
const xAOD::EventFormatElement * getEventFormatElement(SG::sgkey_t sgkey) const
Get the metadata object for a given "SG key".

◆ getEntries()

Long64_t xAOD::Experimental::REvent::getEntries ( ) const
overridevirtualinherited

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

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

Implements xAOD::Event.

Definition at line 527 of file REvent.cxx.

527 {
528
529 if (m_eventReader) {
530 return m_eventReader->GetNEntries();
531 } else if (m_inputNTupleIsMissing) {
532 return 0u;
533 } else {
534 ATH_MSG_ERROR("Function called on an uninitialised object");
535 return 0u;
536 }
537}
bool m_inputNTupleIsMissing
Whether the input has an event RNTuple or not.
Definition REvent.h:133
@ u
Enums for curvilinear frames.
Definition ParamDefs.h:77

◆ getEntry()

Int_t xAOD::Experimental::REvent::getEntry ( ::Long64_t entry,
::Int_t getall = 0 )
overridevirtualinherited

Function loading a given entry of the input RNTuple.

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

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 RNtuple 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

Implements xAOD::Event.

Definition at line 553 of file REvent.cxx.

553 {
554
555 // A little sanity check:
556 if (!m_eventReader) {
557 ATH_MSG_ERROR("Function called on an uninitialised object");
558 return -1;
559 }
560
561 // Check if anything needs to be done.
562 if (entry == m_entry) {
563 ATH_MSG_DEBUG("Entry " << entry << " is already the active one");
564 return 0;
565 }
566
567 // Set entry value
568 m_entry = entry;
569
570 // Stats counter needs to know it's the next event.
572
573 // Loop over all input object managers, and force them to load their
574 // content. But only if getall was used.
575 ::Int_t result = 0;
576 if (getall) {
577 for (auto& [key, inObj] : m_inputObjects) {
578 result += inObj->getEntry(getall);
579 }
580 }
581
582 // Notify the listeners that a new event was loaded.
583 const TIncident incident(IncidentType::BeginEvent);
584 for (TVirtualIncidentListener* listener : m_listeners) {
585 listener->handle(incident);
586 }
587
588 // Return the number of bytes read.
589 return result;
590}
void nextEvent()
Function incrementing the processed event counter.
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

◆ 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 265 of file EventIO.cxx.

267 {
268
269 // Check if a name remapping should be applied or not:
270 std::string keyToUse = key;
271 auto remap_itr = m_nameRemapping.find(key);
272 if ((remap_itr != m_nameRemapping.end()) &&
273 (!m_inputEventFormat.exists(key)) &&
274 m_inputEventFormat.exists(remap_itr->second)) {
275 keyToUse = remap_itr->second;
276 }
277
278 // The following catches the cases when we ask for a transient
279 // ConstDataVector object to be returned as "const DataVector".
280 TStore* store = TActiveStore::store();
281 if (store && store->contains(keyToUse, ti) && store->isConst(keyToUse, ti)) {
282 const void* result = store->getConstObject(keyToUse, ti);
283 return result;
284 }
285
286 // A sanity check before checking for an object from the input file.
287 if (hasInput() == false) {
288 if (silent == false) {
289 ATH_MSG_WARNING("No input file connected to the Event object");
290 }
291 return nullptr;
292 }
293
294 // Make sure that the requested input is connected to.
295 const StatusCode sc = (metadata ? connectMetaObject(keyToUse, silent)
296 : connectObject(keyToUse, silent));
297 if (sc.isSuccess() == false) {
298 return nullptr;
299 }
300
301 // Select which object container to use:
302 Object_t& objects = (metadata ? m_inputMetaObjects : m_inputObjects);
303
304 // Access the object's manager:
305 auto itr = objects.find(keyToUse);
306 if (itr == objects.end()) {
307 ATH_MSG_FATAL("There is an internal logic error in the code...");
308 return nullptr;
309 }
310
311 // This has to be an ObjectManager object:
312 Details::IObjectManager* mgr =
313 dynamic_cast<Details::IObjectManager*>(itr->second.get());
314 if (mgr == nullptr) {
315 if (key == keyToUse) {
316 ATH_MSG_ERROR("Object of wrong type found for key \"" << key << "\"");
317 } else {
318 ATH_MSG_ERROR("Object of wrong type found for key \""
319 << key << "\"/\"" << keyToUse << "\"");
320 }
321 return nullptr;
322 }
323
324 // Make sure that the current entry is loaded for event data objects.
325 if (metadata == false) {
326 const Int_t readBytes = mgr->getEntry();
327 if (readBytes > 0) {
328 // Connect the auxiliary store to objects needing it. This call also
329 // takes care of updating the dynamic store of auxiliary containers,
330 // when they are getting accessed directly.
331 static const bool IS_METADATA = false;
332 if (setAuxStore(key, *mgr, IS_METADATA).isSuccess() == false) {
333 ATH_MSG_ERROR("Failed to set the auxiliary store for "
334 << mgr->holder()->getClass()->GetName() << "/"
335 << keyToUse);
336 return nullptr;
337 }
338 } else if (readBytes < 0) {
339 ATH_MSG_ERROR("Failed to load current entry for object "
340 << mgr->holder()->getClass()->GetName() << "/" << keyToUse);
341 return nullptr;
342 }
343 }
344
345 // Ask the holder object for the object of this type:
346 const void* result = mgr->holder()->getAsConst(ti, silent);
347 if (result == nullptr) {
348 if (!silent) {
349 ATH_MSG_WARNING("Could not retrieve object with key \""
350 << keyToUse << "\" as \""
351 << SG::normalizedTypeinfoName(ti) << "\"");
352 }
353 return nullptr;
354 }
355
356 // We succeeded:
357 return result;
358}
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:333
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.
TestStore store
Definition TestStore.cxx:23
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::Experimental::REvent::getNames ( const std::string & targetClassName,
std::vector< std::string > & vkeys,
bool metadata ) const
overrideprivatevirtualinherited

Function determining the list keys associated with a type name.

Implements xAOD::Event.

Definition at line 743 of file REvent.cxx.

745 {
746
747 // The results go in here
748 std::set<std::string> keys;
749
750 // Get list of fields from
751 // the input metadata tree or input tree
752
753 ROOT::RNTupleReader* reader = (metadata) ? m_metaReader.get() : m_eventReader.get();
754 if (reader == nullptr) {
755 ATH_MSG_ERROR("No input file is connected");
756 return StatusCode::FAILURE;
757 }
758 if (metadata) ATH_MSG_DEBUG("scanning input objects for metadata for type name " << targetClassName);
759 else ATH_MSG_DEBUG("scanning input objects for event data for type name " << targetClassName);
760
761 // add in names for all top level fields
762 for (const auto &topLevelField : reader->GetDescriptor().GetTopLevelFields()) {
763 std::string objClassName = topLevelField.GetTypeName();
764 std::string key = topLevelField.GetFieldName();
765 if (objClassName == targetClassName) {
766 ATH_MSG_VERBOSE("Matched " << targetClassName << " to key " << key);
767 keys.insert(std::move(key));
768 }
769 }
770
771 // check output objects
772 if (m_eventWriter && !metadata){
773 ATH_MSG_DEBUG("scanning output objects for type name " << targetClassName);
774 // add in names for all top level fields
775 for (const auto& topLevelFieldName : m_eventWriter->GetModel().GetRegisteredSubfieldNames()) {
776 auto& topLevelField = m_eventWriter->GetModel().GetConstField(topLevelFieldName);
777 std::string objClassName = topLevelField.GetTypeName();
778 std::string key = topLevelField.GetFieldName();
779 ATH_MSG_VERBOSE("Inspecting " << objClassName << "/" << key);
780 if (objClassName == targetClassName) {
781 ATH_MSG_VERBOSE("Matched " << targetClassName << " to key " << key);
782 keys.insert(std::move(key));
783 }
784 }
785 }
786
787 const Object_t& outAux = ( metadata ?
789
790 // Search though EventFormat for entries where class matches the provided
791 // typeName
792
793 ATH_MSG_DEBUG("scanning output Aux objects for type name " << targetClassName);
794
795 for( const auto& object : outAux ) {
796 // All metadata objects should be held by ROutObjManager objects.
797 // Anything else is an error.
798 std::string objClassName;
799 if ( metadata ) {
800 ROutObjManager* mgr = dynamic_cast< ROutObjManager* >( object.second.get() );
801 if ( ! mgr ) continue;
802 objClassName = mgr->holder()->getClass()->GetName();
803 }
804 const std::string& key = object.first;
805 ATH_MSG_VERBOSE("Inspecting " << objClassName << "/" << key);
806 if (objClassName == targetClassName) {
807 ATH_MSG_VERBOSE("Matched " << targetClassName << " to key " << key);
808 keys.insert(std::move(key));
809 }
810 }
811
812 vkeys.insert(vkeys.end(), keys.begin(), keys.end());
813
814 return StatusCode::SUCCESS;
815}
reader
read the goodrunslist xml file(s)
Definition collisions.py:22

◆ 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 201 of file EventIO.cxx.

202 {
203
204 // Select which object container to use:
206
207 // Check if the object can be found:
208 auto itr = objects.find(key);
209 if (itr == objects.end()) {
210 // Do the following only for event data:
211 if (!metadata) {
212 // It's not in the event. Let's check if we find it in an active
213 // TStore object...
214 TStore* store = TActiveStore::store();
215 if ((!store) || (!store->contains(key, ti)) || store->isConst(key, ti)) {
216 // Nope, not there either...
217 return nullptr;
218 }
219 // Let's return the object from the TStore:
220 void* result = store->getObject(key, ti);
221 return result;
222 } else {
223 // For metadata we don't use external resources.
224 return nullptr;
225 }
226 }
227
228 // If the object is not set in this event yet, we can't continue:
229 if (itr->second->isSet() == false) {
230 return nullptr;
231 }
232
233 // If it does exist, check if it's the right kind of object:
234 Details::IObjectManager* mgr =
235 dynamic_cast<Details::IObjectManager*>(itr->second.get());
236 if (mgr == nullptr) {
237 ATH_MSG_ERROR("Object of wrong type found for key \"" << key << "\"");
238 return nullptr;
239 }
240
241 // Ask the holder object for the object of this type:
242 void* result = mgr->holder()->getAs(ti);
243 if (result == nullptr) {
244 ATH_MSG_WARNING("Couldn't retrieve object as \""
245 << SG::normalizedTypeinfoName(ti) << "\"");
246 return nullptr;
247 }
248
249 // Return the object:
250 return result;
251}

◆ 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::Experimental::REvent::hasInput ( ) const
overrideprivatevirtualinherited

Check if an input file is connected to the object.

Implements xAOD::Event.

Definition at line 592 of file REvent.cxx.

592 {
593
595}

◆ hasOutput()

bool xAOD::Experimental::REvent::hasOutput ( ) const
overrideprivatevirtualinherited

Check if an output file is connected to the object.

Implements xAOD::Event.

Definition at line 597 of file REvent.cxx.

597 {
598 return (m_outputFile != nullptr);
599}

◆ 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::Experimental::REvent::initStats ( )
privateinherited

Function to initialise the statistics for all RNTuple 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 values

Definition at line 1723 of file REvent.cxx.

1723 {
1724
1725 // A little sanity check.
1726 if (!m_eventReader) {
1727 ATH_MSG_ERROR("Function called on an uninitialised object");
1728 return StatusCode::FAILURE;
1729 }
1730
1731 // Reset the number of input branches information.
1733
1734 // Loop over the EventFormat information.
1735 for (const auto& [key, format] : m_inputEventFormat) {
1736
1737 ATH_MSG_DEBUG("Investigating object \"" << key << "\" of class \""
1738 << format.className() << "\"");
1739
1740 // If it's an auxiliary container, scan it using RAuxStore.
1741 if (key.ends_with("Aux.")) {
1742
1743 // But first decide whether it describes a container, or just
1744 // a single object. For that, first get the class that it was
1745 // written with.
1746 TClass* cl = TClass::GetClass(format.className().c_str());
1747 if ((cl == nullptr) || (cl->IsLoaded() == false)) {
1749 "Couldn't find the dictionary for type: " << format.className());
1750 continue;
1751 }
1752
1753 // And then check if it inherits from xAOD::AuxContainerBase or from
1754 // xAOD::AuxInfoBase.
1755 static TClass* const auxContCl = TClass::GetClass(
1756 SG::normalizedTypeinfoName(typeid(xAOD::AuxContainerBase)).c_str());
1757 static TClass* const auxInfoCl = TClass::GetClass(
1758 SG::normalizedTypeinfoName(typeid(xAOD::AuxInfoBase)).c_str());
1759 if ((auxContCl == nullptr) || (auxInfoCl == nullptr)) {
1761 "Couldn't get dictionary for xAOD::AuxContainerBase or "
1762 "xAOD::AuxInfoBase");
1763 return StatusCode::FAILURE;
1764 }
1765 const bool isContainer = cl->InheritsFrom(auxContCl);
1766 const bool isInfo = cl->InheritsFrom(auxInfoCl);
1767 if ((isContainer == false) && (isInfo == false)) {
1768 ATH_MSG_WARNING("Auxiliary store \""
1769 << key
1770 << "\" is of an unknown type: " << format.className());
1771 continue;
1772 }
1773 ATH_MSG_VERBOSE("isContainer = " << isContainer
1774 << ", isInfo = " << isInfo);
1775
1776 // Scan the branches using a temporary RAuxStore instance.
1777 const std::string fieldName = key.substr(0, key.size() - 1) + ":";
1781 static constexpr bool TOP_STORE = true;
1782 RAuxStore temp(fieldName, TOP_STORE, mode);
1783 ATH_CHECK(temp.readFrom(*m_eventReader));
1784
1785 // Add all the auxids to the statistics object:
1786 ReadStats& stats = IOStats::instance().stats();
1787 for (SG::auxid_t id : temp.getAuxIDs()) {
1788 stats.branch(fieldName, id);
1789 }
1790
1791 // Increment the number of known branches.
1792 stats.setBranchNum(stats.branchNum() + temp.getAuxIDs().size());
1793 }
1794 // If it's an interface container.
1795 else {
1796 // Check if it's part of the input ntuple.
1797 if (m_eventReader->GetDescriptor().FindFieldId(key) !=
1798 ROOT::kInvalidDescriptorId) {
1800 }
1801 }
1802 }
1803
1804 // Return gracefully:
1805 return StatusCode::SUCCESS;
1806}
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
@ kObjectStore
The object describes a single object.
@ kContainerStore
The object describes an entire container.
size_t auxid_t
Identifier for a particular aux data item.
Definition AuxTypes.h:27

◆ 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}

◆ loadInputObjects()

StatusCode REventClass::loadInputObjects ( )
inline

Function loading all interface objects of the event.

Definition at line 42 of file xAODRNFileReadTest.cxx.

42 {
43 // Get the event format object:
44 const xAOD::EventFormat* ef = this->inputEventFormat();
45 if( ! ef ) {
46 return StatusCode::FAILURE;
47 }
48 // Loop over the objects of the file:
49 for( const auto & ef_itr : *ef ) {
50 // A helper object:
51 const xAOD::EventFormatElement& efe = ef_itr.second;
52 // Skip auxiliary objects:
53 if( efe.branchName().rfind( "Aux." ) ==
54 ( efe.branchName().size() - 4 ) ) {
55 continue;
56 }
57 // And dynamic variables:
58 if( efe.parentName() != "" ) {
59 continue;
60 }
61 // Skip auxiliary stores with non-standard names:
62 ::TClass* cl = ::TClass::GetClass( efe.className().c_str(), kTRUE,
63 kTRUE );
64 if( ! cl ) continue;
65 if( cl->InheritsFrom( "SG::IConstAuxStore" ) ) {
66 continue;
67 }
68 // Get the type of the branch:
69 const std::type_info* ti = cl->GetTypeInfo();
70 if( ! ti ) {
71 ::Warning( "REventClass::loadInputObjects",
72 "Couldn't find std::type_info object for type %s "
73 "(key=%s)", cl->GetName(), efe.branchName().c_str() );
74 continue;
75 }
76 // Check if the branch exists in the file:
77 static constexpr bool METADATA = false;
78 if( ! this->contains( efe.branchName(), *ti, METADATA ) ) {
79 continue;
80 }
81 // Try to load the object/container:
82 static constexpr bool SILENT = false;
83 if( ! this->getInputObject( efe.branchName(), *ti, SILENT, METADATA ) ) {
84 Error( "REventClass::loadInputObjects",
85 XAOD_MESSAGE( "Couldn't load object: %s" ),
86 efe.branchName().c_str() );
87 return StatusCode::FAILURE;
88 }
89 }
90 // Return gracefully:
91 return StatusCode::SUCCESS;
92 }
#define XAOD_MESSAGE(MESSAGE)
Simple macro for printing error/verbose messages.
const std::string & parentName() const
Get the name of the parent auxiliary object.
const std::string & className() const
Get the class name of this branch/key.
const EventFormat * inputEventFormat() const
Get information about the input objects.
Error
The different types of error that can be flagged in the L1TopoRDO.
Definition Error.h:16

◆ 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}

◆ 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::Experimental::REvent::putAux ( TVirtualManager & vmgr,
::Bool_t metadata = kFALSE )
privateinherited

Method 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.) The first time an aux store variable is encountered, an RAuxFieldManager is created to manage it. And for each call, the manager holder is set to point to the aux variable. Note: this may be called when recording an aux container, but new aux variables may be created up to a call to fill One also needs to keep track of empty aux containers on the first event to allow to add in the aux fields to the RNTuple model for the next event which has a non-empty container

Parameters
mgrThe object manager of the output object
metadataFlag specifying whether the info written is metadata or not
Returns
kTRUE if the setup was successful, or kFALSE if it was not

Add field to RNTuple model

Definition at line 1497 of file REvent.cxx.

1497 {
1498
1499 // A little sanity check:
1500 assert( m_outputEventFormat != 0 );
1501
1502 // Do the conversion:
1503 ROutObjManager* mgr = dynamic_cast< ROutObjManager* >( &vmgr );
1504
1505 ATH_MSG_DEBUG("REvent::putAux - vmgr " << mgr);
1506
1507 if( ! mgr ) {
1508 // It's not an error any more when we don't get a ROutObjManager.
1509 return StatusCode::SUCCESS;
1510 }
1511
1512 // Check if this class has an auxiliary store, if not nothing needs to be done:
1513 if( ! mgr->holder()->getClass()->InheritsFrom( "SG::IAuxStoreIO" ) ) {
1514
1515 ATH_MSG_DEBUG("REvent::putAux - no Aux store ");
1516
1517 return StatusCode::SUCCESS;
1518 }
1519
1520 // Get a pointer to the auxiliary store I/O interface:
1521 SG::IAuxStoreIO* aux = reinterpret_cast< SG::IAuxStoreIO* >(mgr->holder()->getAs( typeid( SG::IAuxStoreIO ) ) );
1522 if( ! aux ) {
1523 ATH_MSG_FATAL( "There is a logic error in the code!" );
1524 }
1525
1526 // Check if we have rules defined for which auxiliary properties
1527 // to write out:
1528 xAOD::AuxSelection sel;
1529 if( ! metadata ) {
1530 auto item_itr = m_auxItemList.find( mgr->key() );
1531 if( item_itr != m_auxItemList.end() ) {
1532 sel.selectAux( item_itr->second );
1533 }
1534 }
1535
1536 // Get the dynamic auxiliary variables held by this object, which
1537 // were selected to be written:
1538 const SG::auxid_set_t auxids = sel.getSelectedAuxIDs (aux->getSelectedAuxIDs());
1539
1540 // Decide what should be the prefix of all the dynamic branches:
1541 const std::string dynNamePrefix = Utils::dynBranchPrefix( mgr->key() );
1542
1543 ATH_MSG_DEBUG("REvent::putAux - dynNamePrefix " << dynNamePrefix);
1544
1545
1546 // Select which container to add the variables to:
1548
1549 // RDS: is the following needed in an RNTuple?
1550 // This iteration will determine the ordering of branches within
1551 // the tree, so sort auxids by name.
1552 const SG::AuxTypeRegistry& r = SG::AuxTypeRegistry::instance();
1553 typedef std::pair< std::string, SG::auxid_t > AuxVarSort_t;
1554 std::vector< AuxVarSort_t > varsort;
1555 varsort.reserve( auxids.size() );
1556 for( SG::auxid_t id : auxids ) {
1557 varsort.emplace_back( r.getName( id ), id );
1558 }
1559 std::sort( varsort.begin(), varsort.end() );
1560
1561 // Extract all the dynamic variables from the object:
1562 for( const auto& p : varsort ) {
1563
1564 // The auxiliary ID:
1565 const SG::auxid_t id = p.second;
1566
1567 // Construct a dynamic key name for the field that we will write:
1568 const std::string dynKey = dynNamePrefix + p.first;
1569
1570 ATH_MSG_DEBUG("REvent::putAux - id, dynKey " << id << ", " << dynKey);
1571
1572
1573 // Try to find the object manager:
1574 Object_t::iterator bmgr = objects.find( dynKey );
1575
1576 // Check if we already know about this variable:
1577 if( bmgr == objects.end() ) {
1578 // Construct the full type name of the variable:
1579 const std::type_info* brType = aux->getIOType( id );
1580 if( ! brType ) {
1581 ATH_MSG_FATAL( "No I/O type found for variable " << dynKey );
1582 return StatusCode::FAILURE;
1583 }
1584 const std::string brTypeName = Utils::getTypeName( *brType );
1585 std::string brProperTypeName = "<unknown>";
1586
1587 // Check if it's a primitive type or not:
1588 bool isPrimitive = false;
1589 TVirtualManager* outmgrPtr = nullptr;
1590
1591 if( strlen( brType->name() ) == 1 ) {
1592 isPrimitive = true;
1593
1594 ATH_MSG_DEBUG("REvent::putAux - primitive " << id << ", " << brTypeName << " brType name " << brType->name());
1595
1596
1597 // Making the "proper" type name is simple in this case:
1598 brProperTypeName = std::move(brTypeName);
1599
1600 // Let's create an RAuxFieldManager for this property:
1601 static constexpr bool IS_OWNER = false;
1602 auto auxmgr = std::make_unique<RAuxFieldManager>(
1603 std::make_unique<THolder>(aux->getIOData( id ), *brType, IS_OWNER), isPrimitive );
1604 outmgrPtr = auxmgr.get();
1605
1606 objects[ dynKey ] = std::move(auxmgr);
1607
1608 } else {
1609
1610 ATH_MSG_DEBUG("REvent::putAux - not primitive " << id << ", " << brTypeName);
1611
1612 // Check if we have a dictionary for this type:
1613 TClass* cl = TClass::GetClass( *brType, kTRUE, kTRUE );
1614 if( ! cl ) {
1615 // The dictionary needs to be loaded now. This could be an
1616 // issue. But let's hope for the best...
1617 cl = TClass::GetClass( brTypeName.c_str() );
1618 // If still not found...
1619 if( ! cl ) {
1620 ATH_MSG_FATAL( "Dictionary not available for variable \"" << dynKey
1621 << "\" of type \"" << brTypeName << "\"" );
1622 return StatusCode::FAILURE;
1623 }
1624 }
1625
1626 // The proper type name comes from the dictionary in this case:
1627 brProperTypeName = cl->GetName();
1628
1629 // Let's create an RAuxFieldManager for this property - not a primitive:
1630 static constexpr bool IS_OWNER = false;
1631 auto auxmgr = std::make_unique<RAuxFieldManager>(
1632 std::make_unique<THolder>(aux->getIOData( id ), cl, IS_OWNER), isPrimitive );
1633 outmgrPtr = auxmgr.get();
1634 objects[ dynKey ] = std::move(auxmgr);
1635 }
1636
1637 // For event data, add in the the new fields to the RNTuple model and event format metadata
1638 if (!metadata) {
1639
1641 ATH_CHECK( addField(dynKey, *outmgrPtr) );
1642
1643 // If all went fine, let's add this branch to the event format
1644 // metadata (but not for regular metadata):
1645 if( ! m_outputEventFormat->exists( dynKey ) ) {
1647 EventFormatElement( dynKey,
1648 brProperTypeName,
1649 mgr->key(),
1650 getHash( dynKey ) ) );
1651 }
1652 }
1653
1654 // We don't need to do the rest:
1655 continue;
1656 }
1657
1658 ATH_MSG_DEBUG("REvent::putAux - setObj " << dynKey);
1659
1660 // Access the object manager:
1661 bmgr = objects.find( dynKey );
1662 if( bmgr == objects.end() ) {
1663 ATH_MSG_FATAL( "There is an internal logic error in the code..." );
1664 }
1665 // Replace the managed object:
1666 void* nc_data ATLAS_THREAD_SAFE = // we hold non-const pointers but check on retrieve
1667 const_cast< void* >( static_cast< const void* >( aux->getIOData( id ) ) );
1668 bmgr->second->setObject( nc_data );
1669 }
1670
1671 // Return gracefully:
1672 return StatusCode::SUCCESS;
1673}
std::atomic_flag m_initialized ATLAS_THREAD_SAFE
Messaging initialized (initMessaging)
bit_t size() const
Count the number of 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:355
StatusCode addField(const std::string &key, const TVirtualManager &mgr)
Add field to RNTuple model given the StoreGate key and output object manager.
Definition REvent.cxx:1677
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.
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...
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::Experimental::REvent::readFrom ( std::string_view fileName)
inherited

Set up the reading of an input file via a file name.

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

This can be considered the 'native' interface as an RNTupleReader opens a file with a name

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

Parameters
fileNamename of file needed for metadata access

Definition at line 165 of file REvent.cxx.

165 {
166
167 ATH_MSG_INFO("REvent::readFrom: fileName " << fileName);
168
169 // Clear the cached input objects.
170 m_inputObjects.clear();
171 m_inputMissingObjects.clear();
172 m_inputMetaObjects.clear();
173 {
175 lock.upgrade();
176 m_branches.clear();
177 }
178 m_eventReader.reset();
179
180 // Reset the internal flags.
181 m_entry = -1;
183
184 // Clear out the current object.
186
187
188 ATH_MSG_DEBUG("Create RNTupleReader for \"" << METADATA_OBJECT_NAME
189 << "\" in file: " << fileName);
190
191 // Set up a reader for the metadata ntuple.
192 // Since some types are non-xAOD types and so not 'visible' when running in AnalysisBase
193 // we need to protect for unknown types with SetEmulateUnknownTypes(true)
194 ROOT::RNTupleDescriptor::RCreateModelOptions opts;
195 opts.SetEmulateUnknownTypes(true);
196 m_metaReader = ROOT::RNTupleReader::Open(opts, METADATA_OBJECT_NAME, fileName);
197 if (!m_metaReader) {
198 ATH_MSG_ERROR("Couldn't find \"" << METADATA_OBJECT_NAME
199 << "\" tree in input file: " << fileName);
200 return StatusCode::FAILURE;
201 }
202 ATH_MSG_DEBUG("Created RNTupleReader for \"" << METADATA_OBJECT_NAME
203 << "\" in file: " << fileName);
204
205 // Make sure that the xAOD::EventFormat dictonary is loaded.
206 // This may not be the case if streamer information reading is turned
207 // off.
208 static const std::string eventFormatTypeName =
210 if (::TClass::GetClass(eventFormatTypeName.c_str()) == nullptr) {
211 ATH_MSG_WARNING("Couldn't load the EventFormat dictionary");
212 }
213 ATH_MSG_VERBOSE("Loaded the xAOD::EventFormat dictionary");
214
215 // Helper lambda for collecting the event format metadata from an RNTuple
216 // with a given name.
217 auto readEventFormatMetadata = [&](std::string_view tupleName) -> StatusCode {
218 // Set up a reader. This may technically be the same as m_metaReader, but
219 // it's easier to write the code this way.
220 auto metaReader = ROOT::RNTupleReader::Open(tupleName, fileName);
221 if (!metaReader) {
222 ATH_MSG_ERROR("Couldn't find \""
223 << tupleName << "\" ntuple in input file: " << fileName);
224 return StatusCode::FAILURE;
225 }
226 ATH_MSG_VERBOSE("Created temporary RNTupleReader for \""
227 << tupleName << "\" in file: " << fileName);
228
229 // Try to read in the event format metadata.
230 const std::string eventFormatFieldName =
231 getFirstFieldMatch(*m_metaReader, "EventFormat");
232 try {
233 // Add its elements to m_inputEventFormat.
234 auto ef = m_metaReader->GetView<xAOD::EventFormat>(eventFormatFieldName);
235 for (const auto& [key, element] : ef(0u)) {
236 m_inputEventFormat.add(element);
237 }
238 } catch (const ROOT::RException&) {
239 ATH_MSG_WARNING("Input file provides no event or metadata");
240 return StatusCode::RECOVERABLE;
241 }
242 ATH_MSG_VERBOSE("Merged event format metadata from \"" << tupleName
243 << "\" ntuple");
244
245 // Return gracefully.
246 return StatusCode::SUCCESS;
247 };
248
249 // Read in the metadata from the "main" metadata ntuple.
250 const StatusCode sc = readEventFormatMetadata(METADATA_OBJECT_NAME);
251 if (sc.isRecoverable()) {
253 return StatusCode::SUCCESS;
254 }
255 ATH_CHECK(sc);
256
257 // List all the other Metadata RNTuples in the input file.
258 // Having several metadata tuples can happen for augmented files
259 // as one metadata tree per stream is produced.
260 std::set<std::string> lOtherMetaTupleNames;
261 {
262 std::unique_ptr<TFile> inFile(TFile::Open(fileName.data(), "READ"));
263 TList* lKeys = inFile->GetListOfKeys();
264 if (lKeys == nullptr) {
265 ATH_MSG_ERROR("Could not get list of keys for input file: " << fileName);
266 return StatusCode::FAILURE;
267 }
268 for (const TObject* obj : *lKeys) {
269 const std::string keyName = obj->GetName();
270 // Make sure the key corresponds to a metadata ntuple but
271 // do not add the current metadata tree in the list of other trees
272 // and do not add the metadata tree handlers to the list
273 if ((keyName != METADATA_OBJECT_NAME) &&
274 (keyName.find("MetaData") != std::string::npos) &&
275 (keyName.find("MetaDataHdr") == std::string::npos)) {
276 // Make sure key corresponds to an RNTuple
277 const TKey* key = dynamic_cast<const TKey*>(obj);
278 if (key == nullptr) {
279 ATH_MSG_ERROR("Object describing \"" << keyName << "\" in file \""
280 << fileName
281 << "\" is not a TKey?");
282 return StatusCode::FAILURE;
283 }
284 const char* className = key->GetClassName();
285 static constexpr bool LOAD = kFALSE;
286 static constexpr bool SILENT = kTRUE;
287 ::TClass* cl = ::TClass::GetClass(className, LOAD, SILENT);
288 if ((cl != nullptr) && cl->InheritsFrom(ROOT::RNTuple::Class())) {
289 lOtherMetaTupleNames.insert(std::move(keyName));
290 }
291 }
292 }
293 }
294
295 // Read in the metadata from any additonal NTuples found (if any).
296 for (const std::string& tupleName : lOtherMetaTupleNames) {
297 ATH_CHECK(readEventFormatMetadata(tupleName));
298 }
299
300 // Set up the main ntuple reader.
301 m_eventReader = ROOT::RNTupleReader::Open(EVENT_RNTUPLE_NAME, fileName);
302 if (!m_eventReader) {
303 ATH_MSG_ERROR("Couldn't access RNTuple \"" << EVENT_RNTUPLE_NAME
304 << "\" in file: " << fileName);
305 return StatusCode::FAILURE;
306 }
307 ATH_MSG_DEBUG("Created RNTupleReader for \"" << EVENT_RNTUPLE_NAME
308 << "\" in file: " << fileName);
309
310 // Init the statistics collection.
312 // Update the event counter in the statistics object:
313 xAOD::ReadStats& stats = IOStats::instance().stats();
314 stats.setNEvents(stats.nEvents() + m_eventReader->GetNEntries());
315
316 // Notify the listeners that a new file was opened:
317 const TIncident beginIncident(IncidentType::BeginInputFile);
318 for (TVirtualIncidentListener* listener : m_listeners) {
319 listener->handle(beginIncident);
320 }
321 // For now implement a very simple scheme in which we claim already
322 // at the start that the entire file was processed. Since we have no way
323 // of ensuring that the user indeed does this. And we can't delay calling
324 // this function, as the user may likely close his/her output file before
325 // closing the last opened input file.
326 const TIncident endIncident(IncidentType::EndInputFile);
327 for (TVirtualIncidentListener* listener : m_listeners) {
328 listener->handle(endIncident);
329 }
330
331 // The initialisation was successful:
332 return StatusCode::SUCCESS;
333}
StatusCode initStats()
Function to initialise the statistics for all RNTuple content.
Definition REvent.cxx:1723
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

◆ readFrom() [2/2]

StatusCode xAOD::Experimental::REvent::readFrom ( TFile & inFile)
overridevirtualinherited

Set up the reading of an input file from TFile This method implements the interface from Event.

Implementation of interface method taking a TFile object. Forwards to the method with a string view below.

Implements xAOD::Event.

Definition at line 154 of file REvent.cxx.

154 {
155 ATH_CHECK(readFrom(inFile.GetName()));
156 return StatusCode::SUCCESS;
157}
StatusCode readFrom(TFile &inFile) override
Set up the reading of an input file from TFile This method implements the interface from Event.
Definition REvent.cxx:154

◆ record() [1/3]

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

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

◆ record() [2/3]

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

Add an output object to the event.

◆ record() [3/3]

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

Record an object into a connected output file.

This is the function doing the heavy lifting when recording a new object into the output RNTuple.

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
kTRUE if the operation was successful, or kFALSE if it was not

Add field to RNTuple model

Implements xAOD::Event.

Definition at line 1342 of file REvent.cxx.

1347 {
1348
1349
1350 // Check if we have an output file when writing an event:
1351 if ( !hasOutput() ) {
1352 ATH_MSG_FATAL("No output output file defined. Did you forget to call writeTo(...)?" );
1353 return StatusCode::FAILURE;
1354 }
1355 assert( m_outputEventFormat != 0 );
1356
1357 ATH_MSG_DEBUG("REvent::record - key, type " << key << ", " << typeName);
1358
1359
1360 // If this is metadata, just take ownership of it. The object will only
1361 // be recorded into the output file when calling finishWriting(...).
1362 if( metadata ) {
1363 // Check whether we already have such an object:
1364 if( ( ! overwrite ) &&
1365 ( m_outputMetaObjects.find( key ) !=
1366 m_outputMetaObjects.end() ) ) {
1367 ATH_MSG_FATAL("Meta-object " << typeName << "/" << key << " already recorded" );
1368 return StatusCode::FAILURE;
1369 }
1370 // Check if we have a dictionary for this object:
1371 TClass* cl = TClass::GetClass( typeName.c_str() );
1372 if( ! cl ) {
1373 ATH_MSG_ERROR( "Didn't find dictionary for type: " << typeName );
1374 return StatusCode::FAILURE;
1375 }
1376 // Create output object manager with a holder for the object:
1377 auto outmgr = std::make_unique<ROutObjManager>( key, std::make_unique<THolder>(obj, cl, isOwner));
1378 m_outputMetaObjects[key] = std::move(outmgr);
1379 // We're done. The rest will be done later on.
1380 return StatusCode::SUCCESS;
1381 }
1382
1383 // Check if we accessed this object on the input. If yes, then this
1384 // key may not be used for recording.
1385 if( ( ! overwrite ) &&
1386 ( m_inputObjects.find( key ) != m_inputObjects.end() ) ) {
1387 ATH_MSG_FATAL( "Object " << typeName << "/" << key <<
1388 " already accessed from the input, can't be overwritten in memory" );
1389 return StatusCode::FAILURE;
1390 }
1391
1392 // Check if we need to add it to the event record:
1393 Object_t::iterator vitr = m_outputObjects.find( key );
1394 if( vitr == m_outputObjects.end() ) {
1395
1396 // Check if we have a dictionary for this object:
1397 TClass* cl = TClass::GetClass( typeName.c_str() );
1398 if( ! cl ) {
1399 ATH_MSG_ERROR( "Didn't find dictionary for type: " << typeName );
1400 return StatusCode::FAILURE;
1401 }
1402 // Check if this is a new object "type" or not:
1403 if( ! m_outputEventFormat->exists( key ) ) {
1404 m_outputEventFormat->add( EventFormatElement( key, cl->GetName(),
1405 "", getHash( key ) ) );
1406 }
1407 // Create output object manager with a holder for the object:
1408 auto outmgr = std::make_unique<ROutObjManager>( key, std::make_unique<THolder>(obj, cl, isOwner));
1409 ROutObjManager* outmgrPtr = outmgr.get();
1410 m_outputObjects[ key ] = std::move(outmgr);
1411
1412 ATH_MSG_DEBUG("REvent::record - save outObjMgr for key, type " << key << ", " << typeName);
1413
1414 // Set up the saving of all the dynamic auxiliary properties
1415 // of the object if it has any:
1416 ATH_CHECK( putAux( *outmgrPtr ) );
1417
1419 ATH_CHECK( addField(key, *outmgrPtr) );
1420
1421 // Return at this point, as we don't want to run the rest of
1422 // the function's code:
1423 return StatusCode::SUCCESS;
1424 }
1425
1426 // Access the object manager:
1427 ROutObjManager* omgr = dynamic_cast< ROutObjManager* >( vitr->second.get() );
1428 if( ! omgr ) {
1429 ATH_MSG_FATAL( "Manager object of the wrong type encountered" );
1430 return StatusCode::FAILURE;
1431 }
1432
1433 // RDS: Is the following still needed?
1434 // // Check that the type of the object matches that of the previous
1435 // // object:
1436 // if( typeName != omgr->holder()->getClass()->GetName() ) {
1437 // // This may still be, when the ROOT dictionary name differs from the
1438 // // "simple type name" known to C++. So let's get the ROOT name of the
1439 // // new type:
1440 // TClass* cl = TClass::GetClass( typeName.c_str() );
1441 // if( ( ! cl ) || ::strcmp( cl->GetName(),
1442 // omgr->holder()->getClass()->GetName() ) ) {
1443 // ATH_MSG_FATAL(
1444 // XAOD_MESSAGE( "For output key \"%s\" the previous type "
1445 // "was \"%s\", the newly requested type is "
1446 // "\"%s\"" ),
1447 // key.c_str(), omgr->holder()->getClass()->GetName(),
1448 // typeName.c_str() );
1449 // return StatusCode::FAILURE;
1450 // }
1451 // }
1452
1453 // Replace the managed object:
1454 omgr->setObject( obj );
1455
1456 // Replace the auxiliary objects:
1457 return putAux( *omgr );
1458} // record
bool hasOutput() const override
Check if an output file is connected to the object.
Definition REvent.cxx:597

◆ recordAux()

StatusCode xAOD::Experimental::REvent::recordAux ( TVirtualManager & mgr,
const std::string & key,
bool metadata )
overrideprivatevirtualinherited

Record an auxiliary store into a connected output file.

Implements xAOD::Event.

Definition at line 1460 of file REvent.cxx.

1461 {
1462
1463 // Check if the auxiliary store is a generic object.
1464 Details::IObjectManager* iomgr = dynamic_cast<Details::IObjectManager*>(&mgr);
1465 if (iomgr != nullptr) {
1466 // Record the auxiliary object using the main record function.
1467 static const bool OVERWRITE = true;
1468 static const bool IS_OWNER = true;
1469 ATH_CHECK(record(iomgr->object(), iomgr->holder()->getClass()->GetName(),
1470 key, OVERWRITE, metadata, IS_OWNER));
1471 return StatusCode::SUCCESS;
1472 }
1473
1474 // Apparently we didn't recorgnize the auxiliary store type.
1475 ATH_MSG_ERROR("Unknown auxiliary store manager type encountered");
1476 return StatusCode::FAILURE;
1477}
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.
Definition REvent.cxx:1342

◆ 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.

◆ REvent()

xAOD::Experimental::REvent::REvent ( )

Default constructor.

Definition at line 37 of file REvent.cxx.

142: Event("xAOD::Experimental::REvent") {}

◆ 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::Experimental::REvent::setAuxStore ( const std::string & key,
Details::IObjectManager & mgr,
bool metadata )
overrideprivatevirtualinherited

Function connecting a DV object to its auxiliary store.

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

This function takes care of this.

Parameters
keyThe key (field name) of the object whose auxiliary store should be set up
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 1217 of file REvent.cxx.

1218 {
1219
1220 // Check if we need to do anything:
1221 if ((Details::hasAuxStore(*(mgr.holder()->getClass())) == false) &&
1222 (Details::isAuxStore(*(mgr.holder()->getClass())) == false)) {
1223 return StatusCode::SUCCESS;
1224 }
1225
1226 // Select which object container to use:
1228
1229 // Look up the auxiliary object's manager:
1230 TVirtualManager* auxMgr = nullptr;
1231 std::string auxKey;
1232 if (Details::isAuxStore(*(mgr.holder()->getClass()))) {
1233 auxMgr = &mgr;
1234 auxKey = key;
1235 } else {
1236 auto itr = objects.find(key + "Aux.");
1237 if (itr == objects.end()) {
1238 // Apparently there's no auxiliary object for this DV, so let's
1239 // give up.
1240 return StatusCode::SUCCESS;
1241 }
1242 auxMgr = itr->second.get();
1243 auxKey = key + "Aux:";
1244 }
1245
1246 if (!metadata) {
1247 // Make sure the auxiliary object is up to date.
1248 ::Int_t readBytes = auxMgr->getEntry();
1249
1250 // Check if there is a separate auxiliary object for the dynamic
1251 // variables, which would need to be updated.
1252 const std::string dynAuxKey = auxKey + "Dynamic";
1253 auto dynAuxMgr = objects.find(dynAuxKey);
1254 if ((dynAuxMgr != objects.end()) && (readBytes || (auxMgr == &mgr))) {
1255
1256 // Tell the dynamic store object to switch to a new entry.
1257 dynAuxMgr->second->getEntry();
1258 }
1259 }
1260
1261 // Stop here if we've set up an auxiliary store.
1262 if (auxMgr == &mgr) {
1263 return StatusCode::SUCCESS;
1264 }
1265
1266 // Access the auxiliary base class of the object/vector:
1267 SG::AuxVectorBase* vec = 0;
1268 SG::AuxElement* aux = 0;
1269 switch (mgr.holder()->typeKind()) {
1270 case THolder::DATAVECTOR: {
1271 void* vvec = mgr.holder()->getAs(typeid(SG::AuxVectorBase));
1272 vec = reinterpret_cast<SG::AuxVectorBase*>(vvec);
1273 } break;
1274 case THolder::AUXELEMENT: {
1275 void* vaux = mgr.holder()->getAs(typeid(SG::AuxElement));
1276 aux = reinterpret_cast<SG::AuxElement*>(vaux);
1277 } break;
1278 default:
1279 break;
1280 }
1281
1282 // Check whether index tracking is enabled for the type. If not, then
1283 // we need to fix it...
1284 if (vec && (!vec->trackIndices())) {
1285 Details::forceTrackIndices(*vec);
1286 }
1287
1288 // Check if we were successful:
1289 if ((!vec) && (!aux)) {
1290 ATH_MSG_FATAL("Couldn't access class \""
1291 << mgr.holder()->getClass()->GetName()
1292 << "\" as SG::AuxVectorBase or SG::AuxElement");
1293 return StatusCode::FAILURE;
1294 }
1295
1296 // Get the concrete auxiliary manager:
1297 RObjectManager* omgr = dynamic_cast<RObjectManager*>(auxMgr);
1298 if (!omgr) {
1299 ATH_MSG_FATAL("Auxiliary manager for \"" << auxKey
1300 << "\" is not of the right type");
1301 return StatusCode::FAILURE;
1302 }
1303 void* p = omgr->holder()->getAs(typeid(SG::IConstAuxStore));
1304 const SG::IConstAuxStore* store =
1305 reinterpret_cast<const SG::IConstAuxStore*>(p);
1306 if (store == nullptr) {
1307 ATH_MSG_FATAL("There's a logic error in the code");
1308 return StatusCode::FAILURE;
1309 }
1310
1311 // Connect the two:
1312 if (vec) {
1313 vec->setStore(store);
1314 } else if (aux) {
1315 aux->setStore(store);
1316 } else {
1317 ATH_MSG_FATAL("There's a logic error in the code");
1318 return StatusCode::FAILURE;
1319 }
1320
1321 // We succeeded:
1322 return StatusCode::SUCCESS;
1323}
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}

◆ setUpDynamicStore()

StatusCode xAOD::Experimental::REvent::setUpDynamicStore ( RObjectManager & mgr,
ROOT::RNTupleReader & reader )
privateinherited

event uses RNTupleReader:

This function is used by connectObject(...) and connectMetaObject(...) 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
readerThe RNTuple reader to read dynamic variables from
Returns
The usual StatusCode types

Definition at line 1816 of file REvent.cxx.

1817 {
1818
1819 // The name of the field that the object is connected to.
1820 const std::string fieldName = mgr.field().GetField().GetFieldName();
1821
1822 // Check if we can call setName(...) on the object.
1823 ::TMethodCall setNameCall;
1824 setNameCall.InitWithPrototype(mgr.holder()->getClass(), "setName",
1825 "const char*");
1826 if (setNameCall.IsValid()) {
1827 // Yes, there is such a function. Let's call it with the field
1828 // name.
1829 const ::TString params = ::TString::Format("\"%s\"", fieldName.c_str());
1830 const char* charParams = params.Data();
1831 setNameCall.Execute(mgr.holder()->get(), charParams);
1832 } else {
1833 // This is weird. What sort of auxiliary container is this? :-/
1834 ATH_MSG_WARNING("Couldn't find setName(...) function for container \""
1835 << fieldName << "\" (type: "
1836 << mgr.holder()->getClass()->GetName() << ")");
1837 }
1838
1839 // Check if we can switch out the internal store of this object:
1840 static const TClass* const holderClass =
1841 TClass::GetClass(typeid(SG::IAuxStoreHolder));
1842 if (!mgr.holder()->getClass()->InheritsFrom(holderClass)) {
1843 // Nope... So let's just end the journey here.
1844 return StatusCode::SUCCESS;
1845 }
1846
1847 // Try to get the object as an IAuxStoreHolder:
1848 SG::IAuxStoreHolder* storeHolder = reinterpret_cast<SG::IAuxStoreHolder*>(
1849 mgr.holder()->getAs(typeid(SG::IAuxStoreHolder)));
1850 if (!storeHolder) {
1851 ATH_MSG_FATAL("There's a logic error in the code");
1852 return StatusCode::FAILURE;
1853 }
1854
1855 // Create an RAuxStore instance that will read the dynamic variables
1856 // of this container. Notice that the RAuxManager doesn't own the
1857 // RAuxStore object. It will be owned by the SG::IAuxStoreHolder
1858 // object.
1859 static constexpr bool TOP_STORE = false;
1860 auto store = std::make_unique<RAuxStore>(
1861 fieldName, TOP_STORE,
1865 // This object is used to read data from the input, it needs to be
1866 // locked:
1867 store->lock();
1868
1869 // Set it up to read from the input RNTuple.
1870 ATH_CHECK(store->readFrom(reader));
1871 // Tell the auxiliary store which entry to use. This is essential for
1872 // metadata objects, and non-important for event data objects, which will
1873 // get a possibly different entry loaded in setAuxStore(...).
1874 ATH_CHECK(store->getEntry(0));
1875
1876 // Set up a manager for it.
1877 static constexpr bool SHARED_OWNER = false;
1878 m_inputObjects[fieldName + "Dynamic"] =
1879 std::make_unique<RAuxManager>(store.get(), m_entry, SHARED_OWNER);
1880
1881 // Give this object to the store holder.
1882 storeHolder->setStore(store.release());
1883
1884 // Return gracefully:
1885 return StatusCode::SUCCESS;
1886}
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::Experimental::REvent::writeTo ( TFile & file)
overridevirtualinherited

Connect the object to an output file.

This function should be called to create a file for writing and setup the output RNTuple and metadata trees.

Parameters
filethe TFile to which the output is writter

Implements xAOD::Event.

Definition at line 342 of file REvent.cxx.

342 {
343
344 // Save filefor writing
346
347 ATH_MSG_DEBUG("REvent::writeTo - opened output file " << m_outputFile->GetName());
348
349 // Access the EventFormat object associated with this file:
352
353 ATH_MSG_DEBUG("REvent::writeTo - creating RNTupleModel ");
354
355 // Create new model for this file
356 m_model = ROOT::RNTupleModel::Create();
357
358 // Set output RNTuple name as model description
359 const char* rnTupleName = EVENT_RNTUPLE_NAME;
360 m_model->SetDescription(rnTupleName);
361
362 // Return gracefully:
363 return StatusCode::SUCCESS;
364}
static const TEventFormatRegistry & instance()
Access the only instance of the object in memory.
EventFormat & getEventFormat(const TFile *file) const
Access the managed EventFormat object.

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 387 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_RNTUPLE_NAME

const char *const Event::EVENT_RNTUPLE_NAME = "EventData"
staticinherited

Name of the event RNTuple.

Definition at line 77 of file Event.h.

◆ EVENT_TREE_NAME

const char *const Event::EVENT_TREE_NAME = "CollectionTree"
staticinherited

Default name of the event TTree.

Name of the event TTree.

Definition at line 76 of file Event.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 355 of file Event.h.

◆ m_branchesMutex

upgrade_mutex_t xAOD::Event::m_branchesMutex
mutableprotectedinherited

Mutex for multithread synchronization.

Definition at line 383 of file Event.h.

◆ m_entry

::Long64_t xAOD::Experimental::REvent::m_entry {}
privateinherited

The entry to look at from the input.

Definition at line 138 of file REvent.h.

138{};

◆ m_eventReader

std::unique_ptr<ROOT::RNTupleReader> xAOD::Experimental::REvent::m_eventReader
privateinherited

The main event data reader.

Definition at line 131 of file REvent.h.

◆ m_eventWriter

std::unique_ptr<ROOT::RNTupleWriter> xAOD::Experimental::REvent::m_eventWriter
privateinherited

The main event writer: RNTupleWeader.

Definition at line 144 of file REvent.h.

◆ m_imsg

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

MessageSvc pointer.

Definition at line 135 of file AthMessaging.h.

135{ nullptr };

◆ m_inputEventFormat

EventFormat xAOD::Event::m_inputEventFormat
protectedinherited

Format of the current input file.

Definition at line 350 of file Event.h.

◆ m_inputMetaObjects

Object_t xAOD::Event::m_inputMetaObjects
protectedinherited

Collection of all the managed input meta-objects.

Definition at line 345 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 340 of file Event.h.

◆ m_inputNTupleIsMissing

bool xAOD::Experimental::REvent::m_inputNTupleIsMissing = false
privateinherited

Whether the input has an event RNTuple or not.

Definition at line 133 of file REvent.h.

◆ m_inputObjects

Object_t xAOD::Event::m_inputObjects
protectedinherited

Collection of all the managed input objects.

Definition at line 337 of file Event.h.

◆ m_listeners

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

Listeners who should be notified when certain incidents happen.

Definition at line 358 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_metaReader

std::unique_ptr<ROOT::RNTupleReader> xAOD::Experimental::REvent::m_metaReader
privateinherited

The metadata reader.

Definition at line 135 of file REvent.h.

◆ m_model

std::unique_ptr<ROOT::RNTupleModel> xAOD::Experimental::REvent::m_model
privateinherited

The RNTuple model used for event fields.

Definition at line 141 of file REvent.h.

◆ 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 361 of file Event.h.

◆ m_nm

std::string AthMessaging::m_nm
privateinherited

Message source name.

Definition at line 129 of file AthMessaging.h.

◆ m_outputEventFormat

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

Format of the current output file.

Definition at line 352 of file Event.h.

◆ m_outputFile

::TFile* xAOD::Experimental::REvent::m_outputFile {nullptr}
privateinherited

The output file for writing.

Definition at line 147 of file REvent.h.

147{nullptr};

◆ m_outputMetaObjects

Object_t xAOD::Event::m_outputMetaObjects
protectedinherited

Collection of all the managed output meta-objects.

Definition at line 347 of file Event.h.

◆ m_outputObjects

Object_t xAOD::Event::m_outputObjects
protectedinherited

Collection of all the managed output object.

Definition at line 342 of file Event.h.

◆ m_printEventProxyWarnings

bool xAOD::Event::m_printEventProxyWarnings = false
protectedinherited

Option to silence common warnings that seem to be harmless.

Definition at line 364 of file Event.h.

◆ METADATA_OBJECT_NAME

const char *const Event::METADATA_OBJECT_NAME = "MetaData"
staticinherited

Name of the metadata tree or RNTuple.

Definition at line 78 of file Event.h.


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