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