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