ATLAS Offline Software
EventIO.cxx
Go to the documentation of this file.
1 // Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2 
3 // Local include(s).
4 #include "xAODRootAccess/Event.h"
8 
9 // Project include(s).
11 
12 // System include(s).
13 #include <regex>
14 #include <string>
15 #include <vector>
16 
17 namespace xAOD {
18 
28 StatusCode Event::copy(const std::string& pattern) {
29 
30  // Tell the user what's happening.
31  ATH_MSG_DEBUG("Copying objects matching pattern \"" << pattern
32  << "\" to the output");
33 
34  // Collect a list of keys to copy.
35  std::set<std::string> keys;
36 
37  // The regular expression to use.
39 
40  // Loop over the known input containers.
41  for (const auto& [key, efe] : m_inputEventFormat) {
42 
43  // Tell the user what's happening.
44  ATH_MSG_VERBOSE("Considering input object with key \"" << key << "\"");
45 
46  // Check if the class in question matches the requested pattern.
47  if (std::regex_match(key, re) == false) {
48  continue;
49  }
50  // Ignore objects that don't exist on the input.
51  static const bool SILENT = true;
52  if (connectObject(key, SILENT).isSuccess() == false) {
53  continue;
54  }
55  // Skip all branches ending in "Aux.":
56  if (key.ends_with("Aux.")) {
57  continue;
58  }
59  // Also skip dynamic branches:
60  if (efe.parentName() != "") {
61  continue;
62  }
63  // Add the key to the list.
64  ATH_MSG_VERBOSE("Matched key \"" << key << "\"");
65  keys.insert(key);
66  }
67 
68  // Check if the pattern matches any of the name remapping rules.
69  for (const auto& [newname, onfile] : m_nameRemapping) {
70 
71  // Tell the user what's happening.
72  ATH_MSG_VERBOSE("Considering remapped key \"" << newname << "\"");
73 
74  // Check if the remapped name matches the pattern.
75  if (std::regex_match(newname, re) == false) {
76  continue;
77  }
78  // Ignore objects that don't exist on the input.
79  static const bool SILENT = true;
80  if (connectObject(onfile, SILENT).isSuccess() == false) {
81  continue;
82  }
83  // Add the remapped name to the list.
84  ATH_MSG_VERBOSE("Matched remapped key \"" << newname << "\"");
85  keys.insert(newname);
86  }
87 
88  // Now loop over all of the found keys.
89  for (const std::string& key : keys) {
90 
91  // Check if a name re-mapping should be applied or not.
92  std::string keyToUse = key;
93  auto remap_itr = m_nameRemapping.find(key);
94  if ((remap_itr != m_nameRemapping.end()) &&
96  m_inputEventFormat.exists(remap_itr->second)) {
97  keyToUse = remap_itr->second;
98  }
99 
100  // Make sure that the input object got connected to.
101  static const bool SILENT = false;
102  ATH_CHECK(connectObject(keyToUse, SILENT));
103 
104  // Make sure that the input object is properly updated.
105  Object_t::const_iterator vobjMgr = m_inputObjects.find(keyToUse);
106  if (vobjMgr == m_inputObjects.end()) {
107  ATH_MSG_FATAL("Internal logic error detected");
108  return StatusCode::FAILURE;
109  }
110  Details::IObjectManager* objMgr =
111  dynamic_cast<Details::IObjectManager*>(vobjMgr->second.get());
112  if (objMgr == nullptr) {
113  ATH_MSG_FATAL("Internal logic error detected");
114  return StatusCode::FAILURE;
115  }
116  static const bool METADATA = false;
117  if (getInputObject(keyToUse, *(objMgr->holder()->getClass()->GetTypeInfo()),
118  SILENT, METADATA) == nullptr) {
119  ATH_MSG_FATAL("Internal logic error detected");
120  return StatusCode::FAILURE;
121  }
122 
123  // Put the interface object into the output.
124  static const bool OVERWRITE = true;
125  static const bool IS_OWNER = true;
126  ATH_CHECK(record(objMgr->object(), objMgr->holder()->getClass()->GetName(),
127  key, OVERWRITE, METADATA, IS_OWNER));
128 
129  // If there is also an auxiliary store for this object/container, copy that
130  // as well.
131  const std::string auxKey = keyToUse + "Aux.";
132  if (m_inputObjects.contains(auxKey)) {
133  ATH_CHECK(
134  recordAux(*(m_inputObjects.at(auxKey)), key + "Aux.", METADATA));
135  }
136  }
137 
138  // Return gracefully:
139  return StatusCode::SUCCESS;
140 }
141 
154 void* Event::getOutputObject(const std::string& key, const std::type_info& ti,
155  bool metadata) const {
156 
157  // Select which object container to use:
159 
160  // Check if the object can be found:
161  auto itr = objects.find(key);
162  if (itr == objects.end()) {
163  // Do the following only for event data:
164  if (!metadata) {
165  // It's not in the event. Let's check if we find it in an active
166  // TStore object...
168  if ((!store) || (!store->contains(key, ti)) || store->isConst(key, ti)) {
169  // Nope, not there either...
170  return nullptr;
171  }
172  // Let's return the object from the TStore:
173  void* result = store->getObject(key, ti);
174  return result;
175  } else {
176  // For metadata we don't use external resources.
177  return nullptr;
178  }
179  }
180 
181  // If the object is not set in this event yet, we can't continue:
182  if (itr->second->isSet() == false) {
183  return nullptr;
184  }
185 
186  // If it does exist, check if it's the right kind of object:
188  dynamic_cast<Details::IObjectManager*>(itr->second.get());
189  if (mgr == nullptr) {
190  ATH_MSG_ERROR("Object of wrong type found for key \"" << key << "\"");
191  return nullptr;
192  }
193 
194  // Ask the holder object for the object of this type:
195  void* result = mgr->holder()->getAs(ti);
196  if (result == nullptr) {
197  ATH_MSG_WARNING("Couldn't retrieve object as \""
198  << SG::normalizedTypeinfoName(ti) << "\"");
199  return nullptr;
200  }
201 
202  // Return the object:
203  return result;
204 }
205 
218 const void* Event::getInputObject(const std::string& key,
219  const std::type_info& ti, bool silent,
220  bool metadata) {
221 
222  // Check if a name remapping should be applied or not:
223  std::string keyToUse = key;
224  auto remap_itr = m_nameRemapping.find(key);
225  if ((remap_itr != m_nameRemapping.end()) &&
227  m_inputEventFormat.exists(remap_itr->second)) {
228  keyToUse = remap_itr->second;
229  }
230 
231  // The following catches the cases when we ask for a transient
232  // ConstDataVector object to be returned as "const DataVector".
234  if (store && store->contains(keyToUse, ti) && store->isConst(keyToUse, ti)) {
235  const void* result = store->getConstObject(keyToUse, ti);
236  return result;
237  }
238 
239  // A sanity check before checking for an object from the input file.
240  if (hasInput() == false) {
241  if (silent == false) {
242  ATH_MSG_WARNING("No input file connected to the Event object");
243  }
244  return nullptr;
245  }
246 
247  // Make sure that the requested input is connected to.
248  const StatusCode sc = (metadata ? connectMetaObject(keyToUse, silent)
249  : connectObject(keyToUse, silent));
250  if (sc.isSuccess() == false) {
251  return nullptr;
252  }
253 
254  // Select which object container to use:
256 
257  // Access the object's manager:
258  auto itr = objects.find(keyToUse);
259  if (itr == objects.end()) {
260  ATH_MSG_FATAL("There is an internal logic error in the code...");
261  return nullptr;
262  }
263 
264  // This has to be an ObjectManager object:
266  dynamic_cast<Details::IObjectManager*>(itr->second.get());
267  if (mgr == nullptr) {
268  if (key == keyToUse) {
269  ATH_MSG_ERROR("Object of wrong type found for key \"" << key << "\"");
270  } else {
271  ATH_MSG_ERROR("Object of wrong type found for key \""
272  << key << "\"/\"" << keyToUse << "\"");
273  }
274  return nullptr;
275  }
276 
277  // Make sure that the current entry is loaded for event data objects.
278  if (metadata == false) {
279  const Int_t readBytes = mgr->getEntry();
280  if (readBytes > 0) {
281  // Connect the auxiliary store to objects needing it. This call also
282  // takes care of updating the dynamic store of auxiliary containers,
283  // when they are getting accessed directly.
284  static const bool IS_METADATA = false;
285  if (setAuxStore(key, *mgr, IS_METADATA).isSuccess() == false) {
286  ATH_MSG_ERROR("Failed to set the auxiliary store for "
287  << mgr->holder()->getClass()->GetName() << "/"
288  << keyToUse);
289  return nullptr;
290  }
291  } else if (readBytes < 0) {
292  ATH_MSG_ERROR("Failed to load current entry for object "
293  << mgr->holder()->getClass()->GetName() << "/" << keyToUse);
294  return nullptr;
295  }
296  }
297 
298  // Ask the holder object for the object of this type:
299  const void* result = mgr->holder()->getAsConst(ti, silent);
300  if (result == nullptr) {
301  if (!silent) {
302  ATH_MSG_WARNING("Could not retrieve object with key \""
303  << keyToUse << "\" as \""
304  << SG::normalizedTypeinfoName(ti) << "\"");
305  }
306  return nullptr;
307  }
308 
309  // We succeeded:
310  return result;
311 }
312 
322 ::Bool_t Event::contains(const std::string& key, const std::type_info& ti,
323  ::Bool_t metadata) {
324 
325  static const bool SILENT = true;
326  return ((getOutputObject(key, ti, metadata) != nullptr) ||
327  (getInputObject(key, ti, SILENT, metadata) != nullptr));
328 }
329 
341 ::Bool_t Event::transientContains(const std::string& key,
342  const std::type_info& ti,
343  ::Bool_t metadata) const {
344 
345  return (getOutputObject(key, ti, metadata) != nullptr);
346 }
347 
348 } // namespace xAOD
xAOD::Event::keys
StatusCode keys(std::vector< std::string > &vkeys, bool metadata) const
Provide a list of all data object keys associated with a specific type.
mergePhysValFiles.pattern
pattern
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:25
SGTest::store
TestStore store
Definition: TestStore.cxx:23
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
get_generator_info.result
result
Definition: get_generator_info.py:21
LArConditions2Ntuple.objects
objects
Definition: LArConditions2Ntuple.py:64
xAOD::Event::setAuxStore
virtual StatusCode setAuxStore(const std::string &key, Details::IObjectManager &mgr, bool metadata)=0
Function connecting a DV object to its auxiliary store.
xAOD::Event::m_inputObjects
Object_t m_inputObjects
Collection of all the managed input objects.
Definition: Event.h:308
SG::normalizedTypeinfoName
std::string normalizedTypeinfoName(const std::type_info &info)
Convert a type_info to a normalized string representation (matching the names used in the root dictio...
Definition: normalizedTypeinfoName.cxx:120
xAOD::Event::m_outputMetaObjects
Object_t m_outputMetaObjects
Collection of all the managed output meta-objects.
Definition: Event.h:318
xAOD::Event::m_inputEventFormat
EventFormat m_inputEventFormat
Format of the current input file.
Definition: Event.h:321
xAOD::Details::IObjectManager::holder
const THolder * holder() const
Accessor to the Holder object.
Definition: IObjectManager.cxx:43
xAOD::TActiveStore::store
static TStore * store()
Access the currently active TStore object.
Definition: TActiveStore.cxx:16
xAOD
ICaloAffectedTool is abstract interface for tools checking if 4 mom is in calo affected region.
Definition: ICaloAffectedTool.h:24
xAOD::Event::m_nameRemapping
std::unordered_map< std::string, std::string > m_nameRemapping
Container name re-mapping rules.
Definition: Event.h:332
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
xAOD::Event::copy
StatusCode copy(const std::string &pattern=".*")
Copy an object directly from the input to the output.
Definition: EventIO.cxx:28
xAOD::Event::Object_t
std::unordered_map< std::string, std::unique_ptr< TVirtualManager > > Object_t
Definition of the internal data structure type.
Definition: Event.h:305
xAOD::Event::m_inputMetaObjects
Object_t m_inputMetaObjects
Collection of all the managed input meta-objects.
Definition: Event.h:316
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
xAOD::THolder::getClass
const ::TClass * getClass() const
Definition: THolder.cxx:401
PrepareReferenceFile.regex
regex
Definition: PrepareReferenceFile.py:43
python.checkMetadata.metadata
metadata
Definition: checkMetadata.py:175
BchCleanup.mgr
mgr
Definition: BchCleanup.py:294
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
xAOD::Event::connectMetaObject
virtual StatusCode connectMetaObject(const std::string &key, bool silent)=0
Function setting up access to a particular metadata object.
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
IObjectManager.h
xAOD::Event::getOutputObject
void * getOutputObject(SG::sgkey_t key, const std::type_info &ti) override
Function for retrieving an output object in a non-template way.
Definition: EventTVirtualEvent.cxx:138
xAOD::Event::recordAux
virtual StatusCode recordAux(TVirtualManager &mgr, const std::string &key, bool metadata)=0
Record an auxiliary store into a connected output file.
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Event.h
xAOD::Event::getInputObject
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.
Definition: EventTVirtualEvent.cxx:162
xAOD::Event::hasInput
virtual bool hasInput() const =0
Check if an input file is connected to the object.
xAOD::Event::record
StatusCode record(T *obj, const std::string &key)
Add an output object to the event.
normalizedTypeinfoName.h
Convert a type_info to a normalized string representation (matching the names used in the root dictio...
xAOD::Event::m_outputObjects
Object_t m_outputObjects
Collection of all the managed output object.
Definition: Event.h:313
xAOD::Event::connectObject
virtual StatusCode connectObject(const std::string &key, bool silent)=0
Function setting up access to a particular object.
xAOD::Event::contains
bool contains(const std::string &key)
Function checking if an object is available from the store.
xAOD::TStore
A relatively simple transient store for objects created in analysis.
Definition: TStore.h:45
python.trfDecorators.silent
def silent(func)
Redirect stdout/err to /dev/null Useful wrapper to get rid of ROOT verbosity...
Definition: trfDecorators.py:24
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
re
const boost::regex re(r_e)
xAOD::TVirtualManager::object
virtual const void * object() const =0
Function getting a const pointer to the object being handled.
createCoolChannelIdFile.newname
newname
Definition: createCoolChannelIdFile.py:105
xAOD::Details::IObjectManager
Manager for EDM objects created by ROOT.
Definition: IObjectManager.h:20
TActiveStore.h
xAOD::Event::transientContains
bool transientContains(const std::string &key) const
Function checking if an object is already in memory.
TStore.h
xAOD::EventFormat_v1::exists
bool exists(const std::string &key) const
Check if a description exists about a given branch.
Definition: EventFormat_v1.cxx:65
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37