CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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 <TH1F.h>
10 
11 // CMSSW headers
25 
26 struct MEPSet {
29  int nbins;
30  double xmin;
31  double xmax;
32 };
33 
35 public:
36  explicit FastTimerServiceClient(edm::ParameterSet const &);
38 
39  static void fillDescriptions(edm::ConfigurationDescriptions & descriptions);
41 
42 private:
44 
45  void dqmEndLuminosityBlock(DQMStore::IBooker & booker, DQMStore::IGetter & getter, edm::LuminosityBlock const &, edm::EventSetup const&) override;
46  void dqmEndJob(DQMStore::IBooker & booker, DQMStore::IGetter & getter) override;
47 
48  void fillSummaryPlots( DQMStore::IBooker & booker, DQMStore::IGetter & getter);
50  void fillPathSummaryPlots( DQMStore::IBooker & booker, DQMStore::IGetter & getter, double events, std::string const & path);
51  void fillPlotsVsLumi(DQMStore::IBooker & booker, DQMStore::IGetter & getter, std::string const & current_path, std::string const & suffix, MEPSet pset);
52 
54 
57 
60 
61 };
62 
63 
65  m_dqm_path( config.getUntrackedParameter<std::string>( "dqmPath" ) )
66  , doPlotsVsScalLumi_ ( config.getParameter<bool>( "doPlotsVsScalLumi" ) )
67  , doPlotsVsPixelLumi_( config.getParameter<bool>( "doPlotsVsPixelLumi" ) )
68  , scalLumiMEPSet_ ( doPlotsVsScalLumi_ ? getHistoPSet(config.getParameter<edm::ParameterSet>("scalLumiME")) : MEPSet{} )
69  , pixelLumiMEPSet_( doPlotsVsPixelLumi_ ? getHistoPSet(config.getParameter<edm::ParameterSet>("pixelLumiME")) : MEPSet{} )
70 {
71 }
72 
74 {
75 }
76 
77 void
79 {
80  fillSummaryPlots(booker, getter);
81 }
82 
83 void
85 {
86  fillSummaryPlots(booker, getter);
87 }
88 
89 void
91 {
92  if (getter.get(m_dqm_path + "/event")) {
93  // the plots are directly in the configured folder
94  fillProcessSummaryPlots(booker, getter, m_dqm_path);
95  } else {
96  static const boost::regex running_n_processes(".*/Running [0-9]+ processes");
98  std::vector<std::string> subdirs = getter.getSubdirs();
99  for (auto const & subdir: subdirs) {
100  if (boost::regex_match(subdir, running_n_processes)) {
101  // the plots are in a per-number-of-processes folder
102  if (getter.get(subdir + "/event"))
103  fillProcessSummaryPlots(booker, getter, subdir);
104  }
105  }
106  }
107 }
108 
109 
110 
111 void
113 
114  MonitorElement * me = getter.get(current_path + "/event");
115  if (me == 0)
116  // no FastTimerService DQM information
117  return;
118 
119  if ( doPlotsVsScalLumi_ ) {
120  fillPlotsVsLumi( booker,getter, current_path, "VsScalLumi", scalLumiMEPSet_ );
121  }
122  if ( doPlotsVsPixelLumi_ ) {
123  fillPlotsVsLumi( booker,getter, current_path, "VsPixelLumi", pixelLumiMEPSet_ );
124  }
125 
126  getter.setCurrentFolder(current_path);
127 
128  double events = me->getTH1F()->GetEntries();
129 
130  // look for per-process directories
131  static const boost::regex process_name(".*/process .*");
132  booker.setCurrentFolder(current_path);
133  std::vector<std::string> subdirs = getter.getSubdirs();
134  for (auto const & subdir: subdirs) {
135  if (boost::regex_match(subdir, process_name)) {
136  // look for per-path plots inside each per-process directory
137  if (getter.dirExists(subdir + "/Paths"))
138  fillPathSummaryPlots(booker, getter, events, subdir);
139  }
140  }
141 
142  // look for per-path plots inside the current directory
143  if (getter.dirExists(current_path + "/Paths"))
144  fillPathSummaryPlots(booker, getter, events, current_path);
145 }
146 
147 void
149  // note: the following checks need to be kept separate, as any of these histograms might be missing
150  // if any of them is filled, size will have the total number of paths, and "paths" can be used to extract the list of labels
151  MonitorElement * me;
152  TProfile const * paths = nullptr;
153  uint32_t size = 0;
154 
155  // extract the list of Paths and EndPaths from the summary plots
156  if (( me = getter.get(current_path + "/paths_active_time") )) {
157  paths = me->getTProfile();
158  size = paths->GetXaxis()->GetNbins();
159  } else
160  if (( me = getter.get(current_path + "/paths_total_time") )) {
161  paths = me->getTProfile();
162  size = paths->GetXaxis()->GetNbins();
163  } else
164  if (( me = getter.get(current_path + "/paths_exclusive_time") )) {
165  paths = me->getTProfile();
166  size = paths->GetXaxis()->GetNbins();
167  }
168  if (paths == nullptr)
169  return;
170 
171  // for each path, fill histograms with
172  // - the average time spent in each module (total time spent in that module, averaged over all events)
173  // - the running time spent in each module (total time spent in that module, averaged over the events where that module actually ran)
174  // - the "efficiency" of each module (number of time a module succeded divided by the number of times the has run)
175  booker.setCurrentFolder(current_path + "/Paths");
176  for (uint32_t p = 1; p <= size; ++p) {
177  // extract the list of Paths and EndPaths from the bin labels of one of the summary plots
178  std::string label = paths->GetXaxis()->GetBinLabel(p);
179  MonitorElement * me_counter = getter.get( current_path + "/Paths/" + label + "_module_counter" );
180  MonitorElement * me_total = getter.get( current_path + "/Paths/" + label + "_module_total" );
181  if (me_counter == 0 or me_total == 0)
182  continue;
183  TH1F * counter = me_counter->getTH1F();
184  TH1F * total = me_total ->getTH1F();
185  uint32_t bins = counter->GetXaxis()->GetNbins() - 1;
186  double min = counter->GetXaxis()->GetXmin();
187  double max = counter->GetXaxis()->GetXmax() - 1;
188  booker.setCurrentFolder(current_path + "/Paths");
189 
190  TH1F * average;
191  TH1F * running;
192  TH1F * efficiency;
193  MonitorElement * me;
194 
195  me = getter.get( current_path + "/Paths/" + label + "_module_average" );
196  if (me) {
197  average = me->getTH1F();
198  //assert( me->getTH1F()->GetXaxis()->GetNbins() == (int) bins );
199  assert( me->getTH1F()->GetXaxis()->GetXmin() == min );
200  assert( me->getTH1F()->GetXaxis()->GetXmax() == max );
201  average->Reset();
202  } else {
203  average = booker.book1D(label + "_module_average", label + " module average", bins, min, max)->getTH1F();
204  average->SetYTitle("processing time [ms]");
205  for (uint32_t i = 1; i <= bins; ++i) {
206  const char * module = counter->GetXaxis()->GetBinLabel(i);
207  average->GetXaxis()->SetBinLabel(i, module);
208  }
209  }
210 
211  me = getter.get( current_path + "/Paths/" + label + "_module_running" );
212  if (me) {
213  running = me->getTH1F();
214  //assert( me->getTH1F()->GetXaxis()->GetNbins() == (int) bins );
215  assert( me->getTH1F()->GetXaxis()->GetXmin() == min );
216  assert( me->getTH1F()->GetXaxis()->GetXmax() == max );
217  running->Reset();
218  } else {
219  running = booker.book1D(label + "_module_running", label + " module running", bins, min, max)->getTH1F();
220  running->SetYTitle("processing time [ms]");
221  for (uint32_t i = 1; i <= bins; ++i) {
222  const char * module = counter->GetXaxis()->GetBinLabel(i);
223  running->GetXaxis()->SetBinLabel(i, module);
224  }
225  }
226 
227  me = getter.get( current_path + "/Paths/" + label + "_module_efficiency" );
228  if (me) {
229  efficiency = me->getTH1F();
230  //assert( me->getTH1F()->GetXaxis()->GetNbins() == (int) bins );
231  assert( me->getTH1F()->GetXaxis()->GetXmin() == min );
232  assert( me->getTH1F()->GetXaxis()->GetXmax() == max );
233  efficiency->Reset();
234  } else {
235  efficiency = booker.book1D(label + "_module_efficiency", label + " module efficiency", bins, min, max)->getTH1F();
236  efficiency->SetYTitle("filter efficiency");
237  efficiency->SetMaximum(1.05);
238  for (uint32_t i = 1; i <= bins; ++i) {
239  const char * module = counter->GetXaxis()->GetBinLabel(i);
240  efficiency->GetXaxis()->SetBinLabel(i, module);
241  }
242  }
243 
244  for (uint32_t i = 1; i <= bins; ++i) {
245  double t = total ->GetBinContent(i);
246  double n = counter->GetBinContent(i);
247  double p = counter->GetBinContent(i+1);
248  average ->SetBinContent(i, t / events);
249  if (n) {
250  running ->SetBinContent(i, t / n);
251  efficiency->SetBinContent(i, p / n);
252  }
253  }
254  }
255 
256 }
257 
259 void
261 
262  std::vector<std::string> menames;
263 
264  static const boost::regex byls(".*byls");
265  static const boost::regex test(suffix);
266  // get all MEs in the current_path
267  getter.setCurrentFolder(current_path);
268  std::vector<std::string> allmenames = getter.getMEs();
269  for ( auto m : allmenames )
270  // get only MEs vs LS
271  if (boost::regex_match(m, byls))
272  menames.push_back(m);
273 
274  // if no MEs available, return
275  if ( menames.size() == 0 )
276  return;
277 
278 
279  // get info for getting the lumi VS LS histogram
280  std::string folder = pset.folder;
281  std::string name = pset.name;
282  int nbins = pset.nbins;
283  double xmin = pset.xmin;
284  double xmax = pset.xmax;
285 
286  // get lumi VS LS ME
287  getter.setCurrentFolder(folder);
288  MonitorElement* lumiVsLS = getter.get(folder+"/"+name);
289  // if no ME available, return
290  if ( !lumiVsLS ) {
291  edm::LogWarning("FastTimerServiceClient") << "no " << name << " ME is available in " << folder << std::endl;
292  return;
293  }
294 
295  // get range and binning for new MEs x-axis
296  size_t size = lumiVsLS->getTProfile()->GetXaxis()->GetNbins();
297  std::string xtitle = lumiVsLS->getTProfile()->GetYaxis()->GetTitle();
298 
299  std::vector<double> lumi;
300  std::vector<int> LS;
301  for ( size_t ibin=1; ibin <= size; ++ibin ) {
302  // avoid to store points w/ no info
303  if ( lumiVsLS->getTProfile()->GetBinContent(ibin) == 0. ) continue;
304 
305  lumi.push_back( lumiVsLS->getTProfile()->GetBinContent(ibin) );
306  LS.push_back ( lumiVsLS->getTProfile()->GetXaxis()->GetBinCenter(ibin) );
307  }
308 
309  booker.setCurrentFolder(current_path);
310  getter.setCurrentFolder(current_path);
311  for ( auto m : menames ) {
312  std::string label = m;
313  label.erase(label.find("_byls"));
314 
315  MonitorElement* me = getter.get(current_path + "/" + m);
316  double ymin = me->getTProfile()->GetMinimum();
317  double ymax = me->getTProfile()->GetMaximum();
318  std::string ytitle = me->getTProfile()->GetYaxis()->GetTitle();
319 
320  MonitorElement* meVsLumi = getter.get( current_path + "/" + label + "_" + suffix );
321  if (meVsLumi) {
322  assert( meVsLumi->getTProfile()->GetXaxis()->GetXmin() == xmin );
323  assert( meVsLumi->getTProfile()->GetXaxis()->GetXmax() == xmax );
324  meVsLumi->Reset(); // do I have to do it ?!?!?
325  } else {
326  meVsLumi = booker.bookProfile(label + "_" + suffix, label + "_" + suffix, nbins, xmin, xmax, ymin, ymax);
327  // TProfile* meVsLumi_p = meVsLumi->getTProfile();
328  meVsLumi->getTProfile()->GetXaxis()->SetTitle(xtitle.c_str());
329  meVsLumi->getTProfile()->GetYaxis()->SetTitle(ytitle.c_str());
330  }
331  for ( size_t ils=0; ils < LS.size(); ++ils ) {
332  int ibin = me->getTProfile()->GetXaxis()->FindBin(LS[ils]);
333  double y = me->getTProfile()->GetBinContent(ibin);
334 
335  meVsLumi->Fill(lumi[ils],y);
336  }
337  }
338 
339 
340 }
341 
342 void
344  pset.add<std::string>("folder", "HLT/LumiMonitoring");
345  pset.add<std::string>("name" , "lumiVsLS");
346  pset.add<int> ("nbins", 6500 );
347  pset.add<double>("xmin", 0.);
348  pset.add<double>("xmax", 13000.);
349 }
350 
351 
353 {
354  return MEPSet{
355  pset.getParameter<std::string>("folder"),
356  pset.getParameter<std::string>("name"),
357  pset.getParameter<int>("nbins"),
358  pset.getParameter<double>("xmin"),
359  pset.getParameter<double>("xmax"),
360  };
361 }
362 
363 void
365  // The following says we do not know what parameters are allowed so do no validation
366  // Please change this to state exactly what you do use, even if it is no parameters
368  desc.addUntracked<std::string>( "dqmPath", "HLT/TimerService");
369  desc.add<bool>( "doPlotsVsScalLumi", true );
370  desc.add<bool>( "doPlotsVsPixelLumi", false );
371 
372  edm::ParameterSetDescription scalLumiMEPSet;
373  fillLumiMePSetDescription(scalLumiMEPSet);
374  desc.add<edm::ParameterSetDescription>("scalLumiME", scalLumiMEPSet);
375 
376  edm::ParameterSetDescription pixelLumiMEPSet;
377  fillLumiMePSetDescription(pixelLumiMEPSet);
378  desc.add<edm::ParameterSetDescription>("pixelLumiME", pixelLumiMEPSet);
379 
380  descriptions.add("fastTimerServiceClient", desc);
381 }
382 
383 //define this as a plug-in
T getParameter(std::string const &) const
int i
Definition: DBlmapReader.cc:9
static MEPSet getHistoPSet(edm::ParameterSet pset)
void dqmEndLuminosityBlock(DQMStore::IBooker &booker, DQMStore::IGetter &getter, edm::LuminosityBlock const &, edm::EventSetup const &) override
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
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
MonitorElement * bookProfile(Args &&...args)
Definition: DQMStore.h:157
void fillPlotsVsLumi(DQMStore::IBooker &booker, DQMStore::IGetter &getter, std::string const &current_path, std::string const &suffix, MEPSet pset)
MonitorElement * get(const std::string &path)
Definition: DQMStore.cc:305
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
tuple lumi
Definition: fjr2json.py:35
std::string folder
assert(m_qm.get())
void fillProcessSummaryPlots(DQMStore::IBooker &booker, DQMStore::IGetter &getter, std::string const &path)
void Fill(long long x)
void dqmEndJob(DQMStore::IBooker &booker, DQMStore::IGetter &getter) override
void fillPathSummaryPlots(DQMStore::IBooker &booker, DQMStore::IGetter &getter, double events, std::string const &path)
MonitorElement * book1D(Args &&...args)
Definition: DQMStore.h:115
static void fillLumiMePSetDescription(edm::ParameterSetDescription &pset)
T min(T a, T b)
Definition: MathUtil.h:58
ParameterDescriptionBase * add(U const &iLabel, T const &value)
std::vector< std::string > getMEs(void)
Definition: DQMStore.cc:327
FastTimerServiceClient(edm::ParameterSet const &)
std::string name
void fillSummaryPlots(DQMStore::IBooker &booker, DQMStore::IGetter &getter)
bool dirExists(const std::string &path)
Definition: DQMStore.cc:335
void setCurrentFolder(const std::string &fullpath)
Definition: DQMStore.cc:277
TH1F * getTH1F(void) const
void add(std::string const &label, ParameterSetDescription const &psetDescription)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
int average
Definition: PDRates.py:137
std::vector< std::string > getSubdirs(void)
Definition: DQMStore.cc:323
void setCurrentFolder(const std::string &fullpath)
Definition: DQMStore.cc:347
tuple events
Definition: patZpeak.py:19
static std::atomic< unsigned int > counter
TProfile * getTProfile(void) const
volatile std::atomic< bool > shutdown_flag false
void Reset(void)
reset ME (ie. contents, errors, etc)
Definition: vlib.h:208
tuple size
Write out results.
tuple folder
Histograms Source for live online DQM in P5