ATLAS Offline Software
Loading...
Searching...
No Matches
IOVDbMetaDataTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
15
16#include "IOVDbMetaDataTool.h"
17
18#include "GaudiKernel/IIncidentSvc.h"
19#include "GaudiKernel/FileIncident.h"
20#include "GaudiKernel/EventIDBase.h"
21#include "GaudiKernel/EventIDRange.h"
22
32#include "CoralBase/AttributeListSpecification.h"
33#include "nlohmann/json.hpp"
34
35
37 const std::string& name,
38 const IInterface* parent)
39 : base_class(type, name, parent)
40 , m_metaDataStore ("StoreGateSvc/MetaDataStore", name)
41 , m_inputStore ("StoreGateSvc/InputMetaDataStore", name)
42 , m_condStore ("StoreGateSvc/ConditionStore", name)
43 , m_overrideRunNumber(false)
49 , m_modifyFolders(false)
50{
51}
52
53//--------------------------------------------------------------------------
56
57
58//--------------------------------------------------------------------------
59
61{
62 ATH_MSG_DEBUG("in initialize()");
63
64 // Set to be listener for FirstInputFile
65 ServiceHandle<IIncidentSvc> incSvc("IncidentSvc", this->name());
66 ATH_CHECK(incSvc.retrieve());
67 incSvc->addListener(this, "FirstInputFile", 60); // pri has to be < 100 to be after MetaDataSvc.
68
69 // locate the meta data stores
70 ATH_CHECK(m_metaDataStore.retrieve());
71 ATH_CHECK(m_inputStore.retrieve());
72
73 // Check whether folders need to be modified
74 m_modifyFolders = (m_foldersToBeModified.value().size()>0);
75 ATH_MSG_DEBUG("initialize(): " << (m_modifyFolders ? "" : "No ") << "need to modify folders");
76
77 // Process direct payloads if configured
78 if (!m_payloads.value().empty()) {
79 // Group by folder: parse "folder:key" format from flat map
80 std::map<std::string, std::map<std::string, std::string>> folderPayloads;
81
82 for (const auto& [key, value] : m_payloads.value()) {
83 // Split key on ':' to get folder and parameter name
84 size_t colonPos = key.find(':');
85 if (colonPos == std::string::npos) {
86 ATH_MSG_ERROR("Invalid payload key format: " << key << " (expected 'folder:key')");
87 return StatusCode::FAILURE;
88 }
89
90 std::string folderName = key.substr(0, colonPos);
91 std::string paramName = key.substr(colonPos + 1);
92 folderPayloads[folderName][paramName] = value;
93 }
94
95 ATH_MSG_DEBUG("Processing " << folderPayloads.size() << " folder(s) for direct payload registration");
96
97 for (const auto& [folderName, parameters] : folderPayloads) {
98 // Extract beginRun and endRun from parameters
99 if (!parameters.contains("beginRun") || !parameters.contains("endRun")) {
100 ATH_MSG_ERROR("Payload for folder " << folderName << " missing beginRun or endRun");
101 return StatusCode::FAILURE;
102 }
103
104 unsigned int beginRun = std::stoul(parameters.at("beginRun"));
105 unsigned int endRun = std::stoul(parameters.at("endRun"));
106
107 // Create filtered parameters map without beginRun/endRun
108 std::map<std::string, std::string> filteredParams;
109 std::ranges::copy_if(parameters, std::inserter(filteredParams, filteredParams.end()),
110 [](const auto& p) { return p.first != "beginRun" && p.first != "endRun"; });
111
112 ATH_MSG_DEBUG("Registering folder " << folderName << " with " << filteredParams.size()
113 << " parameters, IOV [" << beginRun << ", " << endRun << "]");
114
115 ATH_CHECK(registerFolder(folderName));
116
117 // Build payload for MetaDataStore
118 // Note: AttributeListSpecification has protected destructor, must use new
119 // The AttributeList constructor with 'true' takes ownership and will call release()
120 coral::AttributeListSpecification* spec = new coral::AttributeListSpecification();
121 for (const auto& [key, value] : filteredParams) {
122 spec->extend(key, "string");
123 }
124
125 coral::AttributeList attrList(*spec, true);
126 for (const auto& [key, value] : filteredParams) {
127 attrList[key].setValue(value);
128 }
129
130 auto payload = std::make_unique<CondAttrListCollection>(true);
131 payload->addNewStart(IOVTime(beginRun, 0));
132 payload->addNewStop(IOVTime(endRun, IOVTime::MAXEVENT));
133 payload->add(0, attrList);
134
135 ATH_MSG_DEBUG("Created payload with IOV [" << beginRun << ", " << endRun << "]");
136
137 // Add to MetaDataStore
138 ATH_CHECK(addPayload(folderName, payload.release()));
139 }
140
141 // Note: ConditionStore population is NOT done here because during initialize()
142 // there is no valid EventContext, which is required for CondCont::insert().
143 // Instead, use MetaDataToCondAlg (configured via MetaDataToCondAlgCfg) to populate
144 // ConditionStore during event processing when a valid EventContext is available.
145 }
146
147 return(StatusCode::SUCCESS);
148}
149
150//--------------------------------------------------------------------------
151
152StatusCode
154{
155 return StatusCode::SUCCESS;
156}
157
158//--------------------------------------------------------------------------
159
160void IOVDbMetaDataTool::handle(const Incident& inc)
161{
162 const FileIncident* fileInc = dynamic_cast<const FileIncident*>(&inc);
163 if(!fileInc) throw std::runtime_error("Unable to get FileName from FirstInputFile incident");
164
165 const std::string fileName = fileInc->fileName();
166 ATH_MSG_DEBUG("handle() " << inc.type() << " for " << fileName);
167
168 // Check if we need to override run number - only needed for simulation
170
171 StatusCode sc = processInputFileMetaData(fileName);
172 if(!sc.isSuccess()) throw std::runtime_error("Could not process input file meta data");
173 m_filesProcessed.insert(std::move(fileName));
174}
175
177{
178 if (!m_filesProcessed.contains(sid)) {
180 m_filesProcessed.insert(sid);
181 }
182 return StatusCode::SUCCESS;
183}
184
186{
187 return StatusCode::SUCCESS;
188}
189
191{
192 // Check if we have folders to serialize to ByteStream metadata
193 if (m_foldersToSerializeToBSMetadata.value().empty()) {
194 ATH_MSG_DEBUG("No folders configured for serialization");
195 return StatusCode::SUCCESS;
196 }
197
198 // Collect IOV metadata strings first
199 std::vector<std::string> iovMetaStrings;
200 for (const std::string& folderName : m_foldersToSerializeToBSMetadata.value()) {
202 if (!container) {
203 ATH_MSG_WARNING("Could not find IOVMetaDataContainer for folder " << folderName << ", skipping");
204 continue;
205 }
206
207 std::string jsonStr = serializeContainerToJSON(container);
208 if (!jsonStr.empty()) {
209 iovMetaStrings.push_back("IOVMeta." + folderName + "=" + jsonStr);
210 ATH_MSG_DEBUG("Serialized folder " << folderName << " (" << jsonStr.size() << " bytes JSON)");
211 }
212 }
213
214 if (iovMetaStrings.empty()) {
215 ATH_MSG_DEBUG("No IOV metadata serialized");
216 return StatusCode::SUCCESS;
217 }
218
219 // Store the IOV metadata strings in MetaDataStore for ByteStreamCnvSvc to retrieve
220 // Check if the object already exists and update it, or create a new one
221 if (m_metaDataStore->contains<std::vector<std::string>>("IOVMetaDataStrings")) {
222 // Retrieve existing and append
223 std::vector<std::string>* existingStrings = nullptr;
224 ATH_CHECK(m_metaDataStore->retrieve(existingStrings, "IOVMetaDataStrings"));
225 existingStrings->insert(existingStrings->end(), iovMetaStrings.begin(), iovMetaStrings.end());
226 ATH_MSG_DEBUG("Appended " << iovMetaStrings.size() << " IOV metadata strings to existing collection");
227 } else {
228 // Create new
229 auto iovMetaData = std::make_unique<std::vector<std::string>>(std::move(iovMetaStrings));
230 ATH_CHECK(m_metaDataStore->record(std::move(iovMetaData), "IOVMetaDataStrings"));
231 ATH_MSG_DEBUG("Stored " << iovMetaStrings.size() << " IOV metadata strings in MetaDataStore");
232 }
233
234 return StatusCode::SUCCESS;
235}
236
238{
239 return StatusCode::SUCCESS;
240}
241
242//--------------------------------------------------------------------------
243
244void
246{
247 ATH_MSG_DEBUG("begin checkOverrideRunNumber");
248
249 // Check if override run numbers have been set by properties or by
250 // the EventSelector
251
252 if (m_minMaxRunNumbers.value().size() > 0) {
255 if (m_minMaxRunNumbers.value().size() > 1) m_maxRunNumber = m_minMaxRunNumbers.value()[1];
257
259
260 ATH_MSG_INFO("checkOverrideRunNumber: overriding IOV for range - min: " << m_minRunNumber
261 << " max: " << m_maxRunNumber);
262 return;
263 }
264
265 ATH_MSG_DEBUG("checkOverrideRunNumber: check if tag is set in jobOpts");
266
267 // Get name of event selector from the application manager to
268 // make sure we get the one for MC signal events
269 SmartIF<IProperty> appMgr{serviceLocator()->service("ApplicationMgr")};
270 if (!appMgr) {
271 ATH_MSG_ERROR("checkOverrideRunNumber: Cannot get ApplicationMgr ");
272 return;
273 }
274 StringProperty property("EvtSel", "");
275 StatusCode sc = appMgr->getProperty(&property);
276 if (!sc.isSuccess()) {
277 ATH_MSG_ERROR("checkOverrideRunNumber: unable to get EvtSel: found " << property.value());
278 return;
279 }
280 // Get EventSelector for ApplicationMgr
281 const std::string eventSelector = property.value();
282 SmartIF<IProperty> evtSel{serviceLocator()->service(eventSelector)};
283 if (!evtSel) {
284 ATH_MSG_ERROR("checkOverrideRunNumber: Cannot get EventSelector " << eventSelector);
285 return;
286 }
287
288 // Is flag set to override the run number?
289 BooleanProperty overrideRunNumber("OverrideRunNumberFromInput", false);
290 sc = evtSel->getProperty(&overrideRunNumber);
291 if (!sc.isSuccess()) {
292 // Not all EventSelectors have this property, so we must be tolerant
293 ATH_MSG_DEBUG("resetRunNumber: unable to get OverrideRunNumberFromInput property from EventSelector ");
294 return;
295 }
296 m_overrideRunNumber = overrideRunNumber.value();
298 // New run number
299 IntegerProperty runNumber("RunNumber", 0);
300 sc = evtSel->getProperty(&runNumber);
301 if (!sc.isSuccess()) {
302 ATH_MSG_ERROR("checkOverrideRunNumber: unable to get RunNumber from EventSelector: found "
303 << runNumber.value());
304 return;
305 }
306 m_newRunNumber = runNumber.value();
307 // Old run number
308 IntegerProperty oldRunNumber("OldRunNumber", 0);
309 sc = evtSel->getProperty(&oldRunNumber);
310 if (!sc.isSuccess()) {
311 ATH_MSG_ERROR("checkOverrideRunNumber: unable to get OldRunNumber from EventSelector: found "
312 << oldRunNumber.value());
313 return;
314 }
315 m_oldRunNumber = oldRunNumber.value();
316
317 ATH_MSG_DEBUG("checkOverrideRunNumber: Changing old to new run number: " << m_oldRunNumber
318 << " " << m_newRunNumber << " obtained from " << eventSelector);
319 }
320 else ATH_MSG_DEBUG("checkOverrideRunNumber: OverrideRunNumberFromInput not set for " << eventSelector);
321}
322
323//--------------------------------------------------------------------------
324
325StatusCode
326IOVDbMetaDataTool::registerFolder(const std::string& folderName) const
327{
328 // Set the default folder description for a CondAttrListCollection
329 // which will be read back via IOVDbSvc
330 std::string folderDescr = "<timeStamp>run-event</timeStamp><addrHeader><address_header service_type=\"256\" clid=\"1238547719\" /> </addrHeader><typeName>CondAttrListCollection</typeName>" ;
331
332 return registerFolder(folderName, folderDescr);
333}
334
335//--------------------------------------------------------------------------
336
337StatusCode
338IOVDbMetaDataTool::registerFolder(const std::string& folderName,
339 const std::string& folderDescription) const
340{
341 // lock the tool before getMetaDataContainer() call
342 std::scoped_lock guard( m_mutex );
343
344 ATH_MSG_DEBUG("begin registerFolder ");
345
346 if( ! getMetaDataContainer(folderName, folderDescription) ) {
347 ATH_MSG_ERROR("Unable to register folder " << folderName);
348 return(StatusCode::FAILURE);
349 }
350 else {
351 ATH_MSG_DEBUG("IOVMetaDataContainer for folder " << folderName << " has been registered ");
352 }
353
354 return StatusCode::SUCCESS;
355}
356
357//--------------------------------------------------------------------------
358
359StatusCode IOVDbMetaDataTool::addPayload (const std::string& folderName
360 , CondAttrListCollection* payload) const
361{
362 // lock the tool while it is modifying the folder
363 std::scoped_lock guard( m_mutex );
364
365 ATH_MSG_DEBUG("begin addPayload ");
366
367 // Check if the folder has already been found
368 IOVMetaDataContainer* cont = m_metaDataStore->tryRetrieve<IOVMetaDataContainer>(folderName);
369 if(cont) {
370 ATH_MSG_DEBUG("Retrieved IOVMetaDataContainer from MetaDataStore for folder "
371 << folderName);
372 }
373 else {
374 ATH_MSG_ERROR("addPayload: Could not find IOVMetaDataContainer in MetaDataStore for folder "
375 << folderName
376 << ". One must have previously called registerFolder. ");
377 return StatusCode::FAILURE;
378 }
379
380 // Override run number if requested
382 ATH_CHECK( overrideIOV(payload) );
383 }
384
385 // Add payload to container
386 bool success = cont->merge(payload);
387 if (success) {
388 ATH_MSG_DEBUG("Added new payload for folder " << folderName);
389 }
390 else {
391 ATH_MSG_DEBUG("Could not add new payload for folder "
392 << folderName
393 << " (may be duplicate payload).");
394
395 // To Do: the function implicitly assumes ownership on the payload pointer
396 delete payload;
397 payload = nullptr;
398 }
399
400 // Debug printout
401 if(payload && msgLvl(MSG::DEBUG)) {
402 std::ostringstream stream;
403 payload->dump(stream);
404 ATH_MSG_DEBUG(stream.str());
405 }
406
407 return StatusCode::SUCCESS;
408}
409
410//--------------------------------------------------------------------------
411
412StatusCode
413IOVDbMetaDataTool::modifyPayload (const std::string& folderName,
414 CondAttrListCollection*& coll) const
415{
416 // protected by lock in processInputFileMetaData()
417
420 ATH_MSG_DEBUG("begin modifyPayload for folder " << folderName);
421
422 // check if this folder needs to be modified
423 bool modifyAttr = false;
424 std::string attributeName;
425 const std::vector<std::string>& folders = m_foldersToBeModified.value();
426 const std::vector<std::string>& attrs = m_attributesToBeRemoved.value();
427 for (unsigned int i = 0; i < folders.size(); ++i) {
428 if (folderName == folders[i]) {
429 if (attrs.size() > i) {
430 attributeName = attrs[i];
431 modifyAttr = true;
432 ATH_MSG_DEBUG("modifyPayload: remove attribute " << attributeName);
433 break;
434 }
435 }
436 }
437
438 if (!modifyAttr) {
439 ATH_MSG_DEBUG("modifyPayload: folder " << folderName << " OK ");
440 return StatusCode::SUCCESS;
441 }
442
443 bool iovSizeIsZero = coll->iov_size() == 0;
444 IOVRange testIOV = coll->minRange();
445 IOVTime start = testIOV.start();
446 IOVTime stop = testIOV.stop();
447 // Set the IOV
449 if (iovSizeIsZero) {
450 // Only add in overall range if channels do not have
451 // IOVs - otherwise this is automatically calculated
452 coll1->addNewStart(start);
453 coll1->addNewStop (stop);
454 }
455 // Add in channels
456 unsigned int nchans = coll->size();
457 bool hasChanNames = (coll->name_size() == nchans);
458 for (unsigned int ichan = 0; ichan < nchans; ++ichan) {
459 CondAttrListCollection::ChanNum chan = coll->chanNum(ichan);
460 // Now filter out the unwanted attribute
462 const CondAttrListCollection::AttributeList& oldAttrList = coll->attributeList(chan);
463 for (unsigned int iatt = 0; iatt < oldAttrList.size(); ++iatt) {
464 // skip the unwanted attribute
465 if (attributeName == oldAttrList[iatt].specification().name()) {
466 ATH_MSG_DEBUG("modifyPayload: skipping attribute name " << oldAttrList[iatt].specification().name());
467 continue;
468 }
469
470 // copy the rest
471 newAttrList.extend(oldAttrList[iatt].specification().name(),
472 oldAttrList[iatt].specification().type());
473 const coral::Attribute& oldAttr = oldAttrList[iatt];
474 coral::Attribute& newAttr = newAttrList[oldAttrList[iatt].specification().name()];
475 newAttr = oldAttr;
476 // newAttr.setValue(oldAttr.data());
477 ATH_MSG_DEBUG("modifyPayload: copying attr name "
478 << oldAttrList[iatt].specification().name() << " "
479 /*<< newAttr*/);
480 }
481 coll1->add(chan, newAttrList);
482 if (!iovSizeIsZero) coll1->add(chan, coll->iovRange(chan));
483 if(hasChanNames)coll1->add(chan, coll->chanName(chan));
484 ATH_MSG_DEBUG("modifyPayload: copied attribute list for channel " << chan);
485 }
486 delete coll;
487 coll = coll1;
488 if (msgLvl(MSG::DEBUG)) {
489 std::ostringstream stream;
490 coll->dump(stream);
491 ATH_MSG_DEBUG(stream.str());
492 }
493
494 return StatusCode::SUCCESS;
495}
496
497//--------------------------------------------------------------------------
498
500IOVDbMetaDataTool::findMetaDataContainer(const std::string& folderName) const
501{
502 // lock the tool before this call
503 // Return the folder if it is in the meta data store
504 return m_metaDataStore->tryRetrieve<IOVMetaDataContainer>(folderName);
505}
506
507
509IOVDbMetaDataTool::getMetaDataContainer(const std::string& folderName
510 , const std::string& folderDescription) const
511{
512 // protected by locks in addPayload() and registerFolder()
513 ATH_MSG_DEBUG("begin getMetaDataContainer ");
514
515 IOVMetaDataContainer* cont{nullptr};
516 // See if it is in the meta data store
517 if (!m_metaDataStore->contains<IOVMetaDataContainer>(folderName)) {
518 // Container not found, add in new one
519 cont = new IOVMetaDataContainer(folderName, folderDescription);
520 ATH_MSG_DEBUG("No IOVMetaDataContainer in MetaDataStore for folder " << folderName
521 << ". Created a new instance");
522 StatusCode sc = m_metaDataStore->record(cont, folderName);
523 if (!sc.isSuccess()) {
524 ATH_MSG_ERROR("Could not record IOVMetaDataContainer in MetaDataStore for folder " << folderName);
525 delete cont;
526 cont = nullptr;
527 }
528 }
529 else {
530 ATH_MSG_DEBUG("IOVMetaDataContainer already in MetaDataStore for folder " << folderName);
531 StatusCode sc = m_metaDataStore->retrieve(cont, folderName);
532 if (!sc.isSuccess()) {
533 ATH_MSG_ERROR("Could not retrieve IOVMetaDataContainer in MetaDataStore for folder " << folderName);
534 cont = nullptr;
535 }
536 }
537 return cont;
538}
539
540//--------------------------------------------------------------------------
541
542StatusCode IOVDbMetaDataTool::processInputFileMetaData(const std::string& fileName)
543{
544 // lock the tool while it is processing input metadata
545 std::scoped_lock guard( m_mutex );
546
547 ATH_MSG_DEBUG("processInputFileMetaData: file name " << fileName);
548
549 // Retrieve all meta data containers from InputMetaDataStore
552
553 StatusCode sc = m_inputStore->retrieve(cont, contEnd);
554 if (!sc.isSuccess()) {
555 ATH_MSG_DEBUG("processInputFileMetaData: Could not retrieve IOVMetaDataContainer objects from InputMetaDataStore - cannot process input file meta data");
556 return StatusCode::SUCCESS;
557 }
558
559 ATH_MSG_DEBUG("processInputFileMetaData: Retrieved from IOVMetaDataContainer(s) from InputMetaDataStore");
560
561 // For each container, merge its contents into the MetaDataStore
562 unsigned int ncolls = 0;
563 unsigned int ndupColls = 0;
564 for (; cont != contEnd; ++cont) {
565 IOVMetaDataContainer* contMaster = getMetaDataContainer(cont->folderName()
566 , cont->folderDescription());
567
568 // We assume that the folder is the same for all versions, and
569 // now we loop over versions for the payloads
570 std::list<SG::ObjectWithVersion<IOVMetaDataContainer> > allVersions;
571 sc = m_inputStore->retrieveAllVersions(allVersions, cont.key());
572 if (!sc.isSuccess()) {
573 ATH_MSG_ERROR("Could not retrieve all versions for " << cont.key());
574 return sc;
575 }
576
577 for (SG::ObjectWithVersion<IOVMetaDataContainer>& obj : allVersions) {
578 const IOVPayloadContainer* payload = obj.dataObject->payloadContainer();
579
580 ATH_MSG_DEBUG("processInputFileMetaData: New container: payload size " << payload->size() << " version key " << obj.versionedKey);
581
582 // detailed printout before merge
583 if (msgLvl(MSG::VERBOSE)) {
584 const IOVPayloadContainer* payloadMaster = contMaster->payloadContainer();
585 ATH_MSG_VERBOSE("Before merge, payload minRange for folder " << cont->folderName());
586 if (payloadMaster && payloadMaster->size()) {
587 // Loop over AttrColls and print out minRange
588 IOVPayloadContainer::const_iterator itColl = payloadMaster->begin();
589 IOVPayloadContainer::const_iterator itCollEnd = payloadMaster->end();
590 unsigned int iPayload = 0;
591 for (; itColl != itCollEnd; ++itColl, ++iPayload) {
592 ATH_MSG_VERBOSE(iPayload << " " << (*itColl)->minRange() << " "
593 << (*itColl)->size());
594 }
595 }
596 else {
597 ATH_MSG_VERBOSE(" no payloads yet!");
598 }
599 }
600 }
601
602 // Detailed printout
603 if (msgLvl(MSG::DEBUG)) {
604 ATH_MSG_DEBUG("processInputFileMetaData: Current payload before merge " << contMaster->folderName());
606 IOVPayloadContainer::const_iterator itCollEnd1 = contMaster->payloadContainer()->end();
607 std::ostringstream stream;
608 for (; itColl1 != itCollEnd1; ++itColl1) (*itColl1)->dump(stream);
609 ATH_MSG_DEBUG(stream.str());
610 }
611
612 //
613 // Loop over CondAttrListCollections and do merge
614 //
615 for (SG::ObjectWithVersion<IOVMetaDataContainer>& obj : allVersions) {
616 const IOVPayloadContainer* payload = obj.dataObject->payloadContainer();
617 IOVPayloadContainer::const_iterator itColl = payload->begin();
618 IOVPayloadContainer::const_iterator itCollEnd = payload->end();
619 for (; itColl != itCollEnd; ++itColl) {
620
621 // Make a copy of the collection and merge it into
622 // master container in meta data store
624 // Override run number if requested
626 ATH_CHECK( overrideIOV(coll) );
627 }
628
629 // first check if we need to modify the incoming payload
630 if (!modifyPayload (contMaster->folderName(), coll).isSuccess()) {
631 ATH_MSG_ERROR("processInputFileMetaData: Could not modify the payload for folder " << contMaster->folderName());
632 return StatusCode::FAILURE;
633 }
634
635 ATH_MSG_VERBOSE("processInputFileMetaData: merge minRange: " << coll->minRange());
636 if (!contMaster->merge(coll)) {
637 // Did not merge it in - was a duplicate, so we need to delete it
638 delete coll;
639 ++ndupColls;
640 ATH_MSG_VERBOSE(" => not merged ");
641 }
642 else {
643 ++ncolls;
644 ATH_MSG_VERBOSE(" => merged ");
645 }
646
647 }
648 ATH_MSG_DEBUG("processInputFileMetaData: Merged together containers for folder " << cont->folderName() << " ncoll/ndup "
649 << ncolls << " " << ndupColls);
650
651 // Check for consistency after merge
652 const IOVPayloadContainer* payloadMaster = contMaster->payloadContainer();
653 if (payloadMaster && payloadMaster->size()) {
654 // Loop over AttrColls and print out minRange
655 IOVPayloadContainer::const_iterator itColl = payloadMaster->begin();
656 IOVPayloadContainer::const_iterator itCollEnd = payloadMaster->end();
657 IOVTime lastStop;
658 if ((*itColl)->minRange().start().isTimestamp()) lastStop = IOVTime(0);
659 else lastStop = IOVTime(0,0);
660 bool hasError = false;
661 for (; itColl != itCollEnd; ++itColl) {
662 if ((*itColl)->minRange().start() < lastStop) hasError = true;
663 lastStop = (*itColl)->minRange().stop();
664 }
665 if (hasError) {
666 ATH_MSG_ERROR("processInputFileMetaData: error after merge of file meta data. " );
667 ATH_MSG_ERROR("processInputFileMetaData: Filename " << fileName);
668 ATH_MSG_ERROR("processInputFileMetaData: folder " << contMaster->folderName());
669 ATH_MSG_ERROR("processInputFileMetaData: MinRange for meta data folders ");
670 unsigned int iPayload = 0;
671 itColl = payloadMaster->begin();
672 for (; itColl != itCollEnd; ++itColl, ++iPayload) {
673 ATH_MSG_ERROR(iPayload << " " << (*itColl)->minRange() << " " << (*itColl)->size());
674 }
675 }
676 }
677
678 // detailed printout after merge
679 if (msgLvl(MSG::VERBOSE)) {
680 const IOVPayloadContainer* payloadMaster = contMaster->payloadContainer();
681 ATH_MSG_VERBOSE("processInputFileMetaData: After merge, payload minRange ");
682 if (payloadMaster) {
683 // Loop over AttrColls and print out minRange
684 IOVPayloadContainer::const_iterator itColl = payloadMaster->begin();
685 IOVPayloadContainer::const_iterator itCollEnd = payloadMaster->end();
686 unsigned int iPayload = 0;
687 for (; itColl != itCollEnd; ++itColl, ++iPayload) {
688 ATH_MSG_VERBOSE(iPayload << " " << (*itColl)->minRange() << " "
689 << (*itColl)->size());
690 }
691 }
692 else { ATH_MSG_ERROR(" no payloads yet!"); }
693 }
694
695 // Detailed printout
696 if (msgLvl(MSG::DEBUG)) {
697 ATH_MSG_DEBUG("processInputFileMetaData: Input payload " << cont->folderName());
698 std::ostringstream streamInp;
699 itColl = payload->begin();
700 itCollEnd = payload->end();
701 for (; itColl != itCollEnd; ++itColl) (*itColl)->dump(streamInp);
702 ATH_MSG_DEBUG(streamInp.str());
703 ATH_MSG_DEBUG("processInputFileMetaData: Output payload " << contMaster->folderName());
704 std::ostringstream streamOut;
705 itColl = contMaster->payloadContainer()->begin();
706 itCollEnd = contMaster->payloadContainer()->end();
707 for (; itColl != itCollEnd; ++itColl) (*itColl)->dump(streamOut);
708 ATH_MSG_DEBUG(streamOut.str());
709 }
710 }
711 }
712
713 ATH_MSG_DEBUG("processInputFileMetaData: Total number of attribute collections merged together " << ncolls
714 << " Number of duplicate collections " << ndupColls);
715
716 // Note: ConditionStore population for parameter folders (direct in-file metadata mode)
717 // is now handled by MetaDataToCondAlg, which runs during event processing when
718 // a valid EventContext is available.
719
720 // Serialize requested IOV folders to ByteStream metadata
722
723 return StatusCode::SUCCESS;
724}
725
726//--------------------------------------------------------------------------
727
728std::string
730{
731 const IOVPayloadContainer* payloads = container->payloadContainer();
732 if (!payloads || payloads->size() == 0) {
733 ATH_MSG_WARNING("No payloads for folder " << container->folderName());
734 return "";
735 }
736
737 using json = nlohmann::json;
738 json jsonData;
739
740 jsonData["folder"] = container->folderName();
741 jsonData["description"] = container->folderDescription();
742 jsonData["iovs"] = json::array();
743
744 // Serialize each IOV payload
745 for (const CondAttrListCollection* coll : *payloads) {
746 json iov;
747
748 // Get IOV range
749 IOVRange range = coll->minRange();
750 IOVTime start = range.start();
751 IOVTime stop = range.stop();
752
753 // IOV range
754 if (start.isRunEvent()) {
755 iov["range"]["start"] = {{"run", start.run()}, {"event", start.event()}};
756 iov["range"]["stop"] = {{"run", stop.run()}, {"event", stop.event()}};
757 } else {
758 iov["range"]["start"] = {{"timestamp", start.timestamp()}};
759 iov["range"]["stop"] = {{"timestamp", stop.timestamp()}};
760 }
761
762 // Attributes (serialize each channel)
763 iov["attrs"] = json::object();
764 for (const auto& chanAttrPair : *coll) {
765 CondAttrListCollection::ChanNum chan = chanAttrPair.first;
766 const coral::AttributeList& attrList = chanAttrPair.second;
767
768 std::string chanKey = "chan" + std::to_string(chan);
769 iov["attrs"][chanKey] = json::object();
770
771 for (const auto& attr : attrList) {
772 auto & thisAttribute = iov["attrs"][chanKey][attr.specification().name()];
773 // Serialize attribute value based on type
774 const std::type_info& type = attr.specification().type();
775 if (type == typeid(std::string)) {
776 thisAttribute = attr.data<std::string>();
777 } else if (type == typeid(int)) {
778 thisAttribute = attr.data<int>();
779 } else if (type == typeid(unsigned int)) {
780 thisAttribute = attr.data<unsigned int>();
781 } else if (type == typeid(long)) {
782 thisAttribute = attr.data<long>();
783 } else if (type == typeid(unsigned long)) {
784 thisAttribute = attr.data<unsigned long>();
785 } else if (type == typeid(long long)) {
786 thisAttribute = attr.data<long long>();
787 } else if (type == typeid(unsigned long long)) {
788 thisAttribute = attr.data<unsigned long long>();
789 } else if (type == typeid(float)) {
790 thisAttribute = attr.data<float>();
791 } else if (type == typeid(double)) {
792 thisAttribute = attr.data<double>();
793 } else if (type == typeid(bool)) {
794 thisAttribute = attr.data<bool>();
795 } else {
796 // For other types, convert to string representation
797 std::ostringstream oss;
798 attr.toOutputStream(oss);
799 thisAttribute = oss.str();
800 ATH_MSG_DEBUG("Attribute " << attr.specification().name() << " has unsupported type, converted to string: " << oss.str());
801 }
802 }
803 }
804
805 jsonData["iovs"].push_back(iov);
806 }
807
808 return jsonData.dump();
809}
810
811//--------------------------------------------------------------------------
812
813StatusCode
815{
816 ATH_MSG_DEBUG("overrideIOV ");
817
818 // Override the IOV for run/event IOVs
819
820 // (ONLY TRUE FOR OVERRIDE COMING IN VIA EVENTSELECTOR:)
821 // NOTE: we require that the old run number falls within the
822 // IOVRange of the incoming collection. We override ALL IOVs for
823 // ALL channels forcing the IOVRange to be (newRunNumber,1) to
824 // (newRunNumber+1,1)
825
826 bool iovSizeIsZero = coll->iov_size() == 0;
827 IOVRange testIOV = coll->minRange();
828 IOVTime start = testIOV.start();
829 IOVTime stop = testIOV.stop();
830 IOVTime oldRun(m_oldRunNumber, 0);
831 if (start.isRunEvent() && stop.isRunEvent()) { // only for run/event
832 IOVRange newRange;
833 // Two ways of resetting
835 else if (m_overrideRunNumber) newRange = IOVRange(IOVTime(m_newRunNumber, 0), IOVTime(m_newRunNumber + 1, 0));
836
837 if (m_overrideRunNumber && !testIOV.isInRange(oldRun)) {
838 // old run must be in the range
839 ATH_MSG_ERROR("overrideIOV: old run number does not match. Old run number " << m_oldRunNumber << " IOVRange: " << testIOV);
840 return StatusCode::SUCCESS;
841 }
842
843 ATH_MSG_DEBUG("overrideIOV: overrideMinMaxRunNumber: " << (int)m_overrideMinMaxRunNumber
844 << " overrideRunNumber " << (int)m_overrideRunNumber
845 << " iovSizeIsZero: " << (int)iovSizeIsZero
846 << " newRange " << newRange);
847
848 // Now over ride IOVs - two cases: 1) single IOV for full collection, 2) IOVs for individual channels.
849 // Must treat the reset of collection IOV differently
850 if (iovSizeIsZero) {
851 // Only add in overall range if channels do not have
852 // IOVs - otherwise this is automatically calculated
853 coll->resetMinRange(); // must first reset to 'full range' and then reduce the IOVRange accordingly
854 coll->addNewStart(newRange.start());
855 coll->addNewStop (newRange.stop());
856 }
857 else {
858 // Add in channels
859 unsigned int nchans = coll->size();
860 ATH_MSG_DEBUG("overrideIOV: nchans " << nchans);
861 for (unsigned int ichan = 0; ichan < nchans; ++ichan) {
862 // FIXME: O(N^2)!
863 CondAttrListCollection::ChanNum chan = coll->chanNum(ichan);
864 coll->add(chan, newRange);
865 ATH_MSG_DEBUG("overrideIOV: overriding the IOV of collection chan " << chan);
866 }
867 // must reset the collection range AFTER the channels, because the collection range will be
868 // 'narrowed' to that of the channels
869 coll->resetMinRange();
870 }
871 if (msgLvl(MSG::DEBUG)) {
872 ATH_MSG_DEBUG("overrideIOV: after overriding the IOV of collection");
873 std::ostringstream stream;
874 coll->dump(stream);
875 ATH_MSG_DEBUG(stream.str());
876 }
877 }
878 else ATH_MSG_DEBUG("overrideIOV: IOV is not run/event ");
879
880 return StatusCode::SUCCESS;
881}
882
883
884//--------------------------------------------------------------------------
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#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...
Hold mappings of ranges to condition objects.
a traits class that associates a CLID to a type T It also detects whether T inherits from Gaudi DataO...
nlohmann::json json
This is a tool used to manage the IOV Meta Data for a given object into the Meta Data Store.
This class is a container for conditions data.
Basic time unit for IOVSvc.
read-copy-update (RCU) style synchronization for Athena.
static Double_t sc
This class is a collection of AttributeLists where each one is associated with a channel number.
const AttributeList & attributeList(ChanNum chanNum) const
attribute list for a given channel number
ChanNum chanNum(unsigned int index) const
channel number for index: (index = 0 to size-1)
void addNewStart(const IOVTime &start)
Add new start time to minRange - make sure that start is >= to new start.
name_size_type name_size() const
number of Chan/Name pairs
bool add(ChanNum chanNum, const AttributeList &attributeList)
Adding in chan/attrList pairs.
void addNewStop(const IOVTime &stop)
Add new stop time to minRange - make sure that stop is <= to new stop.
void dump() const
Dump our contents to std::cout.
const std::string & chanName(ChanNum chanNum) const
find name for particular channel
void resetMinRange()
Reset minRange according to the IOVs of the contained channels.
const IOVRange & minRange() const
Current minimal IOVRange.
size_type size() const
number of Chan/AttributeList pairs
iov_size_type iov_size() const
number of Chan/IOV pairs
coral::AttributeList AttributeList
const IOVRange & iovRange(ChanNum chanNum) const
IOVRange list for a given channel number.
virtual StatusCode processInputFileMetaData(const std::string &fileName) override
Explicit call to process IOV meta data from the input meta data store, transferring it to the main me...
IOVDbMetaDataTool(const std::string &type, const std::string &name, const IInterface *parent)
StoreGateSvc_t m_inputStore
virtual StatusCode metaDataStop() override
Function called when the tool should write out its metadata.
virtual StatusCode endInputFile(const SG::SourceID &) override
Function called when the currently open input file got completely processed.
StringArrayProperty m_foldersToBeModified
unsigned int m_minRunNumber
std::string serializeContainerToJSON(const IOVMetaDataContainer *container) const
Serialize IOVMetaDataContainer to JSON format for ByteStream metadata.
virtual void handle(const Incident &incident) override
Incident service handle listening for BeginInputFile and EndInputFile.
StatusCode overrideIOV(CondAttrListCollection *&coll) const
override IOV with new run number
StatusCode serializeIOVMetadataToBSMetadata()
Serialize IOV metadata to ByteStream metadata (called from processInputFileMetaData)
std::set< std::string > m_filesProcessed
StoreGateSvc_t m_condStore
virtual StatusCode finalize() override
Finalize AlgTool.
virtual StatusCode addPayload(const std::string &folderName, CondAttrListCollection *payload) const override
Add an IOV and Payload for a particular folder - replaces payloads if there is an IOV overlap.
unsigned int m_maxRunNumber
IOVMetaDataContainer * getMetaDataContainer(const std::string &folderName, const std::string &folderDescription) const
return meta data container from the meta data store
UnsignedIntegerArrayProperty m_minMaxRunNumbers
unsigned int m_oldRunNumber
StoreGateSvc_t m_metaDataStore
virtual IOVMetaDataContainer * findMetaDataContainer(const std::string &folderName) const override final
virtual StatusCode beginInputFile(const SG::SourceID &) override
Function called when a new input file is opened.
virtual StatusCode initialize() override
Initialize AlgTool.
Gaudi::Property< std::map< std::string, std::string > > m_payloads
std::shared_mutex m_mutex
unsigned int m_newRunNumber
virtual StatusCode registerFolder(const std::string &folderName, const std::string &folderDescription) const override
Register folder in the IOV Db MetaData - done once at initialize.
void checkOverrideRunNumber()
check if we should override the run number in the incoming meta data
Gaudi::Property< std::vector< std::string > > m_foldersToSerializeToBSMetadata
StatusCode modifyPayload(const std::string &folderName, CondAttrListCollection *&payload) const
Modify a Payload for a particular folder - replaces one of the internal attributes.
StringArrayProperty m_attributesToBeRemoved
This class is a container for conditions data.
bool merge(CondAttrListCollection *payload)
Add in new payload.
const std::string & folderName() const
Folder name.
const IOVPayloadContainer * payloadContainer() const
Access to payload container.
This class is a container for the payload of conditions data.
size_type size() const
size of payload vector
payloadVec::const_iterator const_iterator
const_iterator begin() const
Begin of payload vector.
const_iterator end() const
End of payload vector.
Validity Range object.
Definition IOVRange.h:30
const IOVTime & stop() const
Definition IOVRange.h:39
bool isInRange(const IOVTime &t) const
Definition IOVRange.h:41
const IOVTime & start() const
Definition IOVRange.h:38
Basic time unit for IOVSvc.
Definition IOVTime.h:33
static constexpr uint32_t MAXRUN
Definition IOVTime.h:48
static constexpr uint32_t MAXEVENT
Definition IOVTime.h:51
a const_iterator facade to DataHandle.
Definition SGIterator.h:164
associate a data object with its VersionedKey The object is held by a ReadHandle to delay its retriev...
const std::string & key() const
Get the key string with which the current object was stored.
ElementLink_p1< typename GenerateELinkIndexType_p1< typename LINK::index_type >::type > type