CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
TriggerRatesMonitor.cc
Go to the documentation of this file.
1 // Note to self: the implementation uses TH1F's to store the L1 and HLT rates.
2 // Assuming a maximum rate of 100 kHz times a period of 23.31 s, one needs to store counts up to ~2.3e6.
3 // A "float" has 24 bits of precision, so it can store up to 2**24 ~ 16.7e6 without loss of precision.
4 
5 
6 // C++ headers
7 #include <string>
8 #include <cstring>
9 
10 // boost headers
11 #include <boost/regex.hpp>
12 #include <boost/format.hpp>
13 
14 // Root headers
15 #include <TH1F.h>
16 
17 // CMSSW headers
42 
43 // length of a lumisections, corresponding to 2**18 LHC orbits, or 23.31 seconds
44 static const double SECS_PER_LUMI = 23.31040958083832;
45 
46 // helper functions
47 template <typename T>
48 static
49 const T * get(const edm::Event & event, const edm::EDGetTokenT<T> & token) {
51  event.getByToken(token, handle);
52  if (not handle.isValid())
53  throw * handle.whyFailed();
54  return handle.product();
55 }
56 
57 template <typename R, typename T>
58 static
59 const T * get(const edm::EventSetup & setup) {
61  setup.get<R>().get(handle);
62  return handle.product();
63 }
64 
65 
67 public:
68  explicit TriggerRatesMonitor(edm::ParameterSet const &);
70 
71  static void fillDescriptions(edm::ConfigurationDescriptions & descriptions);
72 
73 private:
74  virtual void dqmBeginRun(edm::Run const &, edm::EventSetup const &) override;
75  virtual void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override;
76  virtual void analyze(edm::Event const &, edm::EventSetup const &) override;
77 
78  // module configuration
83 
84  // L1T and HLT configuration
85  struct HLTIndices {
86  unsigned int index_l1_seed;
87  unsigned int index_prescale;
88 
90  index_l1_seed( (unsigned int) -1),
91  index_prescale( (unsigned int) -1)
92  { }
93  };
94 
99  std::vector<HLTIndices> m_hltIndices;
100 
101  std::vector<std::vector<unsigned int>> m_datasets;
102  std::vector<std::vector<unsigned int>> m_streams;
103 
104 
105  struct HLTRatesPlots {
106  TH1F * wasrun;
107  TH1F * pass_l1_seed;
109  TH1F * accept;
110  TH1F * reject;
111  TH1F * error;
112  };
113 
114  // overall event count and event types
119 
120  // L1T triggers
121  std::vector<TH1F *> m_l1t_algo_counts;
122  std::vector<TH1F *> m_l1t_tech_counts;
123 
124  // HLT triggers
125  std::vector<HLTRatesPlots> m_hlt_counts;
126 
127  // datasets
128  std::vector<TH1F *> m_dataset_counts;
129 
130  // streams
131  std::vector<TH1F *> m_stream_counts;
132 
133 };
134 
135 
136 
138 {
140  desc.addUntracked<edm::InputTag>( "l1tResults", edm::InputTag("gtDigis"));
141  desc.addUntracked<edm::InputTag>( "hltResults", edm::InputTag("TriggerResults"));
142  desc.addUntracked<std::string>( "dqmPath", "HLT/TriggerRates" );
143  desc.addUntracked<uint32_t>( "lumisectionRange", 2500 ); // ~16 hours
144  descriptions.add("triggerRatesMonitor", desc);
145 }
146 
147 
149  // module configuration
150  m_l1t_results( consumes<L1GlobalTriggerReadoutRecord>( config.getUntrackedParameter<edm::InputTag>( "l1tResults" ) ) ),
151  m_hlt_results( consumes<edm::TriggerResults>( config.getUntrackedParameter<edm::InputTag>( "hltResults" ) ) ),
152  m_dqm_path( config.getUntrackedParameter<std::string>( "dqmPath" ) ),
153  m_lumisections_range( config.getUntrackedParameter<uint32_t>( "lumisectionRange" ) ),
154  // L1T and HLT configuration
155  m_l1tMenu( nullptr ),
156  m_l1tAlgoMask( nullptr ),
157  m_l1tTechMask( nullptr),
158  m_hltConfig(),
159  m_hltIndices(),
160  m_datasets(),
161  m_streams(),
162  // overall event count and event types
163  m_events_processed( nullptr ),
164  m_events_physics( nullptr ),
165  m_events_calibration( nullptr ),
166  m_events_random( nullptr ),
167  // L1T triggers
168  m_l1t_algo_counts(),
169  m_l1t_tech_counts(),
170  // HLT triggers
171  m_hlt_counts(),
172  // datasets
173  m_dataset_counts(),
174  // streams
175  m_stream_counts()
176 {
177 }
178 
180 {
181 }
182 
184 {
185  m_events_processed = nullptr;
186  m_events_physics = nullptr;
187  m_events_calibration = nullptr;
188  m_events_random = nullptr;
189 
190  // cache the L1 trigger menu
191  m_l1tMenu = get<L1GtTriggerMenuRcd, L1GtTriggerMenu>(setup);
192  // FIXME - do we really need this ?
193  //(const_cast<L1GtTriggerMenu *>(m_l1tMenu))->buildGtConditionMap();
194  m_l1tAlgoMask = get<L1GtTriggerMaskAlgoTrigRcd, L1GtTriggerMask>(setup);
195  m_l1tTechMask = get<L1GtTriggerMaskTechTrigRcd, L1GtTriggerMask>(setup);
196  if (m_l1tMenu and m_l1tAlgoMask and m_l1tTechMask) {
197  m_l1t_algo_counts.clear();
198  m_l1t_algo_counts.resize( m_l1tAlgoMask->gtTriggerMask().size(), nullptr );
199  m_l1t_tech_counts.clear();
200  m_l1t_tech_counts.resize( m_l1tTechMask->gtTriggerMask().size(), nullptr );
201  } else {
202  // L1GtUtils not initialised, skip the the L1T monitoring
203  edm::LogError("TriggerRatesMonitor") << "failed to read the L1 menu or masks from the EventSetup, the L1 trigger rates will not be monitored";
204  }
205 
206  // initialise the HLTConfigProvider
207  bool changed = true;
209  labelsForToken(m_hlt_results, labels);
210  if (m_hltConfig.init(run, setup, labels.process, changed)) {
211  m_hlt_counts.clear();
213  m_hltIndices.resize( m_hltConfig.size(), HLTIndices() );
214 
215  unsigned int datasets = m_hltConfig.datasetNames().size();
216  m_datasets.clear();
217  m_datasets.resize( datasets, {} );
218  for (unsigned int i = 0; i < datasets; ++i) {
219  auto const & paths = m_hltConfig.datasetContent(i);
220  m_datasets[i].reserve(paths.size());
221  for (auto const & path: paths)
223  }
224  m_dataset_counts.clear();
225  m_dataset_counts.resize( datasets, nullptr );
226 
227  unsigned int streams = m_hltConfig.streamNames().size();
228  m_streams.clear();
229  m_streams.resize( streams, {} );
230  for (unsigned int i = 0; i < streams; ++i) {
231  for (auto const & dataset : m_hltConfig.streamContent(i)) {
232  for (auto const & path : m_hltConfig.datasetContent(dataset))
233  m_streams[i].push_back(m_hltConfig.triggerIndex(path));
234  }
236  auto unique_end = std::unique(m_streams[i].begin(), m_streams[i].end());
237  m_streams[i].resize(unique_end - m_streams[i].begin());
238  m_streams[i].shrink_to_fit();
239  }
240  m_stream_counts.clear();
241  m_stream_counts.resize( streams, nullptr );
242  } else {
243  // HLTConfigProvider not initialised, skip the the HLT monitoring
244  edm::LogError("TriggerRatesMonitor") << "failed to initialise HLTConfigProvider, the HLT trigger and datasets rates will not be monitored";
245  }
246 }
247 
249 {
250  // book the overall event count and event types histograms
251  booker.setCurrentFolder( m_dqm_path );
252  m_events_processed = booker.book1D("processed", "Processed events", m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
253  m_events_physics = booker.book1D("physics", "Physics evenst", m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
254  m_events_calibration = booker.book1D("calibration", "Calibration events", m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
255  m_events_random = booker.book1D("random", "Random events", m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
256 
257  if (m_l1tMenu and m_l1tAlgoMask) {
258  // book the rate histograms for the L1 Algorithm triggers
259  booker.setCurrentFolder( m_dqm_path + "/L1 Algo" );
260 
261  // book the histograms for L1 algo triggers that are included in the L1 menu
262  for (auto const & keyval: m_l1tMenu->gtAlgorithmAliasMap()) {
263  int bit = keyval.second.algoBitNumber();
264  // check if the trigger is unmasked in *any* partition
265  bool masked = ((m_l1tAlgoMask->gtTriggerMask().at(bit) & 0xff) == 0xff);
266  std::string const & name = (boost::format("%s (bit %d)") % keyval.first.substr(0, keyval.first.find_first_of(".")) % bit).str();
267  std::string const & title = (boost::format("%s (bit %d)%s") % keyval.first % bit % (masked ? " (masked)" : "")).str();
268  m_l1t_algo_counts.at(bit) = booker.book1D(name, title, m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
269  }
270  // book the histograms for L1 algo triggers that are not included in the L1 menu
271  for (unsigned int bit = 0; bit < m_l1tAlgoMask->gtTriggerMask().size(); ++bit) if (not m_l1t_algo_counts.at(bit)) {
272  // check if the trigger is unmasked in *any* partition
273  bool masked = ((m_l1tAlgoMask->gtTriggerMask().at(bit) & 0xff) == 0xff);
274  std::string const & name = (boost::format("L1 Algo (bit %d)") % bit).str();
275  std::string const & title = (boost::format("L1 Algo (bit %d)%s") % bit % (masked ? " (masked)" : "")).str();
276  m_l1t_algo_counts.at(bit) = booker.book1D(name, title, m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
277  }
278  }
279 
280  if (m_l1tMenu and m_l1tTechMask) {
281  // book the rate histograms for the L1 Technical triggers
282  booker.setCurrentFolder( m_dqm_path + "/L1 Tech" );
283 
284  // book the histograms for L1 tech triggers that are included in the L1 menu
285  for (auto const & keyval: m_l1tMenu->gtTechnicalTriggerMap()) {
286  int bit = keyval.second.algoBitNumber();
287  // check if the trigger is unmasked in *any* partition
288  bool masked = ((m_l1tTechMask->gtTriggerMask().at(bit) & 0xff) == 0xff);
289  std::string const & name = (boost::format("%s (bit %d)") % keyval.first.substr(0, keyval.first.find_first_of(".")) % bit).str();
290  std::string const & title = (boost::format("%s (bit %d)%s") % keyval.first % bit % (masked ? " (masked)" : "")).str();
291  m_l1t_tech_counts.at(bit) = booker.book1D(name, title, m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
292  }
293  // book the histograms for L1 tech triggers that are not included in the L1 menu
294  for (unsigned int bit = 0; bit < m_l1tTechMask->gtTriggerMask().size(); ++bit) if (not m_l1t_tech_counts.at(bit)) {
295  // check if the trigger is unmasked in *any* partition
296  bool masked = ((m_l1tTechMask->gtTriggerMask().at(bit) & 0xff) == 0xff);
297  std::string const & name = (boost::format("L1 Tech (bit %d)") % bit).str();
298  std::string const & title = (boost::format("L1 Tech (bit %d)%s") % bit % (masked ? " (masked)" : "")).str();
299  m_l1t_tech_counts.at(bit) = booker.book1D(name, title, m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
300  }
301 
302  }
303 
304  if (m_hltConfig.inited()) {
305  // book the HLT triggers rate histograms
306  booker.setCurrentFolder( m_dqm_path + "/HLT" );
307  for (unsigned int i = 0; i < m_hltConfig.size(); ++i) {
309  m_hlt_counts[i].wasrun = booker.book1D(name + " counts", name + " counts", m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
310  m_hlt_counts[i].pass_l1_seed = booker.book1D(name + " pass L1 seed", name + " pass L1 seed", m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
311  m_hlt_counts[i].pass_prescale = booker.book1D(name + " pass prescaler", name + " pass prescaler", m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
312  m_hlt_counts[i].accept = booker.book1D(name + " accept", name + " accept", m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
313  m_hlt_counts[i].reject = booker.book1D(name + " reject", name + " reject", m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
314  m_hlt_counts[i].error = booker.book1D(name + " error", name + " error", m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
315  // look for the index of the (last) L1 seed and prescale module in each path
316  m_hltIndices[i].index_l1_seed = m_hltConfig.size(i);
317  m_hltIndices[i].index_prescale = m_hltConfig.size(i);
318  for (unsigned int j = 0; j < m_hltConfig.size(i); ++j) {
320  std::string const & type = m_hltConfig.moduleType(label);
321  if (type == "HLTLevel1GTSeed" or type == "HLTLevel1Activity" or type == "HLTLevel1Pattern") {
322  // there might be more L1 seed filters in sequence
323  // keep looking and store the index of the last one
324  m_hltIndices[i].index_l1_seed = j;
325  } else if (type == "HLTPrescaler") {
326  // there should be only one prescaler in a path, and it should follow all L1 seed filters
327  m_hltIndices[i].index_prescale = j;
328  break;
329  }
330 
331  }
332  }
333 
334  // book the HLT datasets rate histograms
335  booker.setCurrentFolder( m_dqm_path + "/Datasets" );
336  auto const & datasets = m_hltConfig.datasetNames();
337  for (unsigned int i = 0; i < datasets.size(); ++i)
339 
340  // book the HLT streams rate histograms
341  booker.setCurrentFolder( m_dqm_path + "/Streams" );
342  auto const & streams = m_hltConfig.streamNames();
343  for (unsigned int i = 0; i < streams.size(); ++i)
344  m_stream_counts[i] = booker.book1D(streams[i], streams[i], m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
345  }
346 }
347 
348 
350 {
351  unsigned int lumisection = event.luminosityBlock();
352 
353  // book the overall event count and event types rates
354  m_events_processed->Fill(lumisection);
355  switch (event.experimentType()) {
357  m_events_physics->Fill(lumisection);
358  break;
360  m_events_calibration->Fill(lumisection);
361  break;
363  m_events_random->Fill(lumisection);
364  break;
370  // ignore these event types
371  break;
372  }
373 
374  // monitor the L1 triggers rates
375  if (m_l1tMenu and m_l1tAlgoMask and m_l1tTechMask) {
376  L1GlobalTriggerReadoutRecord const & l1tResults = * get<L1GlobalTriggerReadoutRecord>(event, m_l1t_results);
377 
378  const std::vector<bool> & algoword = l1tResults.decisionWord();
379  if (algoword.size() == m_l1t_algo_counts.size()) {
380  for (unsigned int i = 0; i < m_l1t_algo_counts.size(); ++i)
381  if (algoword[i])
382  m_l1t_algo_counts[i]->Fill(lumisection);
383  } else {
384  edm::LogWarning("TriggerRatesMonitor") << "This should never happen: the size of the L1 Algo Trigger mask does not match the number of L1 Algo Triggers";
385  }
386 
387  const std::vector<bool> & techword = l1tResults.technicalTriggerWord();
388  if (techword.size() == m_l1t_tech_counts.size()) {
389  for (unsigned int i = 0; i < m_l1t_tech_counts.size(); ++i)
390  if (techword[i])
391  m_l1t_tech_counts[i]->Fill(lumisection);
392  } else {
393  edm::LogWarning("TriggerRatesMonitor") << "This should never happen: the size of the L1 Tech Trigger mask does not match the number of L1 Tech Triggers";
394  }
395  }
396 
397  // monitor the HLT triggers and datsets rates
398  if (m_hltConfig.inited()) {
399  edm::TriggerResults const & hltResults = * get<edm::TriggerResults>(event, m_hlt_results);
400  if (hltResults.size() == m_hlt_counts.size()) {
401  for (unsigned int i = 0; i < m_hlt_counts.size(); ++i) {
402  edm::HLTPathStatus const & path = hltResults.at(i);
403  if (path.wasrun())
404  m_hlt_counts[i].wasrun->Fill(lumisection);
405  if (path.index() > m_hltIndices[i].index_l1_seed)
406  m_hlt_counts[i].pass_l1_seed->Fill(lumisection);
407  if (path.index() > m_hltIndices[i].index_prescale)
408  m_hlt_counts[i].pass_prescale->Fill(lumisection);
409  if (path.accept())
410  m_hlt_counts[i].accept->Fill(lumisection);
411  else if (path.error())
412  m_hlt_counts[i].error ->Fill(lumisection);
413  else
414  m_hlt_counts[i].reject->Fill(lumisection);
415  }
416  } else {
417  edm::LogWarning("TriggerRatesMonitor") << "This should never happen: the number of HLT paths has changed since the beginning of the run";
418  }
419 
420  for (unsigned int i = 0; i < m_datasets.size(); ++i)
421  for (unsigned int j: m_datasets[i])
422  if (hltResults.at(j).accept()) {
423  m_dataset_counts[i]->Fill(lumisection);
424  // ensure each dataset is incremented only once per event
425  break;
426  }
427 
428  for (unsigned int i = 0; i < m_streams.size(); ++i)
429  for (unsigned int j: m_streams[i])
430  if (hltResults.at(j).accept()) {
431  m_stream_counts[i]->Fill(lumisection);
432  // ensure each stream is incremented only once per event
433  break;
434  }
435  }
436 }
437 
438 
439 //define this as a plug-in
unsigned int size() const
number of trigger paths in trigger table
type
Definition: HCALResponse.h:21
int i
Definition: DBlmapReader.cc:9
const std::string moduleType(const std::string &module) const
C++ class name of module.
const TechnicalTriggerWord & technicalTriggerWord(int bxInEventValue) const
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
const std::string & triggerName(unsigned int triggerIndex) const
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventIDconst &, edm::Timestampconst & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
bool wasrun() const
was this path run?
Definition: HLTPathStatus.h:60
edm::EDGetTokenT< L1GlobalTriggerReadoutRecord > m_l1t_results
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
std::vector< TH1F * > m_l1t_algo_counts
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
string format
Some error handling for the usage.
#define nullptr
bool accept(const edm::Event &event, const edm::TriggerResults &triggerTable, const std::string &triggerPath)
Definition: TopDQMHelpers.h:25
L1GtTriggerMask const * m_l1tAlgoMask
const std::string & moduleLabel(unsigned int trigger, unsigned int module) const
bool inited() const
Accessors (const methods)
unsigned int triggerIndex(const std::string &triggerName) const
slot position of trigger path in trigger table (0 to size-1)
std::vector< std::vector< unsigned int > > m_streams
virtual void analyze(edm::Event const &, edm::EventSetup const &) override
tuple TriggerResults
Definition: old-fu_pass.py:28
const std::vector< std::string > & streamNames() const
tuple path
else: Piece not in the list, fine.
std::vector< TH1F * > m_dataset_counts
void Fill(HcalDetId &id, double val, std::vector< TH2F > &depth)
unsigned int size() const
Get number of paths stored.
const std::vector< std::string > & streamContent(unsigned int stream) const
names of datasets in stream with index i
std::vector< std::vector< unsigned int > > m_datasets
std::vector< TH1F * > m_l1t_tech_counts
virtual void dqmBeginRun(edm::Run const &, edm::EventSetup const &) override
MonitorElement * book1D(Args &&...args)
Definition: DQMStore.h:115
tuple handle
Definition: patZpeak.py:22
L1GtTriggerMask const * m_l1tTechMask
int j
Definition: DBlmapReader.cc:9
virtual void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override
#define end
Definition: vmac.h:37
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
bool isValid() const
Definition: HandleBase.h:76
const DecisionWord & decisionWord(int bxInEventValue) const
const HLTPathStatus & at(const unsigned int i) const
HLTConfigProvider m_hltConfig
const std::vector< std::string > & datasetContent(unsigned int dataset) const
names of trigger paths in dataset with index i
bool error() const
has this path encountered an error (exception)?
Definition: HLTPathStatus.h:64
void setCurrentFolder(const std::string &fullpath)
Definition: DQMStore.cc:274
T const * product() const
Definition: Handle.h:81
bool init(const edm::Run &iRun, const edm::EventSetup &iSetup, const std::string &processName, bool &changed)
d&#39;tor
tuple dataset
Definition: dataset.py:400
T const * product() const
Definition: ESHandle.h:86
TH1F * getTH1F(void) const
std::vector< HLTRatesPlots > m_hlt_counts
void add(std::string const &label, ParameterSetDescription const &psetDescription)
std::vector< TH1F * > m_stream_counts
bool accept() const
has this path accepted the event?
Definition: HLTPathStatus.h:62
void labelsForToken(EDGetToken iToken, Labels &oLabels) const
L1GtTriggerMenu const * m_l1tMenu
edm::EDGetTokenT< edm::TriggerResults > m_hlt_results
#define begin
Definition: vmac.h:30
TriggerRatesMonitor(edm::ParameterSet const &)
edm::EventAuxiliary::ExperimentType experimentType() const
Definition: EventBase.h:61
static const double SECS_PER_LUMI
const AlgorithmMap & gtTechnicalTriggerMap() const
get / set the technical trigger map
std::shared_ptr< cms::Exception > whyFailed() const
Definition: HandleBase.h:111
const AlgorithmMap & gtAlgorithmAliasMap() const
get / set the algorithm map (by alias)
long double T
std::vector< HLTIndices > m_hltIndices
void setup(std::vector< TH2F > &depth, std::string name, std::string units="")
Definition: Run.h:41
const std::vector< std::string > & datasetNames() const
unsigned int index() const
Definition: HLTPathStatus.h:55