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 m_hasInputFile = true;
69 if (!updateFromNonEvent().isSuccess())
70 ATH_MSG_DEBUG("Failed to fill FileMetaData with non-event info");
71 }
72 }
73
74StatusCode
76 return StatusCode::SUCCESS;
77 }
78
79StatusCode
81 return StatusCode::SUCCESS;
82 }
83
84StatusCode
86 return StatusCode::SUCCESS;
87 }
88
89StatusCode
91 std::lock_guard lock(m_toolMutex);
92
93 if (!m_filledNonEvent) {
94 ATH_MSG_DEBUG("Not writing empty or incomplete FileMetaData object");
95 return StatusCode::SUCCESS;
96 }
97
98 // Set metadata with content created for given stream
99 for (const std::string& key : m_metaDataSvc->getPerStreamKeysFor(m_key)) {
100 // Remove any existing objects with this key
101 if (!m_metaDataSvc->contains<xAOD::FileMetaData>(key)) {
102 auto info = std::make_unique<xAOD::FileMetaData>();
103 auto aux = std::make_unique<xAOD::FileMetaDataAuxInfo>();
104 info->setStore(aux.get());
105 ATH_CHECK(m_metaDataSvc->record(std::move(info), key));
106 ATH_CHECK(m_metaDataSvc->record(std::move(aux), key + "Aux."));
107 }
108
109 auto* output = m_metaDataSvc->tryRetrieve<xAOD::FileMetaData>(key);
110 if (output) {
111 // save event info that we've already had
112 float orig_mcProcID = -1;
113 std::vector<uint32_t> orig_runNumbers, orig_lumiBlocks;
114 if (!output->value(xAOD::FileMetaData::mcProcID, orig_mcProcID))
115 ATH_MSG_DEBUG("Could not get mcProcID");
116 if (!output->value("runNumbers", orig_runNumbers))
117 ATH_MSG_DEBUG("Could not get runNumbers");
118 if (!output->value("lumiBlocks", orig_lumiBlocks))
119 ATH_MSG_DEBUG("Could not get lumiBlocks");
120
121 // Replace content in store with content created for this stream
122 *output = *m_info;
123 ATH_MSG_DEBUG("FileMetaData payload replaced in store with content created for this stream");
124 if (!m_filledEvent) {
125 // restore original event info if it was not filled for this stream
126 ATH_MSG_DEBUG("Event information was not filled, restoring what we had");
127 if (!output->setValue(xAOD::FileMetaData::mcProcID, orig_mcProcID))
128 ATH_MSG_DEBUG("Could not set " << xAOD::FileMetaData::mcProcID << " to " << orig_mcProcID);
129 if (!output->setValue("runNumbers", orig_runNumbers))
130 ATH_MSG_DEBUG("Could not restore runNumbers");
131 if (!output->setValue("lumiBlocks", orig_lumiBlocks))
132 ATH_MSG_DEBUG("Could not restore lumiBlocks");
133 }
134 } else {
135 ATH_MSG_DEBUG("cannot copy FileMetaData payload to output");
136 }
137 }
138
139 return StatusCode::SUCCESS;
140}
141
142StatusCode
144 return StatusCode::SUCCESS;
145 }
146
147StatusCode
149 // Lock the tool while working with FileMetaData
150 std::lock_guard lock(m_toolMutex);
151
152 // Fill information from TagInfo and Simulation Parameters
153 if (!updateFromNonEvent().isSuccess())
154 ATH_MSG_DEBUG("Failed to fill FileMetaData with non-event info");
155
156 // Sanity check
157 if (!(m_info && m_aux)) {
158 ATH_MSG_DEBUG("No xAOD::FileMetaData object to fill");
159 return StatusCode::SUCCESS;
160 }
161
162 { // MC channel, run and/or lumi block numbers
163 const xAOD::EventInfo* eventInfo = nullptr;
164 StatusCode sc = StatusCode::FAILURE;
165
167 sc = m_eventStore->retrieve(eventInfo, m_eventInfoKey);
168 else if (m_eventStore->contains< xAOD::EventInfo >("Mc" + m_eventInfoKey))
169 sc = m_eventStore->retrieve(eventInfo, "Mc" + m_eventInfoKey);
170
171 if (eventInfo && sc.isSuccess()) {
172 addUniqueValue("runNumbers", eventInfo->runNumber());
173 addUniqueValue("lumiBlocks", eventInfo->lumiBlock());
174 // Return if object has already been filled
175 if (m_filledEvent) return StatusCode::SUCCESS;
176
177 try {
178 ATH_MSG_DEBUG("Retrieved " << m_eventInfoKey);
179
181 const float id = static_cast< float >(eventInfo->mcChannelNumber());
182
183 if (m_info->setValue(type, id))
184 ATH_MSG_DEBUG("setting " << type << " to " << id);
185 else
186 ATH_MSG_DEBUG("error setting " << type << " to " << id);
187 } catch (std::exception&) {
188 // Processing data not generated events
189 ATH_MSG_DEBUG("Failed to set " << xAOD::FileMetaData::mcProcID);
190 }
191 } else {
193 "Failed to retrieve " << m_eventInfoKey << " => cannot set "
195 << ", runNumbers, or lumiBlockNumbers");
196 }
197 }
198
199 m_filledEvent = true;
200
201 return StatusCode::SUCCESS;
202 }
203
204StatusCode
206
207 // Have we already done this?
208 if (m_filledNonEvent) return StatusCode::SUCCESS;
209
210 // Sanity check
211 if (!(m_info && m_aux)) {
212 ATH_MSG_DEBUG("No xAOD::FileMetaData object to fill");
213 return StatusCode::SUCCESS;
214 }
215
216 if (m_hasInputFile && m_tagInfoMgr->getInputTags().empty()) {
217 ATH_MSG_DEBUG("Deferring non-event fill due to eventless-input");
218 return StatusCode::SUCCESS;
219 }
220
222 m_tagInfoMgr->findTag("AtlasRelease"));
223
224 set(xAOD::FileMetaData::amiTag, m_tagInfoMgr->findTag("AMITag"));
225
227
229 m_tagInfoMgr->findTag("IOVDbGlobalTag"));
230
231 set(xAOD::FileMetaData::beamType, m_tagInfoMgr->findTag("beam_type"));
232
233 set(xAOD::FileMetaData::mcCampaign, m_tagInfoMgr->findTag("mc_campaign"));
234
235 set(xAOD::FileMetaData::generatorsInfo, m_tagInfoMgr->findTag("generators"));
236
237 std::string beamEnergy = m_tagInfoMgr->findTag("beam_energy");
238 try {
240 std::stof(beamEnergy));
241 } catch (std::invalid_argument& e) {
242 ATH_MSG_DEBUG("beam energy \"" << beamEnergy << "\" tag could not be converted to float");
243 } catch (std::out_of_range& e) {
244 ATH_MSG_DEBUG("converted beam energy value (\"" << beamEnergy << "\") outside float range");
245 }
246
247 std::string dataYear = m_tagInfoMgr->findTag("data_year");
248 if (!dataYear.empty()) {
249 try {
251 static_cast<uint32_t>(std::stoul(dataYear)));
252 } catch (std::invalid_argument& e) {
253 ATH_MSG_DEBUG("data year \"" << dataYear << "\" tag could not be converted to unsigned long");
254 } catch (std::out_of_range& e) {
255 ATH_MSG_DEBUG("converted data year value (\"" << dataYear << "\") outside unsigned long range");
256 }
257 }
258
259 // Read simulation parameters
260 const IOVMetaDataContainer * simInfo = nullptr;
261 StatusCode sc = StatusCode::FAILURE;
263 sc = m_inputMetaDataStore->retrieve(simInfo, m_simInfoKey);
264 } else if (m_metaDataStore->contains< IOVMetaDataContainer >(m_simInfoKey)) {
265 sc = m_metaDataStore->retrieve(simInfo, m_simInfoKey);
266 }
267 const coral::AttributeList * attrList = nullptr;
268 if (simInfo && sc.isSuccess()) {
269 for (const CondAttrListCollection* payload : *simInfo->payloadContainer()) {
270 for (const auto& itr : *payload) {
271 attrList = &(itr.second);
272 }
273 }
274 }
275
276 bool simFlavourSet{};
277 bool isDataOverlaySet{};
278 if (attrList) {
279 { // set simulation flavor
280 std::string key = "SimulationFlavour";
281 if (attrList->exists(key)) {
282 std::string value = (*attrList)[key].data< std::string >();
283
284 // remap simulation flavor "default" to "FullSim"
285 if (value == "default")
286 value = "FullSim";
287
289 simFlavourSet = true;
290 }
291 }
292
293 { // set whether this is overlay
294 std::string key = "IsDataOverlay";
295 if (attrList->exists(key)) {
296 std::string attr = (*attrList)[key].data< std::string >();
297 set(xAOD::FileMetaData::isDataOverlay, attr == "True");
298 isDataOverlaySet = true;
299 }
300 }
301 }
302
303 if (!simFlavourSet || !isDataOverlaySet) {
305 "Failed to set "
308 << ". Trying to get them from input metadata store." );
309
310 for (const std::string& key : m_metaDataSvc->getPerStreamKeysFor(m_key)) {
311 const xAOD::FileMetaData* input = nullptr;
312 input = m_inputMetaDataStore->tryConstRetrieve< xAOD::FileMetaData >(key);
313 if (input) {
314 if (!simFlavourSet) {
315 std::string orig_simFlavour = "none";
316 if (!input->value(xAOD::FileMetaData::simFlavour, orig_simFlavour)) {
318 "Could not get xAOD::FileMetaData::simFlavour "
319 "from input metadata "
320 "store");
321 } else {
322 ATH_MSG_DEBUG("Retrieved from input metadata store: "
324 << orig_simFlavour);
325 set(xAOD::FileMetaData::simFlavour, orig_simFlavour);
326 }
327 }
328
329 if (!isDataOverlaySet) {
330 bool orig_isDataOverlay = false;
331 if (!input->value(xAOD::FileMetaData::isDataOverlay, orig_isDataOverlay)) {
333 "Could not get "
334 "xAOD::FileMetaData::isDataOverlay from input "
335 "metadata store");
336 } else {
337 ATH_MSG_DEBUG("Retrieved from input metadata store: "
339 << orig_isDataOverlay);
340 set(xAOD::FileMetaData::isDataOverlay, orig_isDataOverlay);
341 }
342 }
343 }
344 }
345 }
346
347 if (m_filledNonEvent) return StatusCode::SUCCESS;
348
349 { // get dataType
351 try {
352 if (m_info->setValue(type, m_dataHeaderKey.value()))
353 ATH_MSG_DEBUG("set " << type << " to " << m_dataHeaderKey.value());
354 else
355 ATH_MSG_DEBUG("error setting " << type << " to " << m_dataHeaderKey.value());
356 } catch (std::exception&) {
357 // This is unexpected
358 ATH_MSG_DEBUG("Failed to set " << xAOD::FileMetaData::dataType);
359 }
360 }
361
362 // FileMetaData object has been filled with non event info
363 m_filledNonEvent = true;
364
365 return StatusCode::SUCCESS;
366 }
367
368void
371 bool value) {
372 try {
373 if (m_info->setValue(key, value))
374 ATH_MSG_DEBUG("setting " << key << " to " << value);
375 else
376 ATH_MSG_DEBUG("error setting " << key << " to " << std::boolalpha << value
377 << std::noboolalpha);
378 } catch (std::exception&) {
379 // Processing data not generated events
380 ATH_MSG_DEBUG("Failed to set " << key);
381 }
382 }
383
384void
387 uint32_t value) {
388 try {
389 if (m_info->setValue(key, value))
390 ATH_MSG_DEBUG("setting " << key << " to " << value);
391 else
392 ATH_MSG_DEBUG("error setting " << key << " to " << value);
393 } catch (std::exception&) {
394 // Processing data not generated events
395 ATH_MSG_DEBUG("Failed to set " << key);
396 }
397 }
398
399void
402 float value) {
403 try {
404 if (m_info->setValue(key, value))
405 ATH_MSG_DEBUG("setting " << key << " to " << value);
406 else
407 ATH_MSG_DEBUG("error setting " << key << " to " << value);
408 } catch (std::exception&) {
409 // Processing data not generated events
410 ATH_MSG_DEBUG("Failed to set " << key);
411 }
412 }
413
414void
417 const std::string& value) {
418 if (value.empty()) return;
419 try {
420 if (m_info->setValue(key, value))
421 ATH_MSG_DEBUG("setting " << key << " to " << value);
422 else
423 ATH_MSG_DEBUG("error setting " << key << " to " << value);
424 } catch (std::exception&) {
425 // Processing data not generated events
426 ATH_MSG_DEBUG("Failed to set " << key);
427 }
428 }
429
431 const std::string& type, uint32_t value) {
432 try {
433 std::vector<uint32_t> list;
434 if (m_info->value(type, list)) {
435 ATH_MSG_DEBUG("retrieved existing list of " << type);
436 } else {
437 ATH_MSG_DEBUG("adding new list for " << type);
438 }
439 // we want a sorted list of unique values (without using std::set)
440 std::sort(list.begin(), list.end());
441 auto it = std::lower_bound(list.begin(), list.end(), value);
442 if (it == list.end() || (*it) != value) {
443 list.insert(it, value);
444 ATH_MSG_DEBUG("added " << value << " to list of " << type);
445 }
446 if (!m_info->setValue(type, list)) {
447 ATH_MSG_WARNING("error updating list for " + type);
448 }
449 } catch (std::exception& e) {
450 // Processing generated events not data
451 ATH_MSG_WARNING(e.what());
452 }
453}
454
455} // 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...
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
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.
bool m_hasInputFile
Input file incident check.
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.