CMS 3D CMS Logo

EffPurFromHistos2D.cc
Go to the documentation of this file.
4 #include "TStyle.h"
5 #include "TCanvas.h"
6 
7 #include <iostream>
8 #include <cmath>
9 
13 
14 using namespace std;
15 using namespace RecoBTag;
16 
17 EffPurFromHistos2D::EffPurFromHistos2D(const std::string & ext, TH2F * h_d, TH2F * h_u,
18  TH2F * h_s, TH2F * h_c, TH2F * h_b, TH2F * h_g, TH2F * h_ni,
19  TH2F * h_dus, TH2F * h_dusg, TH2F * h_pu,
20  const std::string& label, unsigned int mc,
21  int nBinX, double startOX, double endOX) :
22  fromDiscriminatorDistr(false),
23  mcPlots_(mc), doCTagPlots_(false), label_(label),
24  histoExtension(ext), effVersusDiscr_d(h_d), effVersusDiscr_u(h_u),
25  effVersusDiscr_s(h_s), effVersusDiscr_c(h_c), effVersusDiscr_b(h_b),
26  effVersusDiscr_g(h_g), effVersusDiscr_ni(h_ni), effVersusDiscr_dus(h_dus),
27  effVersusDiscr_dusg(h_dusg), effVersusDiscr_pu(h_pu),
28  nBinOutputX(nBinX), startOutputX(startOX), endOutputX(endOX)
29 {
30  // consistency check
31  check();
32 }
33 
35  const std::string& label, unsigned int mc,
36  DQMStore::IBooker & ibook,
37  int nBinX, double startOX, double endOX):
39  mcPlots_(mc), doCTagPlots_(false), label_(label),
40  nBinOutputX(nBinX), startOutputX(startOX), endOutputX(endOX)
41 {
42  histoExtension = "_" + dDiscriminatorFC.baseNameTitle();
43 
44  discrNoCutEffic = std::make_unique<FlavourHistograms2D<double, double>>(
45  "totalEntries" + histoExtension, "Total Entries: " + dDiscriminatorFC.baseNameDescription(),
46  dDiscriminatorFC.nBinsX(), dDiscriminatorFC.lowerBoundX(), dDiscriminatorFC.upperBoundX(), dDiscriminatorFC.nBinsY(),
47  dDiscriminatorFC.lowerBoundY(), dDiscriminatorFC.upperBoundY(),
48  false, label, mcPlots_, false, ibook);
49 
50  // conditional discriminator cut for efficiency histos
51  discrCutEfficScan = std::make_unique<FlavourHistograms2D<double, double>>(
52  "effVsDiscrCut" + histoExtension, "Eff. vs Disc. Cut: " + dDiscriminatorFC.baseNameDescription(),
53  dDiscriminatorFC.nBinsX(), dDiscriminatorFC.lowerBoundX(), dDiscriminatorFC.upperBoundX(), dDiscriminatorFC.nBinsY(),
54  dDiscriminatorFC.lowerBoundY(), dDiscriminatorFC.upperBoundY(),
55  false, label, mcPlots_, false, ibook);
56  discrCutEfficScan->SetMinimum(1E-4);
57 
58  if (mcPlots_) {
59 
60  if (mcPlots_ > 2) {
61  effVersusDiscr_d = discrCutEfficScan->histo_d ();
62  effVersusDiscr_u = discrCutEfficScan->histo_u ();
63  effVersusDiscr_s = discrCutEfficScan->histo_s ();
64  effVersusDiscr_g = discrCutEfficScan->histo_g ();
65  effVersusDiscr_dus = discrCutEfficScan->histo_dus();
66  } else {
67  effVersusDiscr_d = nullptr;
68  effVersusDiscr_u = nullptr;
69  effVersusDiscr_s = nullptr;
70  effVersusDiscr_g = nullptr;
71  effVersusDiscr_dus = nullptr;
72  }
73  effVersusDiscr_c = discrCutEfficScan->histo_c ();
74  effVersusDiscr_b = discrCutEfficScan->histo_b ();
75  effVersusDiscr_ni = discrCutEfficScan->histo_ni ();
76  effVersusDiscr_dusg = discrCutEfficScan->histo_dusg();
77  effVersusDiscr_pu = discrCutEfficScan->histo_pu();
78 
79 
80  if (mcPlots_ > 2) {
81  effVersusDiscr_d->SetXTitle( "Discriminant" );
82  effVersusDiscr_d->GetXaxis()->SetTitleOffset( 0.75 );
83  effVersusDiscr_u->SetXTitle( "Discriminant" );
84  effVersusDiscr_u->GetXaxis()->SetTitleOffset( 0.75 );
85  effVersusDiscr_s->SetXTitle( "Discriminant" );
86  effVersusDiscr_s->GetXaxis()->SetTitleOffset( 0.75 );
87  effVersusDiscr_g->SetXTitle( "Discriminant" );
88  effVersusDiscr_g->GetXaxis()->SetTitleOffset( 0.75 );
89  effVersusDiscr_dus->SetXTitle( "Discriminant" );
90  effVersusDiscr_dus->GetXaxis()->SetTitleOffset( 0.75 );
91  }
92  effVersusDiscr_c->SetXTitle( "Discriminant" );
93  effVersusDiscr_c->GetXaxis()->SetTitleOffset( 0.75 );
94  effVersusDiscr_b->SetXTitle( "Discriminant" );
95  effVersusDiscr_b->GetXaxis()->SetTitleOffset( 0.75 );
96  effVersusDiscr_ni->SetXTitle( "Discriminant" );
97  effVersusDiscr_ni->GetXaxis()->SetTitleOffset( 0.75 );
98  effVersusDiscr_dusg->SetXTitle( "Discriminant" );
99  effVersusDiscr_dusg->GetXaxis()->SetTitleOffset( 0.75 );
100  effVersusDiscr_pu->SetXTitle( "Discriminant" );
101  effVersusDiscr_pu->GetXaxis()->SetTitleOffset( 0.75 );
102  } else {
103  effVersusDiscr_d = nullptr;
104  effVersusDiscr_u = nullptr;
105  effVersusDiscr_s = nullptr;
106  effVersusDiscr_c = nullptr;
107  effVersusDiscr_b = nullptr;
108  effVersusDiscr_g = nullptr;
109  effVersusDiscr_ni = nullptr;
110  effVersusDiscr_dus = nullptr;
111  effVersusDiscr_dusg = nullptr;
112  effVersusDiscr_pu = nullptr;
113  }
114 
115  // discr. for computation
116  vector<TH2F*> discrCfHistos = dDiscriminatorFC.getHistoVector();
117  // discr no cut
118  vector<TH2F*> discrNoCutHistos = discrNoCutEffic->getHistoVector();
119  // discr no cut
120  vector<TH2F*> discrCutHistos = discrCutEfficScan->getHistoVector();
121 
122  const int& dimHistos = discrCfHistos.size(); // they all have the same size
123 
124  // DISCR-CUT LOOP:
125  // fill the histos for eff-pur computations by scanning the discriminatorFC histogram
126 
127  // better to loop over bins -> discrCut no longer needed
128  const int& nBinsX = dDiscriminatorFC.nBinsX();
129  const int& nBinsY = dDiscriminatorFC.nBinsY();
130 
131  // loop over flavours
132  for (int iFlav = 0; iFlav < dimHistos; iFlav++) {
133  if (discrCfHistos[iFlav] == nullptr) continue;
134  discrNoCutHistos[iFlav]->SetXTitle("Discriminant A");
135  discrNoCutHistos[iFlav]->GetXaxis()->SetTitleOffset(0.75);
136  discrNoCutHistos[iFlav]->SetYTitle("Discriminant B");
137  discrNoCutHistos[iFlav]->GetYaxis()->SetTitleOffset(0.75);
138 
139  // In Root histos, bin counting starts at 1 to nBins.
140  // bin 0 is the underflow, and nBins+1 is the overflow.
141  const double& nJetsFlav = discrCfHistos[iFlav]->GetEntries();
142 
143  for (int iDiscrX = nBinsX; iDiscrX > 0; --iDiscrX) {
144  for (int iDiscrY = nBinsY; iDiscrY > 0; --iDiscrY) {
145  // fill all jets into NoCut histo
146  discrNoCutHistos[iFlav]->SetBinContent(iDiscrX, iDiscrY, nJetsFlav);
147  discrNoCutHistos[iFlav]->SetBinError(iDiscrX, iDiscrY, sqrt(nJetsFlav));
148  const double& sum = nJetsFlav - discrCfHistos[iFlav]->Integral( 0, iDiscrX-1, 0, iDiscrY-1);
149  discrCutHistos[iFlav]->SetBinContent(iDiscrX, iDiscrY, sum);
150  discrCutHistos[iFlav]->SetBinError(iDiscrX, iDiscrY, sqrt(sum));
151  }
152  }
153  }
154 
155  // divide to get efficiency vs. discriminator cut from absolute numbers
156  discrCutEfficScan->divide(*discrNoCutEffic); // does: histos including discriminator cut / flat histo
157  discrCutEfficScan->setEfficiencyFlag();
158 }
159 
161 
163 {
165  discrNoCutEffic->epsPlot(name);
166  discrCutEfficScan->epsPlot(name);
167  }
168  plot(name, ".eps");
169 }
170 
172 {
173  plot(name, ".ps");
174 }
175 
177 {
178  std::string hX = "";
179  std::string Title = "";
180  if (!doCTagPlots_) {
181  hX = "FlavEffVsBEff";
182  Title = "b";
183  } else {
184  hX = "FlavEffVsCEff";
185  Title = "c";
186  }
187  TCanvas tc((hX +histoExtension).c_str(), ("Flavour misidentification vs. " + Title + "-tagging efficiency " + histoExtension).c_str());
188  plot(&tc);
189  tc.Print((name + hX + histoExtension + ext).c_str());
190 }
191 
192 void EffPurFromHistos2D::plot(TPad * plotCanvas /* = 0 */) {
193 
194  setTDRStyle()->cd();
195 
196  if (plotCanvas)
197  plotCanvas->cd();
198 
199  gPad->UseCurrentStyle();
200  gPad->SetFillColor( 0 );
201  gPad->SetLogy ( 1 );
202  gPad->SetGridx( 1 );
203  gPad->SetGridy( 1 );
204 }
205 
206 
208  // number of bins
209  int nBinsX_d = 0;
210  int nBinsX_u = 0;
211  int nBinsX_s = 0;
212  int nBinsX_g = 0;
213  int nBinsX_dus = 0;
214  int nBinsY_d = 0;
215  int nBinsY_u = 0;
216  int nBinsY_s = 0;
217  int nBinsY_g = 0;
218  int nBinsY_dus = 0;
219  if (mcPlots_ > 2) {
220  nBinsX_d = effVersusDiscr_d -> GetNbinsX();
221  nBinsX_u = effVersusDiscr_u -> GetNbinsX();
222  nBinsX_s = effVersusDiscr_s -> GetNbinsX();
223  nBinsX_g = effVersusDiscr_g -> GetNbinsX();
224  nBinsX_dus = effVersusDiscr_dus -> GetNbinsX();
225  nBinsY_d = effVersusDiscr_d -> GetNbinsY();
226  nBinsY_u = effVersusDiscr_u -> GetNbinsY();
227  nBinsY_s = effVersusDiscr_s -> GetNbinsY();
228  nBinsY_g = effVersusDiscr_g -> GetNbinsY();
229  nBinsY_dus = effVersusDiscr_dus -> GetNbinsY();
230  }
231  const int& nBinsX_c = effVersusDiscr_c -> GetNbinsX();
232  const int& nBinsX_b = effVersusDiscr_b -> GetNbinsX();
233  const int& nBinsX_ni = effVersusDiscr_ni -> GetNbinsX();
234  const int& nBinsX_dusg = effVersusDiscr_dusg -> GetNbinsX();
235  const int& nBinsX_pu = effVersusDiscr_pu -> GetNbinsX();
236  const int& nBinsY_c = effVersusDiscr_c -> GetNbinsY();
237  const int& nBinsY_b = effVersusDiscr_b -> GetNbinsY();
238  const int& nBinsY_ni = effVersusDiscr_ni -> GetNbinsY();
239  const int& nBinsY_dusg = effVersusDiscr_dusg -> GetNbinsY();
240  const int& nBinsY_pu = effVersusDiscr_pu -> GetNbinsY();
241 
242  const bool& lNBinsX =
243  ((nBinsX_d == nBinsX_u &&
244  nBinsX_d == nBinsX_s &&
245  nBinsX_d == nBinsX_c &&
246  nBinsX_d == nBinsX_b &&
247  nBinsX_d == nBinsX_g &&
248  nBinsX_d == nBinsX_ni &&
249  nBinsX_d == nBinsX_dus &&
250  nBinsX_d == nBinsX_dusg)||
251  (nBinsX_c == nBinsX_b &&
252  nBinsX_c == nBinsX_dusg &&
253  nBinsX_c == nBinsX_ni &&
254  nBinsX_c == nBinsX_pu) );
255 
256  const bool& lNBinsY =
257  ((nBinsY_d == nBinsY_u &&
258  nBinsY_d == nBinsY_s &&
259  nBinsY_d == nBinsY_c &&
260  nBinsY_d == nBinsY_b &&
261  nBinsY_d == nBinsY_g &&
262  nBinsY_d == nBinsY_ni &&
263  nBinsY_d == nBinsY_dus &&
264  nBinsY_d == nBinsY_dusg)||
265  (nBinsY_c == nBinsY_b &&
266  nBinsY_c == nBinsY_dusg &&
267  nBinsY_c == nBinsY_ni &&
268  nBinsY_c == nBinsY_pu) );
269 
270  if ( !lNBinsX || !lNBinsY ) {
271  throw cms::Exception("Configuration")
272  << "Input histograms do not all have the same number of bins!\n";
273  }
274 
275  // start
276  float sBin_d = 0;
277  float sBin_u = 0;
278  float sBin_s = 0;
279  float sBin_g = 0;
280  float sBin_dus = 0;
281  if (mcPlots_>2){
282  sBin_d = effVersusDiscr_d -> GetBinCenter(1);
283  sBin_u = effVersusDiscr_u -> GetBinCenter(1);
284  sBin_s = effVersusDiscr_s -> GetBinCenter(1);
285  sBin_g = effVersusDiscr_g -> GetBinCenter(1);
286  sBin_dus = effVersusDiscr_dus -> GetBinCenter(1);
287  }
288  const float& sBin_c = effVersusDiscr_c -> GetBinCenter(1);
289  const float& sBin_b = effVersusDiscr_b -> GetBinCenter(1);
290  const float& sBin_ni = effVersusDiscr_ni -> GetBinCenter(1);
291  const float& sBin_dusg = effVersusDiscr_dusg -> GetBinCenter(1);
292  const float& sBin_pu = effVersusDiscr_pu -> GetBinCenter(1);
293 
294  const bool& lSBin =
295  ((sBin_d == sBin_u &&
296  sBin_d == sBin_s &&
297  sBin_d == sBin_c &&
298  sBin_d == sBin_b &&
299  sBin_d == sBin_g &&
300  sBin_d == sBin_ni &&
301  sBin_d == sBin_dus &&
302  sBin_d == sBin_dusg)||
303  (sBin_c == sBin_b &&
304  sBin_c == sBin_dusg &&
305  sBin_c == sBin_ni &&
306  sBin_c == sBin_pu) );
307 
308  if ( !lSBin ) {
309  throw cms::Exception("Configuration")
310  << "EffPurFromHistos::check() : Input histograms do not all have the same start bin!\n";
311  }
312 
313  // end
314  float eBin_d = 0;
315  float eBin_u = 0;
316  float eBin_s = 0;
317  float eBin_g = 0;
318  float eBin_dus = 0;
319  const int& binEnd = effVersusDiscr_b -> GetBin(nBinsX_b - 1, nBinsY_b - 1);
320  if (mcPlots_>2){
321  eBin_d = effVersusDiscr_d -> GetBinCenter( binEnd );
322  eBin_u = effVersusDiscr_u -> GetBinCenter( binEnd );
323  eBin_s = effVersusDiscr_s -> GetBinCenter( binEnd );
324  eBin_g = effVersusDiscr_g -> GetBinCenter( binEnd );
325  eBin_dus = effVersusDiscr_dus -> GetBinCenter( binEnd );
326  }
327  const float& eBin_c = effVersusDiscr_c -> GetBinCenter( binEnd );
328  const float& eBin_b = effVersusDiscr_b -> GetBinCenter( binEnd );
329  const float& eBin_ni = effVersusDiscr_ni -> GetBinCenter( binEnd );
330  const float& eBin_dusg = effVersusDiscr_dusg -> GetBinCenter( binEnd );
331  const float& eBin_pu = effVersusDiscr_pu -> GetBinCenter( binEnd );
332 
333  const bool& lEBin =
334  ((eBin_d == eBin_u &&
335  eBin_d == eBin_s &&
336  eBin_d == eBin_c &&
337  eBin_d == eBin_b &&
338  eBin_d == eBin_g &&
339  eBin_d == eBin_ni &&
340  eBin_d == eBin_dus &&
341  eBin_d == eBin_dusg)||
342  (eBin_c == eBin_b &&
343  eBin_c == eBin_dusg &&
344  eBin_c == eBin_ni &&
345  eBin_c == eBin_pu) );
346 
347  if ( !lEBin ) {
348  throw cms::Exception("Configuration")
349  << "EffPurFromHistos::check() : Input histograms do not all have the same end bin!\n";
350  }
351 }
352 
353 void EffPurFromHistos2D::compute(DQMStore::IBooker & ibook, vector<double> fixedEff)
354 {
355 
356  if (!mcPlots_ || fixedEff.empty()) {
357  return;
358  }
359 
360  // to have shorter names ......
361  const std::string & hE = histoExtension;
362  std::string hX = "DUSG_vs_B_eff_at_fixedCeff_";
363  if (!doCTagPlots_) hX = "DUSG_vs_C_eff_at_fixedBeff_";
364 
365  // create histograms from base name and extension as given from user
366  HistoProviderDQM prov("Btag", label_, ibook);
367 
368  for (unsigned int ieff = 0; ieff < fixedEff.size(); ieff++){
369  std::string fixedEfficiency = std::to_string(fixedEff[ieff]);
370  fixedEfficiency.replace(1, 1, "_");
371  X_vs_Y_eff_at_fixedZeff.push_back((prov.book1D( hX + fixedEfficiency + hE, hX + fixedEfficiency + hE, nBinOutputX, startOutputX, endOutputX )) );
372  X_vs_Y_eff_at_fixedZeff[ieff]->setEfficiencyFlag();
373 
374  X_vs_Y_eff_at_fixedZeff[ieff]->getTH1F()->SetXTitle("Light mistag");
375  X_vs_Y_eff_at_fixedZeff[ieff]->getTH1F()->SetYTitle("B mistag");
376  if (!doCTagPlots_) X_vs_Y_eff_at_fixedZeff[ieff]->getTH1F()->SetYTitle("C mistag");
377  X_vs_Y_eff_at_fixedZeff[ieff]->getTH1F()->GetXaxis()->SetTitleOffset(0.75);
378  X_vs_Y_eff_at_fixedZeff[ieff]->getTH1F()->GetYaxis()->SetTitleOffset(0.75);
379  }
380  // loop over eff. vs. discriminator cut b-histo and look in which bin the closest entry is;
381  // use fact that eff decreases monotonously
382 
383  // any of the histos to be created can be taken here:
384  MonitorElement * EffFlavVsXEff = X_vs_Y_eff_at_fixedZeff[0];
385 
386  const int& nBinX = EffFlavVsXEff->getTH1F()->GetNbinsX();
387 
388  for (int iBinX = 1; iBinX <= nBinX; iBinX++) { // loop over the bins on the x-axis of the histograms to be filled
389  const float& effBinWidthX = EffFlavVsXEff->getTH1F()->GetBinWidth (iBinX);
390  const float& effMidX = EffFlavVsXEff->getTH1F()->GetBinCenter(iBinX); // middle of efficiency bin
391  const float& effLeftX = effMidX - 0.5*effBinWidthX; // left edge of bin
392  const float& effRightX = effMidX + 0.5*effBinWidthX; // right edge of bin
393 
394  vector<int> binClosest;
395  if (doCTagPlots_)
396  binClosest = findBinClosestYValueAtFixedZ(effVersusDiscr_dusg, effMidX, effLeftX, effRightX, effVersusDiscr_c, fixedEff);
397  else
398  binClosest = findBinClosestYValueAtFixedZ(effVersusDiscr_dusg, effMidX, effLeftX, effRightX, effVersusDiscr_b, fixedEff);
399 
400  for (unsigned int ieff = 0; ieff < binClosest.size(); ieff++) {
401  const bool& binFound =( binClosest[ieff] > 0 );
402  //
403  if (binFound) {
404  // fill the histos
405  if (doCTagPlots_) {
406  X_vs_Y_eff_at_fixedZeff[ieff]->Fill(effMidX, effVersusDiscr_b->GetBinContent( binClosest[ieff] ));
407  X_vs_Y_eff_at_fixedZeff[ieff]->getTH1F()->SetBinError(iBinX, effVersusDiscr_b->GetBinError( binClosest[ieff] ));
408  } else {
409  X_vs_Y_eff_at_fixedZeff[ieff]->Fill(effMidX, effVersusDiscr_c->GetBinContent( binClosest[ieff] ));
410  X_vs_Y_eff_at_fixedZeff[ieff]->getTH1F()->SetBinError(iBinX, effVersusDiscr_c->GetBinError( binClosest[ieff] ));
411  }
412  }
413  }
414  }
415 }
416 
417 
418 
419 #include <typeinfo>
double lowerBoundX() const
double lowerBoundY() const
TH1F * getTH1F() const
std::unique_ptr< FlavourHistograms2D< double, double > > discrNoCutEffic
std::string baseNameTitle() const
std::unique_ptr< FlavourHistograms2D< double, double > > discrCutEfficScan
std::string histoExtension
char const * label
virtual MonitorElement * book1D(const std::string &name, const std::string &title, const int &nchX, const double &lowX, const double &highX)
EffPurFromHistos2D(const std::string &ext, TH2F *h_d, TH2F *h_u, TH2F *h_s, TH2F *h_c, TH2F *h_b, TH2F *h_g, TH2F *h_ni, TH2F *h_dus, TH2F *h_dusg, TH2F *h_pu, const std::string &label, unsigned int mc, int nBinX=100, double startOX=0.05, double endOX=1.05)
T sqrt(T t)
Definition: SSEVec.h:18
std::vector< MonitorElement * > X_vs_Y_eff_at_fixedZeff
def setTDRStyle()
Definition: plotscripts.py:88
double upperBoundX() const
void epsPlot(const std::string &name)
std::vector< TH2F * > getHistoVector() const
std::string baseNameDescription() const
Definition: Tools.h:23
void psPlot(const std::string &name)
std::vector< int > findBinClosestYValueAtFixedZ(const TH2F *, const float &yVal, const float &yLow, const float &yHigh, const TH2F *, const std::vector< double > &zVal)
Definition: Tools.cc:286
void plot(TPad *theCanvas=0)
Definition: memstream.h:15
double upperBoundY() const
void compute(DQMStore::IBooker &ibook, std::vector< double > fixedEff)