ATLAS Offline Software
Loading...
Searching...
No Matches
EventFormatStreamHelperTool.cxx
Go to the documentation of this file.
1/* Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration */
2
3// Local include(s).
5
6// system includes
7#include <iterator>
8#include <memory>
9#include <regex>
10#include <utility>
11
12#include "GaudiKernel/Algorithm.h"
14
15// EDM include(s).
17
18namespace xAODMaker {
19
22 // Retrieve all needed components.
23 ATH_CHECK(m_metadataStore.retrieve());
24
25 // Compile the configured patterns once, so that the event loop doesn't
26 // have to do it for every object of every event.
27 m_ignoreKeyRegexes.reserve(m_ignoreKeys.size());
28 for (const std::string& pattern : m_ignoreKeys.value())
29 m_ignoreKeyRegexes.emplace_back(pattern, std::regex::optimize);
30 m_typeNameRegexes.reserve(m_typeNames.size());
31 for (const std::string& pattern : m_typeNames.value())
32 m_typeNameRegexes.emplace_back(pattern, std::regex::optimize);
33
34 if (m_dataHeaderKey.empty()) {
35 // find out name of stream we are working for
36 const Gaudi::Algorithm *parentAlg =
37 dynamic_cast< const Gaudi::Algorithm* >(parent());
38 if (parentAlg) m_dataHeaderKey = parentAlg->name();
39 }
40
41 // Return gracefully
42 return StatusCode::SUCCESS;
43 }
44
45StatusCode
47 // Notify the event format service that it should collect the metadata
48 // that it needs.
50 ATH_MSG_VERBOSE("Triggered metadata collection on: " << m_key.value());
51
52 // Return gracefully.
53 return StatusCode::SUCCESS;
54 }
55
56StatusCode
58 // Get the EventFormat object
59 xAOD::EventFormat * event_format =
60 m_metadataStore->tryRetrieve< xAOD::EventFormat >(m_key.value());
61
62 if (!event_format) {
63 auto p_event_format = std::make_unique< xAOD::EventFormat >();
64 event_format = p_event_format.get();
65 ATH_CHECK(m_metadataStore->record(std::move(p_event_format), m_key));
66 ATH_MSG_VERBOSE("Created new xAOD::EventFormat: " << m_key.value());
67 } else {
68 ATH_MSG_VERBOSE("Use existing xAOD::EventFormat: " << m_key.value());
69 }
70
71 // Grab output stream data header
73 if (!dataHeader.isValid()) {
74 // DataHeader won't exist if this event was rejected.
75 return StatusCode::SUCCESS;
76 }
77
78 // Loop over objects in output stream
79 for (const DataHeaderElement& elem : *dataHeader) {
80 // Caveat: assume branch name that Athena I/O is going to give to
81 // this object is the key name
82 const std::string& key = elem.getKey();
83 const CLID classID = elem.getPrimaryClassID();
84
85 // Skip objects that were set up to be ignored.
86 {
87 bool ignoreObject = false;
88 for (const std::regex& ignorePattern : m_ignoreKeyRegexes) {
89 if (std::regex_match(key, ignorePattern)) {
90 ignoreObject = true;
91 break;
92 }
93 }
94 if (ignoreObject) continue;
95 }
96
97 // Get the type name of this object.
98 std::string typeName;
99 if (m_clidSvc->getTypeInfoNameOfID(classID, typeName).isFailure()) {
100 // Make sure that nobody else is using @c m_warnedCLIDs right now.
101 std::lock_guard< std::mutex > lock(m_warnedCLIDsMutex);
102
103 // Print a warning if this CLID didn't produce a warning yet:
104 if (m_warnedCLIDs.insert(classID).second)
105 ATH_MSG_WARNING("Couldn't get type name for CLID = " << classID );
106
107 continue;
108 }
109
110 // Now that we have the type name, check whether metadata for this type
111 // should be stored.
112 {
113 bool ignoreObject = true;
114 for (const std::regex& typePattern : m_typeNameRegexes) {
115 if (std::regex_match(typeName, typePattern)) {
116 ignoreObject = false;
117 break;
118 }
119 }
120 if (ignoreObject) continue;
121 }
122
123 // Update the metadata object
124 try {
125 const sgkey_t hash =
126 lookUpHash(classID, elem.getClassIDs(), elem.getHashes());
127
128 // Make sure that nobody else is modifying @c m_ef or @c m_spool
129 // right now.
130 std::lock_guard< std::mutex > lock(m_efMutex);
131 // If we already know about this object, then don't bother.
132 if (event_format->exists(key)) continue;
133 static const std::string emptyStr{};
134 // Add the info.
135 event_format->add(xAOD::EventFormatElement(key, typeName, emptyStr, hash));
136
137 // Tell the user what happened.
138 ATH_MSG_VERBOSE("Adding info: key = \"" << key
139 << ", typeName = \"" << typeName << "\""
140 << ", hash = 0x" << std::hex << std::setw(8)
141 << std::setfill('0') << hash);
142 } catch (const std::exception& e) {
143 ATH_MSG_WARNING(e.what());
144 }
145 }
146
147 // Return gracefully.
148 return StatusCode::SUCCESS;
149 }
150
153 CLID primaryClassID,
154 const std::set<CLID>& classIDs,
155 const std::vector<sgkey_t>& hashes) const {
156 // two collections of different size would cause undefined behaviour
157 if (classIDs.size() != hashes.size())
158 throw(std::runtime_error("CLID and hash sets not equal in size"));
159
160 auto it = classIDs.find(primaryClassID);
161
162 // bail if we don't find the primary class ID
163 if (it == classIDs.end())
164 throw(std::range_error("Primary class ID not in list of class IDs"));
165
166 return hashes[std::distance(classIDs.begin(), it)];
167 }
168
169} // namespace xAODMaker
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
This file contains the class definition for the DataHeader and DataHeaderElement classes.
uint32_t CLID
The Class ID type.
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
This class provides a persistent form for the TransientAddress.
Definition DataHeader.h:37
virtual bool isValid() override final
Can the handle be successfully dereferenced?
std::mutex m_efMutex
Mutex for the m_ef variable.
std::vector< std::regex > m_ignoreKeyRegexes
m_ignoreKeys, compiled once in initialize()
Gaudi::Property< std::vector< std::string > > m_typeNames
Type names for which a metadata entry should be added.
StatusCode postExecute() override
Called at the end of execute.
std::vector< std::regex > m_typeNameRegexes
m_typeNames, compiled once in initialize()
ServiceHandle< IAthMetaDataSvc > m_metadataStore
Use the metadata tool interface to store the EventFormat object.
std::set< CLID > m_warnedCLIDs
CLIDs about which warnings have already been printed.
Gaudi::Property< std::vector< std::string > > m_ignoreKeys
StoreGate keys that should be ignored during the metadata collection.
ServiceHandle< IClassIDSvc > m_clidSvc
Connection to the CLID service.
std::mutex m_warnedCLIDsMutex
Mutex for the m_warnedCLIDs variable.
StatusCode initialize() override
Initialise the tool.
sgkey_t lookUpHash(CLID primaryClassID, const std::set< CLID > &classIDs, const std::vector< sgkey_t > &hashes) const
look up hash corresponding to primary class ID
Class describing one branch of the ROOT file.
void add(const EventFormatElement &element, bool updatePersistent=true)
Add the description of a new branch.
bool exists(const std::string &key) const
Check if a description exists about a given branch.
const EventFormatElement * get(const std::string &key, bool quiet=false) const
Get the description of a given branch.
::StatusCode StatusCode
StatusCode definition for legacy code.
EventFormat_v1 EventFormat
Definition of the current event format version.
Definition EventFormat.h:16