Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 11:15:39

0001 // -*- C++ -*-
0002 //
0003 // Package:    FWLiteESRecordWriterAnalyzer
0004 // Class:      FWLiteESRecordWriterAnalyzer
0005 //
0006 /**\class FWLiteESRecordWriterAnalyzer FWLiteESRecordWriterAnalyzer.cc PhysicsTools/FWLiteESRecordWriterAnalyzer/src/FWLiteESRecordWriterAnalyzer.cc
0007 
0008  Description: [one line class summary]
0009 
0010  Implementation:
0011      [Notes on implementation]
0012 */
0013 //
0014 // Original Author:  Chris Jones
0015 //         Created:  Fri Jun 18 14:23:07 CDT 2010
0016 //
0017 //
0018 
0019 // system include files
0020 #include <memory>
0021 #include "TFile.h"
0022 #include "FWCore/Reflection/interface/TypeWithDict.h"
0023 
0024 // user include files
0025 #include "FWCore/Framework/interface/Frameworkfwd.h"
0026 #include "FWCore/Framework/interface/one/EDAnalyzer.h"
0027 
0028 #include "FWCore/Framework/interface/EventSetup.h"
0029 #include "FWCore/Framework/interface/EventSetupRecord.h"
0030 #include "FWCore/Framework/interface/EventSetupRecordImplementation.h"
0031 #include "FWCore/Framework/interface/eventsetuprecord_registration_macro.h"
0032 #include "FWCore/Framework/interface/MakerMacros.h"
0033 #include "FWCore/Framework/interface/ESRecordsToProxyIndices.h"
0034 #include "FWCore/Framework/interface/HCTypeTag.h"
0035 
0036 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0037 
0038 #include "PhysicsTools/CondLiteIO/interface/RecordWriter.h"
0039 #include "FWCore/Utilities/interface/EDMException.h"
0040 #include "FWCore/Utilities/interface/ESGetTokenGeneric.h"
0041 
0042 //
0043 // class declaration
0044 //
0045 
0046 namespace {
0047 
0048   struct DataInfo {
0049     DataInfo(const edm::eventsetup::heterocontainer::HCTypeTag& iTag, const std::string& iLabel)
0050         : m_tag(iTag), m_label(iLabel) {}
0051     edm::eventsetup::heterocontainer::HCTypeTag m_tag;
0052     edm::ESGetTokenGeneric m_runToken;
0053     edm::ESGetTokenGeneric m_lumiToken;
0054     std::string m_label;
0055   };
0056 }  // namespace
0057 
0058 namespace fwliteeswriter {
0059   struct DummyType {
0060     const edm::eventsetup::heterocontainer::HCTypeTag* m_tag;
0061     mutable const void* m_data;
0062   };
0063 
0064   class FWLWEventSetupRecord : public edm::eventsetup::EventSetupRecordImplementation<FWLWEventSetupRecord> {
0065   public:
0066     FWLWEventSetupRecord& operator=(const edm::eventsetup::EventSetupRecordGeneric& iOther) {
0067       edm::eventsetup::EventSetupRecord::operator=(iOther);
0068       return *this;
0069     }
0070   };
0071 
0072 }  // namespace fwliteeswriter
0073 
0074 namespace edm {
0075 
0076   template <>
0077   class ESHandle<fwliteeswriter::DummyType> : public ESHandleBase {
0078   public:
0079     //typedef T value_type;
0080 
0081     ESHandle() = default;
0082     ESHandle(void const* iData) : ESHandleBase(iData, nullptr) {}
0083     ESHandle(void const* iData, edm::eventsetup::ComponentDescription const* desc) : ESHandleBase(iData, desc) {}
0084     ESHandle(std::shared_ptr<ESHandleExceptionFactory>&& iWhyFailed) : ESHandleBase(std::move(iWhyFailed)) {}
0085 
0086     // ---------- const member functions ---------------------
0087     void const* product() const { return productStorage(); }
0088     // ---------- static member functions --------------------
0089     static constexpr bool transientAccessOnly = false;
0090 
0091     // ---------- member functions ---------------------------
0092   };
0093 
0094   template <>
0095   class ESGetToken<fwliteeswriter::DummyType, fwliteeswriter::FWLWEventSetupRecord> {
0096     friend class eventsetup::EventSetupRecord;
0097 
0098   public:
0099     explicit constexpr ESGetToken(DataInfo const& info, bool isRun) noexcept : m_info{info}, m_isRun{isRun} {}
0100 
0101     constexpr unsigned int transitionID() const noexcept {
0102       return m_isRun ? m_info.m_runToken.transitionID() : m_info.m_lumiToken.transitionID();
0103     }
0104     constexpr bool isInitialized() const noexcept { return transitionID() != std::numeric_limits<unsigned int>::max(); }
0105     constexpr ESTokenIndex index() const noexcept {
0106       return m_isRun ? m_info.m_runToken.index() : m_info.m_lumiToken.index();
0107     }
0108     constexpr bool hasValidIndex() const noexcept { return index() != invalidIndex(); }
0109     static constexpr ESTokenIndex invalidIndex() noexcept { return ESTokenIndex{std::numeric_limits<int>::max()}; }
0110 
0111     constexpr DataInfo const& dataInfo() const noexcept { return m_info; }
0112 
0113   private:
0114     char const* name() const noexcept { return m_info.m_label.c_str(); }
0115     DataInfo const& m_info;
0116     bool m_isRun;
0117   };
0118 
0119   class EventSetupImpl;
0120 
0121   namespace eventsetup {
0122 
0123     template <>
0124     void EventSetupRecordImpl::getImplementation<fwliteeswriter::DummyType>(
0125         fwliteeswriter::DummyType const*& iData,
0126         ESProxyIndex iProxyIndex,
0127         bool iTransientAccessOnly,
0128         ComponentDescription const*& oDesc,
0129         std::shared_ptr<ESHandleExceptionFactory>& whyFailedFactory) const {
0130       DataKey const* dataKey = nullptr;
0131 
0132       if (iProxyIndex.value() == std::numeric_limits<int>::max()) {
0133         throw cms::Exception("NoProxyException") << "No data of type \"" << iData->m_tag->name()
0134                                                  << "\" with unknown label in record \"" << this->key().name() << "\"";
0135         iData->m_data = nullptr;
0136         return;
0137       }
0138       assert(iProxyIndex.value() > -1 and
0139              iProxyIndex.value() < static_cast<ESProxyIndex::Value_t>(keysForProxies_.size()));
0140       void const* pValue = this->getFromProxyAfterPrefetch(iProxyIndex, iTransientAccessOnly, oDesc, dataKey);
0141       if (nullptr == pValue) {
0142         throw cms::Exception("NoDataException")
0143             << "No data of type \"" << iData->m_tag->name() << "\" with label \"" << dataKey->name().value()
0144             << "\" in record \"" << this->key().name() << "\"";
0145       }
0146       iData->m_data = pValue;
0147     }
0148 
0149     template <>
0150     edm::ESHandle<fwliteeswriter::DummyType>
0151     EventSetupRecord::getHandleImpl<edm::ESHandle, fwliteeswriter::DummyType, fwliteeswriter::FWLWEventSetupRecord>(
0152         ESGetToken<fwliteeswriter::DummyType, fwliteeswriter::FWLWEventSetupRecord> const& iToken) const {
0153       if UNLIKELY (not iToken.isInitialized()) {
0154         std::rethrow_exception(makeUninitializedTokenException(this->key(), iToken.dataInfo().m_tag));
0155       }
0156       if UNLIKELY (iToken.transitionID() != transitionID()) {
0157         throwWrongTransitionID();
0158       }
0159       using TheHandle = edm::ESHandle<fwliteeswriter::DummyType>;
0160       assert(getTokenIndices_);
0161       //need to check token has valid index
0162       if UNLIKELY (not iToken.hasValidIndex()) {
0163         return TheHandle{makeESHandleExceptionFactory(
0164             [key = this->key(), tag = iToken.dataInfo().m_tag, transitionID = iToken.transitionID()] {
0165               return makeInvalidTokenException(key, tag, transitionID);
0166             })};
0167       }
0168 
0169       auto proxyIndex = getTokenIndices_[iToken.index().value()];
0170       if UNLIKELY (proxyIndex.value() == std::numeric_limits<int>::max()) {
0171         return TheHandle(makeESHandleExceptionFactory([iToken, key = this->key()] {
0172           cms::Exception exc("NoProxyException");
0173           exc << "No data of type \"" << iToken.dataInfo().m_tag.name() << "\" with label \"" << iToken.name()
0174               << "\" in record \"" << key.name() << "\"";
0175           return std::make_exception_ptr(exc);
0176         }));
0177       }
0178 
0179       fwliteeswriter::DummyType value;
0180       fwliteeswriter::DummyType const* pValue = &value;
0181       ComponentDescription const* desc = nullptr;
0182       std::shared_ptr<ESHandleExceptionFactory> whyFailedFactory;
0183 
0184       impl_->getImplementation(pValue, proxyIndex, false, desc, whyFailedFactory);
0185 
0186       if UNLIKELY (not value.m_data) {
0187         std::rethrow_exception(whyFailedFactory->make());
0188       }
0189       return edm::ESHandle<fwliteeswriter::DummyType>(value.m_data, desc);
0190     }
0191 
0192   }  // namespace eventsetup
0193 }  // namespace edm
0194 
0195 namespace {
0196 
0197   class RecordHandler {
0198   public:
0199     RecordHandler(const edm::eventsetup::EventSetupRecordKey& iRec, TFile* iFile, std::vector<DataInfo>& ioInfo)
0200         : m_key(iRec), m_record(), m_writer(m_key.name(), iFile), m_cacheID(0) {
0201       m_dataInfos.swap(ioInfo);
0202     }
0203 
0204     void update(const edm::EventSetup& iSetup, bool iIsRun) {
0205       if (not m_record) {
0206         m_record = iSetup.find(m_key);
0207         assert(m_record);
0208       }
0209       if (m_cacheID != m_record->cacheIdentifier()) {
0210         m_cacheID = m_record->cacheIdentifier();
0211 
0212         for (std::vector<DataInfo>::const_iterator it = m_dataInfos.begin(), itEnd = m_dataInfos.end(); it != itEnd;
0213              ++it) {
0214           fwliteeswriter::FWLWEventSetupRecord tempRecord;
0215           tempRecord = *m_record;
0216           edm::ESGetToken<fwliteeswriter::DummyType, fwliteeswriter::FWLWEventSetupRecord> token(*it, iIsRun);
0217           auto h = tempRecord.getHandle(token);
0218           m_writer.update(h.product(), (it->m_tag.value()), it->m_label.c_str());
0219         }
0220         edm::ValidityInterval const& iov = m_record->validityInterval();
0221         m_writer.fill(edm::ESRecordAuxiliary(iov.first().eventID(), iov.first().time()));
0222       }
0223     }
0224 
0225   private:
0226     edm::eventsetup::EventSetupRecordKey m_key;
0227     std::optional<edm::eventsetup::EventSetupRecordGeneric> m_record;
0228     fwlite::RecordWriter m_writer;
0229     unsigned long long m_cacheID;
0230     std::vector<DataInfo> m_dataInfos;
0231   };
0232 }  // namespace
0233 
0234 class FWLiteESRecordWriterAnalyzer : public edm::one::EDAnalyzer<edm::one::WatchRuns, edm::one::WatchLuminosityBlocks> {
0235 public:
0236   explicit FWLiteESRecordWriterAnalyzer(const edm::ParameterSet&);
0237   ~FWLiteESRecordWriterAnalyzer() override;
0238 
0239 private:
0240   void beginJob() override;
0241   void analyze(const edm::Event&, const edm::EventSetup&) override;
0242   void endJob() override;
0243   void beginRun(edm::Run const&, edm::EventSetup const&) override;
0244   void beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override;
0245   void endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override {}
0246   void endRun(edm::Run const&, edm::EventSetup const&) override {}
0247 
0248   void update(const edm::EventSetup&, bool isRun);
0249 
0250   void registerLateConsumes(edm::eventsetup::ESRecordsToProxyIndices const&) final;
0251 
0252   // ----------member data ---------------------------
0253   std::vector<std::shared_ptr<RecordHandler> > m_handlers;
0254 
0255   std::map<std::string, std::vector<std::pair<std::string, std::string> > > m_recordToDataNames;
0256   TFile* m_file;
0257 };
0258 
0259 //
0260 // constants, enums and typedefs
0261 //
0262 
0263 //
0264 // static data member definitions
0265 //
0266 
0267 //
0268 // constructors and destructor
0269 //
0270 FWLiteESRecordWriterAnalyzer::FWLiteESRecordWriterAnalyzer(const edm::ParameterSet& iConfig) {
0271   std::vector<std::string> names = iConfig.getParameterNamesForType<std::vector<edm::ParameterSet> >(false);
0272   if (names.empty()) {
0273     throw edm::Exception(edm::errors::Configuration) << "No VPSets were given in configuration";
0274   }
0275   for (std::vector<std::string>::const_iterator it = names.begin(), itEnd = names.end(); it != itEnd; ++it) {
0276     const std::vector<edm::ParameterSet>& ps = iConfig.getUntrackedParameter<std::vector<edm::ParameterSet> >(*it);
0277     std::vector<std::pair<std::string, std::string> >& data = m_recordToDataNames[*it];
0278     for (std::vector<edm::ParameterSet>::const_iterator itPS = ps.begin(), itPSEnd = ps.end(); itPS != itPSEnd;
0279          ++itPS) {
0280       std::string type = itPS->getUntrackedParameter<std::string>("type");
0281       std::string label = itPS->getUntrackedParameter<std::string>("label", std::string());
0282       data.push_back(std::make_pair(type, label));
0283     }
0284   }
0285 
0286   m_file = TFile::Open(iConfig.getUntrackedParameter<std::string>("fileName").c_str(), "NEW");
0287 }
0288 
0289 void FWLiteESRecordWriterAnalyzer::registerLateConsumes(edm::eventsetup::ESRecordsToProxyIndices const& iInfo) {
0290   using edm::eventsetup::heterocontainer::HCTypeTag;
0291 
0292   for (auto it = m_recordToDataNames.begin(), itEnd = m_recordToDataNames.end(); it != itEnd; ++it) {
0293     HCTypeTag tt = HCTypeTag::findType(it->first);
0294     if (tt == HCTypeTag()) {
0295       throw cms::Exception("UnknownESRecordType")
0296           << "The name '" << it->first
0297           << "' is not associated with a known EventSetupRecord.\n"
0298              "Please check spelling or load a module known to link with the package which declares that Record.";
0299     }
0300     edm::eventsetup::EventSetupRecordKey rKey(tt);
0301 
0302     auto recIndex = iInfo.recordIndexFor(rKey);
0303     if (recIndex == iInfo.missingRecordIndex()) {
0304       throw cms::Exception("UnknownESRecordType")
0305           << "The name '" << it->first
0306           << "' is not associated with a type which is not an EventSetupRecord.\n"
0307              "Please check your spelling.";
0308     }
0309 
0310     //now figure out what data
0311     std::vector<std::pair<std::string, std::string> >& data = it->second;
0312     if (data.empty()) {
0313       //get everything from the record
0314       auto keys = iInfo.keysForRecord(rKey);
0315       for (auto itKey = keys.first, itKeyEnd = keys.second; itKey != itKeyEnd; ++itKey) {
0316         data.push_back(std::make_pair(std::string(itKey->type().name()), std::string(itKey->name().value())));
0317       }
0318     }
0319 
0320     std::vector<DataInfo> dataInfos;
0321     for (std::vector<std::pair<std::string, std::string> >::iterator itData = data.begin(), itDataEnd = data.end();
0322          itData != itDataEnd;
0323          ++itData) {
0324       HCTypeTag tt = HCTypeTag::findType(itData->first);
0325       if (tt == HCTypeTag()) {
0326         throw cms::Exception("UnknownESDataType")
0327             << "The name '" << itData->first << "' is not associated with a known type held in the " << it->first
0328             << " Record.\n"
0329                "Please check spelling or load a module known to link with the package which declares that type.";
0330       }
0331       if (!bool(edm::TypeWithDict(tt.value()))) {
0332         throw cms::Exception("NoDictionary")
0333             << "The type '" << itData->first << "' can not be retrieved from the Record " << it->first
0334             << " and stored \n"
0335                "because no dictionary exists for the type.";
0336       }
0337       dataInfos.push_back(DataInfo(tt, itData->second));
0338       dataInfos.back().m_runToken =
0339           esConsumes<edm::Transition::BeginRun>(rKey, edm::eventsetup::DataKey(tt, itData->second.c_str()));
0340       dataInfos.back().m_lumiToken =
0341           esConsumes<edm::Transition::BeginLuminosityBlock>(rKey, edm::eventsetup::DataKey(tt, itData->second.c_str()));
0342     }
0343     m_handlers.push_back(std::make_shared<RecordHandler>(rKey, m_file, dataInfos));
0344   }
0345 }
0346 
0347 FWLiteESRecordWriterAnalyzer::~FWLiteESRecordWriterAnalyzer() {
0348   // do anything here that needs to be done at desctruction time
0349   // (e.g. close files, deallocate resources etc.)
0350   m_file->Close();
0351   delete m_file;
0352 }
0353 
0354 //
0355 // member functions
0356 //
0357 void FWLiteESRecordWriterAnalyzer::update(const edm::EventSetup& iSetup, bool isRun) {
0358   for (std::vector<std::shared_ptr<RecordHandler> >::iterator it = m_handlers.begin(), itEnd = m_handlers.end();
0359        it != itEnd;
0360        ++it) {
0361     (*it)->update(iSetup, isRun);
0362   }
0363 }
0364 
0365 // ------------ method called to for each event  ------------
0366 void FWLiteESRecordWriterAnalyzer::analyze(const edm::Event& /*iEvent*/, const edm::EventSetup& iSetup) {}
0367 
0368 // ------------ method called once each job just before starting event loop  ------------
0369 void FWLiteESRecordWriterAnalyzer::beginJob() {}
0370 
0371 // ------------ method called once each job just after ending the event loop  ------------
0372 void FWLiteESRecordWriterAnalyzer::endJob() { m_file->Write(); }
0373 
0374 void FWLiteESRecordWriterAnalyzer::beginRun(edm::Run const&, edm::EventSetup const& iSetup) { update(iSetup, true); }
0375 void FWLiteESRecordWriterAnalyzer::beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const& iSetup) {
0376   update(iSetup, false);
0377 }
0378 
0379 //define this as a plug-in
0380 DEFINE_FWK_MODULE(FWLiteESRecordWriterAnalyzer);
0381 
0382 EVENTSETUP_RECORD_REG(fwliteeswriter::FWLWEventSetupRecord);