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