CMS 3D CMS Logo

DQMGenericClient.cc
Go to the documentation of this file.
1 /*
2  * Class:DQMGenericClient
3  *
4  *
5  *
6  * \author Junghwan Goh - SungKyunKwan University
7  */
8 
10 
16 
17 #include <TH1F.h>
18 #include <TClass.h>
19 #include <TString.h>
20 #include <TPRegexp.h>
21 
22 #include <cmath>
23 #include <climits>
24 #include <boost/tokenizer.hpp>
25 
26 using namespace std;
27 using namespace edm;
28 
30 
31 TPRegexp metacharacters("[\\^\\$\\.\\*\\+\\?\\|\\(\\)\\{\\}\\[\\]]");
32 TPRegexp nonPerlWildcard("\\w\\*|^\\*");
33 
35  typedef std::vector<edm::ParameterSet> VPSet;
36  typedef std::vector<std::string> vstring;
37  typedef boost::escaped_list_separator<char> elsc;
38 
39  elsc commonEscapes("\\", " \t", "\'");
40 
41  verbose_ = pset.getUntrackedParameter<unsigned int>("verbose", 0);
42  runOnEndLumi_ = pset.getUntrackedParameter<bool>("runOnEndLumi", false);
43  runOnEndJob_ = pset.getUntrackedParameter<bool>("runOnEndJob", true);
44  makeGlobalEffPlot_ = pset.getUntrackedParameter<bool>("makeGlobalEffienciesPlot", true);
45 
46  // Parse efficiency commands
47  vstring effCmds = pset.getParameter<vstring>("efficiency");
48  for (vstring::const_iterator effCmd = effCmds.begin(); effCmd != effCmds.end(); ++effCmd) {
49  if (effCmd->empty())
50  continue;
51 
52  boost::tokenizer<elsc> tokens(*effCmd, commonEscapes);
53 
54  vector<string> args;
55  for (boost::tokenizer<elsc>::const_iterator iToken = tokens.begin(); iToken != tokens.end(); ++iToken) {
56  if (iToken->empty())
57  continue;
58  args.push_back(*iToken);
59  }
60 
61  if (args.size() < 4) {
62  LogInfo("DQMGenericClient") << "Wrong input to effCmds\n";
63  continue;
64  }
65 
67  opt.name = args[0];
68  opt.title = args[1];
69  opt.numerator = args[2];
70  opt.denominator = args[3];
71  opt.isProfile = false;
72 
73  const string typeName = args.size() == 4 ? "eff" : args[4];
74  if (typeName == "eff")
76  else if (typeName == "fake")
77  opt.type = EfficType::fakerate;
78  else if (typeName == "simpleratio")
79  opt.type = EfficType::simpleratio;
80  else
81  opt.type = EfficType::none;
82 
83  efficOptions_.push_back(opt);
84  }
85 
86  VPSet efficSets = pset.getUntrackedParameter<VPSet>("efficiencySets", VPSet());
87  for (VPSet::const_iterator efficSet = efficSets.begin(); efficSet != efficSets.end(); ++efficSet) {
89  opt.name = efficSet->getUntrackedParameter<string>("name");
90  opt.title = efficSet->getUntrackedParameter<string>("title");
91  opt.numerator = efficSet->getUntrackedParameter<string>("numerator");
92  opt.denominator = efficSet->getUntrackedParameter<string>("denominator");
93  opt.isProfile = false;
94 
95  const string typeName = efficSet->getUntrackedParameter<string>("typeName", "eff");
96  if (typeName == "eff")
98  else if (typeName == "fake")
99  opt.type = EfficType::fakerate;
100  else if (typeName == "simpleratio")
101  opt.type = EfficType::simpleratio;
102  else
103  opt.type = EfficType::none;
104 
105  efficOptions_.push_back(opt);
106  }
107 
108  // Parse efficiency profiles
109  vstring effProfileCmds = pset.getUntrackedParameter<vstring>("efficiencyProfile", vstring());
110  for (vstring::const_iterator effProfileCmd = effProfileCmds.begin(); effProfileCmd != effProfileCmds.end();
111  ++effProfileCmd) {
112  if (effProfileCmd->empty())
113  continue;
114 
115  boost::tokenizer<elsc> tokens(*effProfileCmd, commonEscapes);
116 
117  vector<string> args;
118  for (boost::tokenizer<elsc>::const_iterator iToken = tokens.begin(); iToken != tokens.end(); ++iToken) {
119  if (iToken->empty())
120  continue;
121  args.push_back(*iToken);
122  }
123 
124  if (args.size() < 4) {
125  LogInfo("DQMGenericClient") << "Wrong input to effProfileCmds\n";
126  continue;
127  }
128 
130  opt.name = args[0];
131  opt.title = args[1];
132  opt.numerator = args[2];
133  opt.denominator = args[3];
134  opt.isProfile = true;
135 
136  const string typeName = args.size() == 4 ? "eff" : args[4];
137  if (typeName == "eff")
139  else if (typeName == "fake")
140  opt.type = EfficType::fakerate;
141  else if (typeName == "simpleratio")
142  opt.type = EfficType::simpleratio;
143  else
144  opt.type = EfficType::none;
145 
146  efficOptions_.push_back(opt);
147  }
148 
149  VPSet effProfileSets = pset.getUntrackedParameter<VPSet>("efficiencyProfileSets", VPSet());
150  for (VPSet::const_iterator effProfileSet = effProfileSets.begin(); effProfileSet != effProfileSets.end();
151  ++effProfileSet) {
153  opt.name = effProfileSet->getUntrackedParameter<string>("name");
154  opt.title = effProfileSet->getUntrackedParameter<string>("title");
155  opt.numerator = effProfileSet->getUntrackedParameter<string>("numerator");
156  opt.denominator = effProfileSet->getUntrackedParameter<string>("denominator");
157  opt.isProfile = true;
158 
159  const string typeName = effProfileSet->getUntrackedParameter<string>("typeName", "eff");
160  if (typeName == "eff")
162  else if (typeName == "fake")
163  opt.type = EfficType::fakerate;
164  else if (typeName == "simpleratio")
165  opt.type = EfficType::simpleratio;
166  else
167  opt.type = EfficType::none;
168 
169  efficOptions_.push_back(opt);
170  }
171 
172  // Parse resolution commands
173  vstring resCmds = pset.getParameter<vstring>("resolution");
174  for (vstring::const_iterator resCmd = resCmds.begin(); resCmd != resCmds.end(); ++resCmd) {
175  if (resCmd->empty())
176  continue;
177  boost::tokenizer<elsc> tokens(*resCmd, commonEscapes);
178 
179  vector<string> args;
180  for (boost::tokenizer<elsc>::const_iterator iToken = tokens.begin(); iToken != tokens.end(); ++iToken) {
181  if (iToken->empty())
182  continue;
183  args.push_back(*iToken);
184  }
185 
186  if (args.size() != 3) {
187  LogInfo("DQMGenericClient") << "Wrong input to resCmds\n";
188  continue;
189  }
190 
192  opt.namePrefix = args[0];
193  opt.titlePrefix = args[1];
194  opt.srcName = args[2];
195 
196  resolOptions_.push_back(opt);
197  }
198 
199  VPSet resolSets = pset.getUntrackedParameter<VPSet>("resolutionSets", VPSet());
200  for (VPSet::const_iterator resolSet = resolSets.begin(); resolSet != resolSets.end(); ++resolSet) {
202  opt.namePrefix = resolSet->getUntrackedParameter<string>("namePrefix");
203  opt.titlePrefix = resolSet->getUntrackedParameter<string>("titlePrefix");
204  opt.srcName = resolSet->getUntrackedParameter<string>("srcName");
205 
206  resolOptions_.push_back(opt);
207  }
208 
209  // Parse profiles
210  vstring profileCmds = pset.getUntrackedParameter<vstring>("profile", vstring());
211  for (const auto& profileCmd : profileCmds) {
212  boost::tokenizer<elsc> tokens(profileCmd, commonEscapes);
213 
214  vector<string> args;
215  for (boost::tokenizer<elsc>::const_iterator iToken = tokens.begin(); iToken != tokens.end(); ++iToken) {
216  if (iToken->empty())
217  continue;
218  args.push_back(*iToken);
219  }
220 
221  if (args.size() != 3) {
222  LogInfo("DQMGenericClient") << "Wrong input to profileCmds\n";
223  continue;
224  }
225 
227  opt.name = args[0];
228  opt.title = args[1];
229  opt.srcName = args[2];
230 
231  profileOptions_.push_back(opt);
232  }
233 
234  VPSet profileSets = pset.getUntrackedParameter<VPSet>("profileSets", VPSet());
235  for (const auto& profileSet : profileSets) {
237  opt.name = profileSet.getUntrackedParameter<string>("name");
238  opt.title = profileSet.getUntrackedParameter<string>("title");
239  opt.srcName = profileSet.getUntrackedParameter<string>("srcName");
240 
241  profileOptions_.push_back(opt);
242  }
243 
244  // Parse Normalization commands
245  vstring normCmds = pset.getUntrackedParameter<vstring>("normalization", vstring());
246  for (vstring::const_iterator normCmd = normCmds.begin(); normCmd != normCmds.end(); ++normCmd) {
247  if (normCmd->empty())
248  continue;
249  boost::tokenizer<elsc> tokens(*normCmd, commonEscapes);
250 
251  vector<string> args;
252  for (boost::tokenizer<elsc>::const_iterator iToken = tokens.begin(); iToken != tokens.end(); ++iToken) {
253  if (iToken->empty())
254  continue;
255  args.push_back(*iToken);
256  }
257 
258  if (args.empty() or args.size() > 2) {
259  LogInfo("DQMGenericClient") << "Wrong input to normCmds\n";
260  continue;
261  }
262 
263  NormOption opt;
264  opt.name = args[0];
265  opt.normHistName = args.size() == 2 ? args[1] : args[0];
266 
267  normOptions_.push_back(opt);
268  }
269 
270  VPSet normSets = pset.getUntrackedParameter<VPSet>("normalizationSets", VPSet());
271  for (VPSet::const_iterator normSet = normSets.begin(); normSet != normSets.end(); ++normSet) {
272  NormOption opt;
273  opt.name = normSet->getUntrackedParameter<string>("name");
274  opt.normHistName = normSet->getUntrackedParameter<string>("normalizedTo", opt.name);
275 
276  normOptions_.push_back(opt);
277  }
278 
279  // Cumulative distributions
280  vstring cdCmds = pset.getUntrackedParameter<vstring>("cumulativeDists", vstring());
281  for (vstring::const_iterator cdCmd = cdCmds.begin(); cdCmd != cdCmds.end(); ++cdCmd) {
282  if (cdCmd->empty())
283  continue;
284  boost::tokenizer<elsc> tokens(*cdCmd, commonEscapes);
285 
286  vector<string> args;
287  for (boost::tokenizer<elsc>::const_iterator iToken = tokens.begin(); iToken != tokens.end(); ++iToken) {
288  if (iToken->empty())
289  continue;
290  args.push_back(*iToken);
291  }
292 
293  if (args.empty() || args.size() > 2) {
294  LogInfo("DQMGenericClient") << "Wrong input to cdCmds\n";
295  continue;
296  }
297 
298  CDOption opt;
299  opt.name = args[0];
300  opt.ascending = args.size() == 2 ? (args[1] != "descending") : true;
301 
302  cdOptions_.push_back(opt);
303  }
304 
305  VPSet cdSets = pset.getUntrackedParameter<VPSet>("cumulativeDistSets", VPSet());
306  for (VPSet::const_iterator cdSet = cdSets.begin(); cdSet != cdSets.end(); ++cdSet) {
307  CDOption opt;
308  opt.name = cdSet->getUntrackedParameter<string>("name");
309  opt.ascending = cdSet->getUntrackedParameter<bool>("ascending", true);
310 
311  cdOptions_.push_back(opt);
312  }
313 
314  // move under/overflows to first/last bins
315  vstring noFlowCmds = pset.getUntrackedParameter<vstring>("noFlowDists", vstring());
316  for (vstring::const_iterator noFlowCmd = noFlowCmds.begin(); noFlowCmd != noFlowCmds.end(); ++noFlowCmd) {
317  if (noFlowCmd->empty())
318  continue;
319  boost::tokenizer<elsc> tokens(*noFlowCmd, commonEscapes);
320 
321  vector<string> args;
322  for (boost::tokenizer<elsc>::const_iterator iToken = tokens.begin(); iToken != tokens.end(); ++iToken) {
323  if (iToken->empty())
324  continue;
325  args.push_back(*iToken);
326  }
327 
328  if (args.empty() || args.size() > 2) {
329  LogInfo("DQMGenericClient") << "Wrong input to noFlowCmds\n";
330  continue;
331  }
332 
334  opt.name = args[0];
335 
336  noFlowOptions_.push_back(opt);
337  }
338 
339  VPSet noFlowSets = pset.getUntrackedParameter<VPSet>("noFlowDistSets", VPSet());
340  for (VPSet::const_iterator noFlowSet = noFlowSets.begin(); noFlowSet != noFlowSets.end(); ++noFlowSet) {
342  opt.name = noFlowSet->getUntrackedParameter<string>("name");
343 
344  noFlowOptions_.push_back(opt);
345  }
346 
347  outputFileName_ = pset.getUntrackedParameter<string>("outputFileName", "");
348  subDirs_ = pset.getUntrackedParameter<vstring>("subDirs");
349 
350  resLimitedFit_ = pset.getUntrackedParameter<bool>("resolutionLimitedFit", false);
351  isWildcardUsed_ = false;
352 }
353 
355  DQMStore::IGetter& igetter,
356  const edm::LuminosityBlock& lumiSeg,
357  const edm::EventSetup& c) {
358  if (runOnEndLumi_) {
359  makeAllPlots(ibooker, igetter);
360  }
361 }
362 
364  // Update 2014-04-02
365  // Migrated back to the endJob. the DQMFileSaver logic has
366  // to be reviewed to guarantee that the endJob is properly
367  // considered. The splitting per run is done centrally when
368  // running the harvesting in production
369 
370  // Update 2009-09-23
371  // Migrated all code from endJob to this function
372  // endJob is not necessarily called in the proper sequence
373  // and does not necessarily book histograms produced in
374  // that step.
375  // It more robust to do the histogram manipulation in
376  // this endRun function
377 
378  // needed to access the DQMStore::save method
379  theDQM = nullptr;
380  theDQM = Service<DQMStore>().operator->();
381 
382  if (runOnEndJob_) {
383  makeAllPlots(ibooker, igetter);
384  }
385 
386  if (!outputFileName_.empty())
387  theDQM->save(outputFileName_);
388 }
389 
391  typedef vector<string> vstring;
392 
393  // Process wildcard in the sub-directory
394  set<string> subDirSet;
395 
396  for (vstring::const_iterator iSubDir = subDirs_.begin(); iSubDir != subDirs_.end(); ++iSubDir) {
397  string subDir = *iSubDir;
398 
399  if (subDir[subDir.size() - 1] == '/')
400  subDir.erase(subDir.size() - 1);
401 
402  if (TString(subDir).Contains(metacharacters)) {
403  isWildcardUsed_ = true;
404 
405  const string::size_type shiftPos = subDir.rfind('/');
406  const string searchPath = subDir.substr(0, shiftPos);
407  const string pattern = subDir.substr(shiftPos + 1, subDir.length());
408  //std::cout << "\n\n\n\nLooking for all subdirs of " << subDir << std::endl;
409 
410  findAllSubdirectories(ibooker, igetter, searchPath, &subDirSet, pattern);
411 
412  } else {
413  subDirSet.insert(subDir);
414  }
415  }
416 
417  for (set<string>::const_iterator iSubDir = subDirSet.begin(); iSubDir != subDirSet.end(); ++iSubDir) {
418  const string& dirName = *iSubDir;
419 
420  // First normalize, then move under/overflows, then make
421  // cumulative, and only then efficiency This allows to use the
422  // cumulative distributions for efficiency calculation
423  for (vector<NormOption>::const_iterator normOption = normOptions_.begin(); normOption != normOptions_.end();
424  ++normOption) {
425  normalizeToEntries(ibooker, igetter, dirName, normOption->name, normOption->normHistName);
426  }
427 
428  for (vector<NoFlowOption>::const_iterator noFlowOption = noFlowOptions_.begin();
429  noFlowOption != noFlowOptions_.end();
430  ++noFlowOption) {
431  makeNoFlowDist(ibooker, igetter, dirName, noFlowOption->name);
432  }
433 
434  for (vector<CDOption>::const_iterator cdOption = cdOptions_.begin(); cdOption != cdOptions_.end(); ++cdOption) {
435  makeCumulativeDist(ibooker, igetter, dirName, cdOption->name, cdOption->ascending);
436  }
437 
438  for (vector<EfficOption>::const_iterator efficOption = efficOptions_.begin(); efficOption != efficOptions_.end();
439  ++efficOption) {
440  computeEfficiency(ibooker,
441  igetter,
442  dirName,
443  efficOption->name,
444  efficOption->title,
445  efficOption->numerator,
446  efficOption->denominator,
447  efficOption->type,
448  efficOption->isProfile);
449  }
450 
451  for (vector<ResolOption>::const_iterator resolOption = resolOptions_.begin(); resolOption != resolOptions_.end();
452  ++resolOption) {
453  computeResolution(
454  ibooker, igetter, dirName, resolOption->namePrefix, resolOption->titlePrefix, resolOption->srcName);
455  }
456 
457  for (const auto& profileOption : profileOptions_) {
458  computeProfile(ibooker, igetter, dirName, profileOption.name, profileOption.title, profileOption.srcName);
459  }
460  }
461 }
462 
464  DQMStore::IGetter& igetter,
465  const string& startDir,
466  const string& efficMEName,
467  const string& efficMETitle,
468  const string& recoMEName,
469  const string& simMEName,
470  const EfficType type,
471  const bool makeProfile) {
472  if (!igetter.dirExists(startDir)) {
473  if (verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_)) {
474  LogInfo("DQMGenericClient") << "computeEfficiency() : "
475  << "Cannot find sub-directory " << startDir << endl;
476  }
477  return;
478  }
479 
480  ibooker.cd();
481 
482  ME* simME = igetter.get(startDir + "/" + simMEName);
483  ME* recoME = igetter.get(startDir + "/" + recoMEName);
484 
485  if (!simME) {
486  if (verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_)) {
487  LogInfo("DQMGenericClient") << "computeEfficiency() : "
488  << "No sim-ME '" << simMEName << "' found\n";
489  }
490  return;
491  }
492 
493  if (!recoME) {
494  if (verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_)) {
495  LogInfo("DQMGenericClient") << "computeEfficiency() : "
496  << "No reco-ME '" << recoMEName << "' found\n";
497  }
498  return;
499  }
500 
501  // Treat everything as the base class, TH1
502 
503  TH1* hSim = simME->getTH1();
504  TH1* hReco = recoME->getTH1();
505 
506  if (!hSim || !hReco) {
507  if (verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_)) {
508  LogInfo("DQMGenericClient") << "computeEfficiency() : "
509  << "Cannot create TH1 from ME\n";
510  }
511  return;
512  }
513 
514  string efficDir = startDir;
515  string newEfficMEName = efficMEName;
516  string::size_type shiftPos;
517  if (string::npos != (shiftPos = efficMEName.rfind('/'))) {
518  efficDir += "/" + efficMEName.substr(0, shiftPos);
519  newEfficMEName.erase(0, shiftPos + 1);
520  }
521  ibooker.setCurrentFolder(efficDir);
522 
523  if (makeProfile) {
524  TProfile* efficHist = (hReco->GetXaxis()->GetXbins()->GetSize() == 0)
525  ? new TProfile(newEfficMEName.c_str(),
526  efficMETitle.c_str(),
527  hReco->GetXaxis()->GetNbins(),
528  hReco->GetXaxis()->GetXmin(),
529  hReco->GetXaxis()->GetXmax())
530  : new TProfile(newEfficMEName.c_str(),
531  efficMETitle.c_str(),
532  hReco->GetXaxis()->GetNbins(),
533  hReco->GetXaxis()->GetXbins()->GetArray());
534 
535  efficHist->GetXaxis()->SetTitle(hSim->GetXaxis()->GetTitle());
536  efficHist->GetYaxis()->SetTitle(hSim->GetYaxis()->GetTitle());
537 
538  for (int i = 1; i <= hReco->GetNbinsX(); i++) {
539  const double nReco = hReco->GetBinContent(i);
540  const double nSim = hSim->GetBinContent(i);
541 
542  if (!std::string(hSim->GetXaxis()->GetBinLabel(i)).empty())
543  efficHist->GetXaxis()->SetBinLabel(i, hSim->GetXaxis()->GetBinLabel(i));
544 
545  if (nSim == 0 or nReco < 0 or nReco > nSim)
546  continue;
547  const double effVal = nReco / nSim;
548  const double errLo = TEfficiency::ClopperPearson(nSim, nReco, 0.683, false);
549  const double errUp = TEfficiency::ClopperPearson(nSim, nReco, 0.683, true);
550  const double errVal = (effVal - errLo > errUp - effVal) ? effVal - errLo : errUp - effVal;
551  efficHist->SetBinContent(i, effVal);
552  efficHist->SetBinEntries(i, 1);
553  efficHist->SetBinError(i, std::hypot(effVal, errVal));
554  }
555  ibooker.bookProfile(newEfficMEName, efficHist);
556  delete efficHist;
557  }
558 
559  else {
560  TH1* efficHist = (TH1*)hSim->Clone(newEfficMEName.c_str());
561  efficHist->SetTitle(efficMETitle.c_str());
562 
563  // Here is where you have trouble --- you need
564  // to understand what type of hist you have.
565 
566  ME* efficME = nullptr;
567 
568  // Parse the class name
569  // This works, but there might be a better way
570  TClass* myHistClass = efficHist->IsA();
571  TString histClassName = myHistClass->GetName();
572 
573  if (histClassName == "TH1F") {
574  efficME = ibooker.book1D(newEfficMEName, (TH1F*)efficHist);
575  } else if (histClassName == "TH2F") {
576  efficME = ibooker.book2D(newEfficMEName, (TH2F*)efficHist);
577  } else if (histClassName == "TH3F") {
578  efficME = ibooker.book3D(newEfficMEName, (TH3F*)efficHist);
579  }
580 
581  delete efficHist;
582 
583  if (!efficME) {
584  LogInfo("DQMGenericClient") << "computeEfficiency() : "
585  << "Cannot book effic-ME from the DQM\n";
586  return;
587  }
588 
589  // Update: 2009-9-16 slaunwhj
590  // call the most generic efficiency function
591  // works up to 3-d histograms
592 
593  generic_eff(hSim, hReco, efficME, type);
594 
595  // const int nBin = efficME->getNbinsX();
596  // for(int bin = 0; bin <= nBin; ++bin) {
597  // const float nSim = simME ->getBinContent(bin);
598  // const float nReco = recoME->getBinContent(bin);
599  // float eff =0;
600  // if (type=="fake")eff = nSim ? 1-nReco/nSim : 0.;
601  // else eff= nSim ? nReco/nSim : 0.;
602  // const float err = nSim && eff <= 1 ? sqrt(eff*(1-eff)/nSim) : 0.;
603  // efficME->setBinContent(bin, eff);
604  // efficME->setBinError(bin, err);
605  // }
606  efficME->setEntries(simME->getEntries());
607  }
608 
609  // Global efficiency
610  if (makeGlobalEffPlot_) {
611  ME* globalEfficME = igetter.get(efficDir + "/globalEfficiencies");
612  if (!globalEfficME)
613  globalEfficME = ibooker.book1D("globalEfficiencies", "Global efficiencies", 1, 0, 1);
614  if (!globalEfficME) {
615  LogInfo("DQMGenericClient") << "computeEfficiency() : "
616  << "Cannot book globalEffic-ME from the DQM\n";
617  return;
618  }
619  globalEfficME->setEfficiencyFlag();
620  TH1F* hGlobalEffic = globalEfficME->getTH1F();
621  if (!hGlobalEffic) {
622  LogInfo("DQMGenericClient") << "computeEfficiency() : "
623  << "Cannot create TH1F from ME, globalEfficME\n";
624  return;
625  }
626 
627  const float nSimAll = hSim->GetEntries();
628  const float nRecoAll = hReco->GetEntries();
629  float efficAll = 0;
630  if (type == EfficType::efficiency || type == EfficType::simpleratio)
631  efficAll = nSimAll ? nRecoAll / nSimAll : 0;
632  else if (type == EfficType::fakerate)
633  efficAll = nSimAll ? 1 - nRecoAll / nSimAll : 0;
634  float errorAll = 0;
635  if (type == EfficType::simpleratio) {
636  if (nSimAll) {
637  const float x = nRecoAll / nSimAll;
638  errorAll = std::sqrt(1.f / nSimAll * x * (1 + x));
639  }
640  } else
641  errorAll = nSimAll && efficAll < 1 ? sqrt(efficAll * (1 - efficAll) / nSimAll) : 0;
642 
643  const int iBin = hGlobalEffic->Fill(newEfficMEName.c_str(), 0);
644  hGlobalEffic->SetBinContent(iBin, efficAll);
645  hGlobalEffic->SetBinError(iBin, errorAll);
646  }
647 }
648 
650  DQMStore::IGetter& igetter,
651  const string& startDir,
652  const string& namePrefix,
653  const string& titlePrefix,
654  const std::string& srcName) {
655  if (!igetter.dirExists(startDir)) {
656  if (verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_)) {
657  LogInfo("DQMGenericClient") << "computeResolution() : "
658  << "Cannot find sub-directory " << startDir << endl;
659  }
660  return;
661  }
662 
663  ibooker.cd();
664 
665  ME* srcME = igetter.get(startDir + "/" + srcName);
666  if (!srcME) {
667  if (verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_)) {
668  LogInfo("DQMGenericClient") << "computeResolution() : "
669  << "No source ME '" << srcName << "' found\n";
670  }
671  return;
672  }
673 
674  TH2F* hSrc = srcME->getTH2F();
675  if (!hSrc) {
676  if (verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_)) {
677  LogInfo("DQMGenericClient") << "computeResolution() : "
678  << "Cannot create TH2F from source-ME\n";
679  }
680  return;
681  }
682 
683  const int nBin = hSrc->GetNbinsX();
684 
685  string newDir = startDir;
686  string newPrefix = namePrefix;
687  string::size_type shiftPos;
688  if (string::npos != (shiftPos = namePrefix.rfind('/'))) {
689  newDir += "/" + namePrefix.substr(0, shiftPos);
690  newPrefix.erase(0, shiftPos + 1);
691  }
692 
693  ibooker.setCurrentFolder(newDir);
694 
695  float* lowedgesfloats = new float[nBin + 1];
696  ME* meanME;
697  ME* sigmaME;
698  if (hSrc->GetXaxis()->GetXbins()->GetSize()) {
699  for (int j = 0; j < nBin + 1; ++j)
700  lowedgesfloats[j] = (float)hSrc->GetXaxis()->GetXbins()->GetAt(j);
701  meanME = ibooker.book1D(newPrefix + "_Mean", titlePrefix + " Mean", nBin, lowedgesfloats);
702  sigmaME = ibooker.book1D(newPrefix + "_Sigma", titlePrefix + " Sigma", nBin, lowedgesfloats);
703  } else {
704  meanME = ibooker.book1D(
705  newPrefix + "_Mean", titlePrefix + " Mean", nBin, hSrc->GetXaxis()->GetXmin(), hSrc->GetXaxis()->GetXmax());
706  sigmaME = ibooker.book1D(
707  newPrefix + "_Sigma", titlePrefix + " Sigma", nBin, hSrc->GetXaxis()->GetXmin(), hSrc->GetXaxis()->GetXmax());
708  }
709 
710  if (meanME && sigmaME) {
711  meanME->setEfficiencyFlag();
712  sigmaME->setEfficiencyFlag();
713 
714  if (!resLimitedFit_) {
715  FitSlicesYTool fitTool(srcME);
716  fitTool.getFittedMeanWithError(meanME);
717  fitTool.getFittedSigmaWithError(sigmaME);
719  } else {
720  limitedFit(srcME, meanME, sigmaME);
721  }
722  }
723  delete[] lowedgesfloats;
724 }
725 
727  DQMStore::IGetter& igetter,
728  const std::string& startDir,
729  const std::string& profileMEName,
730  const std::string& profileMETitle,
731  const std::string& srcMEName) {
732  if (!igetter.dirExists(startDir)) {
733  if (verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_)) {
734  LogInfo("DQMGenericClient") << "computeProfile() : "
735  << "Cannot find sub-directory " << startDir << endl;
736  }
737  return;
738  }
739 
740  ibooker.cd();
741 
742  ME* srcME = igetter.get(startDir + "/" + srcMEName);
743  if (!srcME) {
744  if (verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_)) {
745  LogInfo("DQMGenericClient") << "computeProfile() : "
746  << "No source ME '" << srcMEName << "' found\n";
747  }
748  return;
749  }
750 
751  TH2F* hSrc = srcME->getTH2F();
752  if (!hSrc) {
753  if (verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_)) {
754  LogInfo("DQMGenericClient") << "computeProfile() : "
755  << "Cannot create TH2F from source-ME\n";
756  }
757  return;
758  }
759 
760  string profileDir = startDir;
761  string newProfileMEName = profileMEName;
762  string::size_type shiftPos;
763  if (string::npos != (shiftPos = profileMEName.rfind('/'))) {
764  profileDir += "/" + profileMEName.substr(0, shiftPos);
765  newProfileMEName.erase(0, shiftPos + 1);
766  }
767  ibooker.setCurrentFolder(profileDir);
768 
769  std::unique_ptr<TProfile> profile(hSrc->ProfileX()); // We own the pointer
770  profile->SetTitle(profileMETitle.c_str());
771  ibooker.bookProfile(profileMEName, profile.get()); // ibooker makes a copy
772 }
773 
775  DQMStore::IGetter& igetter,
776  const std::string& startDir,
777  const std::string& histName,
778  const std::string& normHistName) {
779  if (!igetter.dirExists(startDir)) {
780  if (verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_)) {
781  LogInfo("DQMGenericClient") << "normalizeToEntries() : "
782  << "Cannot find sub-directory " << startDir << endl;
783  }
784  return;
785  }
786 
787  ibooker.cd();
788 
789  ME* element = igetter.get(startDir + "/" + histName);
790  ME* normME = igetter.get(startDir + "/" + normHistName);
791 
792  if (!element) {
793  if (verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_)) {
794  LogInfo("DQMGenericClient") << "normalizeToEntries() : "
795  << "No such element '" << histName << "' found\n";
796  }
797  return;
798  }
799 
800  if (!normME) {
801  if (verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_)) {
802  LogInfo("DQMGenericClient") << "normalizeToEntries() : "
803  << "No such element '" << normHistName << "' found\n";
804  }
805  return;
806  }
807 
808  TH1F* hist = element->getTH1F();
809  if (!hist) {
810  if (verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_)) {
811  LogInfo("DQMGenericClient") << "normalizeToEntries() : "
812  << "Cannot create TH1F from ME\n";
813  }
814  return;
815  }
816 
817  TH1F* normHist = normME->getTH1F();
818  if (!normHist) {
819  if (verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_)) {
820  LogInfo("DQMGenericClient") << "normalizeToEntries() : "
821  << "Cannot create TH1F from ME\n";
822  }
823  return;
824  }
825 
826  const double entries = normHist->GetEntries();
827  if (entries != 0) {
828  hist->Scale(1. / entries);
829  } else {
830  LogInfo("DQMGenericClient") << "normalizeToEntries() : "
831  << "Zero entries in histogram\n";
832  }
833 
834  return;
835 }
836 
838  DQMStore::IGetter& igetter,
839  const std::string& startDir,
840  const std::string& cdName,
841  bool ascending) {
842  if (!igetter.dirExists(startDir)) {
843  if (verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_)) {
844  LogInfo("DQMGenericClient") << "makeCumulativeDist() : "
845  << "Cannot find sub-directory " << startDir << endl;
846  }
847  return;
848  }
849 
850  ibooker.cd();
851 
852  ME* element_cd = igetter.get(startDir + "/" + cdName);
853 
854  if (!element_cd) {
855  if (verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_)) {
856  LogInfo("DQMGenericClient") << "makeCumulativeDist() : "
857  << "No such element '" << cdName << "' found\n";
858  }
859  return;
860  }
861 
862  TH1F* cd = element_cd->getTH1F();
863 
864  if (!cd) {
865  if (verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_)) {
866  LogInfo("DQMGenericClient") << "makeCumulativeDist() : "
867  << "Cannot create TH1F from ME\n";
868  }
869  return;
870  }
871 
872  int n_bins = cd->GetNbinsX() + 1;
873 
874  if (ascending) {
875  for (int i = 1; i <= n_bins; i++) {
876  cd->SetBinContent(i, cd->GetBinContent(i) + cd->GetBinContent(i - 1));
877  }
878  } else {
879  for (int i = n_bins - 1; i >= 0; i--) { // n_bins points to the overflow bin
880  cd->SetBinContent(i, cd->GetBinContent(i) + cd->GetBinContent(i + 1));
881  }
882  }
883 
884  return;
885 }
886 
888  DQMStore::IGetter& igetter,
889  const std::string& startDir,
890  const std::string& noFlowName) {
891  if (!igetter.dirExists(startDir)) {
892  if (verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_)) {
893  LogInfo("DQMGenericClient") << "makeNoFlowDist() : "
894  << "Cannot find sub-directory " << startDir << endl;
895  }
896  return;
897  }
898 
899  ibooker.cd();
900 
901  ME* element_noFlow = igetter.get(startDir + "/" + noFlowName);
902 
903  if (!element_noFlow) {
904  if (verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_)) {
905  LogInfo("DQMGenericClient") << "makeNoFlowDist() : "
906  << "No such element '" << noFlowName << "' found\n";
907  }
908  return;
909  }
910 
911  TH1F* noFlow = element_noFlow->getTH1F();
912 
913  if (!noFlow) {
914  if (verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_)) {
915  LogInfo("DQMGenericClient") << "makeNoFlowDist() : "
916  << "Cannot create TH1F from ME\n";
917  }
918  return;
919  }
920 
921  noFlow->AddBinContent(1, noFlow->GetBinContent(0));
922  noFlow->SetBinContent(0, 0.);
923 
924  const auto lastBin = noFlow->GetNbinsX();
925  noFlow->AddBinContent(lastBin, noFlow->GetBinContent(lastBin + 1));
926  noFlow->SetBinContent(lastBin + 1, 0.);
927 }
928 
930  TH2F* histo = srcME->getTH2F();
931 
932  static int i = 0;
933  i++;
934 
935  // Fit slices projected along Y from bins in X
936  double cont_min = 100; //Minimum number of entries
937  Int_t binx = histo->GetXaxis()->GetNbins();
938 
939  for (int i = 1; i <= binx; i++) {
940  TString iString(i);
941  TH1* histoY = histo->ProjectionY(" ", i, i);
942  double cont = histoY->GetEntries();
943 
944  if (cont >= cont_min) {
945  float minfit = histoY->GetMean() - histoY->GetRMS();
946  float maxfit = histoY->GetMean() + histoY->GetRMS();
947 
948  TF1* fitFcn = new TF1(TString("g") + histo->GetName() + iString, "gaus", minfit, maxfit);
949  double x1, x2;
950  fitFcn->GetRange(x1, x2);
951 
952  histoY->Fit(fitFcn, "QR0 SERIAL", "", x1, x2);
953 
954  // histoY->Fit(fitFcn->GetName(),"RME");
955  double* par = fitFcn->GetParameters();
956  const double* err = fitFcn->GetParErrors();
957 
958  meanME->setBinContent(i, par[1]);
959  meanME->setBinError(i, err[1]);
960  // meanME->setBinEntries(i, 1.);
961  // meanME->setBinError(i,sqrt(err[1]*err[1]+par[1]*par[1]));
962 
963  sigmaME->setBinContent(i, par[2]);
964  sigmaME->setBinError(i, err[2]);
965  // sigmaME->setBinEntries(i, 1.);
966  // sigmaME->setBinError(i,sqrt(err[2]*err[2]+par[2]*par[2]));
967 
968  if (fitFcn)
969  delete fitFcn;
970  if (histoY)
971  delete histoY;
972  } else {
973  if (histoY)
974  delete histoY;
975  continue;
976  }
977  }
978 }
979 
980 //=================================
981 
983  DQMStore::IGetter& igetter,
985  std::set<std::string>* myList,
986  const TString& _pattern = TString("")) {
987  TString pattern = _pattern;
988  if (!igetter.dirExists(dir)) {
989  LogError("DQMGenericClient") << " DQMGenericClient::findAllSubdirectories ==> Missing folder " << dir << " !!!";
990  return;
991  }
992  if (pattern != "") {
993  if (pattern.Contains(nonPerlWildcard))
994  pattern.ReplaceAll("*", ".*");
995  TPRegexp regexp(pattern);
996  ibooker.cd(dir);
997  vector<string> foundDirs = igetter.getSubdirs();
998  for (vector<string>::const_iterator iDir = foundDirs.begin(); iDir != foundDirs.end(); ++iDir) {
999  TString dirName = iDir->substr(iDir->rfind('/') + 1, iDir->length());
1000  if (dirName.Contains(regexp))
1001  findAllSubdirectories(ibooker, igetter, *iDir, myList);
1002  }
1003  }
1004  //std::cout << "Looking for directory " << dir ;
1005  else if (igetter.dirExists(dir)) {
1006  //std::cout << "... it exists! Inserting it into the list ";
1007  myList->insert(dir);
1008  //std::cout << "... now list has size " << myList->size() << std::endl;
1009  ibooker.cd(dir);
1010  findAllSubdirectories(ibooker, igetter, dir, myList, "*");
1011  } else {
1012  //std::cout << "... DOES NOT EXIST!!! Skip bogus dir" << std::endl;
1013 
1014  LogInfo("DQMGenericClient") << "Trying to find sub-directories of " << dir << " failed because " << dir
1015  << " does not exist";
1016  }
1017  return;
1018 }
1019 
1020 void DQMGenericClient::generic_eff(TH1* denom, TH1* numer, MonitorElement* efficiencyHist, const EfficType type) {
1021  for (int iBinX = 1; iBinX < denom->GetNbinsX() + 1; iBinX++) {
1022  for (int iBinY = 1; iBinY < denom->GetNbinsY() + 1; iBinY++) {
1023  for (int iBinZ = 1; iBinZ < denom->GetNbinsZ() + 1; iBinZ++) {
1024  int globalBinNum = denom->GetBin(iBinX, iBinY, iBinZ);
1025 
1026  float numerVal = numer->GetBinContent(globalBinNum);
1027  float denomVal = denom->GetBinContent(globalBinNum);
1028 
1029  float effVal = 0;
1030 
1031  // fake eff is in use
1032  if (type == EfficType::fakerate) {
1033  effVal = denomVal ? (1 - numerVal / denomVal) : 0;
1034  } else {
1035  effVal = denomVal ? numerVal / denomVal : 0;
1036  }
1037 
1038  float errVal = 0;
1039  if (type == EfficType::simpleratio) {
1040  // errVal = denomVal ? 1.f/denomVal*effVal*(1+effVal) : 0;
1041  float numerErr = numer->GetBinError(globalBinNum);
1042  float denomErr = denom->GetBinError(globalBinNum);
1043  float denomsq = denomVal * denomVal;
1044  errVal = denomVal ? sqrt(pow(1.f / denomVal * numerErr, 2.0) + pow(numerVal / denomsq * denomErr, 2)) : 0;
1045  } else {
1046  errVal = (denomVal && (effVal <= 1)) ? sqrt(effVal * (1 - effVal) / denomVal) : 0;
1047  }
1048 
1049  LogDebug("DQMGenericClient") << "(iBinX, iBinY, iBinZ) = " << iBinX << ", " << iBinY << ", " << iBinZ
1050  << "), global bin = " << globalBinNum << "eff = " << numerVal << " / "
1051  << denomVal << " = " << effVal << " ... setting the error for that bin ... "
1052  << endl
1053  << endl;
1054 
1055  efficiencyHist->setBinContent(globalBinNum, effVal);
1056  efficiencyHist->setBinError(globalBinNum, errVal);
1057  efficiencyHist->setEfficiencyFlag();
1058  }
1059  }
1060  }
1061 
1062  //efficiencyHist->setMinimum(0.0);
1063  //efficiencyHist->setMaximum(1.0);
1064 }
1065 
1066 /* vim:set ts=2 sts=2 sw=2 expandtab: */
#define LogDebug(id)
type
Definition: HCALResponse.h:21
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX)
Definition: DQMStore.cc:239
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
void dqmEndJob(DQMStore::IBooker &, DQMStore::IGetter &) override
virtual TH2F * getTH2F() const
void getFittedSigmaWithError(MonitorElement *)
Fill the ME with the sigma value (with error) of the gaussian fit in each slice.
vector< string > vstring
Definition: ExoticaDQM.cc:8
void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:418
TPRegexp metacharacters("[\\^\\$\\.\\*\\+\\?\\|\\(\\)\\{\\}\\[\\]]")
void makeCumulativeDist(DQMStore::IBooker &ibooker, DQMStore::IGetter &igetter, const std::string &startDir, const std::string &cdName, bool ascending=true)
uint16_t size_type
Definition: ME.h:11
bool dirExists(std::string const &path)
Definition: DQMStore.cc:461
DQMGenericClient::MonitorElement ME
T sqrt(T t)
Definition: SSEVec.h:19
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
void makeAllPlots(DQMStore::IBooker &, DQMStore::IGetter &)
MonitorElement * bookProfile(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, char const *option="s")
Definition: DQMStore.cc:333
void normalizeToEntries(DQMStore::IBooker &ibooker, DQMStore::IGetter &igetter, const std::string &startDir, const std::string &histName, const std::string &normHistName)
MonitorElement * book3D(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, int nchZ, double lowZ, double highZ)
Definition: DQMStore.cc:317
double f[11][100]
void computeResolution(DQMStore::IBooker &ibooker, DQMStore::IGetter &igetter, const std::string &startDir, const std::string &fitMEPrefix, const std::string &fitMETitlePrefix, const std::string &srcMEName)
void makeNoFlowDist(DQMStore::IBooker &ibooker, DQMStore::IGetter &igetter, const std::string &startDir, const std::string &cdName)
void findAllSubdirectories(DQMStore::IBooker &ibooker, DQMStore::IGetter &igetter, std::string dir, std::set< std::string > *myList, const TString &pattern)
virtual void setBinContent(int binx, double content)
set content of bin (1-D)
void dqmEndLuminosityBlock(DQMStore::IBooker &ibooker, DQMStore::IGetter &igetter, const edm::LuminosityBlock &lumiSeg, const edm::EventSetup &c) override
void getFittedMeanWithError(MonitorElement *)
Fill the ME with the mean value (with error) of the gaussian fit in each slice.
TPRegexp nonPerlWildcard("\\w\\*|^\\*")
HLT enums.
void computeEfficiency(DQMStore::IBooker &ibooker, DQMStore::IGetter &igetter, const std::string &startDir, const std::string &efficMEName, const std::string &efficMETitle, const std::string &recoMEName, const std::string &simMEName, const EfficType type=EfficType::efficiency, const bool makeProfile=false)
MonitorElement * book2D(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY)
Definition: DQMStore.cc:266
DQMGenericClient(const edm::ParameterSet &pset)
def efficSet(nameIn, titleIn, numeratorIn, denominatorIn, typeIn="eff")
void computeProfile(DQMStore::IBooker &ibooker, DQMStore::IGetter &igetter, const std::string &startDir, const std::string &profileMEName, const std::string &profileMETitle, const std::string &srcMEName)
virtual void setBinError(int binx, double error)
set uncertainty on content of bin (1-D)
MonitorElement * get(std::string const &path)
Definition: DQMStore.cc:437
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:30
void limitedFit(MonitorElement *srcME, MonitorElement *meanME, MonitorElement *sigmaME)
cont
load Luminosity info ##
Definition: generateEDF.py:629
void generic_eff(TH1 *denom, TH1 *numer, MonitorElement *efficiencyHist, const EfficType type=EfficType::efficiency)
std::vector< std::string > getSubdirs()
Definition: DQMStore.cc:453