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