Skip to content

Commit

Permalink
Import DQMEDHarvester from new DQMStore branch.
Browse files Browse the repository at this point in the history
Compared to the old code, this properly uses tokens, and exposes a few
more callbacks to allow porting more legacy modules.
  • Loading branch information
schneiml committed Nov 5, 2019
1 parent 7b735fe commit 361c26a
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 55 deletions.
147 changes: 125 additions & 22 deletions DQMServices/Core/interface/DQMEDHarvester.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,150 @@
#define CORE_DQMED_HARVESTER_H

#include "DQMServices/Core/interface/DQMStore.h"

#include "FWCore/Framework/interface/one/EDProducer.h"

#include "FWCore/Framework/interface/Run.h"
#include "FWCore/Framework/interface/Event.h"
#include "FWCore/Framework/interface/EventSetup.h"
#include "FWCore/Framework/interface/LuminosityBlock.h"
#include "FWCore/Framework/interface/Run.h"
#include "FWCore/Framework/interface/one/EDProducer.h"

#include "FWCore/Framework/interface/InputTagMatch.h"
#include "FWCore/Framework/interface/GetterOfProducts.h"
#include "FWCore/ServiceRegistry/interface/Service.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/Utilities/interface/EDPutToken.h"

#include "DataFormats/Histograms/interface/DQMToken.h"

