Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:13:46

0001 #ifndef DQMServices_Core_DQMOneEDAnalyzer_h
0002 #define DQMServices_Core_DQMOneEDAnalyzer_h
0003 
0004 #include "DQMServices/Core/interface/DQMStore.h"
0005 #include "FWCore/Framework/interface/Event.h"
0006 #include "FWCore/Framework/interface/Run.h"
0007 #include "FWCore/ServiceRegistry/interface/Service.h"
0008 #include "FWCore/Framework/interface/one/EDProducer.h"
0009 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0010 #include "DataFormats/Histograms/interface/DQMToken.h"
0011 
0012 /**
0013  * A "one" module base class that can only produce per-run histograms. This
0014  * allows to easily wrap non-thread-safe code and is ok'ish performance-wise,
0015  * since it only blocks concurrent runs, not concurrent lumis.
0016  * It can be combined with edm::LuminosityBlockCache to watch per-lumi things,
0017  * and fill per-run histograms with the results.
0018  */
0019 template <typename... Args>
0020 class DQMOneEDAnalyzer
0021     : public edm::one::EDProducer<edm::EndRunProducer, edm::one::WatchRuns, edm::Accumulator, Args...> {
0022 public:
0023   typedef dqm::reco::DQMStore DQMStore;
0024   typedef dqm::reco::MonitorElement MonitorElement;
0025 
0026   virtual bool getCanSaveByLumi() { return true; }
0027 
0028   // framework calls in the order of invocation
0029   DQMOneEDAnalyzer() {
0030     // for whatever reason we need the explicit `template` keyword here.
0031     runToken_ = this->template produces<DQMToken, edm::Transition::EndRun>("DQMGenerationRecoRun");
0032   }
0033 
0034   void beginRun(edm::Run const& run, edm::EventSetup const& setup) final {
0035     // if we run booking multiple times because there are multiple runs in a
0036     // job, this is needed to make sure all existing MEs are in a valid state
0037     // before the booking code runs.
0038     edm::Service<DQMStore>()->initLumi(run.run(), /* lumi */ 0, this->moduleDescription().id());
0039     edm::Service<DQMStore>()->enterLumi(run.run(), /* lumi */ 0, this->moduleDescription().id());
0040     dqmBeginRun(run, setup);
0041     edm::Service<DQMStore>()->bookTransaction(
0042         [this, &run, &setup](DQMStore::IBooker& booker) {
0043           booker.cd();
0044           this->bookHistograms(booker, run, setup);
0045         },
0046         this->moduleDescription().id(),
0047         this->getCanSaveByLumi());
0048     edm::Service<DQMStore>()->initLumi(run.run(), /* lumi */ 0, this->moduleDescription().id());
0049     edm::Service<DQMStore>()->enterLumi(run.run(), /* lumi */ 0, this->moduleDescription().id());
0050   }
0051 
0052   void accumulate(edm::Event const& event, edm::EventSetup const& setup) override {
0053     auto& lumi = event.getLuminosityBlock();
0054     edm::Service<dqm::legacy::DQMStore>()->enterLumi(
0055         lumi.run(), lumi.luminosityBlock(), this->moduleDescription().id());
0056     analyze(event, setup);
0057     edm::Service<dqm::legacy::DQMStore>()->leaveLumi(
0058         lumi.run(), lumi.luminosityBlock(), this->moduleDescription().id());
0059   }
0060 
0061   void endRunProduce(edm::Run& run, edm::EventSetup const& setup) final {
0062     dqmEndRun(run, setup);
0063     edm::Service<DQMStore>()->leaveLumi(run.run(), /* lumi */ 0, this->moduleDescription().id());
0064     run.emplace<DQMToken>(runToken_);
0065   }
0066 
0067   // Subsystems could safely override this, but any changes to MEs would not be
0068   // noticeable since the product was made already.
0069   void endRun(edm::Run const&, edm::EventSetup const&) final{};
0070 
0071 protected:
0072   // methods to be implemented by the user, in order of invocation
0073   virtual void dqmBeginRun(edm::Run const&, edm::EventSetup const&) {}
0074   virtual void bookHistograms(DQMStore::IBooker&, edm::Run const&, edm::EventSetup const&) = 0;
0075   virtual void analyze(edm::Event const&, edm::EventSetup const&) {}
0076   virtual void dqmEndRun(edm::Run const&, edm::EventSetup const&) {}
0077 
0078   edm::EDPutTokenT<DQMToken> runToken_;
0079 };
0080 
0081 /**
0082  * A "one" module base class that can also watch lumi transitions and produce
0083  * per-lumi MEs. This should be used carefully, since it will block concurrent
0084  * lumisections in the entire job!
0085  * Combining with edm::LuminosityBlockCache is pointless and will not work
0086  * properly, due to the ordering of global/produce transitions.
0087  */
0088 
0089 template <typename... Args>
0090 class DQMOneLumiEDAnalyzer
0091     : public DQMOneEDAnalyzer<edm::EndLuminosityBlockProducer, edm::one::WatchLuminosityBlocks, Args...> {
0092 public:
0093   bool getCanSaveByLumi() override { return true; }
0094 
0095   // framework calls in the order of invocation
0096   DQMOneLumiEDAnalyzer() {
0097     // for whatever reason we need the explicit `template` keyword here.
0098     lumiToken_ = this->template produces<DQMToken, edm::Transition::EndLuminosityBlock>("DQMGenerationRecoLumi");
0099   }
0100 
0101   void beginLuminosityBlock(edm::LuminosityBlock const& lumi, edm::EventSetup const& setup) final {
0102     edm::Service<dqm::legacy::DQMStore>()->enterLumi(
0103         lumi.run(), lumi.luminosityBlock(), this->moduleDescription().id());
0104     dqmBeginLuminosityBlock(lumi, setup);
0105   }
0106 
0107   void accumulate(edm::Event const& event, edm::EventSetup const& setup) override { this->analyze(event, setup); }
0108 
0109   void endLuminosityBlockProduce(edm::LuminosityBlock& lumi, edm::EventSetup const& setup) final {
0110     dqmEndLuminosityBlock(lumi, setup);
0111     // fully qualified name required for... reasons.
0112     edm::Service<dqm::legacy::DQMStore>()->leaveLumi(
0113         lumi.run(), lumi.luminosityBlock(), this->moduleDescription().id());
0114     lumi.emplace(lumiToken_);
0115   }
0116 
0117   // Subsystems could safely override this, but any changes to MEs would not be
0118   // noticeable since the product was made already.
0119   void endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) final{};
0120 
0121 protected:
0122   // methods to be implemented by the user, in order of invocation
0123   virtual void dqmBeginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) {}
0124   virtual void dqmEndLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) {}
0125 
0126   edm::EDPutTokenT<DQMToken> lumiToken_;
0127 };
0128 
0129 #endif  // DQMServices_Core_DQMOneEDAnalyzer_h