CMS 3D CMS Logo

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