Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-10-07 04:59:51

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/ESRecordsToProductResolverIndices.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         ESResolverIndex iResolverIndex,
0127         bool iTransientAccessOnly,
0128         ComponentDescription const*& oDesc,
0129         std::shared_ptr<ESHandleExceptionFactory>& whyFailedFactory) const {
0130       DataKey const* dataKey = nullptr;
0131 
0132       if (iResolverIndex.value() == std::numeric_limits<int>::max()) {
0133         throw cms::Exception("NoProductResolverException")
0134             << "No data of type \"" << iData->m_tag->name() << "\" with unknown label in record \""
0135             << this->key().name() << "\"";
0136         iData->m_data = nullptr;
0137         return;
0138       }
0139       assert(iResolverIndex.value() > -1 and
0140              iResolverIndex.value() < static_cast<ESResolverIndex::Value_t>(keysForResolvers_.size()));
0141       void const* pValue = this->getFromResolverAfterPrefetch(iResolverIndex, iTransientAccessOnly, oDesc, dataKey);
0142       if (nullptr == pValue) {
0143         throw cms::Exception("NoDataException")
0144             << "No data of type \"" << iData->m_tag->name() << "\" with label \"" << dataKey->name().value()
0145             << "\" in record \"" << this->key().name() << "\"";
0146       }
0147       iData->m_data = pValue;
0148     }
0149 
0150     template <>
0151     edm::ESHandle<fwliteeswriter::DummyType>
0152     EventSetupRecord::getHandleImpl<edm::ESHandle, fwliteeswriter::DummyType, fwliteeswriter::FWLWEventSetupRecord>(
0153         ESGetToken<fwliteeswriter::DummyType, fwliteeswriter::FWLWEventSetupRecord> const& iToken) const {
0154       if UNLIKELY (not iToken.isInitialized()) {
0155         std::rethrow_exception(makeUninitializedTokenException(this->key(), iToken.dataInfo().m_tag));
0156       }
0157       if UNLIKELY (iToken.transitionID() != transitionID()) {
0158         throwWrongTransitionID();
0159       }
0160       using TheHandle = edm::ESHandle<fwliteeswriter::DummyType>;
0161       assert(getTokenIndices_);
0162       //need to check token has valid index
0163       if UNLIKELY (not iToken.hasValidIndex()) {
0164         return TheHandle{makeESHandleExceptionFactory(
0165             [key = this->key(), tag = iToken.dataInfo().m_tag, transitionID = iToken.transitionID()] {
0166               return makeInvalidTokenException(key, tag, transitionID);
0167             })};
0168       }
0169 
0170       auto proxyIndex = getTokenIndices_[iToken.index().value()];
0171       if UNLIKELY (proxyIndex.value() == std::numeric_limits<int>::max()) {
0172         return TheHandle(makeESHandleExceptionFactory([iToken, key = this->key()] {
0173           cms::Exception exc("NoProductResolverException");
0174           exc << "No data of type \"" << iToken.dataInfo().m_tag.name() << "\" with label \"" << iToken.name()
0175               << "\" in record \"" << key.name() << "\"";
0176           return std::make_exception_ptr(exc);
0177         }));
0178       }
0179 
0180       fwliteeswriter::DummyType value;
0181       fwliteeswriter::DummyType const* pValue = &value;
0182       ComponentDescription const* desc = nullptr;
0183       std::shared_ptr<ESHandleExceptionFactory> whyFailedFactory;
0184 
0185       impl_->getImplementation(pValue, proxyIndex, false, desc, whyFailedFactory);
0186 
0187       if UNLIKELY (not value.m_data) {
0188         std::rethrow_exception(whyFailedFactory->make());
0189       }
0190       return edm::ESHandle<fwliteeswriter::DummyType>(value.m_data, desc);
0191     }
0192 
0193   }  // namespace eventsetup
0194 }  // namespace edm
0195 
0196 namespace {
0197 
0198   class RecordHandler {
0199   public:
0200     RecordHandler(const edm::eventsetup::EventSetupRecordKey& iRec, TFile* iFile, std::vector<DataInfo>& ioInfo)
0201         : m_key(iRec), m_record(), m_writer(m_key.name(), iFile), m_cacheID(0) {
0202       m_dataInfos.swap(ioInfo);
0203     }
0204 
0205     void update(const edm::EventSetup& iSetup, bool iIsRun) {
0206       if (not m_record) {
0207         m_record = iSetup.find(m_key);
0208         assert(m_record);
0209       }
0210       if (m_cacheID != m_record->cacheIdentifier()) {
0211         m_cacheID = m_record->cacheIdentifier();
0212 
0213         for (std::vector<DataInfo>::const_iterator it = m_dataInfos.begin(), itEnd = m_dataInfos.end(); it != itEnd;
0214              ++it) {
0215           fwliteeswriter::FWLWEventSetupRecord tempRecord;
0216           tempRecord = *m_record;
0217           edm::ESGetToken<fwliteeswriter::DummyType, fwliteeswriter::FWLWEventSetupRecord> token(*it, iIsRun);
0218           auto h = tempRecord.getHandle(token);
0219           m_writer.update(h.product(), (it->m_tag.value()), it->m_label.c_str());
0220         }
0221         edm::ValidityInterval const& iov = m_record->validityInterval();
0222         m_writer.fill(edm::ESRecordAuxiliary(iov.first().eventID(), iov.first().time()));
0223       }
0224     }
0225 
0226   private:
0227     edm::eventsetup::EventSetupRecordKey m_key;
0228     std::optional<edm::eventsetup::EventSetupRecordGeneric> m_record;
0229     fwlite::RecordWriter m_writer;
0230     unsigned long long m_cacheID;
0231     std::vector<DataInfo> m_dataInfos;
0232   };
0233 }  // namespace
0234 
0235 class FWLiteESRecordWriterAnalyzer : public edm::one::EDAnalyzer<edm::one::WatchRuns, edm::one::WatchLuminosityBlocks> {
0236 public:
0237   explicit FWLiteESRecordWriterAnalyzer(const edm::ParameterSet&);
0238   ~FWLiteESRecordWriterAnalyzer() override;
0239 
0240 private:
0241   void beginJob() override;
0242   void analyze(const edm::Event&, const edm::EventSetup&) override;
0243   void endJob() override;
0244   void beginRun(edm::Run const&, edm::EventSetup const&) override;
0245   void beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override;
0246   void endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override {}
0247   void endRun(edm::Run const&, edm::EventSetup const&) override {}
0248 
0249   void update(const edm::EventSetup&, bool isRun);
0250 
0251   void registerLateConsumes(edm::eventsetup::ESRecordsToProductResolverIndices const&) final;
0252 
0253   // ----------member data ---------------------------
0254   std::vector<std::shared_ptr<RecordHandler> > m_handlers;
0255 
0256   std::map<std::string, std::vector<std::pair<std::string, std::string> > > m_recordToDataNames;
0257   TFile* m_file;
0258 };
0259 
0260 //
0261 // constants, enums and typedefs
0262 //
0263 
0264 //
0265 // static data member definitions
0266 //
0267 
0268 //
0269 // constructors and destructor
0270 //
0271 FWLiteESRecordWriterAnalyzer::FWLiteESRecordWriterAnalyzer(const edm::ParameterSet& iConfig) {
0272   std::vector<std::string> names = iConfig.getParameterNamesForType<std::vector<edm::ParameterSet> >(false);
0273   if (names.empty()) {
0274     throw edm::Exception(edm::errors::Configuration) << "No VPSets were given in configuration";
0275   }
0276   for (std::vector<std::string>::const_iterator it = names.begin(), itEnd = names.end(); it != itEnd; ++it) {
0277     const std::vector<edm::ParameterSet>& ps = iConfig.getUntrackedParameter<std::vector<edm::ParameterSet> >(*it);
0278     std::vector<std::pair<std::string, std::string> >& data = m_recordToDataNames[*it];
0279     for (std::vector<edm::ParameterSet>::const_iterator itPS = ps.begin(), itPSEnd = ps.end(); itPS != itPSEnd;
0280          ++itPS) {
0281       std::string type = itPS->getUntrackedParameter<std::string>("type");
0282       std::string label = itPS->getUntrackedParameter<std::string>("label", std::string());
0283       data.push_back(std::make_pair(type, label));
0284     }
0285   }
0286 
0287   m_file = TFile::Open(iConfig.getUntrackedParameter<std::string>("fileName").c_str(), "NEW");
0288 }
0289 
0290 void FWLiteESRecordWriterAnalyzer::registerLateConsumes(
0291     edm::eventsetup::ESRecordsToProductResolverIndices const& iInfo) {
0292   using edm::eventsetup::heterocontainer::HCTypeTag;
0293 
0294   for (auto it = m_recordToDataNames.begin(), itEnd = m_recordToDataNames.end(); it != itEnd; ++it) {
0295     HCTypeTag tt = HCTypeTag::findType(it->first);
0296     if (tt == HCTypeTag()) {
0297       throw cms::Exception("UnknownESRecordType")
0298           << "The name '" << it->first
0299           << "' is not associated with a known EventSetupRecord.\n"
0300              "Please check spelling or load a module known to link with the package which declares that Record.";
0301     }
0302     edm::eventsetup::EventSetupRecordKey rKey(tt);
0303 
0304     auto recIndex = iInfo.recordIndexFor(rKey);
0305     if (recIndex == iInfo.missingRecordIndex()) {
0306       throw cms::Exception("UnknownESRecordType")
0307           << "The name '" << it->first
0308           << "' is not associated with a type which is not an EventSetupRecord.\n"
0309              "Please check your spelling.";
0310     }
0311 
0312     //now figure out what data
0313     std::vector<std::pair<std::string, std::string> >& data = it->second;
0314     if (data.empty()) {
0315       //get everything from the record
0316       auto keys = iInfo.keysForRecord(rKey);
0317       for (auto itKey = keys.first, itKeyEnd = keys.second; itKey != itKeyEnd; ++itKey) {
0318         data.push_back(std::make_pair(std::string(itKey->type().name()), std::string(itKey->name().value())));
0319       }
0320     }
0321 
0322     std::vector<DataInfo> dataInfos;
0323     for (std::vector<std::pair<std::string, std::string> >::iterator itData = data.begin(), itDataEnd = data.end();
0324          itData != itDataEnd;
0325          ++itData) {
0326       HCTypeTag tt = HCTypeTag::findType(itData->first);
0327       if (tt == HCTypeTag()) {
0328         throw cms::Exception("UnknownESDataType")
0329             << "The name '" << itData->first << "' is not associated with a known type held in the " << it->first
0330             << " Record.\n"
0331                "Please check spelling or load a module known to link with the package which declares that type.";
0332       }
0333       if (!bool(edm::TypeWithDict(tt.value()))) {
0334         throw cms::Exception("NoDictionary")
0335             << "The type '" << itData->first << "' can not be retrieved from the Record " << it->first
0336             << " and stored \n"
0337                "because no dictionary exists for the type.";
0338       }
0339       dataInfos.push_back(DataInfo(tt, itData->second));
0340       dataInfos.back().m_runToken =
0341           esConsumes<edm::Transition::BeginRun>(rKey, edm::eventsetup::DataKey(tt, itData->second.c_str()));
0342       dataInfos.back().m_lumiToken =
0343           esConsumes<edm::Transition::BeginLuminosityBlock>(rKey, edm::eventsetup::DataKey(tt, itData->second.c_str()));
0344     }
0345     m_handlers.push_back(std::make_shared<RecordHandler>(rKey, m_file, dataInfos));
0346   }
0347 }
0348 
0349 FWLiteESRecordWriterAnalyzer::~FWLiteESRecordWriterAnalyzer() {
0350   // do anything here that needs to be done at desctruction time
0351   // (e.g. close files, deallocate resources etc.)
0352   m_file->Close();
0353   delete m_file;
0354 }
0355 
0356 //
0357 // member functions
0358 //
0359 void FWLiteESRecordWriterAnalyzer::update(const edm::EventSetup& iSetup, bool isRun) {
0360   for (std::vector<std::shared_ptr<RecordHandler> >::iterator it = m_handlers.begin(), itEnd = m_handlers.end();
0361        it != itEnd;
0362        ++it) {
0363     (*it)->update(iSetup, isRun);
0364   }
0365 }
0366 
0367 // ------------ method called to for each event  ------------
0368 void FWLiteESRecordWriterAnalyzer::analyze(const edm::Event& /*iEvent*/, const edm::EventSetup& iSetup) {}
0369 
0370 // ------------ method called once each job just before starting event loop  ------------
0371 void FWLiteESRecordWriterAnalyzer::beginJob() {}
0372 
0373 // ------------ method called once each job just after ending the event loop  ------------
0374 void FWLiteESRecordWriterAnalyzer::endJob() { m_file->Write(); }
0375 
0376 void FWLiteESRecordWriterAnalyzer::beginRun(edm::Run const&, edm::EventSetup const& iSetup) { update(iSetup, true); }
0377 void FWLiteESRecordWriterAnalyzer::beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const& iSetup) {
0378   update(iSetup, false);
0379 }
0380 
0381 //define this as a plug-in
0382 DEFINE_FWK_MODULE(FWLiteESRecordWriterAnalyzer);
0383 
0384 EVENTSETUP_RECORD_REG(fwliteeswriter::FWLWEventSetupRecord);