18#include "GaudiKernel/IIncidentSvc.h"
19#include "GaudiKernel/FileIncident.h"
20#include "GaudiKernel/EventIDBase.h"
21#include "GaudiKernel/EventIDRange.h"
32#include "CoralBase/AttributeListSpecification.h"
33#include "nlohmann/json.hpp"
37 const std::string& name,
38 const IInterface* parent)
39 : base_class(
type, name, parent)
67 incSvc->addListener(
this,
"FirstInputFile", 60);
80 std::map<std::string, std::map<std::string, std::string>> folderPayloads;
82 for (
const auto& [key, value] :
m_payloads.value()) {
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;
90 std::string folderName = key.substr(0, colonPos);
91 std::string paramName = key.substr(colonPos + 1);
92 folderPayloads[folderName][paramName] = value;
95 static const std::string beginRunKey{
"beginRun"};
96 static const std::string endRunKey{
"endRun"};
97 static const std::string specType{
"string"};
100 const auto isIOVKey = [](
const std::string& key) {
101 return key == beginRunKey || key == endRunKey;
103 ATH_MSG_DEBUG(
"Processing " << folderPayloads.size() <<
" folder(s) for direct payload registration");
104 for (
const auto& [folderName, parameters] : folderPayloads) {
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;
113 unsigned int beginRun = std::stoul(beginRunItr->second);
114 unsigned int endRun = std::stoul(endRunItr->second);
116 ATH_MSG_DEBUG(
"Registering folder " << folderName <<
" with " << parameters.size() - 2
117 <<
" parameters, IOV [" << beginRun <<
", " << endRun <<
"]");
121 static const std::string attrListDescr{
"<timeStamp>run-event</timeStamp><addrHeader><address_header service_type=\"71\" clid=\"40774348\" /></addrHeader><typeName>AthenaAttributeList</typeName>"};
127 coral::AttributeListSpecification* spec =
new coral::AttributeListSpecification();
128 for (
const auto& [key, value] : parameters) {
129 if (!isIOVKey(key)) {
130 spec->extend(key, specType);
134 coral::AttributeList attrList(*spec,
true);
135 for (
const auto& [key, value] : parameters) {
136 if (!isIOVKey(key)) {
137 attrList[key].setValue(value);
143 auto payload = std::make_unique<CondAttrListCollection>(
true);
145 payload->add(0xFFFF, attrList);
146 payload->add(0xFFFF, range);
148 ATH_MSG_DEBUG(
"Created payload with IOV [" << beginRun <<
", " << endRun <<
"]");
160 return(StatusCode::SUCCESS);
168 return StatusCode::SUCCESS;
175 const FileIncident* fileInc =
dynamic_cast<const FileIncident*
>(&inc);
176 if(!fileInc)
throw std::runtime_error(
"Unable to get FileName from FirstInputFile incident");
178 const std::string fileName = fileInc->fileName();
179 ATH_MSG_DEBUG(
"handle() " << inc.type() <<
" for " << fileName);
185 if(!
sc.isSuccess())
throw std::runtime_error(
"Could not process input file meta data");
195 return StatusCode::SUCCESS;
200 return StatusCode::SUCCESS;
208 return StatusCode::SUCCESS;
212 std::vector<std::string> iovMetaStrings;
216 ATH_MSG_WARNING(
"Could not find IOVMetaDataContainer for folder " << folderName <<
", skipping");
221 if (!jsonStr.empty()) {
222 iovMetaStrings.push_back(
"IOVMeta." + folderName +
"=" + jsonStr);
223 ATH_MSG_DEBUG(
"Serialized folder " << folderName <<
" (" << jsonStr.size() <<
" bytes JSON)");
227 if (iovMetaStrings.empty()) {
229 return StatusCode::SUCCESS;
234 if (
m_metaDataStore->contains<std::vector<std::string>>(
"IOVMetaDataStrings")) {
236 std::vector<std::string>* existingStrings =
nullptr;
238 existingStrings->insert(existingStrings->end(), iovMetaStrings.begin(), iovMetaStrings.end());
239 ATH_MSG_DEBUG(
"Appended " << iovMetaStrings.size() <<
" IOV metadata strings to existing collection");
242 auto iovMetaData = std::make_unique<std::vector<std::string>>(std::move(iovMetaStrings));
244 ATH_MSG_DEBUG(
"Stored " << iovMetaStrings.size() <<
" IOV metadata strings in MetaDataStore");
247 return StatusCode::SUCCESS;
252 return StatusCode::SUCCESS;
278 ATH_MSG_DEBUG(
"checkOverrideRunNumber: check if tag is set in jobOpts");
282 SmartIF<IProperty> appMgr{serviceLocator()->service(
"ApplicationMgr")};
284 ATH_MSG_ERROR(
"checkOverrideRunNumber: Cannot get ApplicationMgr ");
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());
294 const std::string eventSelector =
property.value();
295 SmartIF<IProperty> evtSel{serviceLocator()->service(eventSelector)};
297 ATH_MSG_ERROR(
"checkOverrideRunNumber: Cannot get EventSelector " << eventSelector);
302 BooleanProperty overrideRunNumber(
"OverrideRunNumberFromInput",
false);
303 sc = evtSel->getProperty(&overrideRunNumber);
304 if (!
sc.isSuccess()) {
306 ATH_MSG_DEBUG(
"resetRunNumber: unable to get OverrideRunNumberFromInput property from EventSelector ");
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());
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());
333 else ATH_MSG_DEBUG(
"checkOverrideRunNumber: OverrideRunNumberFromInput not set for " << eventSelector);
343 std::string folderDescr =
"<timeStamp>run-event</timeStamp><addrHeader><address_header service_type=\"256\" clid=\"1238547719\" /> </addrHeader><typeName>CondAttrListCollection</typeName>" ;
352 const std::string& folderDescription)
const
355 std::scoped_lock guard(
m_mutex );
361 return(StatusCode::FAILURE);
364 ATH_MSG_DEBUG(
"IOVMetaDataContainer for folder " << folderName <<
" has been registered ");
367 return StatusCode::SUCCESS;
376 std::scoped_lock guard(
m_mutex );
383 ATH_MSG_DEBUG(
"Retrieved IOVMetaDataContainer from MetaDataStore for folder "
387 ATH_MSG_ERROR(
"addPayload: Could not find IOVMetaDataContainer in MetaDataStore for folder "
389 <<
". One must have previously called registerFolder. ");
390 return StatusCode::FAILURE;
399 bool success = cont->
merge(payload);
401 ATH_MSG_DEBUG(
"Added new payload for folder " << folderName);
406 <<
" (may be duplicate payload).");
414 if(payload && msgLvl(MSG::DEBUG)) {
415 std::ostringstream stream;
416 payload->dump(stream);
420 return StatusCode::SUCCESS;
433 ATH_MSG_DEBUG(
"begin modifyPayload for folder " << folderName);
436 bool modifyAttr =
false;
437 std::string attributeName;
440 for (
unsigned int i = 0; i < folders.size(); ++i) {
441 if (folderName == folders[i]) {
442 if (attrs.size() > i) {
443 attributeName = attrs[i];
445 ATH_MSG_DEBUG(
"modifyPayload: remove attribute " << attributeName);
452 ATH_MSG_DEBUG(
"modifyPayload: folder " << folderName <<
" OK ");
453 return StatusCode::SUCCESS;
456 bool iovSizeIsZero = coll->
iov_size() == 0;
469 unsigned int nchans = coll->
size();
470 bool hasChanNames = (coll->
name_size() == nchans);
471 for (
unsigned int ichan = 0; ichan < nchans; ++ichan) {
476 for (
unsigned int iatt = 0; iatt < oldAttrList.size(); ++iatt) {
478 if (attributeName == oldAttrList[iatt].specification().name()) {
479 ATH_MSG_DEBUG(
"modifyPayload: skipping attribute name " << oldAttrList[iatt].specification().name());
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()];
491 << oldAttrList[iatt].specification().name() <<
" "
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);
501 if (msgLvl(MSG::DEBUG)) {
502 std::ostringstream stream;
507 return StatusCode::SUCCESS;
523 ,
const std::string& folderDescription)
const
533 ATH_MSG_DEBUG(
"No IOVMetaDataContainer in MetaDataStore for folder " << folderName
534 <<
". Created a new instance");
536 if (!
sc.isSuccess()) {
537 ATH_MSG_ERROR(
"Could not record IOVMetaDataContainer in MetaDataStore for folder " << folderName);
543 ATH_MSG_DEBUG(
"IOVMetaDataContainer already in MetaDataStore for folder " << folderName);
545 if (!
sc.isSuccess()) {
546 ATH_MSG_ERROR(
"Could not retrieve IOVMetaDataContainer in MetaDataStore for folder " << folderName);
558 std::scoped_lock guard(
m_mutex );
560 ATH_MSG_DEBUG(
"processInputFileMetaData: file name " << fileName);
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;
572 ATH_MSG_DEBUG(
"processInputFileMetaData: Retrieved from IOVMetaDataContainer(s) from InputMetaDataStore");
575 unsigned int ncolls = 0;
576 unsigned int ndupColls = 0;
577 for (; cont != contEnd; ++cont) {
579 , cont->folderDescription());
583 std::list<SG::ObjectWithVersion<IOVMetaDataContainer> > allVersions;
585 if (!
sc.isSuccess()) {
593 ATH_MSG_DEBUG(
"processInputFileMetaData: New container: payload size " << payload->size() <<
" version key " << obj.versionedKey);
596 if (msgLvl(MSG::VERBOSE)) {
598 ATH_MSG_VERBOSE(
"Before merge, payload minRange for folder " << cont->folderName());
599 if (payloadMaster && payloadMaster->
size()) {
603 unsigned int iPayload = 0;
604 for (; itColl != itCollEnd; ++itColl, ++iPayload) {
606 << (*itColl)->size());
616 if (msgLvl(MSG::DEBUG)) {
620 std::ostringstream stream;
621 for (; itColl1 != itCollEnd1; ++itColl1) (*itColl1)->dump(stream);
632 for (; itColl != itCollEnd; ++itColl) {
644 ATH_MSG_ERROR(
"processInputFileMetaData: Could not modify the payload for folder " << contMaster->
folderName());
645 return StatusCode::FAILURE;
649 if (!contMaster->
merge(coll)) {
661 ATH_MSG_DEBUG(
"processInputFileMetaData: Merged together containers for folder " << cont->folderName() <<
" ncoll/ndup "
662 << ncolls <<
" " << ndupColls);
666 if (payloadMaster && payloadMaster->
size()) {
671 if ((*itColl)->minRange().start().isTimestamp()) lastStop =
IOVTime(0);
673 bool hasError =
false;
674 for (; itColl != itCollEnd; ++itColl) {
675 if ((*itColl)->minRange().start() < lastStop) hasError =
true;
676 lastStop = (*itColl)->minRange().stop();
679 ATH_MSG_ERROR(
"processInputFileMetaData: error after merge of file meta data. " );
680 ATH_MSG_ERROR(
"processInputFileMetaData: Filename " << fileName);
682 ATH_MSG_ERROR(
"processInputFileMetaData: MinRange for meta data folders ");
683 unsigned int iPayload = 0;
684 itColl = payloadMaster->
begin();
685 for (; itColl != itCollEnd; ++itColl, ++iPayload) {
686 ATH_MSG_ERROR(iPayload <<
" " << (*itColl)->minRange() <<
" " << (*itColl)->size());
692 if (msgLvl(MSG::VERBOSE)) {
694 ATH_MSG_VERBOSE(
"processInputFileMetaData: After merge, payload minRange ");
699 unsigned int iPayload = 0;
700 for (; itColl != itCollEnd; ++itColl, ++iPayload) {
702 << (*itColl)->size());
709 if (msgLvl(MSG::DEBUG)) {
710 ATH_MSG_DEBUG(
"processInputFileMetaData: Input payload " << cont->folderName());
711 std::ostringstream streamInp;
712 itColl = payload->begin();
713 itCollEnd = payload->end();
714 for (; itColl != itCollEnd; ++itColl) (*itColl)->dump(streamInp);
717 std::ostringstream streamOut;
720 for (; itColl != itCollEnd; ++itColl) (*itColl)->dump(streamOut);
726 ATH_MSG_DEBUG(
"processInputFileMetaData: Total number of attribute collections merged together " << ncolls
727 <<
" Number of duplicate collections " << ndupColls);
736 return StatusCode::SUCCESS;
745 if (!payloads || payloads->
size() == 0) {
750 using json = nlohmann::json;
753 jsonData[
"folder"] = container->folderName();
754 jsonData[
"description"] = container->folderDescription();
755 jsonData[
"iovs"] = json::array();
767 if (start.isRunEvent()) {
768 iov[
"range"][
"start"] = {{
"run", start.run()}, {
"event", start.event()}};
769 iov[
"range"][
"stop"] = {{
"run", stop.run()}, {
"event", stop.event()}};
771 iov[
"range"][
"start"] = {{
"timestamp", start.timestamp()}};
772 iov[
"range"][
"stop"] = {{
"timestamp", stop.timestamp()}};
776 iov[
"attrs"] = json::object();
777 for (
const auto& chanAttrPair : *coll) {
779 const coral::AttributeList& attrList = chanAttrPair.second;
781 std::string chanKey =
"chan" + std::to_string(chan);
782 iov[
"attrs"][chanKey] = json::object();
784 for (
const auto& attr : attrList) {
785 auto & thisAttribute = iov[
"attrs"][chanKey][attr.specification().name()];
787 const std::type_info&
type = attr.specification().
type();
788 if (
type ==
typeid(std::string)) {
789 thisAttribute = attr.data<std::string>();
790 }
else if (
type ==
typeid(
int)) {
791 thisAttribute = attr.data<
int>();
792 }
else if (
type ==
typeid(
unsigned int)) {
793 thisAttribute = attr.data<
unsigned int>();
794 }
else if (
type ==
typeid(
long)) {
795 thisAttribute = attr.data<
long>();
796 }
else if (
type ==
typeid(
unsigned long)) {
797 thisAttribute = attr.data<
unsigned long>();
798 }
else if (
type ==
typeid(
long long)) {
799 thisAttribute = attr.data<
long long>();
800 }
else if (
type ==
typeid(
unsigned long long)) {
801 thisAttribute = attr.data<
unsigned long long>();
802 }
else if (
type ==
typeid(
float)) {
803 thisAttribute = attr.data<
float>();
804 }
else if (
type ==
typeid(
double)) {
805 thisAttribute = attr.data<
double>();
806 }
else if (
type ==
typeid(
bool)) {
807 thisAttribute = attr.data<
bool>();
810 std::ostringstream oss;
811 attr.toOutputStream(oss);
812 thisAttribute = oss.str();
813 ATH_MSG_DEBUG(
"Attribute " << attr.specification().name() <<
" has unsupported type, converted to string: " << oss.str());
818 jsonData[
"iovs"].push_back(iov);
821 return jsonData.dump();
839 bool iovSizeIsZero = coll->
iov_size() == 0;
844 if (start.isRunEvent() && stop.isRunEvent()) {
853 return StatusCode::SUCCESS;
858 <<
" iovSizeIsZero: " << (
int)iovSizeIsZero
859 <<
" newRange " << newRange);
872 unsigned int nchans = coll->
size();
874 for (
unsigned int ichan = 0; ichan < nchans; ++ichan) {
877 coll->
add(chan, newRange);
878 ATH_MSG_DEBUG(
"overrideIOV: overriding the IOV of collection chan " << chan);
884 if (msgLvl(MSG::DEBUG)) {
885 ATH_MSG_DEBUG(
"overrideIOV: after overriding the IOV of collection");
886 std::ostringstream stream;
893 return StatusCode::SUCCESS;
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(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...
Basic time unit for IOVSvc.
read-copy-update (RCU) style synchronization for Athena.
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.
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.
const IOVTime & stop() const
bool isInRange(const IOVTime &t) const
const IOVTime & start() const
Basic time unit for IOVSvc.
static constexpr uint32_t MAXRUN
static constexpr uint32_t MAXEVENT
a const_iterator facade to DataHandle.
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