Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:28:47

0001 // -*- C++ -*-
0002 //
0003 // Package:    EventSetupRecordDataGetter
0004 // Class:      EventSetupRecordDataGetter
0005 //
0006 /**\class EventSetupRecordDataGetter EventSetupRecordDataGetter.cc src/EventSetupRecordDataGetter/src/EventSetupRecordDataGetter.cc
0007 
0008  Description: Can be configured to 'get' any Data in any EventSetup Record.  Primarily used for testing.
0009 
0010  Implementation:
0011      <Notes on implementation>
0012 */
0013 //
0014 // Original Author:  Chris Jones
0015 //         Created:  Tue Jun 28 11:10:24 EDT 2005
0016 //
0017 //
0018 
0019 // system include files
0020 #include <map>
0021 #include <vector>
0022 #include <memory>
0023 #include <set>
0024 #include <iostream>
0025 
0026 // user include files
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/ESRecordsToProxyIndices.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 // class decleration
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::ESRecordsToProxyIndices const&) final;
0060 
0061     using RecordToTokens = std::map<eventsetup::EventSetupRecordKey, std::vector<ESGetTokenGeneric>>;
0062     void doGet(EventSetup const&, RecordToTokens const&) const;
0063     // ----------member data ---------------------------
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   // constructors and destructor
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     // do anything here that needs to be done at desctruction time
0085     // (e.g. close files, deallocate resources etc.)
0086   }
0087 
0088   //
0089   // member functions
0090   //
0091 
0092   // ------------ method called to produce the data  ------------
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& /*iEvent*/,
0139                                            edm::EventSetup const& iSetup) const {}
0140 
0141   void EventSetupRecordDataGetter::registerLateConsumes(eventsetup::ESRecordsToProxyIndices 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         //record not found
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           //not found
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       //This means we should get everything in the EventSetup
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     //For each requested Record get the requested data only if the Record is in a new IOV
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 }  // namespace edm
0234 using edm::EventSetupRecordDataGetter;
0235 DEFINE_FWK_MODULE(EventSetupRecordDataGetter);