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 
103 
104  struct HLTRatesPlots {
105  TH1F * wasrun;
106  TH1F * pass_l1_seed;
108  TH1F * accept;
109  TH1F * reject;
110  TH1F * error;
111  };
112 
113  // overall event count and event types
118 
119  // L1T triggers
120  std::vector<TH1F *> m_l1t_algo_counts;
121  std::vector<TH1F *> m_l1t_tech_counts;
122 
123  // HLT triggers
124  std::vector<HLTRatesPlots> m_hlt_counts;
125 
126  // datasets
127  std::vector<TH1F *> m_dataset_counts;
128 
129 };
130 
131 
132 
134 {
136  desc.addUntracked<edm::InputTag>( "l1tResults", edm::InputTag("gtDigis"));
137  desc.addUntracked<edm::InputTag>( "hltResults", edm::InputTag("TriggerResults"));
138  desc.addUntracked<std::string>( "dqmPath", "HLT/TriggerRates" );
139  desc.addUntracked<uint32_t>( "lumisectionRange", 2500 ); // ~16 hours
140  descriptions.add("triggerRatesMonitor", desc);
141 }
142 
143 
145  // module configuration
146  m_l1t_results( consumes<L1GlobalTriggerReadoutRecord>( config.getUntrackedParameter<edm::InputTag>( "l1tResults" ) ) ),
147  m_hlt_results( consumes<edm::TriggerResults>( config.getUntrackedParameter<edm::InputTag>( "hltResults" ) ) ),
148  m_dqm_path( config.getUntrackedParameter<std::string>( "dqmPath" ) ),
149  m_lumisections_range( config.getUntrackedParameter<uint32_t>( "lumisectionRange" ) ),
150  // L1T and HLT configuration
151  m_l1tMenu( nullptr ),
152  m_l1tAlgoMask( nullptr ),
153  m_l1tTechMask( nullptr),
154  m_hltConfig(),
155  m_hltIndices(),
156  m_datasets(),
157  // overall event count and event types
158  m_events_processed( nullptr ),
159  m_events_physics( nullptr ),
160  m_events_calibration( nullptr ),
161  m_events_random( nullptr ),
162  // L1T triggers
163  m_l1t_algo_counts(),
164  m_l1t_tech_counts(),
165  // HLT triggers
166  m_hlt_counts(),
167  // datasets
168  m_dataset_counts()
169 {
170 }
171 
173 {
174 }
175 
177 {
178  m_events_processed = nullptr;
179  m_events_physics = nullptr;
180  m_events_calibration = nullptr;
181  m_events_random = nullptr;
182 
183  // cache the L1 trigger menu
184  m_l1tMenu = get<L1GtTriggerMenuRcd, L1GtTriggerMenu>(setup);
185  // FIXME - do we really need this ?
186  //(const_cast<L1GtTriggerMenu *>(m_l1tMenu))->buildGtConditionMap();
187  m_l1tAlgoMask = get<L1GtTriggerMaskAlgoTrigRcd, L1GtTriggerMask>(setup);
188  m_l1tTechMask = get<L1GtTriggerMaskTechTrigRcd, L1GtTriggerMask>(setup);
189  if (m_l1tMenu and m_l1tAlgoMask and m_l1tTechMask) {
190  m_l1t_algo_counts.clear();
191  m_l1t_algo_counts.resize( m_l1tAlgoMask->gtTriggerMask().size(), nullptr );
192  m_l1t_tech_counts.clear();
193  m_l1t_tech_counts.resize( m_l1tTechMask->gtTriggerMask().size(), nullptr );
194  } else {
195  // L1GtUtils not initialised, skip the the L1T monitoring
196  edm::LogError("TriggerRatesMonitor") << "failed to read the L1 menu or masks from the EventSetup, the L1 trigger rates will not be monitored";
197  }
198 
199  // initialise the HLTConfigProvider
200  bool changed = true;
202  labelsForToken(m_hlt_results, labels);
203  if (m_hltConfig.init(run, setup, labels.process, changed)) {
204  m_hlt_counts.clear();
206  m_hltIndices.resize( m_hltConfig.size(), HLTIndices() );
207 
208  unsigned int datasets = m_hltConfig.datasetNames().size();
209  m_datasets.clear();
210  m_datasets.resize( datasets, {} );
211  for (unsigned int i = 0; i < datasets; ++i) {
212  auto const & paths = m_hltConfig.datasetContent(i);
213  m_datasets[i].reserve(paths.size());
214  for (auto const & path: paths)
216  }
217  m_dataset_counts.clear();
218  m_dataset_counts.resize( datasets, nullptr );
219  } else {
220  // HLTConfigProvider not initialised, skip the the HLT monitoring
221  edm::LogError("TriggerRatesMonitor") << "failed to initialise HLTConfigProvider, the HLT trigger and datasets rates will not be monitored";
222  }
223 }
224 
226 {
227  // book the overall event count and event types histograms
228  booker.setCurrentFolder( m_dqm_path );
229  m_events_processed = booker.book1D("processed", "Processed events", m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
230  m_events_physics = booker.book1D("physics", "Physics evenst", m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
231  m_events_calibration = booker.book1D("calibration", "Calibration events", m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
232  m_events_random = booker.book1D("random", "Random events", m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
233 
234  if (m_l1tMenu and m_l1tAlgoMask and m_l1tTechMask) {
235  // book the L1T rate histograms
236  booker.setCurrentFolder( m_dqm_path + "/L1" );
237 
238  // book the histograms for L1 algo triggers that are included in the L1 menu
239  for (auto const & keyval: m_l1tMenu->gtAlgorithmAliasMap()) {
240  int bit = keyval.second.algoBitNumber();
241  std::string const & name = keyval.first.substr( 0, keyval.first.find_first_of(".") );
242  std::string const & title = keyval.first;
243  // check if the trigger is unmasked in *any* partition
244  if ((m_l1tAlgoMask->gtTriggerMask().at(bit) & 0xff) != 0xff)
245  m_l1t_algo_counts[bit] = booker.book1D(name, title, m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
246  else
247  m_l1t_algo_counts[bit] = booker.book1D(name, title + " (masked)", m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
248  }
249  // book the histograms for L1 algo triggers that are not included in the L1 menu
250  for (unsigned int bit = 0; bit < m_l1tAlgoMask->gtTriggerMask().size(); ++bit) if (not m_l1t_algo_counts[bit]) {
251  std::string const & name = (boost::format("L1_algo_bit_%03d") % bit).str();
252  std::string const & title = (boost::format("L1 algo bit %03d") % bit).str();
253  // check if the trigger is unmasked in *any* partition
254  if ((m_l1tAlgoMask->gtTriggerMask().at(bit) & 0xff) != 0xff)
255  m_l1t_algo_counts[bit] = booker.book1D(name, title, m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
256  else
257  m_l1t_algo_counts[bit] = booker.book1D(name, title + " (masked)", m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
258  }
259  // book the histograms for L1 tech triggers that are included in the L1 menu
260  for (auto const & keyval: m_l1tMenu->gtTechnicalTriggerMap()) {
261  int bit = keyval.second.algoBitNumber();
262  std::string const & name = keyval.first.substr( 0, keyval.first.find_first_of(".") );
263  std::string const & title = keyval.first;
264  // check if the trigger is unmasked in *any* partition
265  if ((m_l1tTechMask->gtTriggerMask()[bit] & 0xff) != 0xff)
266  m_l1t_tech_counts[bit] = booker.book1D(name, title, m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
267  else
268  m_l1t_tech_counts[bit] = booker.book1D(name, title + " (masked)", m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
269  }
270  // book the histograms for L1 tech triggers that are not included in the L1 menu
271  for (unsigned int bit = 0; bit < m_l1tTechMask->gtTriggerMask().size(); ++bit) if (not m_l1t_tech_counts[bit]) {
272  std::string const & name = (boost::format("L1_tech_bit_%03d") % bit).str();
273  std::string const & title = (boost::format("L1 tech bit %03d") % bit).str();
274  // check if the trigger is unmasked in *any* partition
275  if ((m_l1tTechMask->gtTriggerMask()[bit] & 0xff) != 0xff)
276  m_l1t_tech_counts[bit] = booker.book1D(name, title, m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
277  else
278  m_l1t_tech_counts[bit] = booker.book1D(name, title + " (masked)", m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
279  }
280  }
281 
282  if (m_hltConfig.inited()) {
283  // book the HLT triggers rate histograms
284  booker.setCurrentFolder( m_dqm_path + "/HLT" );
285  for (unsigned int i = 0; i < m_hltConfig.size(); ++i) {
287  m_hlt_counts[i].wasrun = booker.book1D(name + "_wasrun", name + " counts", m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
288  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();
289  m_hlt_counts[i].pass_prescale = booker.book1D(name + "_pass_prescale", name + " pass prescaler", m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
290  m_hlt_counts[i].accept = booker.book1D(name + "_accept", name + " trigger", m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
291  m_hlt_counts[i].reject = booker.book1D(name + "_reject", name + " reject", m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
292  m_hlt_counts[i].error = booker.book1D(name + "_error", name + " error count", m_lumisections_range + 1, -0.5, m_lumisections_range + 0.5)->getTH1F();
293  // look for the index of the (last) L1 seed and prescale module in each path
294  m_hltIndices[i].index_l1_seed = m_hltConfig.size(i);
295  m_hltIndices[i].index_prescale = m_hltConfig.size(i);
296  for (unsigned int j = 0; j < m_hltConfig.size(i); ++j) {
298  std::string const & type = m_hltConfig.moduleType(label);
299  if (type == "HLTLevel1GTSeed" or type == "HLTLevel1Activity" or type == "HLTLevel1Pattern") {
300  // there might be more L1 seed filters in sequence
301  // keep looking and store the index of the last one
302  m_hltIndices[i].index_l1_seed = j;
303  } else if (type == "HLTPrescaler") {
304  // there should be only one prescaler in a path, and it should follow all L1 seed filters
305  m_hltIndices[i].index_prescale = j;
306  break;
307  }
308 
309  }
310  }
311 
312  // book the HLT datasets rate histograms
313  booker.setCurrentFolder( m_dqm_path + "/Datasets" );
314  auto const & datasets = m_hltConfig.datasetNames();
315  for (unsigned int i = 0; i < datasets.size(); ++i)
317  }
318 }
319 
320 
322 {
323  unsigned int lumisection = event.luminosityBlock();
324 
325  // book the overall event count and event types rates
326  m_events_processed->Fill(lumisection);
327  switch (event.experimentType()) {
329  m_events_physics->Fill(lumisection);
330  break;
332  m_events_calibration->Fill(lumisection);
333  break;
335  m_events_random->Fill(lumisection);
336  break;
342  // ignore these event types
343  break;
344  }
345 
346  // monitor the L1 triggers rates
347  if (m_l1tMenu and m_l1tAlgoMask and m_l1tTechMask) {
348  L1GlobalTriggerReadoutRecord const & l1tResults = * get<L1GlobalTriggerReadoutRecord>(event, m_l1t_results);
349 
350  const std::vector<bool> & algoword = l1tResults.decisionWord();
351  assert(algoword.size() == m_l1t_algo_counts.size());
352  for (unsigned int i = 0; i < m_l1t_algo_counts.size(); ++i)
353  if (algoword[i])
354  m_l1t_algo_counts[i]->Fill(lumisection);
355 
356  const std::vector<bool> & techword = l1tResults.technicalTriggerWord();
357  assert(techword.size() == m_l1t_tech_counts.size());
358  for (unsigned int i = 0; i < m_l1t_tech_counts.size(); ++i)
359  if (techword[i])
360  m_l1t_tech_counts[i]->Fill(lumisection);
361  }
362 
363  // monitor the HLT triggers and datsets rates
364  if (m_hltConfig.inited()) {
365  edm::TriggerResults const & hltResults = * get<edm::TriggerResults>(event, m_hlt_results);
366  assert(hltResults.size() == m_hlt_counts.size());
367  for (unsigned int i = 0; i < m_hlt_counts.size(); ++i) {
368  edm::HLTPathStatus const & path = hltResults.at(i);
369  if (path.wasrun())
370  m_hlt_counts[i].wasrun->Fill(lumisection);
371  if (path.index() > m_hltIndices[i].index_l1_seed)
372  m_hlt_counts[i].pass_l1_seed->Fill(lumisection);
373  if (path.index() > m_hltIndices[i].index_prescale)
374  m_hlt_counts[i].pass_prescale->Fill(lumisection);
375  if (path.accept())
376  m_hlt_counts[i].accept->Fill(lumisection);
377  else if (path.error())
378  m_hlt_counts[i].error ->Fill(lumisection);
379  else
380  m_hlt_counts[i].reject->Fill(lumisection);
381  }
382 
383  for (unsigned int i = 0; i < m_datasets.size(); ++i)
384  for (unsigned int j: m_datasets[i])
385  if (hltResults.at(j).accept()) {
386  m_dataset_counts[i]->Fill(lumisection);
387  // ensure each dataset is incremented only once per event
388  break;
389  }
390  }
391 }
392 
393 
394 //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
#define nullptr
std::vector< TH1F * > m_l1t_algo_counts
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
string format
Some error handling for the usage.
bool accept(const edm::Event &event, const edm::TriggerResults &triggerTable, const std::string &triggerPath)
Definition: TopDQMHelpers.h:26
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)
virtual void analyze(edm::Event const &, edm::EventSetup const &) override
tuple TriggerResults
Definition: old-fu_pass.py:28
tuple path
else: Piece not in the list, fine.
std::vector< TH1F * > m_dataset_counts
const std::vector< unsigned int > & gtTriggerMask() const
get the trigger mask
void Fill(HcalDetId &id, double val, std::vector< TH2F > &depth)
unsigned int size() const
Get number of paths stored.
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:113
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
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
bool init(const edm::Run &iRun, const edm::EventSetup &iSetup, const std::string &processName, bool &changed)
d&#39;tor
T const * product() const
Definition: ESHandle.h:62
TH1F * getTH1F(void) const
std::vector< HLTRatesPlots > m_hlt_counts
void add(std::string const &label, ParameterSetDescription const &psetDescription)
T const * product() const
Definition: Handle.h:81
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
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