CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
EmDQMPostProcessor.cc
Go to the documentation of this file.
2 
7 
8 #include <iostream>
9 #include <string.h>
10 #include <iomanip>
11 #include <fstream>
12 #include <math.h>
13 
14 #include <TEfficiency.h>
15 
16 //----------------------------------------------------------------------
17 
19 {
20  subDir_ = pset.getUntrackedParameter<std::string>("subDir");
21 
22  dataSet_ = pset.getUntrackedParameter<std::string>("dataSet","unknown");
23 
24  noPhiPlots = pset.getUntrackedParameter<bool>("noPhiPlots", true);
25 
26  normalizeToReco = pset.getUntrackedParameter<bool>("normalizeToReco",false);
27 }
28 
29 //----------------------------------------------------------------------
30 
32 {
34  // setup DQM stor //
36 
37  DQMStore * dqm = 0;
38  dqm = edm::Service<DQMStore>().operator->();
39 
40  if ( ! dqm ) {
41  edm::LogInfo("EmDQMPostProcessor") << "Cannot create DQMStore instance\n";
42  return;
43  }
44 
45 
46  //go to the directory to be processed
47  if(dqm->dirExists(subDir_)) dqm->cd(subDir_);
48  else {
49  edm::LogWarning("EmDQMPostProcessor") << "cannot find directory: " << subDir_ << " , skipping";
50  return;
51  }
52 
53  //--------------------
54  // with respect to what are (some) efficiencies calculated ?
55  std::string shortReferenceName;
56  if (normalizeToReco)
57  shortReferenceName = "RECO";
58  else
59  shortReferenceName = "gen";
60 
61 
62 
63  //--------------------
64 
65 
67  //loop over all triggers/samples//
69 
70  // store dataset name (if defined) in output file
71  // DQMStore:bookString seems to put a key in the file which is
72  // of the form <dataSet>s=....</dataSet> which is not very convenient
73  // (it points to a null pointer, one would have to loop over
74  // all keys of the corresponding directory in the ROOT file
75  // and check whether it is of the desired form and then parse
76  // it from this string...).
77  //
78  // So we store the name of the dataset as the title of a histogram,
79  // which is much easier to access...
80  // TH1D *dataSetNameHisto =
81  dqm->book1D("DataSetNameHistogram",dataSet_,1,0,1);
82 
83  std::vector<std::string> subdirectories = dqm->getSubdirs();
85  // Do everything twice: once for mc-matched histos, //
86  // once for unmatched histos //
88 
89  std::vector<std::string> postfixes;
90  postfixes.push_back(""); //unmatched histograms
91  postfixes.push_back("_RECO_matched"); // for data
92  // we put this on the list even when we're running on
93  // data (where there is no generator information).
94  // The first test in the loop will then fail and
95  // the iteration is skipped.
96  postfixes.push_back("_MC_matched");
97 
98  std::vector<TProfile *> allElePaths;
99  int nEle = 0;
100  int nPhoton = 0;
101 
102  // find the number of electron and photon paths
103  for(std::vector<std::string>::iterator dir = subdirectories.begin() ;dir!= subdirectories.end(); ++dir) {
104  if (dir->find("HLT_Ele") != std::string::npos || dir->find("HLT_DoubleEle") != std::string::npos || dir->find("HLT_TripleEle") != std::string::npos) ++nEle;
105  else if (dir->find("HLT_Photon") != std::string::npos || dir->find("HLT_DoublePhoton") != std::string::npos) ++nPhoton;
106  }
107 
108  std::vector<TProfile *> allPhotonPaths;
109  for(std::vector<std::string>::iterator postfix=postfixes.begin(); postfix!=postfixes.end();postfix++){
110  bool pop = false;
111  int elePos = 1;
112  int photonPos = 1;
113 
115  // computer per-event efficiencies //
117 
118  std::string histoName = "efficiency_by_step" + *postfix;
119  std::string baseName = "total_eff" + *postfix;
120 
121  std::string allEleHistoName = "EfficiencyByPath_Ele" + *postfix;
122  std::string allEleHistoLabel = "Efficiency_for_each_validated_electron_path" + *postfix;
123  allElePaths.push_back(new TProfile(allEleHistoName.c_str(), allEleHistoLabel.c_str(), nEle, 0., (double)nEle, 0., 1.2));
124  std::string allPhotonHistoName = "EfficiencyByPath_Photon" + *postfix;
125  std::string allPhotonHistoLabel = "Efficiency_for_each_validated_photon_path" + *postfix;
126  allPhotonPaths.push_back(new TProfile(allPhotonHistoName.c_str(), allPhotonHistoLabel.c_str(), nPhoton, 0., (double)nPhoton, 0., 1.2));
127 
128  for(std::vector<std::string>::iterator dir = subdirectories.begin(); dir!= subdirectories.end(); dir++) {
129  dqm->cd(*dir);
130 
131  TH1F* basehist = getHistogram(dqm, dqm->pwd() + "/" + baseName);
132  if (basehist == NULL)
133  {
134  //edm::LogWarning("EmDQMPostProcessor") << "histogram " << (dqm->pwd() + "/" + baseName) << " does not exist, skipping postfix '" << *postfix << "'";
135  pop = true;
136  dqm->goUp();
137  continue;
138  }
139  // at least one histogram with postfix was found
140  pop = false;
141 
142  TProfile* total = dqm->bookProfile(histoName,histoName,basehist->GetXaxis()->GetNbins(),basehist->GetXaxis()->GetXmin(),basehist->GetXaxis()->GetXmax(),0.,1.2)->getTProfile();
143  total->GetXaxis()->SetBinLabel(1,basehist->GetXaxis()->GetBinLabel(1));
144 
145 // std::vector<std::string> mes = dqm->getMEs();
146 // for(std::vector<std::string>::iterator me = mes.begin() ;me!= mes.end(); me++ )
147 // std::cout <<*me <<std::endl;
148 // std::cout <<std::endl;
149 
150  double value=0;
151  double errorh=0,errorl=0,error=0;
152  //compute stepwise total efficiencies
153  for(int bin= total->GetNbinsX()-2 ; bin > 1 ; bin--){
154  value=0;
155  errorl=0;
156  errorh=0;
157  error=0;
158  if(basehist->GetBinContent(bin-1) != 0){
159  Efficiency( (int)basehist->GetBinContent(bin), (int)basehist->GetBinContent(bin-1), 0.683, value, errorl, errorh );
160  error = value-errorl>errorh-value ? value-errorl : errorh-value;
161  }
162  total->SetBinContent( bin, value );
163  total->SetBinEntries( bin, 1 );
164  total->SetBinError( bin, sqrt(value*value+error*error) );
165  total->GetXaxis()->SetBinLabel(bin,basehist->GetXaxis()->GetBinLabel(bin));
166  }
167 
168  //set first bin to L1 efficiency
169  if(basehist->GetBinContent(basehist->GetNbinsX()) !=0 ){
170  Efficiency( (int)basehist->GetBinContent(1), (int)basehist->GetBinContent(basehist->GetNbinsX()), 0.683, value, errorl, errorh );
171  error= value-errorl>errorh-value ? value-errorl : errorh-value;
172  }else{
173  value=0;error=0;
174  }
175  total->SetBinContent(1,value);
176  total->SetBinEntries(1, 1 );
177  total->SetBinError(1, sqrt(value*value+error*error) );
178 
179  // total efficiency relative to gen or reco
180  if(basehist->GetBinContent(basehist->GetNbinsX()) !=0 ){
181  Efficiency( (int)basehist->GetBinContent(basehist->GetNbinsX()-2), (int)basehist->GetBinContent(basehist->GetNbinsX()), 0.683, value, errorl, errorh );
182  error= value-errorl>errorh-value ? value-errorl : errorh-value;
183  }else{
184  value=0;error=0;
185  }
186  total->SetBinContent(total->GetNbinsX(),value);
187  total->SetBinEntries(total->GetNbinsX(),1);
188  total->SetBinError(total->GetNbinsX(),sqrt(value*value+error*error));
189  total->GetXaxis()->SetBinLabel(total->GetNbinsX(),("total efficiency rel. " + shortReferenceName).c_str());
190 
191  //total efficiency relative to L1
192  if(basehist->GetBinContent(1) !=0 ){
193  Efficiency( (int)basehist->GetBinContent(basehist->GetNbinsX()-2), (int)basehist->GetBinContent(1), 0.683, value, errorl, errorh );
194  error= value-errorl > errorh-value ? value-errorl : errorh-value;
195  }else{
196  value=0;error=0;
197  }
198  total->SetBinContent(total->GetNbinsX()-1,value);
199  total->SetBinError(total->GetNbinsX()-1,sqrt(value*value+error*error));
200  total->SetBinEntries(total->GetNbinsX()-1,1);
201  total->GetXaxis()->SetBinLabel(total->GetNbinsX()-1,"total efficiency rel. L1");
202 
203  //----------------------------------------
204 
206  // compute per-object efficiencies //
208  //MonitorElement *eff, *num, *denom, *genPlot, *effVsGen, *effL1VsGen;
209  std::vector<std::string> varNames;
210  varNames.push_back("et");
211  varNames.push_back("eta");
212  if (!noPhiPlots) varNames.push_back("phi");
213 
214  std::string filterName;
215  std::string filterName2;
216  std::string denomName;
217  std::string numName;
218 
219  // Get the gen-level (or reco, for data) plots
220  std::string genName;
221 
222  // Get the L1 over gen filter first
223  filterName2= total->GetXaxis()->GetBinLabel(1);
224 
225  //loop over variables (eta/phi/et)
226  for(std::vector<std::string>::iterator var = varNames.begin(); var != varNames.end() ; var++){
227 
228  numName = dqm->pwd() + "/" + filterName2 + *var + *postfix;
229 
230  if (normalizeToReco)
231  genName = dqm->pwd() + "/reco_" + *var ;
232  else
233  genName = dqm->pwd() + "/gen_" + *var ;
234 
235  // Create the efficiency plot
236  if(!dividehistos(dqm,numName,genName,"efficiency_"+filterName2+"_vs_"+*var +*postfix,*var,"eff. of"+filterName2+" vs "+*var +*postfix))
237  break;
238  } // loop over variables
239 
240  // get the filter names from the bin-labels of the master-histogram
241  for (int filter=1; filter < total->GetNbinsX()-2; filter++) {
242  filterName = total->GetXaxis()->GetBinLabel(filter);
243  filterName2= total->GetXaxis()->GetBinLabel(filter+1);
244 
245  //loop over variables (eta/et/phi)
246  for(std::vector<std::string>::iterator var = varNames.begin(); var != varNames.end() ; var++){
247  numName = dqm->pwd() + "/" + filterName2 + *var + *postfix;
248  denomName = dqm->pwd() + "/" + filterName + *var + *postfix;
249 
250  // Is this the last filter? Book efficiency vs gen (or reco, for data) level
251  std::string temp = *postfix;
252  if (filter==total->GetNbinsX()-3 && temp.find("matched")!=std::string::npos) {
253  if (normalizeToReco)
254  genName = dqm->pwd() + "/reco_" + *var;
255  else
256  genName = dqm->pwd() + "/gen_" + *var;
257 
258  if(!dividehistos(dqm,numName,genName,"final_eff_vs_"+*var,*var,"Efficiency Compared to " + shortReferenceName + " vs "+*var))
259  break;
260  }
261 
262  if(!dividehistos(dqm,numName,denomName,"efficiency_"+filterName2+"_vs_"+*var +*postfix,*var,"efficiency_"+filterName2+"_vs_"+*var + *postfix))
263  break;
264 
265  } // loop over variables
266  } // loop over monitoring modules within path
267 
268  dqm->goUp();
269 
270  // fill overall efficiency histograms
271  std::string trigName = dir->substr(dir->rfind("/") + 1);
272  trigName = trigName.replace(trigName.rfind("_DQM"),4,"");
273  double totCont = total->GetBinContent(total->GetNbinsX());
274  double totErr = total->GetBinError(total->GetNbinsX());
275  if (trigName.find("HLT_Ele") != std::string::npos || trigName.find("HLT_DoubleEle") != std::string::npos || trigName.find("HLT_TripleEle") != std::string::npos) {
276  allElePaths.back()->SetBinContent(elePos, totCont);
277  allElePaths.back()->SetBinEntries(elePos, 1);
278  allElePaths.back()->SetBinError(elePos, sqrt(totCont * totCont + totErr * totErr));
279  allElePaths.back()->GetXaxis()->SetBinLabel(elePos, trigName.c_str());
280  ++elePos;
281  }
282  else if (trigName.find("HLT_Photon") != std::string::npos || trigName.find("HLT_DoublePhoton") != std::string::npos) {
283  allPhotonPaths.back()->SetBinContent(photonPos, totCont);
284  allPhotonPaths.back()->SetBinEntries(photonPos, 1);
285  allPhotonPaths.back()->SetBinError(photonPos, sqrt(totCont * totCont + totErr * totErr));
286  allPhotonPaths.back()->GetXaxis()->SetBinLabel(photonPos, trigName.c_str());
287  ++photonPos;
288  }
289 
290  } // loop over dirs
291  if (pop) {
292  allElePaths.pop_back();
293  allPhotonPaths.pop_back();
294  }
295  else {
296  allElePaths.back()->GetXaxis()->SetLabelSize(0.03);
297  allPhotonPaths.back()->GetXaxis()->SetLabelSize(0.03);
298  dqm->bookProfile(allEleHistoName, allElePaths.back())->getTProfile();
299  dqm->bookProfile(allPhotonHistoName, allPhotonPaths.back())->getTProfile();
300  }
301  } // loop over postfixes
302 
303 }
304 
305 //----------------------------------------------------------------------
306 
307 TProfile* EmDQMPostProcessor::dividehistos(DQMStore * dqm, const std::string& numName, const std::string& denomName, const std::string& outName,const std::string& label,const std::string& titel){
308  //std::cout << numName <<std::endl;
309 
310  TH1F* num = getHistogram(dqm,numName);
311 
312  //std::cout << denomName << std::endl;
313  TH1F* denom = getHistogram(dqm, denomName);
314 
315  if (num == NULL)
316  edm::LogWarning("EmDQMPostProcessor") << "numerator histogram " << numName << " does not exist";
317 
318  if (denom == NULL)
319  edm::LogWarning("EmDQMPostProcessor") << "denominator histogram " << denomName << " does not exist";
320 
321  // Check if histograms actually exist
322 
323  if(!num || !denom) return 0;
324 
325  // Make sure we are able to book new element
326  if (!dqm) return 0;
327 
328  TProfile* out = dqm->bookProfile(outName,titel,num->GetXaxis()->GetNbins(),num->GetXaxis()->GetXmin(),num->GetXaxis()->GetXmax(),0.,1.2)->getTProfile();
329  out->GetXaxis()->SetTitle(label.c_str());
330  out->SetYTitle("Efficiency");
331  out->SetOption("PE");
332  out->SetLineColor(2);
333  out->SetLineWidth(2);
334  out->SetMarkerStyle(20);
335  out->SetMarkerSize(0.8);
336  out->SetStats(kFALSE);
337  for(int i=1;i<=num->GetNbinsX();i++){
338  double e, low, high;
339  Efficiency( (int)num->GetBinContent(i), (int)denom->GetBinContent(i), 0.683, e, low, high );
340  double err = e-low>high-e ? e-low : high-e;
341  //here is the trick to store info in TProfile:
342  out->SetBinContent( i, e );
343  out->SetBinEntries( i, 1 );
344  out->SetBinError( i, sqrt(e*e+err*err) );
345  }
346 
347  return out;
348 }
349 
350 //----------------------------------------------------------------------
351 
352 TH1F *
353 EmDQMPostProcessor::getHistogram(DQMStore *dqm, const std::string &histoPath)
354 {
355  MonitorElement *monElement = dqm->get(histoPath);
356  if (monElement != NULL)
357  return monElement->getTH1F();
358  else
359  return NULL;
360 }
361 
362 //----------------------------------------------------------------------
363 
364 void
365 EmDQMPostProcessor::Efficiency(int passing, int total, double level, double &mode, double &lowerBound, double &upperBound)
366 {
367  // protection (see also TGraphAsymmErrors::Efficiency(..), mimick the old behaviour )
368  if (total == 0)
369  {
370  mode = 0.5;
371  lowerBound = 0;
372  upperBound = 1;
373  return;
374  }
375 
376  mode = passing / ((double) total);
377 
378  // note that the order of the two first arguments ('total' and 'passed') is the opposited
379  // with respect to the earlier TGraphAsymmErrors::Efficiency(..) method
380  //
381  // see http://root.cern.ch/root/html/TEfficiency.html#compare for
382  // an illustration of the coverage of the different methods provided by TEfficiency
383 
384  lowerBound = TEfficiency::Wilson(total, passing, level, false);
385  upperBound = TEfficiency::Wilson(total, passing, level, true);
386 }
387 
388 
389 //----------------------------------------------------------------------
390 
392 
393 //----------------------------------------------------------------------
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
TProfile * getTProfile(std::string name, std::string process, std::string rootfolder, DQMStore *dbe_, bool verb, bool clone)
std::vector< std::string > getSubdirs(void) const
Definition: DQMStore.cc:1419
MonitorElement * book1D(const char *name, const char *title, int nchX, double lowX, double highX)
Book 1D histogram.
Definition: DQMStore.cc:717
void cd(void)
go to top directory (ie. root)
Definition: DQMStore.cc:406
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
#define NULL
Definition: scimark2.h:8
void endRun(edm::Run const &, edm::EventSetup const &)
T sqrt(T t)
Definition: SSEVec.h:46
MonitorElement * bookProfile(const char *name, const char *title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, const char *option="s")
Definition: DQMStore.cc:1031
MonitorElement * get(const std::string &path) const
get ME from full pathname (e.g. &quot;my/long/dir/my_histo&quot;)
Definition: DQMStore.cc:1468
EmDQMPostProcessor(const edm::ParameterSet &pset)
bool dirExists(const std::string &path) const
true if directory exists
Definition: DQMStore.cc:493
tuple out
Definition: dbtoconf.py:99
TH1F * getTH1F(void) const
long long int num
Definition: procUtils.cc:71
TProfile * getTProfile(void) const
void goUp(void)
equivalent to &quot;cd ..&quot;
Definition: DQMStore.cc:440
tuple level
Definition: testEve_cfg.py:34
dbl *** dir
Definition: mlp_gen.cc:35
TH1F * getHistogram(DQMStore *dqm, const std::string &histoPath)
static void Efficiency(int passing, int total, double level, double &mode, double &lowerBound, double &upperBound)
Definition: Run.h:33
const std::string & pwd(void) const
Definition: DQMStore.cc:401
TProfile * dividehistos(DQMStore *dqm, const std::string &num, const std::string &denom, const std::string &out, const std::string &label, const std::string &titel="")