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 ATH_MSG_DEBUG(
"Processing " << folderPayloads.size() <<
" folder(s) for direct payload registration");
98 std::map<std::string, std::pair<std::unique_ptr<CondAttrListCollection>, EventIDRange>> payloadsForCondStore;
100 for (
const auto& [folderName, parameters] : folderPayloads) {
102 if (!parameters.contains(
"beginRun") || !parameters.contains(
"endRun")) {
103 ATH_MSG_ERROR(
"Payload for folder " << folderName <<
" missing beginRun or endRun");
104 return StatusCode::FAILURE;
107 unsigned int beginRun = std::stoul(parameters.at(
"beginRun"));
108 unsigned int endRun = std::stoul(parameters.at(
"endRun"));
111 std::map<std::string, std::string> filteredParams;
112 std::ranges::copy_if(parameters, std::inserter(filteredParams, filteredParams.end()),
113 [](
const auto& p) { return p.first !=
"beginRun" && p.first !=
"endRun"; });
115 ATH_MSG_DEBUG(
"Registering folder " << folderName <<
" with " << filteredParams.size()
116 <<
" parameters, IOV [" << beginRun <<
", " << endRun <<
"]");
123 coral::AttributeListSpecification* spec =
new coral::AttributeListSpecification();
124 for (
const auto& [key, value] : filteredParams) {
125 spec->extend(key,
"string");
128 coral::AttributeList attrList(*spec,
true);
129 for (
const auto& [key, value] : filteredParams) {
130 attrList[key].setValue(value);
133 auto payload = std::make_unique<CondAttrListCollection>(
true);
134 payload->addNewStart(
IOVTime(beginRun, 0));
136 payload->add(0, attrList);
138 ATH_MSG_DEBUG(
"Created payload with IOV [" << beginRun <<
", " << endRun <<
"]");
141 EventIDRange iovRange(EventIDBase(beginRun, EventIDBase::UNDEFEVT, 0, 0, 0),
142 EventIDBase(endRun, EventIDBase::UNDEFEVT, EventIDBase::UNDEFNUM, EventIDBase::UNDEFNUM, EventIDBase::UNDEFNUM));
143 payloadsForCondStore[folderName] = std::make_pair(std::make_unique<CondAttrListCollection>(*payload), iovRange);
150 if (!payloadsForCondStore.empty()) {
151 ATH_MSG_INFO(
"Registering " << payloadsForCondStore.size() <<
" payload(s) to ConditionStore");
158 for (
auto& [folderName, payloadPair] : payloadsForCondStore) {
159 auto& [payload, iovRange] = payloadPair;
164 ATH_MSG_INFO(
"Creating CondCont<AthenaAttributeList> for " << folderName);
171 ATH_MSG_ERROR(
"Failed to create CondCont for " << folderName);
172 return StatusCode::FAILURE;
175 if (
m_condStore->recordObject(cb, folderName,
true,
false) ==
nullptr) {
176 ATH_MSG_ERROR(
"Failed to record CondCont for " << folderName);
177 return StatusCode::FAILURE;
184 if (payload->size() != 1) {
185 ATH_MSG_ERROR(
"Expected single-entry CondAttrListCollection for " << folderName <<
", got " << payload->size() <<
" entries");
186 return StatusCode::FAILURE;
189 auto itr = payload->begin();
190 const coral::AttributeList& attrList = itr->second;
191 auto athAttrList = std::make_unique<AthenaAttributeList>(attrList);
193 ATH_CHECK(cc->insert(iovRange, std::move(athAttrList), Gaudi::Hive::currentContext()));
194 ATH_MSG_INFO(
"Inserted payload into CondCont for " << folderName <<
" with IOV " << iovRange);
199 return(StatusCode::SUCCESS);
207 return StatusCode::SUCCESS;
214 const FileIncident* fileInc =
dynamic_cast<const FileIncident*
>(&inc);
215 if(!fileInc)
throw std::runtime_error(
"Unable to get FileName from FirstInputFile incident");
217 const std::string fileName = fileInc->fileName();
218 ATH_MSG_DEBUG(
"handle() " << inc.type() <<
" for " << fileName);
224 if(!
sc.isSuccess())
throw std::runtime_error(
"Could not process input file meta data");
234 return StatusCode::SUCCESS;
239 return StatusCode::SUCCESS;
247 return StatusCode::SUCCESS;
251 std::vector<std::string> iovMetaStrings;
255 ATH_MSG_WARNING(
"Could not find IOVMetaDataContainer for folder " << folderName <<
", skipping");
260 if (!jsonStr.empty()) {
261 iovMetaStrings.push_back(
"IOVMeta." + folderName +
"=" + jsonStr);
262 ATH_MSG_DEBUG(
"Serialized folder " << folderName <<
" (" << jsonStr.size() <<
" bytes JSON)");
266 if (iovMetaStrings.empty()) {
268 return StatusCode::SUCCESS;
273 if (
m_metaDataStore->contains<std::vector<std::string>>(
"IOVMetaDataStrings")) {
275 std::vector<std::string>* existingStrings =
nullptr;
277 existingStrings->insert(existingStrings->end(), iovMetaStrings.begin(), iovMetaStrings.end());
278 ATH_MSG_DEBUG(
"Appended " << iovMetaStrings.size() <<
" IOV metadata strings to existing collection");
281 auto iovMetaData = std::make_unique<std::vector<std::string>>(std::move(iovMetaStrings));
283 ATH_MSG_DEBUG(
"Stored " << iovMetaStrings.size() <<
" IOV metadata strings in MetaDataStore");
286 return StatusCode::SUCCESS;
291 return StatusCode::SUCCESS;
317 ATH_MSG_DEBUG(
"checkOverrideRunNumber: check if tag is set in jobOpts");
321 SmartIF<IProperty> appMgr{serviceLocator()->service(
"ApplicationMgr")};
323 ATH_MSG_ERROR(
"checkOverrideRunNumber: Cannot get ApplicationMgr ");
326 StringProperty property(
"EvtSel",
"");
327 StatusCode
sc = appMgr->getProperty(&property);
328 if (!
sc.isSuccess()) {
329 ATH_MSG_ERROR(
"checkOverrideRunNumber: unable to get EvtSel: found " << property.value());
333 const std::string eventSelector =
property.value();
334 SmartIF<IProperty> evtSel{serviceLocator()->service(eventSelector)};
336 ATH_MSG_ERROR(
"checkOverrideRunNumber: Cannot get EventSelector " << eventSelector);
341 BooleanProperty overrideRunNumber(
"OverrideRunNumberFromInput",
false);
342 sc = evtSel->getProperty(&overrideRunNumber);
343 if (!
sc.isSuccess()) {
345 ATH_MSG_DEBUG(
"resetRunNumber: unable to get OverrideRunNumberFromInput property from EventSelector ");
351 IntegerProperty runNumber(
"RunNumber", 0);
352 sc = evtSel->getProperty(&runNumber);
353 if (!
sc.isSuccess()) {
354 ATH_MSG_ERROR(
"checkOverrideRunNumber: unable to get RunNumber from EventSelector: found "
355 << runNumber.value());
360 IntegerProperty oldRunNumber(
"OldRunNumber", 0);
361 sc = evtSel->getProperty(&oldRunNumber);
362 if (!
sc.isSuccess()) {
363 ATH_MSG_ERROR(
"checkOverrideRunNumber: unable to get OldRunNumber from EventSelector: found "
364 << oldRunNumber.value());
372 else ATH_MSG_DEBUG(
"checkOverrideRunNumber: OverrideRunNumberFromInput not set for " << eventSelector);
382 std::string folderDescr =
"<timeStamp>run-event</timeStamp><addrHeader><address_header service_type=\"256\" clid=\"1238547719\" /> </addrHeader><typeName>CondAttrListCollection</typeName>" ;
391 const std::string& folderDescription)
const
394 std::scoped_lock guard(
m_mutex );
400 return(StatusCode::FAILURE);
403 ATH_MSG_DEBUG(
"IOVMetaDataContainer for folder " << folderName <<
" has been registered ");
406 return StatusCode::SUCCESS;
415 std::scoped_lock guard(
m_mutex );
422 ATH_MSG_DEBUG(
"Retrieved IOVMetaDataContainer from MetaDataStore for folder "
426 ATH_MSG_ERROR(
"addPayload: Could not find IOVMetaDataContainer in MetaDataStore for folder "
428 <<
". One must have previously called registerFolder. ");
429 return StatusCode::FAILURE;
438 bool success = cont->
merge(payload);
440 ATH_MSG_DEBUG(
"Added new payload for folder " << folderName);
445 <<
" (may be duplicate payload).");
453 if(payload && msgLvl(MSG::DEBUG)) {
454 std::ostringstream stream;
455 payload->dump(stream);
459 return StatusCode::SUCCESS;
472 ATH_MSG_DEBUG(
"begin modifyPayload for folder " << folderName);
475 bool modifyAttr =
false;
476 std::string attributeName;
479 for (
unsigned int i = 0; i < folders.size(); ++i) {
480 if (folderName == folders[i]) {
481 if (attrs.size() > i) {
482 attributeName = attrs[i];
484 ATH_MSG_DEBUG(
"modifyPayload: remove attribute " << attributeName);
491 ATH_MSG_DEBUG(
"modifyPayload: folder " << folderName <<
" OK ");
492 return StatusCode::SUCCESS;
495 bool iovSizeIsZero = coll->
iov_size() == 0;
508 unsigned int nchans = coll->
size();
509 bool hasChanNames = (coll->
name_size() == nchans);
510 for (
unsigned int ichan = 0; ichan < nchans; ++ichan) {
515 for (
unsigned int iatt = 0; iatt < oldAttrList.size(); ++iatt) {
517 if (attributeName == oldAttrList[iatt].specification().name()) {
518 ATH_MSG_DEBUG(
"modifyPayload: skipping attribute name " << oldAttrList[iatt].specification().name());
523 newAttrList.extend(oldAttrList[iatt].specification().name(),
524 oldAttrList[iatt].specification().
type());
525 const coral::Attribute& oldAttr = oldAttrList[iatt];
526 coral::Attribute& newAttr = newAttrList[oldAttrList[iatt].specification().name()];
530 << oldAttrList[iatt].specification().name() <<
" "
533 coll1->
add(chan, newAttrList);
534 if (!iovSizeIsZero) coll1->
add(chan, coll->
iovRange(chan));
535 if(hasChanNames)coll1->
add(chan, coll->
chanName(chan));
536 ATH_MSG_DEBUG(
"modifyPayload: copied attribute list for channel " << chan);
540 if (msgLvl(MSG::DEBUG)) {
541 std::ostringstream stream;
546 return StatusCode::SUCCESS;
562 ,
const std::string& folderDescription)
const
572 ATH_MSG_DEBUG(
"No IOVMetaDataContainer in MetaDataStore for folder " << folderName
573 <<
". Created a new instance");
575 if (!
sc.isSuccess()) {
576 ATH_MSG_ERROR(
"Could not record IOVMetaDataContainer in MetaDataStore for folder " << folderName);
582 ATH_MSG_DEBUG(
"IOVMetaDataContainer already in MetaDataStore for folder " << folderName);
584 if (!
sc.isSuccess()) {
585 ATH_MSG_ERROR(
"Could not retrieve IOVMetaDataContainer in MetaDataStore for folder " << folderName);
597 std::scoped_lock guard(
m_mutex );
599 ATH_MSG_DEBUG(
"processInputFileMetaData: file name " << fileName);
606 if (!
sc.isSuccess()) {
607 ATH_MSG_DEBUG(
"processInputFileMetaData: Could not retrieve IOVMetaDataContainer objects from InputMetaDataStore - cannot process input file meta data");
608 return StatusCode::SUCCESS;
611 ATH_MSG_DEBUG(
"processInputFileMetaData: Retrieved from IOVMetaDataContainer(s) from InputMetaDataStore");
614 unsigned int ncolls = 0;
615 unsigned int ndupColls = 0;
616 for (; cont != contEnd; ++cont) {
618 , cont->folderDescription());
622 std::list<SG::ObjectWithVersion<IOVMetaDataContainer> > allVersions;
624 if (!
sc.isSuccess()) {
632 ATH_MSG_DEBUG(
"processInputFileMetaData: New container: payload size " << payload->size() <<
" version key " << obj.versionedKey);
635 if (msgLvl(MSG::VERBOSE)) {
637 ATH_MSG_VERBOSE(
"Before merge, payload minRange for folder " << cont->folderName());
638 if (payloadMaster && payloadMaster->
size()) {
642 unsigned int iPayload = 0;
643 for (; itColl != itCollEnd; ++itColl, ++iPayload) {
645 << (*itColl)->size());
655 if (msgLvl(MSG::DEBUG)) {
659 std::ostringstream stream;
660 for (; itColl1 != itCollEnd1; ++itColl1) (*itColl1)->dump(stream);
671 for (; itColl != itCollEnd; ++itColl) {
683 ATH_MSG_ERROR(
"processInputFileMetaData: Could not modify the payload for folder " << contMaster->
folderName());
684 return StatusCode::FAILURE;
688 if (!contMaster->
merge(coll)) {
700 ATH_MSG_DEBUG(
"processInputFileMetaData: Merged together containers for folder " << cont->folderName() <<
" ncoll/ndup "
701 << ncolls <<
" " << ndupColls);
705 if (payloadMaster && payloadMaster->
size()) {
710 if ((*itColl)->minRange().start().isTimestamp()) lastStop =
IOVTime(0);
712 bool hasError =
false;
713 for (; itColl != itCollEnd; ++itColl) {
714 if ((*itColl)->minRange().start() < lastStop) hasError =
true;
715 lastStop = (*itColl)->minRange().stop();
718 ATH_MSG_ERROR(
"processInputFileMetaData: error after merge of file meta data. " );
719 ATH_MSG_ERROR(
"processInputFileMetaData: Filename " << fileName);
721 ATH_MSG_ERROR(
"processInputFileMetaData: MinRange for meta data folders ");
722 unsigned int iPayload = 0;
723 itColl = payloadMaster->
begin();
724 for (; itColl != itCollEnd; ++itColl, ++iPayload) {
725 ATH_MSG_ERROR(iPayload <<
" " << (*itColl)->minRange() <<
" " << (*itColl)->size());
731 if (msgLvl(MSG::VERBOSE)) {
733 ATH_MSG_VERBOSE(
"processInputFileMetaData: After merge, payload minRange ");
738 unsigned int iPayload = 0;
739 for (; itColl != itCollEnd; ++itColl, ++iPayload) {
741 << (*itColl)->size());
748 if (msgLvl(MSG::DEBUG)) {
749 ATH_MSG_DEBUG(
"processInputFileMetaData: Input payload " << cont->folderName());
750 std::ostringstream streamInp;
751 itColl = payload->begin();
752 itCollEnd = payload->end();
753 for (; itColl != itCollEnd; ++itColl) (*itColl)->dump(streamInp);
756 std::ostringstream streamOut;
759 for (; itColl != itCollEnd; ++itColl) (*itColl)->dump(streamOut);
765 ATH_MSG_DEBUG(
"processInputFileMetaData: Total number of attribute collections merged together " << ncolls
766 <<
" Number of duplicate collections " << ndupColls);
776 const EventContext& currentCtx = Gaudi::Hive::currentContext();
777 if (currentCtx.valid()) {
778 constexpr std::array folderNames{
"/Digitization/Parameters",
"/Simulation/Parameters"};
779 for (std::string_view folderName : folderNames) {
788 bool inPayloads =
false;
790 if (key.find(std::string(folderName) +
":") == 0) {
796 ATH_MSG_DEBUG(
"Folder " << folderName <<
" is in Payloads, skipping auto-read from input");
802 if (
m_metaDataStore->retrieve(contMaster, std::string(folderName)).isSuccess() && contMaster) {
804 if (payloadMaster && payloadMaster->
size() > 0) {
812 ATH_MSG_DEBUG(
"CondCont for " << folderName <<
" already exists, skipping");
827 std::string(folderName));
829 ATH_MSG_ERROR(
"Failed to create CondCont for " << folderName);
830 return StatusCode::FAILURE;
833 if (
m_condStore->recordObject(cb, std::string(folderName),
true,
false) ==
nullptr) {
834 ATH_MSG_ERROR(
"Failed to record CondCont for " << folderName);
835 return StatusCode::FAILURE;
842 auto itr = coll->
begin();
843 const coral::AttributeList& attrList = itr->second;
844 auto athAttrList = std::make_unique<AthenaAttributeList>(attrList);
848 EventIDBase start, stop;
849 start.set_run_number(iovRange.
start().
run());
850 start.set_lumi_block(iovRange.
start().
event());
851 stop.set_run_number(iovRange.
stop().
run());
852 stop.set_lumi_block(iovRange.
stop().
event());
853 EventIDRange range(start, stop);
856 ATH_CHECK(cc->insert(range, std::move(athAttrList), currentCtx));
858 ATH_MSG_DEBUG(
"Populated ConditionStore for " << folderName <<
" from file metadata");
868 return StatusCode::SUCCESS;
877 if (!payloads || payloads->
size() == 0) {
882 using json = nlohmann::json;
885 jsonData[
"folder"] =
container->folderName();
886 jsonData[
"description"] =
container->folderDescription();
887 jsonData[
"iovs"] = json::array();
899 if (start.isRunEvent()) {
900 iov[
"range"][
"start"] = {{
"run", start.run()}, {
"event", start.event()}};
901 iov[
"range"][
"stop"] = {{
"run", stop.run()}, {
"event", stop.event()}};
903 iov[
"range"][
"start"] = {{
"timestamp", start.timestamp()}};
904 iov[
"range"][
"stop"] = {{
"timestamp", stop.timestamp()}};
908 iov[
"attrs"] = json::object();
909 for (
const auto& chanAttrPair : *coll) {
911 const coral::AttributeList& attrList = chanAttrPair.second;
913 std::string chanKey =
"chan" + std::to_string(chan);
914 iov[
"attrs"][chanKey] = json::object();
916 for (
const auto& attr : attrList) {
917 auto & thisAttribute = iov[
"attrs"][chanKey][attr.specification().name()];
919 const std::type_info&
type = attr.specification().
type();
920 if (
type ==
typeid(std::string)) {
921 thisAttribute = attr.data<std::string>();
922 }
else if (
type ==
typeid(
int)) {
923 thisAttribute = attr.data<
int>();
924 }
else if (
type ==
typeid(
unsigned int)) {
925 thisAttribute = attr.data<
unsigned int>();
926 }
else if (
type ==
typeid(
long)) {
927 thisAttribute = attr.data<
long>();
928 }
else if (
type ==
typeid(
unsigned long)) {
929 thisAttribute = attr.data<
unsigned long>();
930 }
else if (
type ==
typeid(
long long)) {
931 thisAttribute = attr.data<
long long>();
932 }
else if (
type ==
typeid(
unsigned long long)) {
933 thisAttribute = attr.data<
unsigned long long>();
934 }
else if (
type ==
typeid(
float)) {
935 thisAttribute = attr.data<
float>();
936 }
else if (
type ==
typeid(
double)) {
937 thisAttribute = attr.data<
double>();
938 }
else if (
type ==
typeid(
bool)) {
939 thisAttribute = attr.data<
bool>();
942 std::ostringstream oss;
943 attr.toOutputStream(oss);
944 thisAttribute = oss.str();
945 ATH_MSG_DEBUG(
"Attribute " << attr.specification().name() <<
" has unsupported type, converted to string: " << oss.str());
950 jsonData[
"iovs"].push_back(iov);
953 return jsonData.dump();
971 bool iovSizeIsZero = coll->
iov_size() == 0;
976 if (start.isRunEvent() && stop.isRunEvent()) {
985 return StatusCode::SUCCESS;
990 <<
" iovSizeIsZero: " << (
int)iovSizeIsZero
991 <<
" newRange " << newRange);
1004 unsigned int nchans = coll->
size();
1006 for (
unsigned int ichan = 0; ichan < nchans; ++ichan) {
1009 coll->
add(chan, newRange);
1010 ATH_MSG_DEBUG(
"overrideIOV: overriding the IOV of collection chan " << chan);
1016 if (msgLvl(MSG::DEBUG)) {
1017 ATH_MSG_DEBUG(
"overrideIOV: after overriding the IOV of collection");
1018 std::ostringstream stream;
1025 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.
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.
const_iterator begin() const
Access to Chan/AttributeList pairs via iterators.
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.
Hold mapping of ranges to condition objects.
SG::DataObjectSharedPtr< DataObject > Create(Athena::IRCUSvc &rcusvc, const CLID &clid, const std::string &key) const
static CondContFactory & Instance()
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
uint32_t event() const noexcept
uint32_t run() const noexcept
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.
CxxUtils::RefCountedPtr< T > DataObjectSharedPtr
ElementLink_p1< typename GenerateELinkIndexType_p1< typename LINK::index_type >::type > type