test
CMS 3D CMS Logo

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