A DQMGlobalEDAnalyzer
module is similar to a DQMEDanalyzer
, with few differences:
- it is a
global
module rather than astream
module: there is only one copy of it, no matter how many threads or streams the job is configured to use, and it will "see" all events being processed; the advantage is a significant reduction in memory usage as the number of streams increases; on the other hand this means that its internal state (the data members) are not allowed to change during theanalyze()
(ordqmAnalyze()
) method, unless in a concurrency-safe way. See FWMultithreadedFrameworkGlobalModuleInterface for the details. - it uses
ConcurrentMonitorElement
s rather thanMonitorElement
s to expose a concurrecy-safe interface to theDQMStore
; these objects are also "global": theDQMStore
holds a single copy of the histograms, and there is not merge step at the end fo each lumisection or run; theConcurrentMonitorElement
takes care of preventing multiple events from filling the same histogram at the same time. See Concurrent Monitor Elements for an overview. - it provides a special method,
dqmBeginRun(...)
, to cache or setup run-based conditions or confugurations.
If your module is actually a legacy edm::EDAnalyzer
, see How to migrate a legacy DQM edm::EDAnalyzer to a DQMGlobalEDAnalyzer.
From
#include "DQMServices/Core/interface/DQMEDAnalyzer.h"
#include "DQMServices/Core/interface/MonitorElement.h"
to
#include "DQMServices/Core/interface/DQMGlobalEDAnalyzer.h"
#include "DQMServices/Core/interface/ConcurrentMonitorElement.h"
If you had something like
private:
MonitorElement * m_histo;
std::vector<MonitorElement *> m_more_histos;
they need to be moved to a separate struct
or class
outside the EDAnalyzer itself:
namespace {
struct Histograms {
ConcurrentMonitorElement histo;
std::vector<ConcurrentMonitorElement> more_histos;
};
}
From
class MyDQMModule : public DQMEDAnalyzer {
private:
void dqmBeginRun(edm::Run const&, edm::EventSetup const&) override;
void bookHistograms(DQMStore::IBooker &, edm::Run const&, edm::EventSetup const&) override;
void analyze(edm::Event const&, edm::EventSetup const&) override;
to
class MyDQMModule : public DQMGlobalEDAnalyzer<Histograms> {
private:
void dqmBeginRun(edm::Run const&, edm::EventSetup const&, Histograms &) const override;
void bookHistograms(DQMStore::ConcurrentBooker &, edm::Run const&, edm::EventSetup const&, Histograms &) const override;
void dqmAnalyze(edm::Event const&, edm::EventSetup const&, Histograms const&) const override;
and similarly in the individual methods definition, from
void MyDQMModule::dqmBeginRun(edm::Run const& run, edm::EventSetup const& setup) {
...
}
void MyDQMModule::bookHistograms(DQMStore::IBooker & booker, edm::Run const& run, edm::EventSetup const& setup) {
...
}
void MyDQMModule::analyze(edm::Event const& event, edm::EventSetup const& setup) {
...
}
to
void MyDQMModule::dqmBeginRun(edm::Run const& run, edm::EventSetup const& setup, Histograms & histograms) const {
...
}
void MyDQMModule::bookHistograms(DQMStore::ConcurrentBooker & booker, edm::Run const& run, edm::EventSetup const& setup, Histograms & histograms) const {
...
}
void MyDQMModule::dqmAnalyze(edm::Event const& event, edm::EventSetup const& setup, Histograms const& histograms) const {
...
}
Access to the histograms needs to be changed from
m_histo = ...;
m_histo->doSomething();
to
histograms.histo = ...;
histograms.histo.doSomething();
Calls to m_histo->Fill(...)
need to be changed to histograms.histo.fill(...)
.
Calls to m_histo->getTH1F()
and similar need to be removed.
Calls to m_histo->GetXaxis()->SetTitle(...)
and similar need to be replaced by calls to histograms.histo.setXTitle(...)
and similar.
bookHistograms(...)
is called once at the beginning of each run, while holding the DQMStore
lock - meaning that different modules cannot call their bookHistograms(...)
methods at the same time.
For time-consuming per-run initialisation code (e.g. to create a local cache of run-based configurations, or to setup the histograms
structure) it is better to use the dqmBeginRun(...)
method:
void dqmBeginRun(edm::Run const& run, edm::EventSetup const& setup, H & histograms) const override
{
...
}
If you need to customise the ConcurrentmonitorElement
in a way which is not supported by the current interface, please send a request to extend the interface or implement a more general solution.