CMS 3D CMS Logo

FastTimerServiceClient.cc
Go to the documentation of this file.
1 // C++ headers
2 #include <string>
3 #include <cstring>
4 
5 // boost headers
6 #include <boost/regex.hpp>
7 
8 // Root headers
9 #include <TH1D.h>
10 #include <TH1F.h>
11 
12 // CMSSW headers
25 
26 struct MEPSet {
29  int nbins;
30  double xmin;
31  double xmax;
32 };
33 
35 public:
37  ~FastTimerServiceClient() override = default;
38 
39  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
42 
43 private:
45  DQMStore::IGetter& getter,
46  edm::LuminosityBlock const&,
47  edm::EventSetup const&) override;
48  void dqmEndJob(DQMStore::IBooker& booker, DQMStore::IGetter& getter) override;
49 
53  DQMStore::IGetter& getter,
54  double events,
55  std::string const& path);
57  DQMStore::IGetter& getter,
58  std::string const& current_path,
59  std::string const& suffix,
60  MEPSet const& pset);
61 
63 
65 
67  bool const doPlotsVsPixelLumi_;
68  bool const doPlotsVsPU_;
69 
73 
75 };
76 
78  : dqm_path_(config.getUntrackedParameter<std::string>("dqmPath")),
79  doPlotsVsOnlineLumi_(config.getParameter<bool>("doPlotsVsOnlineLumi")),
80  doPlotsVsPixelLumi_(config.getParameter<bool>("doPlotsVsPixelLumi")),
81  doPlotsVsPU_(config.getParameter<bool>("doPlotsVsPU")),
82  onlineLumiMEPSet_(doPlotsVsOnlineLumi_ ? getHistoPSet(config.getParameter<edm::ParameterSet>("onlineLumiME"))
83  : MEPSet{}),
84  pixelLumiMEPSet_(doPlotsVsPixelLumi_ ? getHistoPSet(config.getParameter<edm::ParameterSet>("pixelLumiME"))
85  : MEPSet{}),
86  puMEPSet_(doPlotsVsPU_ ? getHistoPSet(config.getParameter<edm::ParameterSet>("puME")) : MEPSet{}),
87  fillEveryLumiSection_(config.getParameter<bool>("fillEveryLumiSection")) {}
88 
90  fillSummaryPlots(booker, getter);
91 }
92 
94  DQMStore::IGetter& getter,
96  edm::EventSetup const& setup) {
98  fillSummaryPlots(booker, getter);
99 }
100 
102  if (getter.get(dqm_path_ + "/event time_real")) {
103  // the plots are directly in the configured folder
104  fillProcessSummaryPlots(booker, getter, dqm_path_);
105  } else {
106  static const boost::regex running_n_processes(".*/Running .*");
107 
108  booker.setCurrentFolder(dqm_path_);
109  std::vector<std::string> subdirs = getter.getSubdirs();
110  for (auto const& subdir : subdirs) {
111  // the plots are in a per-number-of-processes folder
112  if (boost::regex_match(subdir, running_n_processes)) {
113  booker.setCurrentFolder(subdir);
114  if (getter.get(subdir + "/event time_real"))
115  fillProcessSummaryPlots(booker, getter, subdir);
116 
117  std::vector<std::string> subsubdirs = getter.getSubdirs();
118  for (auto const& subsubdir : subsubdirs) {
119  if (getter.get(subsubdir + "/event time_real"))
120  fillProcessSummaryPlots(booker, getter, subsubdir);
121  }
122  }
123  } // loop on subdirs
124  }
125 }
126 
128  DQMStore::IGetter& getter,
129  std::string const& current_path) {
130  MonitorElement* me = getter.get(current_path + "/event time_real");
131  if (me == nullptr)
132  // no FastTimerService DQM information
133  return;
134 
136  fillPlotsVsLumi(booker, getter, current_path, "vs_lumi", onlineLumiMEPSet_);
138  fillPlotsVsLumi(booker, getter, current_path, "vs_pixelLumi", pixelLumiMEPSet_);
139  if (doPlotsVsPU_)
140  fillPlotsVsLumi(booker, getter, current_path, "vs_pileup", puMEPSet_);
141 
142  // getter.setCurrentFolder(current_path);
143 
144  double events = me->getTH1F()->GetEntries();
145 
146  // look for per-process directories
147  static const boost::regex process_name(".*/process .*");
148 
149  booker.setCurrentFolder(current_path); // ?!?!?
150  std::vector<std::string> subdirs = getter.getSubdirs();
151  for (auto const& subdir : subdirs) {
152  if (boost::regex_match(subdir, process_name)) {
153  getter.setCurrentFolder(subdir);
154  // look for per-path plots inside each per-process directory
155  std::vector<std::string> subsubdirs = getter.getSubdirs();
156  for (auto const& subsubdir : subsubdirs) {
157  if (getter.get(subsubdir + "/path time_real")) {
158  fillPathSummaryPlots(booker, getter, events, subdir);
159  break;
160  }
161  }
162  }
163  } // loop on subdir
164 }
165 
167  DQMStore::IGetter& getter,
168  double events,
169  std::string const& current_path) {
170  // note: the following checks need to be kept separate, as any of these histograms might be missing
171 
172  booker.setCurrentFolder(current_path);
173  std::vector<std::string> subsubdirs = getter.getSubdirs();
174  size_t npaths = subsubdirs.size();
175 
176  MonitorElement* paths_time =
177  booker.book1D("paths_time_real", "Total (real) time spent in each path", npaths, -0.5, double(npaths) - 0.5);
178  MonitorElement* paths_thread =
179  booker.book1D("paths_time_thread", "Total (thread) time spent in each path", npaths, -0.5, double(npaths) - 0.5);
180  MonitorElement* paths_allocated =
181  booker.book1D("paths_allocated", "Total allocated memory in each path", npaths, -0.5, double(npaths) - 0.5);
182  MonitorElement* paths_deallocated =
183  booker.book1D("paths_deallocated", "Total deallocated in each path", npaths, -0.5, double(npaths) - 0.5);
184 
186  double mean = -1.;
187 
188  // extract the list of Paths and EndPaths from the summary plots
189  int ibin = 1;
190  for (auto const& subsubdir : subsubdirs) {
191  std::string test = "/path ";
192  if (subsubdir.find(test) == std::string::npos)
193  continue;
194 
195  static const boost::regex prefix(current_path + "/path ");
196  std::string path = boost::regex_replace(subsubdir, prefix, "");
197 
198  paths_time->setBinLabel(ibin, path);
199  paths_thread->setBinLabel(ibin, path);
200  paths_allocated->setBinLabel(ibin, path);
201  paths_deallocated->setBinLabel(ibin, path);
202 
203  if ((me = getter.get(subsubdir + "/path time_real"))) {
204  mean = me->getMean();
205  paths_time->setBinContent(ibin, mean);
206  }
207  if ((me = getter.get(subsubdir + "/path time_thread"))) {
208  mean = me->getMean();
209  paths_thread->setBinContent(ibin, mean);
210  }
211  if ((me = getter.get(subsubdir + "/path allocated"))) {
212  mean = me->getMean();
213  paths_allocated->setBinContent(ibin, mean);
214  }
215 
216  if ((me = getter.get(subsubdir + "/path deallocated"))) {
217  mean = me->getMean();
218  paths_deallocated->setBinContent(ibin, mean);
219  }
220 
221  ibin++;
222  }
223 
224  for (auto const& subsubdir : subsubdirs) {
225  // for each path, fill histograms with
226  // - the average time spent in each module (total time spent in that module, averaged over all events)
227  // - the running time spent in each module (total time spent in that module, averaged over the events where that module actually ran)
228  // - the "efficiency" of each module (number of time a module succeded divided by the number of times the has run)
229 
230  getter.setCurrentFolder(subsubdir);
231  std::vector<std::string> allmenames = getter.getMEs();
232  if (allmenames.empty())
233  continue;
234 
235  MonitorElement* me_counter = getter.get(subsubdir + "/module_counter");
236  MonitorElement* me_real_total = getter.get(subsubdir + "/module_time_real_total");
237  MonitorElement* me_thread_total = getter.get(subsubdir + "/module_time_thread_total");
238 
239  if (me_counter == nullptr or me_real_total == nullptr)
240  continue;
241 
242  TH1D* counter = me_counter->getTH1D();
243  TH1D* real_total = me_real_total->getTH1D();
244  TH1D* thread_total = me_thread_total->getTH1D();
245  uint32_t bins = counter->GetXaxis()->GetNbins() - 1;
246  double min = counter->GetXaxis()->GetXmin();
247  double max = counter->GetXaxis()->GetXmax() - 1;
248 
249  TH1F* real_average;
250  TH1F* real_running;
251  TH1F* thread_average;
252  TH1F* thread_running;
253  TH1F* efficiency;
255 
256  booker.setCurrentFolder(subsubdir);
257  me = getter.get(subsubdir + "/module_time_real_average");
258  if (me) {
259  real_average = me->getTH1F();
260  assert(me->getTH1F()->GetXaxis()->GetXmin() == min);
261  assert(me->getTH1F()->GetXaxis()->GetXmax() == max);
262  real_average->Reset();
263  } else {
264  real_average = booker.book1D("module_time_real_average", "module real average timing", bins, min, max)->getTH1F();
265  real_average->SetYTitle("average processing (real) time [ms]");
266  for (uint32_t i = 1; i <= bins; ++i) {
267  const char* module = counter->GetXaxis()->GetBinLabel(i);
268  real_average->GetXaxis()->SetBinLabel(i, module);
269  }
270  }
271 
272  me = getter.get(subsubdir + "/module_time_thread_average");
273  if (me) {
274  thread_average = me->getTH1F();
275  assert(me->getTH1F()->GetXaxis()->GetXmin() == min);
276  assert(me->getTH1F()->GetXaxis()->GetXmax() == max);
277  thread_average->Reset();
278  } else {
279  thread_average =
280  booker.book1D("module_time_thread_average", "module thread average timing", bins, min, max)->getTH1F();
281  thread_average->SetYTitle("average processing (thread) time [ms]");
282  for (uint32_t i = 1; i <= bins; ++i) {
283  const char* module = counter->GetXaxis()->GetBinLabel(i);
284  thread_average->GetXaxis()->SetBinLabel(i, module);
285  }
286  }
287 
288  me = getter.get(subsubdir + "/module_time_real_running");
289  if (me) {
290  real_running = me->getTH1F();
291  assert(me->getTH1F()->GetXaxis()->GetXmin() == min);
292  assert(me->getTH1F()->GetXaxis()->GetXmax() == max);
293  real_running->Reset();
294  } else {
295  real_running = booker.book1D("module_time_real_running", "module real running timing", bins, min, max)->getTH1F();
296  real_running->SetYTitle("running processing (real) time [ms]");
297  for (uint32_t i = 1; i <= bins; ++i) {
298  const char* module = counter->GetXaxis()->GetBinLabel(i);
299  real_running->GetXaxis()->SetBinLabel(i, module);
300  }
301  }
302 
303  me = getter.get(subsubdir + "/module_time_thread_running");
304  if (me) {
305  thread_running = me->getTH1F();
306  assert(me->getTH1F()->GetXaxis()->GetXmin() == min);
307  assert(me->getTH1F()->GetXaxis()->GetXmax() == max);
308  thread_running->Reset();
309  } else {
310  thread_running =
311  booker.book1D("module_time_thread_running", "module thread running timing", bins, min, max)->getTH1F();
312  thread_running->SetYTitle("running processing (thread) time [ms]");
313  for (uint32_t i = 1; i <= bins; ++i) {
314  const char* module = counter->GetXaxis()->GetBinLabel(i);
315  thread_running->GetXaxis()->SetBinLabel(i, module);
316  }
317  }
318 
319  me = getter.get(subsubdir + "/module_efficiency");
320  if (me) {
321  efficiency = me->getTH1F();
322  assert(me->getTH1F()->GetXaxis()->GetXmin() == min);
323  assert(me->getTH1F()->GetXaxis()->GetXmax() == max);
324  efficiency->Reset();
325  } else {
326  efficiency = booker.book1D("module_efficiency", "module efficiency", bins, min, max)->getTH1F();
327  efficiency->SetYTitle("filter efficiency");
328  efficiency->SetMaximum(1.05);
329  for (uint32_t i = 1; i <= bins; ++i) {
330  const char* module = counter->GetXaxis()->GetBinLabel(i);
331  efficiency->GetXaxis()->SetBinLabel(i, module);
332  }
333  }
334 
335  for (uint32_t i = 1; i <= bins; ++i) {
336  double n = counter->GetBinContent(i);
337  double p = counter->GetBinContent(i + 1);
338  if (n)
339  efficiency->SetBinContent(i, p / n);
340 
341  // real timing
342  double t = real_total->GetBinContent(i);
343  real_average->SetBinContent(i, t / events);
344  if (n)
345  real_running->SetBinContent(i, t / n);
346 
347  // thread timing
348  t = thread_total->GetBinContent(i);
349  thread_average->SetBinContent(i, t / events);
350  if (n)
351  thread_running->SetBinContent(i, t / n);
352  }
353 
354  // vs lumi
356  fillPlotsVsLumi(booker, getter, subsubdir, "vs_lumi", onlineLumiMEPSet_);
358  fillPlotsVsLumi(booker, getter, subsubdir, "vs_pixelLumi", pixelLumiMEPSet_);
359  if (doPlotsVsPU_)
360  fillPlotsVsLumi(booker, getter, subsubdir, "vs_pileup", puMEPSet_);
361  }
362 }
363 
366  DQMStore::IGetter& getter,
367  std::string const& current_path,
368  std::string const& suffix,
369  MEPSet const& pset) {
370  std::vector<std::string> menames;
371 
372  static const boost::regex byls(".*byls");
373  // get all MEs in the current_path
374  getter.setCurrentFolder(current_path);
375  std::vector<std::string> allmenames = getter.getMEs();
376  for (auto const& m : allmenames) {
377  // get only MEs vs LS
378  if (boost::regex_match(m, byls))
379  menames.push_back(m);
380  }
381  // if no MEs available, return
382  if (menames.empty())
383  return;
384 
385  // get info for getting the lumi VS LS histogram
386  std::string folder = pset.folder;
387  std::string name = pset.name;
388  int nbins = pset.nbins;
389  double xmin = pset.xmin;
390  double xmax = pset.xmax;
391 
392  // get lumi/PU VS LS ME
393  getter.setCurrentFolder(folder);
394  MonitorElement* lumiVsLS = getter.get(folder + "/" + name);
395  // if no ME available, return
396  if (!lumiVsLS) {
397  edm::LogWarning("FastTimerServiceClient") << "no " << name << " ME is available in " << folder << std::endl;
398  return;
399  }
400 
401  // get range and binning for new MEs x-axis
402  size_t size = lumiVsLS->getTProfile()->GetXaxis()->GetNbins();
403  std::string xtitle = lumiVsLS->getTProfile()->GetYaxis()->GetTitle();
404 
405  std::vector<double> lumi;
406  std::vector<int> LS;
407  for (size_t ibin = 1; ibin <= size; ++ibin) {
408  // avoid to store points w/ no info
409  if (lumiVsLS->getTProfile()->GetBinContent(ibin) == 0.)
410  continue;
411 
412  lumi.push_back(lumiVsLS->getTProfile()->GetBinContent(ibin));
413  LS.push_back(lumiVsLS->getTProfile()->GetXaxis()->GetBinCenter(ibin));
414  }
415 
416  booker.setCurrentFolder(current_path);
417  getter.setCurrentFolder(current_path);
418  for (auto const& m : menames) {
419  std::string label = m;
420  label.erase(label.find("_byls"));
421 
422  MonitorElement* me = getter.get(current_path + "/" + m);
423  float ymin = 0.;
425  std::string ytitle = me->getTProfile()->GetYaxis()->GetTitle();
426 
427  MonitorElement* meVsLumi = getter.get(current_path + "/" + label + "_" + suffix);
428  if (meVsLumi) {
429  assert(meVsLumi->getTProfile()->GetXaxis()->GetXmin() == xmin);
430  assert(meVsLumi->getTProfile()->GetXaxis()->GetXmax() == xmax);
431  meVsLumi->Reset(); // do I have to do it ?!?!?
432  } else {
433  meVsLumi = booker.bookProfile(label + "_" + suffix, label + "_" + suffix, nbins, xmin, xmax, ymin, ymax);
434  // TProfile* meVsLumi_p = meVsLumi->getTProfile();
435  meVsLumi->getTProfile()->GetXaxis()->SetTitle(xtitle.c_str());
436  meVsLumi->getTProfile()->GetYaxis()->SetTitle(ytitle.c_str());
437  }
438  for (size_t ils = 0; ils < LS.size(); ++ils) {
439  int ibin = me->getTProfile()->GetXaxis()->FindBin(LS[ils]);
440  double y = me->getTProfile()->GetBinContent(ibin);
441 
442  meVsLumi->Fill(lumi[ils], y);
443  }
444  }
445 }
446 
448  pset.add<std::string>("folder", "HLT/LumiMonitoring");
449  pset.add<std::string>("name", "lumiVsLS");
450  pset.add<int>("nbins", 440);
451  pset.add<double>("xmin", 0.);
452  pset.add<double>("xmax", 22000.);
453 }
454 
456  pset.add<std::string>("folder", "HLT/LumiMonitoring");
457  pset.add<std::string>("name", "puVsLS");
458  pset.add<int>("nbins", 260);
459  pset.add<double>("xmin", 0.);
460  pset.add<double>("xmax", 130.);
461 }
462 
464  return MEPSet{
465  pset.getParameter<std::string>("folder"),
466  pset.getParameter<std::string>("name"),
467  pset.getParameter<int>("nbins"),
468  pset.getParameter<double>("xmin"),
469  pset.getParameter<double>("xmax"),
470  };
471 }
472 
474  // The following says we do not know what parameters are allowed so do no validation
475  // Please change this to state exactly what you do use, even if it is no parameters
477  desc.addUntracked<std::string>("dqmPath", "HLT/TimerService");
478  desc.add<bool>("doPlotsVsOnlineLumi", true);
479  desc.add<bool>("doPlotsVsPixelLumi", false);
480  desc.add<bool>("doPlotsVsPU", true);
481 
482  edm::ParameterSetDescription onlineLumiMEPSet;
483  fillLumiMePSetDescription(onlineLumiMEPSet);
484  desc.add<edm::ParameterSetDescription>("onlineLumiME", onlineLumiMEPSet);
485 
486  edm::ParameterSetDescription pixelLumiMEPSet;
487  fillLumiMePSetDescription(pixelLumiMEPSet);
488  desc.add<edm::ParameterSetDescription>("pixelLumiME", pixelLumiMEPSet);
489 
491  fillPUMePSetDescription(puMEPSet);
492  desc.add<edm::ParameterSetDescription>("puME", puMEPSet);
493  desc.add<bool>("fillEveryLumiSection", true);
494  descriptions.add("fastTimerServiceClient", desc);
495 }
496 
497 // declare this class as a framework plugin
size
Write out results.
static void fillPUMePSetDescription(edm::ParameterSetDescription &pset)
void dqmEndLuminosityBlock(DQMStore::IBooker &booker, DQMStore::IGetter &getter, edm::LuminosityBlock const &, edm::EventSetup const &) override
virtual TProfile * getTProfile() const
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:36
void fillPlotsVsLumi(DQMStore::IBooker &booker, DQMStore::IGetter &getter, std::string const &current_path, std::string const &suffix, MEPSet const &pset)
virtual std::vector< std::string > getMEs() const
Definition: DQMStore.cc:759
std::string folder
void fillProcessSummaryPlots(DQMStore::IBooker &booker, DQMStore::IGetter &getter, std::string const &path)
Definition: config.py:1
~FastTimerServiceClient() override=default
assert(be >=bs)
void Fill(long long x)
virtual void Reset()
Remove all data from the ME, keept the empty histogram with all its settings.
void dqmEndJob(DQMStore::IBooker &booker, DQMStore::IGetter &getter) override
char const * label
static MEPSet getHistoPSet(const edm::ParameterSet &pset)
void fillPathSummaryPlots(DQMStore::IBooker &booker, DQMStore::IGetter &getter, double events, std::string const &path)
MonitorElement * bookProfile(TString const &name, TString const &title, int nchX, double lowX, double highX, int, double lowY, double highY, char const *option="s", FUNC onbooking=NOOP())
Definition: DQMStore.h:408
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::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
static void fillLumiMePSetDescription(edm::ParameterSetDescription &pset)
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
virtual TH1D * getTH1D() const
virtual void setBinLabel(int bin, const std::string &label, int axis=1)
set bin label for x, y or z axis (axis=1, 2, 3 respectively)
FastTimerServiceClient(edm::ParameterSet const &)
std::string name
void fillSummaryPlots(DQMStore::IBooker &booker, DQMStore::IGetter &getter)
virtual void setBinContent(int binx, double content)
set content of bin (1-D)
virtual TH1F * getTH1F() const
void add(std::string const &label, ParameterSetDescription const &psetDescription)
virtual MonitorElement * get(std::string const &fullpath) const
Definition: DQMStore.cc:712
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
HLT enums.
Log< level::Warning, false > LogWarning
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:98
int events
virtual DQM_DEPRECATED std::vector< std::string > getSubdirs() const
Definition: DQMStore.cc:739