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  for ( vector<EfficOption>::const_iterator efficOption = efficOptions_.begin();
362  efficOption != efficOptions_.end(); ++efficOption )
363  {
364  computeEfficiency(ibooker, igetter, dirName, efficOption->name, efficOption->title,
365  efficOption->numerator, efficOption->denominator,
366  efficOption->type, efficOption->isProfile);
367  }
368 
369  for ( vector<ResolOption>::const_iterator resolOption = resolOptions_.begin();
370  resolOption != resolOptions_.end(); ++resolOption )
371  {
372  computeResolution(ibooker, igetter, dirName, resolOption->namePrefix, resolOption->titlePrefix, resolOption->srcName);
373  }
374 
375  for(const auto& profileOption: profileOptions_) {
376  computeProfile(ibooker, igetter, dirName, profileOption.name, profileOption.title, profileOption.srcName);
377  }
378 
379  for ( vector<NormOption>::const_iterator normOption = normOptions_.begin();
380  normOption != normOptions_.end(); ++normOption )
381  {
382  normalizeToEntries(ibooker, igetter, dirName, normOption->name, normOption->normHistName);
383  }
384 
385  for ( vector<CDOption>::const_iterator cdOption = cdOptions_.begin();
386  cdOption != cdOptions_.end(); ++cdOption )
387  {
388  makeCumulativeDist(ibooker, igetter, dirName, cdOption->name);
389  }
390  }
391 
392  if ( ! outputFileName_.empty() ) theDQM->save(outputFileName_);
393 
394 }
395 
396 void DQMGenericClient::computeEfficiency (DQMStore::IBooker& ibooker, DQMStore::IGetter& igetter, const string& startDir, const string& efficMEName,
397  const string& efficMETitle, const string& recoMEName, const string& simMEName, const int type, const bool makeProfile)
398 {
399  if ( ! igetter.dirExists(startDir) ) {
400  if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
401  LogInfo("DQMGenericClient") << "computeEfficiency() : "
402  << "Cannot find sub-directory " << startDir << endl;
403  }
404  return;
405  }
406 
407  ibooker.cd();
408 
409  ME* simME = igetter.get(startDir+"/"+simMEName);
410  ME* recoME = igetter.get(startDir+"/"+recoMEName);
411 
412  if ( !simME ) {
413  if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
414  LogInfo("DQMGenericClient") << "computeEfficiency() : "
415  << "No sim-ME '" << simMEName << "' found\n";
416  }
417  return;
418  }
419 
420  if ( !recoME ) {
421  if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
422  LogInfo("DQMGenericClient") << "computeEfficiency() : "
423  << "No reco-ME '" << recoMEName << "' found\n";
424  }
425  return;
426  }
427 
428  // Treat everything as the base class, TH1
429 
430  TH1* hSim = simME ->getTH1();
431  TH1* hReco = recoME->getTH1();
432 
433  if ( !hSim || !hReco ) {
434  if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
435  LogInfo("DQMGenericClient") << "computeEfficiency() : "
436  << "Cannot create TH1 from ME\n";
437  }
438  return;
439  }
440 
441  string efficDir = startDir;
442  string newEfficMEName = efficMEName;
443  string::size_type shiftPos;
444  if ( string::npos != (shiftPos = efficMEName.rfind('/')) ) {
445  efficDir += "/"+efficMEName.substr(0, shiftPos);
446  newEfficMEName.erase(0, shiftPos+1);
447  }
448  ibooker.setCurrentFolder(efficDir);
449 
450  if (makeProfile) {
451  TProfile * efficHist = (hReco->GetXaxis()->GetXbins()->GetSize()==0) ?
452  new TProfile(newEfficMEName.c_str(), efficMETitle.c_str(),
453  hReco->GetXaxis()->GetNbins(),
454  hReco->GetXaxis()->GetXmin(),
455  hReco->GetXaxis()->GetXmax()) :
456  new TProfile(newEfficMEName.c_str(), efficMETitle.c_str(),
457  hReco->GetXaxis()->GetNbins(),
458  hReco->GetXaxis()->GetXbins()->GetArray());
459 
460  efficHist->GetXaxis()->SetTitle(hSim->GetXaxis()->GetTitle());
461  efficHist->GetYaxis()->SetTitle(hSim->GetYaxis()->GetTitle());
462 
463 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,27,0)
464  for (int i=1; i <= hReco->GetNbinsX(); i++) {
465 
466  const double nReco = hReco->GetBinContent(i);
467  const double nSim = hSim->GetBinContent(i);
468  if(nSim > INT_MAX || nSim < INT_MIN || nReco > INT_MAX || nReco < INT_MIN)
469  {
470  LogError("DQMGenericClient") << "computeEfficiency() : "
471  << "Overflow: bin content either too large or too small to be casted to int";
472  return;
473  }
474 
475  if(std::string(hSim->GetXaxis()->GetBinLabel(i)) != "")
476  efficHist->GetXaxis()->SetBinLabel(i, hSim->GetXaxis()->GetBinLabel(i));
477 
478  if ( nSim == 0 || nReco > nSim ) continue;
479  const double effVal = nReco/nSim;
480 
481  const double errLo = TEfficiency::ClopperPearson((int)nSim,
482  (int)nReco,
483  0.683,false);
484  const double errUp = TEfficiency::ClopperPearson((int)nSim,
485  (int)nReco,
486  0.683,true);
487  const double errVal = (effVal - errLo > errUp - effVal) ? effVal - errLo : errUp - effVal;
488  efficHist->SetBinContent(i, effVal);
489  efficHist->SetBinEntries(i, 1);
490  efficHist->SetBinError(i, sqrt(effVal * effVal + errVal * errVal));
491  }
492 #else
493  for (int i=1; i <= hReco->GetNbinsX(); i++) {
494 
495  const double nReco = hReco->GetBinContent(i);
496  const double nSim = hSim->GetBinContent(i);
497  if(nSim > INT_MAX || nSim < INT_MIN || nReco > INT_MAX || nReco < INT_MIN)
498  {
499  LogError("DQMGenericClient") << "computeEfficiency() : "
500  << "Overflow: bin content either too large or too small to be casted to int";
501  return;
502  }
503 
504  TGraphAsymmErrorsWrapper asymm;
505  std::pair<double, double> efficiencyWithError;
506  efficiencyWithError = asymm.efficiency((int)nReco,
507  (int)nSim);
508  double effVal = efficiencyWithError.first;
509  double errVal = efficiencyWithError.second;
510  if ((int)nSim > 0) {
511  efficHist->SetBinContent(i, effVal);
512  efficHist->SetBinEntries(i, 1);
513  efficHist->SetBinError(i, sqrt(effVal * effVal + errVal * errVal));
514  }
515  if(std::string(hSim->GetXaxis()->GetBinLabel(i)) != "")
516  efficHist->GetXaxis()->SetBinLabel(i, hSim->GetXaxis()->GetBinLabel(i));
517  }
518 #endif
519  ibooker.bookProfile(newEfficMEName.c_str(),efficHist);
520  delete efficHist;
521  }
522 
523  else {
524 
525  TH1* efficHist = (TH1*)hSim->Clone(newEfficMEName.c_str());
526  efficHist->SetTitle(efficMETitle.c_str());
527 
528  // Here is where you have trouble --- you need
529  // to understand what type of hist you have.
530 
531  ME* efficME = 0;
532 
533  // Parse the class name
534  // This works, but there might be a better way
535  TClass * myHistClass = efficHist->IsA();
536  TString histClassName = myHistClass->GetName();
537 
538  if (histClassName == "TH1F"){
539  efficME = ibooker.book1D(newEfficMEName, (TH1F*)efficHist);
540  } else if (histClassName == "TH2F"){
541  efficME = ibooker.book2D(newEfficMEName, (TH2F*)efficHist);
542  } else if (histClassName == "TH3F"){
543  efficME = ibooker.book3D(newEfficMEName, (TH3F*)efficHist);
544  }
545 
546 
547  if ( !efficME ) {
548  LogInfo("DQMGenericClient") << "computeEfficiency() : "
549  << "Cannot book effic-ME from the DQM\n";
550  return;
551  }
552 
553  // Update: 2009-9-16 slaunwhj
554  // call the most generic efficiency function
555  // works up to 3-d histograms
556 
557  generic_eff (hSim, hReco, efficME, type);
558 
559  // const int nBin = efficME->getNbinsX();
560  // for(int bin = 0; bin <= nBin; ++bin) {
561  // const float nSim = simME ->getBinContent(bin);
562  // const float nReco = recoME->getBinContent(bin);
563  // float eff =0;
564  // if (type=="fake")eff = nSim ? 1-nReco/nSim : 0.;
565  // else eff= nSim ? nReco/nSim : 0.;
566  // const float err = nSim && eff <= 1 ? sqrt(eff*(1-eff)/nSim) : 0.;
567  // efficME->setBinContent(bin, eff);
568  // efficME->setBinError(bin, err);
569  // }
570  efficME->setEntries(simME->getEntries());
571 
572  }
573 
574  // Global efficiency
575  ME* globalEfficME = igetter.get(efficDir+"/globalEfficiencies");
576  if ( !globalEfficME ) globalEfficME = ibooker.book1D("globalEfficiencies", "Global efficiencies", 1, 0, 1);
577  if ( !globalEfficME ) {
578  LogInfo("DQMGenericClient") << "computeEfficiency() : "
579  << "Cannot book globalEffic-ME from the DQM\n";
580  return;
581  }
582  TH1F* hGlobalEffic = globalEfficME->getTH1F();
583  if ( !hGlobalEffic ) {
584  LogInfo("DQMGenericClient") << "computeEfficiency() : "
585  << "Cannot create TH1F from ME, globalEfficME\n";
586  return;
587  }
588 
589  const float nSimAll = hSim->GetEntries();
590  const float nRecoAll = hReco->GetEntries();
591  float efficAll=0;
592  if ( type == 1 ) efficAll = nSimAll ? nRecoAll/nSimAll : 0;
593  else if ( type == 2 ) efficAll = nSimAll ? 1-nRecoAll/nSimAll : 0;
594  const float errorAll = nSimAll && efficAll < 1 ? sqrt(efficAll*(1-efficAll)/nSimAll) : 0;
595 
596  const int iBin = hGlobalEffic->Fill(newEfficMEName.c_str(), 0);
597  hGlobalEffic->SetBinContent(iBin, efficAll);
598  hGlobalEffic->SetBinError(iBin, errorAll);
599 }
600 
601 void DQMGenericClient::computeResolution(DQMStore::IBooker& ibooker, DQMStore::IGetter& igetter, const string& startDir, const string& namePrefix, const string& titlePrefix,
602  const std::string& srcName)
603 {
604  if ( ! igetter.dirExists(startDir) ) {
605  if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
606  LogInfo("DQMGenericClient") << "computeResolution() : "
607  << "Cannot find sub-directory " << startDir << endl;
608  }
609  return;
610  }
611 
612  ibooker.cd();
613 
614  ME* srcME = igetter.get(startDir+"/"+srcName);
615  if ( !srcME ) {
616  if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
617  LogInfo("DQMGenericClient") << "computeResolution() : "
618  << "No source ME '" << srcName << "' found\n";
619  }
620  return;
621  }
622 
623  TH2F* hSrc = srcME->getTH2F();
624  if ( !hSrc ) {
625  if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
626  LogInfo("DQMGenericClient") << "computeResolution() : "
627  << "Cannot create TH2F from source-ME\n";
628  }
629  return;
630  }
631 
632  const int nBin = hSrc->GetNbinsX();
633 
634  string newDir = startDir;
635  string newPrefix = namePrefix;
636  string::size_type shiftPos;
637  if ( string::npos != (shiftPos = namePrefix.rfind('/')) ) {
638  newDir += "/"+namePrefix.substr(0, shiftPos);
639  newPrefix.erase(0, shiftPos+1);
640  }
641 
642  ibooker.setCurrentFolder(newDir);
643 
644  float * lowedgesfloats = new float[nBin+1];
645  ME* meanME;
646  ME* sigmaME;
647  if (hSrc->GetXaxis()->GetXbins()->GetSize())
648  {
649  for (int j=0; j<nBin+1; ++j)
650  lowedgesfloats[j] = (float)hSrc->GetXaxis()->GetXbins()->GetAt(j);
651  meanME = ibooker.book1D(newPrefix+"_Mean", titlePrefix+" Mean", nBin, lowedgesfloats);
652  sigmaME = ibooker.book1D(newPrefix+"_Sigma", titlePrefix+" Sigma", nBin, lowedgesfloats);
653  }
654  else
655  {
656  meanME = ibooker.book1D(newPrefix+"_Mean", titlePrefix+" Mean", nBin,
657  hSrc->GetXaxis()->GetXmin(),
658  hSrc->GetXaxis()->GetXmax());
659  sigmaME = ibooker.book1D(newPrefix+"_Sigma", titlePrefix+" Sigma", nBin,
660  hSrc->GetXaxis()->GetXmin(),
661  hSrc->GetXaxis()->GetXmax());
662  }
663 
664  if (meanME && sigmaME)
665  {
666  meanME->setEfficiencyFlag();
667  sigmaME->setEfficiencyFlag();
668 
669  if (! resLimitedFit_ ) {
670  FitSlicesYTool fitTool(srcME);
671  fitTool.getFittedMeanWithError(meanME);
672  fitTool.getFittedSigmaWithError(sigmaME);
674  } else {
675  limitedFit(srcME,meanME,sigmaME);
676  }
677  }
678  delete[] lowedgesfloats;
679 }
680 
681 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) {
682  if(!igetter.dirExists(startDir)) {
683  if(verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
684  LogInfo("DQMGenericClient") << "computeProfile() : "
685  << "Cannot find sub-directory " << startDir << endl;
686  }
687  return;
688  }
689 
690  ibooker.cd();
691 
692  ME* srcME = igetter.get(startDir+"/"+srcMEName);
693  if ( !srcME ) {
694  if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
695  LogInfo("DQMGenericClient") << "computeProfile() : "
696  << "No source ME '" << srcMEName << "' found\n";
697  }
698  return;
699  }
700 
701  TH2F* hSrc = srcME->getTH2F();
702  if ( !hSrc ) {
703  if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
704  LogInfo("DQMGenericClient") << "computeProfile() : "
705  << "Cannot create TH2F from source-ME\n";
706  }
707  return;
708  }
709 
710  string profileDir = startDir;
711  string newProfileMEName = profileMEName;
712  string::size_type shiftPos;
713  if ( string::npos != (shiftPos = profileMEName.rfind('/')) ) {
714  profileDir += "/"+profileMEName.substr(0, shiftPos);
715  newProfileMEName.erase(0, shiftPos+1);
716  }
717  ibooker.setCurrentFolder(profileDir);
718 
719  std::unique_ptr<TProfile> profile(hSrc->ProfileX()); // We own the pointer
720  profile->SetTitle(profileMETitle.c_str());
721  ibooker.bookProfile(profileMEName, profile.get()); // ibooker makes a copy
722 }
723 
724 
725 void DQMGenericClient::normalizeToEntries(DQMStore::IBooker& ibooker, DQMStore::IGetter& igetter, const std::string& startDir, const std::string& histName,
726  const std::string& normHistName)
727 {
728  if ( ! igetter.dirExists(startDir) ) {
729  if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
730  LogInfo("DQMGenericClient") << "normalizeToEntries() : "
731  << "Cannot find sub-directory " << startDir << endl;
732  }
733  return;
734  }
735 
736  ibooker.cd();
737 
738  ME* element = igetter.get(startDir+"/"+histName);
739  ME* normME = igetter.get(startDir+"/"+normHistName);
740 
741  if ( !element ) {
742  if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
743  LogInfo("DQMGenericClient") << "normalizeToEntries() : "
744  << "No such element '" << histName << "' found\n";
745  }
746  return;
747  }
748 
749  if ( !normME ) {
750  if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
751  LogInfo("DQMGenericClient") << "normalizeToEntries() : "
752  << "No such element '" << normHistName << "' found\n";
753  }
754  return;
755  }
756 
757  TH1F* hist = element->getTH1F();
758  if ( !hist) {
759  if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
760  LogInfo("DQMGenericClient") << "normalizeToEntries() : "
761  << "Cannot create TH1F from ME\n";
762  }
763  return;
764  }
765 
766  TH1F* normHist = normME->getTH1F();
767  if ( !normHist ) {
768  if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
769  LogInfo("DQMGenericClient") << "normalizeToEntries() : "
770  << "Cannot create TH1F from ME\n";
771  }
772  return;
773  }
774 
775  const double entries = normHist->GetEntries();
776  if ( entries != 0 ) {
777  hist->Scale(1./entries);
778  }
779  else {
780  LogInfo("DQMGenericClient") << "normalizeToEntries() : "
781  << "Zero entries in histogram\n";
782  }
783 
784  return;
785 }
786 
787 void DQMGenericClient::makeCumulativeDist(DQMStore::IBooker& ibooker, DQMStore::IGetter& igetter, const std::string& startDir, const std::string& cdName)
788 {
789  if ( ! igetter.dirExists(startDir) ) {
790  if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
791  LogInfo("DQMGenericClient") << "makeCumulativeDist() : "
792  << "Cannot find sub-directory " << startDir << endl;
793  }
794  return;
795  }
796 
797  ibooker.cd();
798 
799  ME* element_cd = igetter.get(startDir+"/"+cdName);
800 
801  if ( !element_cd ) {
802  if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
803  LogInfo("DQMGenericClient") << "makeCumulativeDist() : "
804  << "No such element '" << cdName << "' found\n";
805  }
806  return;
807  }
808 
809  TH1F* cd = element_cd->getTH1F();
810 
811  if ( !cd ) {
812  if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
813  LogInfo("DQMGenericClient") << "makeCumulativeDist() : "
814  << "Cannot create TH1F from ME\n";
815  }
816  return;
817  }
818 
819  int n_bins = cd->GetNbinsX() + 1;
820 
821  for (int i = 1; i <= n_bins; i++) {
822  cd->SetBinContent(i,cd->GetBinContent(i) + cd->GetBinContent(i-1));
823  }
824 
825  return;
826 }
827 
829 {
830  TH2F * histo = srcME->getTH2F();
831 
832  static int i = 0;
833  i++;
834 
835  // Fit slices projected along Y from bins in X
836  double cont_min = 100; //Minimum number of entries
837  Int_t binx = histo->GetXaxis()->GetNbins();
838 
839  for (int i = 1; i <= binx ; i++) {
840  TString iString(i);
841  TH1 *histoY = histo->ProjectionY(" ", i, i);
842  double cont = histoY->GetEntries();
843 
844  if (cont >= cont_min) {
845  float minfit = histoY->GetMean() - histoY->GetRMS();
846  float maxfit = histoY->GetMean() + histoY->GetRMS();
847 
848  TF1 *fitFcn = new TF1(TString("g")+histo->GetName()+iString,"gaus",minfit,maxfit);
849  double x1,x2;
850  fitFcn->GetRange(x1,x2);
851 
852  histoY->Fit(fitFcn,"QR0","",x1,x2);
853 
854 // histoY->Fit(fitFcn->GetName(),"RME");
855  double *par = fitFcn->GetParameters();
856  const double *err = fitFcn->GetParErrors();
857 
858  meanME->setBinContent(i, par[1]);
859  meanME->setBinError(i, err[1]);
860 // meanME->setBinEntries(i, 1.);
861 // meanME->setBinError(i,sqrt(err[1]*err[1]+par[1]*par[1]));
862 
863  sigmaME->setBinContent(i, par[2]);
864  sigmaME->setBinError(i, err[2]);
865 // sigmaME->setBinEntries(i, 1.);
866 // sigmaME->setBinError(i,sqrt(err[2]*err[2]+par[2]*par[2]));
867 
868  if(fitFcn) delete fitFcn;
869  if(histoY) delete histoY;
870  }
871  else {
872  if(histoY) delete histoY;
873  continue;
874  }
875  }
876 }
877 
878 //=================================
879 
881  const TString& _pattern = TString("")) {
882  TString pattern = _pattern;
883  if (!igetter.dirExists(dir)) {
884  LogError("DQMGenericClient") << " DQMGenericClient::findAllSubdirectories ==> Missing folder " << dir << " !!!";
885  return;
886  }
887  if (pattern != "") {
888  if (pattern.Contains(nonPerlWildcard)) pattern.ReplaceAll("*",".*");
889  TPRegexp regexp(pattern);
890  ibooker.cd(dir);
891  vector <string> foundDirs = igetter.getSubdirs();
892  for(vector<string>::const_iterator iDir = foundDirs.begin();
893  iDir != foundDirs.end(); ++iDir) {
894  TString dirName = iDir->substr(iDir->rfind('/') + 1, iDir->length());
895  if (dirName.Contains(regexp))
896  findAllSubdirectories (ibooker, igetter, *iDir, myList);
897  }
898  }
899  //std::cout << "Looking for directory " << dir ;
900  else if (igetter.dirExists(dir)){
901  //std::cout << "... it exists! Inserting it into the list ";
902  myList->insert(dir);
903  //std::cout << "... now list has size " << myList->size() << std::endl;
904  ibooker.cd(dir);
905  findAllSubdirectories (ibooker, igetter, dir, myList, "*");
906  } else {
907  //std::cout << "... DOES NOT EXIST!!! Skip bogus dir" << std::endl;
908 
909  LogInfo ("DQMGenericClient") << "Trying to find sub-directories of " << dir
910  << " failed because " << dir << " does not exist";
911 
912  }
913  return;
914 }
915 
916 
917 void DQMGenericClient::generic_eff (TH1* denom, TH1* numer, MonitorElement* efficiencyHist, const int type) {
918  for (int iBinX = 1; iBinX < denom->GetNbinsX()+1; iBinX++){
919  for (int iBinY = 1; iBinY < denom->GetNbinsY()+1; iBinY++){
920  for (int iBinZ = 1; iBinZ < denom->GetNbinsZ()+1; iBinZ++){
921 
922  int globalBinNum = denom->GetBin(iBinX, iBinY, iBinZ);
923 
924  float numerVal = numer->GetBinContent(globalBinNum);
925  float denomVal = denom->GetBinContent(globalBinNum);
926 
927  float effVal = 0;
928 
929  // fake eff is in use
930  if (type == 2 ) {
931  effVal = denomVal ? (1 - numerVal / denomVal) : 0;
932  } else {
933  effVal = denomVal ? numerVal / denomVal : 0;
934  }
935 
936  float errVal = (denomVal && (effVal <=1)) ? sqrt(effVal*(1-effVal)/denomVal) : 0;
937 
938  LogDebug ("DQMGenericClient") << "(iBinX, iBinY, iBinZ) = "
939  << iBinX << ", "
940  << iBinY << ", "
941  << iBinZ << "), global bin = " << globalBinNum
942  << "eff = " << numerVal << " / " << denomVal
943  << " = " << effVal
944  << " ... setting the error for that bin ... " << endl
945  << endl;
946 
947 
948  efficiencyHist->setBinContent(globalBinNum, effVal);
949  efficiencyHist->setBinError(globalBinNum, errVal);
950  efficiencyHist->setEfficiencyFlag();
951  }
952  }
953  }
954 
955  //efficiencyHist->setMinimum(0.0);
956  //efficiencyHist->setMaximum(1.0);
957 }
958 
959 
960 /* 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:86
void cd(void)
Definition: DQMStore.cc:266
MonitorElement * get(const std::string &path)
Definition: DQMStore.cc:302
TPRegexp metacharacters("[\\^\\$\\.\\*\\+\\?\\|\\(\\)\\{\\}\\[\\]]")
list pattern
Definition: chain.py:104
uint16_t size_type
Definition: ME.h:11
T sqrt(T t)
Definition: SSEVec.h:48
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:318
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: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:306
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)