class DQMEDHarvester : public edm::one::EDProducer<edm::Accumulator,
edm::EndLuminosityBlockProducer,
edm::EndRunProducer,
edm::one::WatchLuminosityBlocks,
edm::one::WatchRuns,
edm::one::SharedResources> {
namespace edm {
class VInputTagMatch {
public:
VInputTagMatch(std::vector<edm::InputTag> const &inputTags) {
for (auto &tag : inputTags) {
matchers_.emplace_back(InputTagMatch(tag));
}
}

bool operator()(edm::BranchDescription const &branchDescription) {
for (auto &m : matchers_) {
if (m(branchDescription)) {
return true;
}
}
return false;
}

private:
std::vector<InputTagMatch> matchers_;
};
} // namespace edm

class DQMEDHarvester
: public edm::one::EDProducer<edm::EndLuminosityBlockProducer,
edm::EndRunProducer,
edm::one::WatchLuminosityBlocks,
edm::one::WatchRuns,
// for uncontrolled DQMStore access, and that EDM does not even attempt to
// run things in parallel (which would then be blocked by the booking lock).
edm::one::SharedResources,
edm::Accumulator> {
public:
typedef dqm::harvesting::DQMStore DQMStore;
typedef dqm::harvesting::MonitorElement MonitorElement;
DQMEDHarvester();
~DQMEDHarvester() override = default;

void accumulate(edm::Event const &ev, edm::EventSetup const &es) final{};
protected:
DQMStore *dqmstore_;
edm::GetterOfProducts<DQMToken> runmegetter_;
edm::GetterOfProducts<DQMToken> lumimegetter_;
edm::EDPutTokenT<DQMToken> lumiToken_;
edm::EDPutTokenT<DQMToken> runToken_;

public:
DQMEDHarvester(edm::ParameterSet const &iConfig) {
usesResource("DQMStore");
dqmstore_ = edm::Service<DQMStore>().operator->();
// TODO: Run/Lumi suffix should not be needed, complain to CMSSW core in case.
lumiToken_ = produces<DQMToken, edm::Transition::EndLuminosityBlock>("DQMGenerationHarvestingLumi");
runToken_ = produces<DQMToken, edm::Transition::EndRun>("DQMGenerationHarvestingRun");

// Use explicitly specified inputs, but if there are none...
auto inputtags =
iConfig.getUntrackedParameter<std::vector<edm::InputTag>>("inputMEs", std::vector<edm::InputTag>());
if (inputtags.empty()) {
// ... use all RECO MEs.
inputtags.push_back(edm::InputTag("", "DQMGenerationRecoRun"));
inputtags.push_back(edm::InputTag("", "DQMGenerationRecoLumi"));
}
runmegetter_ = edm::GetterOfProducts<DQMToken>(edm::VInputTagMatch(inputtags), this, edm::InRun);
lumimegetter_ = edm::GetterOfProducts<DQMToken>(edm::VInputTagMatch(inputtags), this, edm::InLumi);
callWhenNewProductsRegistered([this](edm::BranchDescription const &bd) {
runmegetter_(bd);
lumimegetter_(bd);
});
};

DQMEDHarvester() : DQMEDHarvester(edm::ParameterSet()){};

void beginJob() override{};

void beginRun(edm::Run const &run, edm::EventSetup const &) override {
// According to edm experts, it is never save to look at run products
// in beginRun, since they might be merged as new input files how up.
}

void beginLuminosityBlock(edm::LuminosityBlock const &lumi, edm::EventSetup const &) final {
// According to edm experts, it is never save to look at run products
// in beginRun, since they might be merged as new input files how up.
}

void accumulate(edm::Event const &ev, edm::EventSetup const &es) final {
dqmstore_->meBookerGetter(
[this, &ev, &es](DQMStore::IBooker &b, DQMStore::IGetter &g) { this->dqmAnalyze(b, g, ev, es); });
}

void endLuminosityBlockProduce(edm::LuminosityBlock &lumi, edm::EventSetup const &es) final {
// No need to actually get products for now
//auto refs = std::vector<edm::Handle<DQMToken>>();
//lumimegetter_.fillHandles(lumi, refs);

dqmstore_->meBookerGetter([this, &lumi, &es](DQMStore::IBooker &b, DQMStore::IGetter &g) {
this->dqmEndLuminosityBlock(b, g, lumi, es);
});

lumi.put(lumiToken_, std::make_unique<DQMToken>());
}

void endLuminosityBlock(edm::LuminosityBlock const &, edm::EventSetup const &) final{};

void endRunProduce(edm::Run &run, edm::EventSetup const &es) final {
dqmstore_->meBookerGetter(
[this, &run, &es](DQMStore::IBooker &b, DQMStore::IGetter &g) { this->dqmEndRun(b, g, run, es); });

run.put(runToken_, std::make_unique<DQMToken>());
}

void beginRun(edm::Run const &, edm::EventSetup const &) override{};
void endRun(edm::Run const &, edm::EventSetup const &) override{};
void endRunProduce(edm::Run &run, edm::EventSetup const &setup) override;

void beginLuminosityBlock(edm::LuminosityBlock const &, edm::EventSetup const &) final{};
void endLuminosityBlock(edm::LuminosityBlock const &, edm::EventSetup const &) final;
void endLuminosityBlockProduce(edm::LuminosityBlock &, edm::EventSetup const &) final;
void endJob() final {
dqmstore_->meBookerGetter([this](DQMStore::IBooker &b, DQMStore::IGetter &g) { this->dqmEndJob(b, g); });
};

~DQMEDHarvester() override = default;

void endJob() final;
// DQM_EXPERIMENTAL
// Could be used for niche workflows like commissioning.
// Real harvesting jobs have no events and will never call this.
virtual void dqmAnalyze(DQMStore::IBooker &, DQMStore::IGetter &, edm::Event const &, edm::EventSetup const &){};
virtual void dqmEndLuminosityBlock(DQMStore::IBooker &,
DQMStore::IGetter &,
edm::LuminosityBlock const &,
edm::EventSetup const &){};
// DQM_EXPERIMENTAL
// HARVESTING should happen in endJob (or endLumi, for online), but there can
// be applications for end-run harvesting. Better to have a callback than
// have unprotected DQMStore access.
virtual void dqmEndRun(DQMStore::IBooker &, DQMStore::IGetter &, edm::Run const &, edm::EventSetup const &){};
virtual void dqmEndJob(DQMStore::IBooker &, DQMStore::IGetter &) = 0;

protected:
edm::EDPutTokenT<DQMToken> lumiToken_;
edm::EDPutTokenT<DQMToken> runToken_;
};

#endif // CORE_DQMED_HARVESTER_H
33 changes: 0 additions & 33 deletions DQMServices/Core/src/DQMEDHarvester.cc

This file was deleted.

0 comments on commit 361c26a

Please sign in to comment.