ATLAS Offline Software
Loading...
Searching...
No Matches
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).
10
11// Project include(s).
14
15// ROOT include(s).
16#include <TFile.h>
17#include <TKey.h>
18
19// System include(s).
20#include <regex>
21#include <string>
22#include <vector>
23
24// Set up message printing functions for the static function(s).
25ANA_MSG_SOURCE(xAODEvent, "xAOD::Event")
26
27namespace xAOD {
28
29// Initialise some static data.
31const char* const Event::EVENT_RNTUPLE_NAME = "EventData";
33const char* const Event::EVENT_TREE_NAME = "CollectionTree";
35const char* const Event::METADATA_OBJECT_NAME = "MetaData";
36
39std::unique_ptr<Event> Event::createAndReadFrom(TFile& inFile) {
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}
65
75StatusCode Event::copy(const std::string& pattern) {
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 }
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}
188
201void* Event::getOutputObject(const std::string& key, const std::type_info& ti,
202 bool metadata) const {
203
204 // Select which object container to use:
205 const Object_t& objects = (metadata ? m_outputMetaObjects : m_outputObjects);
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:
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}
252
265const void* Event::getInputObject(const std::string& key,
266 const std::type_info& ti, bool silent,
267 bool metadata) {
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:
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}
359
369::Bool_t Event::contains(const std::string& key, const std::type_info& ti,
370 ::Bool_t metadata) {
371
372 static const bool SILENT = true;
373 return ((getOutputObject(key, ti, metadata) != nullptr) ||
374 (getInputObject(key, ti, SILENT, metadata) != nullptr));
375}
376
388::Bool_t Event::transientContains(const std::string& key,
389 const std::type_info& ti,
390 ::Bool_t metadata) const {
391
392 return (getOutputObject(key, ti, metadata) != nullptr);
393}
394
395} // namespace xAOD
const boost::regex re(r_e)
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
macros for messaging and checking status codes
#define ANA_MSG_ERROR(xmsg)
Macro printing error messages.
#define ANA_MSG_SOURCE(NAME, TITLE)
the source code part of ANA_MSG_SOURCE
static Double_t sc
Manager for EDM objects created by ROOT.
const THolder * holder() const
Accessor to the Holder object.
virtual bool hasInput() const =0
Check if an input file is connected to the object.
EventFormat m_inputEventFormat
Format of the current input file.
Definition Event.h:342
virtual StatusCode recordAux(TVirtualManager &mgr, const std::string &key, bool metadata)=0
Record an auxiliary store into a connected output file.
static std::unique_ptr< Event > createAndReadFrom(TFile &file)
static method to create an Event object and readFrom a file, given by a TFile.
Definition EventIO.cxx:39
bool contains(const std::string &key)
Function checking if an object is available from the store.
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.
Object_t m_inputObjects
Collection of all the managed input objects.
Definition Event.h:329
static const char *const EVENT_TREE_NAME
Default name of the event TTree.
Definition Event.h:76
StatusCode copy(const std::string &pattern=".*")
Copy an object directly from the input to the output.
Definition EventIO.cxx:75
std::unordered_map< std::string, std::unique_ptr< TVirtualManager > > Object_t
Definition of the internal data structure type.
Definition Event.h:325
void * getOutputObject(SG::sgkey_t key, const std::type_info &ti) override
Function for retrieving an output object in a non-template way.
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.
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.
static const char *const EVENT_RNTUPLE_NAME
Name of the event RNTuple.
Definition Event.h:77
std::unordered_map< std::string, std::string > m_nameRemapping
Container name re-mapping rules.
Definition Event.h:353
Object_t m_inputMetaObjects
Collection of all the managed input meta-objects.
Definition Event.h:337
Object_t m_outputObjects
Collection of all the managed output object.
Definition Event.h:334
Object_t m_outputMetaObjects
Collection of all the managed output meta-objects.
Definition Event.h:339
static TStore * store()
Access the currently active TStore object.
const ::TClass * getClass() const
Definition THolder.cxx:402
A relatively simple transient store for objects created in analysis.
Definition TStore.h:45
virtual const void * object() const =0
Function getting a const pointer to the object being handled.
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...
ICaloAffectedTool is abstract interface for tools checking if 4 mom is in calo affected region.
Convert a type_info to a normalized string representation (matching the names used in the root dictio...