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