ATLAS Offline Software
Loading...
Searching...
No Matches
FileMetaDataCreatorTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5// Local include(s):
7
8// System include(s):
9#include <algorithm>
10#include <functional>
11#include <memory>
12#include <stdexcept>
13#include <sstream>
14#include <utility>
15
16// Athena metadata EDM:
23
24
25namespace xAODMaker {
26
29 ATH_CHECK(m_eventStore.retrieve());
30 ATH_CHECK(m_metaDataSvc.retrieve());
32 ATH_CHECK(m_metaDataStore.retrieve());
33 ATH_CHECK(m_tagInfoMgr.retrieve());
34
35 // If DataHeader key not specified, try determining it
36 if (m_dataHeaderKey.empty()) {
37 const auto *parentAlg = dynamic_cast< const INamedInterface* >(parent());
38 if (parentAlg)
39 m_dataHeaderKey = parentAlg->name();
40 }
41
42 // Listen for the begin of an input file. Act after MetaDataSvc (prio 80) and
43 // TagInfoMgr (prio 50). That means the FileMetaDataTool be called first
44 ServiceHandle< IIncidentSvc > incidentSvc("IncidentSvc", name());
45 ATH_CHECK(incidentSvc.retrieve());
46 incidentSvc->addListener(this, "EndInputFile", 40);
47
48 // Create a fresh object to fill
49 ATH_MSG_DEBUG("Creating new xAOD::FileMetaData object to fill");
50 m_info = std::make_unique< xAOD::FileMetaData >();
51 m_aux = std::make_unique< xAOD::FileMetaDataAuxInfo >();
52 m_info->setStore(m_aux.get());
53
54 // FileMetaData has no content
55 m_filledNonEvent = false;
56 m_filledEvent = false;
57
58 // Return gracefully:
59 return StatusCode::SUCCESS;
60 }
61
62void
63 FileMetaDataCreatorTool::handle(const Incident& inc) {
64 // gracefully ignore unexpected incident types
65 if (inc.type() == "EndInputFile") {
66 // Lock the tool while we work on the FileMetaData
67 std::lock_guard lock(m_toolMutex);
68 if (!updateFromNonEvent().isSuccess())
69 ATH_MSG_DEBUG("Failed to fill FileMetaData with non-event info");
70 }
71 }
72
73StatusCode
75 return StatusCode::SUCCESS;
76 }
77
78StatusCode
80 return StatusCode::SUCCESS;
81 }
82
83StatusCode
85 return StatusCode::SUCCESS;
86 }
87
88StatusCode
90 std::lock_guard lock(m_toolMutex);
91
92 if (!m_filledNonEvent) {
93 ATH_MSG_DEBUG("Not writing empty or incomplete FileMetaData object");
94 return StatusCode::SUCCESS;
95 }
96
97 // Set metadata with content created for given stream
98 for (const std::string& key : m_metaDataSvc->getPerStreamKeysFor(m_key)) {
99 // Remove any existing objects with this key
100 if (!m_metaDataSvc->contains<xAOD::FileMetaData>(key)) {
101 auto info = std::make_unique<xAOD::FileMetaData>();
102 auto aux = std::make_unique<xAOD::FileMetaDataAuxInfo>();
103 info->setStore(aux.get());
104 ATH_CHECK(m_metaDataSvc->record(std::move(info), key));
105 ATH_CHECK(m_metaDataSvc->record(std::move(aux), key + "Aux."));
106 }
107
108 auto* output = m_metaDataSvc->tryRetrieve<xAOD::FileMetaData>(key);
109 if (output) {
110 // save event info that we've already had
111 float orig_mcProcID = -1;
112 std::vector<uint32_t> orig_runNumbers, orig_lumiBlocks;
113 if (!output->value(xAOD::FileMetaData::mcProcID, orig_mcProcID))
114 ATH_MSG_DEBUG("Could not get mcProcID");
115 if (!output->value("runNumbers", orig_runNumbers))
116 ATH_MSG_DEBUG("Could not get runNumbers");
117 if (!output->value("lumiBlocks", orig_lumiBlocks))
118 ATH_MSG_DEBUG("Could not get lumiBlocks");
119
120 // Replace content in store with content created for this stream
121 *output = *m_info;
122 ATH_MSG_DEBUG("FileMetaData payload replaced in store with content created for this stream");
123 if (!m_filledEvent) {
124 // restore original event info if it was not filled for this stream
125 ATH_MSG_DEBUG("Event information was not filled, restoring what we had");
126 if (!output->setValue(xAOD::FileMetaData::mcProcID, orig_mcProcID))
127 ATH_MSG_DEBUG("Could not set " << xAOD::FileMetaData::mcProcID << " to " << orig_mcProcID);
128 if (!output->setValue("runNumbers", orig_runNumbers))
129 ATH_MSG_DEBUG("Could not restore runNumbers");
130 if (!output->setValue("lumiBlocks", orig_lumiBlocks))
131 ATH_MSG_DEBUG("Could not restore lumiBlocks");
132 }
133 } else {
134 ATH_MSG_DEBUG("cannot copy FileMetaData payload to output");
135 }
136 }
137
138 return StatusCode::SUCCESS;
139}
140
141StatusCode
143 return StatusCode::SUCCESS;
144 }
145
146StatusCode
148 // Lock the tool while working with FileMetaData
149 std::lock_guard lock(m_toolMutex);
150
151 // Fill information from TagInfo and Simulation Parameters
152 if (!updateFromNonEvent().isSuccess())
153 ATH_MSG_DEBUG("Failed to fill FileMetaData with non-event info");
154
155 // Sanity check
156 if (!(m_info && m_aux)) {
157 ATH_MSG_DEBUG("No xAOD::FileMetaData object to fill");
158 return StatusCode::SUCCESS;
159 }
160
161 { // MC channel, run and/or lumi block numbers
162 const xAOD::EventInfo* eventInfo = nullptr;
163 StatusCode sc = StatusCode::FAILURE;
164
166 sc = m_eventStore->retrieve(eventInfo, m_eventInfoKey);
167 else if (m_eventStore->contains< xAOD::EventInfo >("Mc" + m_eventInfoKey))
168 sc = m_eventStore->retrieve(eventInfo, "Mc" + m_eventInfoKey);
169
170 if (eventInfo && sc.isSuccess()) {
171 addUniqueValue("runNumbers", eventInfo->runNumber());
172 addUniqueValue("lumiBlocks", eventInfo->lumiBlock());
173 // Return if object has already been filled
174 if (m_filledEvent) return StatusCode::SUCCESS;
175
176 try {
177 ATH_MSG_DEBUG("Retrieved " << m_eventInfoKey);
178
180 const float id = static_cast< float >(eventInfo->mcChannelNumber());
181
182 if (m_info->setValue(type, id))
183 ATH_MSG_DEBUG("setting " << type << " to " << id);
184 else
185 ATH_MSG_DEBUG("error setting " << type << " to " << id);
186 } catch (std::exception&) {
187 // Processing data not generated events
188 ATH_MSG_DEBUG("Failed to set " << xAOD::FileMetaData::mcProcID);
189 }
190 } else {
192 "Failed to retrieve " << m_eventInfoKey << " => cannot set "
194 << ", runNumbers, or lumiBlockNumbers");
195 }
196 }
197
198 m_filledEvent = true;
199
200 return StatusCode::SUCCESS;
201 }
202
203StatusCode
205
206 // Have we already done this?
207 if (m_filledNonEvent) return StatusCode::SUCCESS;
208
209 // Sanity check
210 if (!(m_info && m_aux)) {
211 ATH_MSG_DEBUG("No xAOD::FileMetaData object to fill");
212 return StatusCode::SUCCESS;
213 }
214
216 m_tagInfoMgr->findTag("AtlasRelease"));
217
218 set(xAOD::FileMetaData::amiTag, m_tagInfoMgr->findTag("AMITag"));
219
221
223 m_tagInfoMgr->findTag("IOVDbGlobalTag"));
224
225 set(xAOD::FileMetaData::beamType, m_tagInfoMgr->findTag("beam_type"));
226
227 set(xAOD::FileMetaData::mcCampaign, m_tagInfoMgr->findTag("mc_campaign"));
228
229 set(xAOD::FileMetaData::generatorsInfo, m_tagInfoMgr->findTag("generators"));
230
231 std::string beamEnergy = m_tagInfoMgr->findTag("beam_energy");
232 try {
234 std::stof(beamEnergy));
235 } catch (std::invalid_argument& e) {
236 ATH_MSG_DEBUG("beam energy \"" << beamEnergy << "\" tag could not be converted to float");
237 } catch (std::out_of_range& e) {
238 ATH_MSG_DEBUG("converted beam energy value (\"" << beamEnergy << "\") outside float range");
239 }
240
241 std::string dataYear = m_tagInfoMgr->findTag("data_year");
242 if (!dataYear.empty()) {
243 try {
245 static_cast<uint32_t>(std::stoul(dataYear)));
246 } catch (std::invalid_argument& e) {
247 ATH_MSG_DEBUG("data year \"" << dataYear << "\" tag could not be converted to unsigned long");
248 } catch (std::out_of_range& e) {
249 ATH_MSG_DEBUG("converted data year value (\"" << dataYear << "\") outside unsigned long range");
250 }
251 }
252
253 // Read simulation parameters
254 const IOVMetaDataContainer * simInfo = nullptr;
255 StatusCode sc = StatusCode::FAILURE;
257 sc = m_inputMetaDataStore->retrieve(simInfo, m_simInfoKey);
258 } else if (m_metaDataStore->contains< IOVMetaDataContainer >(m_simInfoKey)) {
259 sc = m_metaDataStore->retrieve(simInfo, m_simInfoKey);
260 }
261 const coral::AttributeList * attrList = nullptr;
262 if (simInfo && sc.isSuccess()) {
263 for (const CondAttrListCollection* payload : *simInfo->payloadContainer()) {
264 for (const auto& itr : *payload) {
265 attrList = &(itr.second);
266 }
267 }
268 }
269
270 bool simFlavourSet{};
271 bool isDataOverlaySet{};
272 if (attrList) {
273 { // set simulation flavor
274 std::string key = "SimulationFlavour";
275 if (attrList->exists(key)) {
276 std::string value = (*attrList)[key].data< std::string >();
277
278 // remap simulation flavor "default" to "FullSim"
279 if (value == "default")
280 value = "FullSim";
281
283 simFlavourSet = true;
284 }
285 }
286
287 { // set whether this is overlay
288 std::string key = "IsDataOverlay";
289 if (attrList->exists(key)) {
290 std::string attr = (*attrList)[key].data< std::string >();
291 set(xAOD::FileMetaData::isDataOverlay, attr == "True");
292 isDataOverlaySet = true;
293 }
294 }
295 }
296
297 if (!simFlavourSet || !isDataOverlaySet) {
299 "Failed to set "
302 << ". Trying to get them from input metadata store." );
303
304 for (const std::string& key : m_metaDataSvc->getPerStreamKeysFor(m_key)) {
305 const xAOD::FileMetaData* input = nullptr;
306 input = m_inputMetaDataStore->tryConstRetrieve< xAOD::FileMetaData >(key);
307 if (input) {
308 if (!simFlavourSet) {
309 std::string orig_simFlavour = "none";
310 if (!input->value(xAOD::FileMetaData::simFlavour, orig_simFlavour)) {
312 "Could not get xAOD::FileMetaData::simFlavour "
313 "from input metadata "
314 "store");
315 } else {
316 ATH_MSG_DEBUG("Retrieved from input metadata store: "
318 << orig_simFlavour);
319 set(xAOD::FileMetaData::simFlavour, orig_simFlavour);
320 }
321 }
322
323 if (!isDataOverlaySet) {
324 bool orig_isDataOverlay = false;
325 if (!input->value(xAOD::FileMetaData::isDataOverlay, orig_isDataOverlay)) {
327 "Could not get "
328 "xAOD::FileMetaData::isDataOverlay from input "
329 "metadata store");
330 } else {
331 ATH_MSG_DEBUG("Retrieved from input metadata store: "
333 << orig_isDataOverlay);
334 set(xAOD::FileMetaData::isDataOverlay, orig_isDataOverlay);
335 }
336 }
337 }
338 }
339 }
340
341 if (m_filledNonEvent) return StatusCode::SUCCESS;
342
343 { // get dataType
345 try {
346 if (m_info->setValue(type, m_dataHeaderKey.value()))
347 ATH_MSG_DEBUG("set " << type << " to " << m_dataHeaderKey.value());
348 else
349 ATH_MSG_DEBUG("error setting " << type << " to " << m_dataHeaderKey.value());
350 } catch (std::exception&) {
351 // This is unexpected
352 ATH_MSG_DEBUG("Failed to set " << xAOD::FileMetaData::dataType);
353 }
354 }
355
356 // FileMetaData object has been filled with non event info
357 m_filledNonEvent = true;
358
359 return StatusCode::SUCCESS;
360 }
361
362void
365 bool value) {
366 try {
367 if (m_info->setValue(key, value))
368 ATH_MSG_DEBUG("setting " << key << " to " << value);
369 else
370 ATH_MSG_DEBUG("error setting " << key << " to " << std::boolalpha << value
371 << std::noboolalpha);
372 } catch (std::exception&) {
373 // Processing data not generated events
374 ATH_MSG_DEBUG("Failed to set " << key);
375 }
376 }
377
378void
381 uint32_t value) {
382 try {
383 if (m_info->setValue(key, value))
384 ATH_MSG_DEBUG("setting " << key << " to " << value);
385 else
386 ATH_MSG_DEBUG("error setting " << key << " to " << value);
387 } catch (std::exception&) {
388 // Processing data not generated events
389 ATH_MSG_DEBUG("Failed to set " << key);
390 }
391 }
392
393void
396 float value) {
397 try {
398 if (m_info->setValue(key, value))
399 ATH_MSG_DEBUG("setting " << key << " to " << value);
400 else
401 ATH_MSG_DEBUG("error setting " << key << " to " << value);
402 } catch (std::exception&) {
403 // Processing data not generated events
404 ATH_MSG_DEBUG("Failed to set " << key);
405 }
406 }
407
408void
411 const std::string& value) {
412 if (value.empty()) return;
413 try {
414 if (m_info->setValue(key, value))
415 ATH_MSG_DEBUG("setting " << key << " to " << value);
416 else
417 ATH_MSG_DEBUG("error setting " << key << " to " << value);
418 } catch (std::exception&) {
419 // Processing data not generated events
420 ATH_MSG_DEBUG("Failed to set " << key);
421 }
422 }
423
425 const std::string& type, uint32_t value) {
426 try {
427 std::vector<uint32_t> list;
428 if (m_info->value(type, list)) {
429 ATH_MSG_DEBUG("retrieved existing list of " << type);
430 } else {
431 ATH_MSG_DEBUG("adding new list for " << type);
432 }
433 // we want a sorted list of unique values (without using std::set)
434 std::sort(list.begin(), list.end());
435 auto it = std::lower_bound(list.begin(), list.end(), value);
436 if (it == list.end() || (*it) != value) {
437 list.insert(it, value);
438 ATH_MSG_DEBUG("added " << value << " to list of " << type);
439 }
440 if (!m_info->setValue(type, list)) {
441 ATH_MSG_WARNING("error updating list for " + type);
442 }
443 } catch (std::exception& e) {
444 // Processing generated events not data
445 ATH_MSG_WARNING(e.what());
446 }
447}
448
449} // namespace xAODMaker
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
This file defines the class for a collection of AttributeLists where each one is associated with a ch...
static Double_t sc
Handle class for reading from StoreGate.
Handle class for recording to StoreGate.
This class is a collection of AttributeLists where each one is associated with a channel number.
This class is a container for conditions data.
const IOVPayloadContainer * payloadContainer() const
Access to payload container.
std::unique_ptr< xAOD::FileMetaData > m_info
The object created for this output stream.
ServiceHandle< ITagInfoMgr > m_tagInfoMgr
Access to TagInfoMgr for tags.
void addUniqueValue(const std::string &type, uint32_t value)
helper function to add values to lists
StatusCode preStream() override
Called before actually streaming objects.
bool m_filledEvent
FileMetaData has been filled with event information.
StatusCode finalize() override
Called at the end of AthenaOutputStream::finalize() (via release()).
ServiceHandle< IAthMetaDataSvc > m_metaDataSvc
Use MetaDataSvc store interface to support output in EventService.
ServiceHandle< StoreGateSvc > m_metaDataStore
void set(const xAOD::FileMetaData::MetaDataType, bool)
helper method to update FileMetaDataProperty with some checks
StatusCode updateFromNonEvent()
Update from Simulation Parameters and TagInfo.
Gaudi::Property< std::string > m_simInfoKey
Read simulation parameters.
void handle(const Incident &) override
Handle BeginInputFile incident after MetaDataSvc.
ServiceHandle< StoreGateSvc > m_eventStore
DataHeader is produced by another OutputTool, so need StoreGateSvc.
ServiceHandle< StoreGateSvc > m_inputMetaDataStore
Access to the input metadata store.
Gaudi::Property< std::string > m_key
output key for produced xAOD::FileMetaData in MetaDataStore
bool m_filledNonEvent
FileMetaData has been filled with non-event info.
std::mutex m_toolMutex
creation of FileMetaData should happen on a single thread
Gaudi::Property< std::string > m_dataHeaderKey
Key for DataHeader in StoreGateSvc.
Gaudi::Property< std::string > m_eventInfoKey
Key for xAOD::EventInfo to update MC channel number.
StatusCode postExecute() override
Fill the FileMetaData with event information.
StatusCode preFinalize() override
Write the FileMetaData object to the MetaDataStore via the MetaDataSvc.
StatusCode preExecute() override
Called at the beginning of AthenaOutputStream::execute().
std::unique_ptr< xAOD::FileMetaDataAuxInfo > m_aux
The auxiliary containing the created object.
uint32_t lumiBlock() const
The current event's luminosity block number.
uint32_t runNumber() const
The current event's run number.
uint32_t mcChannelNumber() const
The MC generator's channel number.
MetaDataType
Pre-defined metadata value types.
@ beamEnergy
Beam energy [float].
@ mcProcID
Same as mc_channel_number [float].
@ conditionsTag
Conditions version used for simulation/reconstruction [string].
@ dataType
Data type that's in the file [string].
@ generatorsInfo
Generators information [string].
@ mcCampaign
MC campaign [string].
@ amiTag
AMI tag used to process the file the last time [string].
@ dataYear
Data year [uint32_t].
@ beamType
Beam type [string].
@ simFlavour
Fast or Full sim [string].
@ productionRelease
Release that was used to make the file [string].
@ isDataOverlay
Used data overlay for backgrounds [bool].
@ geometryVersion
Geometry version [string].
::StatusCode StatusCode
StatusCode definition for legacy code.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
EventInfo_v1 EventInfo
Definition of the latest event info version.
FileMetaData_v1 FileMetaData
Declare the latest version of the class.