File indexing completed on 2024-04-06 12:12:49
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #include <map>
0021 #include <vector>
0022 #include <memory>
0023 #include <set>
0024 #include <iostream>
0025
0026
0027 #include "FWCore/Framework/interface/global/EDAnalyzer.h"
0028 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0029 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0030 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0031 #include "FWCore/Framework/interface/EventSetupRecord.h"
0032 #include "FWCore/Framework/interface/ESRecordsToProductResolverIndices.h"
0033 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0034 #include "FWCore/Framework/interface/EventSetup.h"
0035 #include "FWCore/Framework/interface/MakerMacros.h"
0036 #include "FWCore/Utilities/interface/ESGetTokenGeneric.h"
0037
0038
0039
0040
0041 namespace edm {
0042 class EventSetupRecordDataGetter
0043 : public edm::global::EDAnalyzer<edm::RunCache<std::nullptr_t>, edm::LuminosityBlockCache<std::nullptr_t>> {
0044 public:
0045 explicit EventSetupRecordDataGetter(ParameterSet const&);
0046 ~EventSetupRecordDataGetter() override;
0047
0048 void analyze(edm::StreamID, Event const&, EventSetup const&) const final;
0049 std::shared_ptr<std::nullptr_t> globalBeginRun(edm::Run const&, edm::EventSetup const&) const final;
0050 void globalEndRun(edm::Run const&, edm::EventSetup const&) const final {}
0051
0052 std::shared_ptr<std::nullptr_t> globalBeginLuminosityBlock(edm::LuminosityBlock const&,
0053 edm::EventSetup const&) const final;
0054 void globalEndLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) const final {}
0055
0056 static void fillDescriptions(ConfigurationDescriptions& descriptions);
0057
0058 private:
0059 void registerLateConsumes(eventsetup::ESRecordsToProductResolverIndices const&) final;
0060
0061 using RecordToTokens = std::map<eventsetup::EventSetupRecordKey, std::vector<ESGetTokenGeneric>>;
0062 void doGet(EventSetup const&, RecordToTokens const&) const;
0063
0064 const ParameterSet pSet_;
0065
0066 typedef std::map<eventsetup::EventSetupRecordKey, std::vector<eventsetup::DataKey>> RecordToDataKeys;
0067 RecordToDataKeys recordToDataKeys_;
0068 RecordToTokens recordToTokensRuns_;
0069 RecordToTokens recordToTokensLumis_;
0070 mutable std::map<eventsetup::EventSetupRecordKey, std::atomic<unsigned long long>> recordToCacheIdentifier_;
0071 const bool verbose_;
0072 };
0073
0074
0075
0076
0077 EventSetupRecordDataGetter::EventSetupRecordDataGetter(ParameterSet const& iConfig)
0078 : pSet_(iConfig),
0079 recordToDataKeys_(),
0080 recordToCacheIdentifier_(),
0081 verbose_(iConfig.getUntrackedParameter<bool>("verbose")) {}
0082
0083 EventSetupRecordDataGetter::~EventSetupRecordDataGetter() {
0084
0085
0086 }
0087
0088
0089
0090
0091
0092
0093 void EventSetupRecordDataGetter::fillDescriptions(ConfigurationDescriptions& descriptions) {
0094 descriptions.setComment("Retrieves specified data from the EventSetup sytem whenever that data changes.");
0095
0096 ParameterSetDescription desc;
0097 desc.addUntracked<bool>("verbose", false)
0098 ->setComment("Print a message to the logger each time a data item is gotten.");
0099
0100 ParameterSetDescription toGet;
0101 toGet.add<std::string>("record")->setComment(
0102 "The name of an EventSetup record holding the data you want obtained.");
0103 toGet.add<std::vector<std::string>>("data")->setComment(
0104 "The identifier for the data you wish to retrieve. "
0105 "The identifier is in two parts separated by a backslash '/'. "
0106 "The first part is the C++ class name of the data and the "
0107 "second part is the label used when getting the data (blank is acceptable). "
0108 "If there is no label, the backslash may be omitted.");
0109
0110 std::vector<edm::ParameterSet> emptyVect;
0111 desc.addVPSet("toGet", toGet, emptyVect)
0112 ->setComment(
0113 "The contained PSets must have the following structure.\n"
0114 "A 'string' named 'record' that holds the name of an EventSetup record holding the data you want to "
0115 "obtain.\n"
0116 "a 'vstring' named 'data' that holds identifiers for the data you wish to retrieve. "
0117 "The identifier is in two parts separated by a backslash '/'. "
0118 "The first part is the C++ class name of the data and the "
0119 "second part is the label used when getting the data (blank is acceptable). "
0120 "If there is no label, the backslash may be omitted.\n"
0121 "If the VPSet is empty it means all data in the EventSetup should be retrieved.");
0122 descriptions.add("getEventSetupData", desc);
0123 }
0124
0125 std::shared_ptr<std::nullptr_t> EventSetupRecordDataGetter::globalBeginRun(Run const&,
0126 EventSetup const& iSetup) const {
0127 doGet(iSetup, recordToTokensRuns_);
0128 return {};
0129 }
0130
0131 std::shared_ptr<std::nullptr_t> EventSetupRecordDataGetter::globalBeginLuminosityBlock(
0132 LuminosityBlock const&, EventSetup const& iSetup) const {
0133 doGet(iSetup, recordToTokensLumis_);
0134 return {};
0135 }
0136
0137 void EventSetupRecordDataGetter::analyze(edm::StreamID,
0138 edm::Event const& ,
0139 edm::EventSetup const& iSetup) const {}
0140
0141 void EventSetupRecordDataGetter::registerLateConsumes(eventsetup::ESRecordsToProductResolverIndices const& iInfo) {
0142 auto const& toGet = pSet_.getParameterSetVector("toGet");
0143
0144 for (auto const& iGet : toGet) {
0145 std::string recordName = iGet.getParameter<std::string>("record");
0146
0147 eventsetup::EventSetupRecordKey recordKey(eventsetup::EventSetupRecordKey::TypeTag::findType(recordName));
0148 if (recordKey.type() == eventsetup::EventSetupRecordKey::TypeTag()) {
0149
0150 edm::LogWarning("DataGetter") << "Record \"" << recordName << "\" does not exist " << std::endl;
0151
0152 continue;
0153 }
0154 auto dataNames = iGet.getParameter<std::vector<std::string>>("data");
0155 std::vector<eventsetup::DataKey> dataKeys;
0156 for (auto const& datum : dataNames) {
0157 std::string datumName(datum, 0, datum.find_first_of('/'));
0158 std::string labelName;
0159 if (datum.size() != datumName.size()) {
0160 labelName = std::string(datum, datumName.size() + 1);
0161 }
0162 eventsetup::TypeTag datumType = eventsetup::TypeTag::findType(datumName);
0163 if (datumType == eventsetup::TypeTag()) {
0164
0165 edm::LogWarning("DataGetter") << "data item of type \"" << datumName << "\" does not exist" << std::endl;
0166
0167 continue;
0168 }
0169 eventsetup::DataKey datumKey(datumType, labelName.c_str());
0170 dataKeys.push_back(datumKey);
0171 }
0172 recordToDataKeys_.insert(std::make_pair(recordKey, dataKeys));
0173 recordToCacheIdentifier_.insert(std::make_pair(recordKey, 0));
0174 }
0175 if (toGet.empty()) {
0176
0177 std::vector<eventsetup::EventSetupRecordKey> recordKeys = iInfo.recordKeys();
0178
0179 for (auto const& rKey : recordKeys) {
0180 auto range = iInfo.keysForRecord(rKey);
0181 recordToDataKeys_.insert(std::make_pair(rKey, std::vector<eventsetup::DataKey>(range.first, range.second)));
0182 recordToCacheIdentifier_.insert(std::make_pair(rKey, 0));
0183 }
0184 }
0185 for (auto const& r : recordToDataKeys_) {
0186 auto& runs = recordToTokensRuns_[r.first];
0187 auto& lumis = recordToTokensLumis_[r.first];
0188 runs.reserve(r.second.size());
0189 lumis.reserve(r.second.size());
0190 for (auto const& dk : r.second) {
0191 runs.push_back(esConsumes<edm::Transition::BeginRun>(r.first, dk));
0192 lumis.push_back(esConsumes<edm::Transition::BeginLuminosityBlock>(r.first, dk));
0193 }
0194 }
0195 }
0196
0197 void EventSetupRecordDataGetter::doGet(EventSetup const& iSetup, RecordToTokens const& iRecordToTokens) const {
0198 using namespace edm::eventsetup;
0199
0200
0201
0202 for (auto const& record : recordToDataKeys_) {
0203 auto pRecord = iSetup.find(record.first);
0204 if (not pRecord) {
0205 edm::LogWarning("RecordNotInIOV")
0206 << "The EventSetup Record '" << record.first.name() << "' is not available for this IOV.";
0207 }
0208 auto const& tokens = iRecordToTokens.find(record.first)->second;
0209 auto ci = recordToCacheIdentifier_[record.first].load();
0210 if (pRecord.has_value() && pRecord->cacheIdentifier() != ci) {
0211 recordToCacheIdentifier_[record.first].compare_exchange_strong(ci, pRecord->cacheIdentifier());
0212 auto const& keys = record.second;
0213 size_t i = 0;
0214 for (auto const& token : tokens) {
0215 if (!pRecord->doGet(token)) {
0216 auto const& key = keys[i];
0217 edm::LogWarning("DataGetter")
0218 << "No data of type \"" << key.type().name() << "\" with name \"" << key.name().value()
0219 << "\" in record " << record.first.type().name() << " found " << std::endl;
0220 } else {
0221 if (verbose_) {
0222 auto const& key = keys[i];
0223 edm::LogSystem("DataGetter")
0224 << "got data of type \"" << key.type().name() << "\" with name \"" << key.name().value()
0225 << "\" in record " << record.first.type().name() << std::endl;
0226 }
0227 }
0228 ++i;
0229 }
0230 }
0231 }
0232 }
0233 }
0234 using edm::EventSetupRecordDataGetter;
0235 DEFINE_FWK_MODULE(EventSetupRecordDataGetter);