Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-02-20 03:45:25

0001 #include "DQMOffline/RecoB/interface/BTagDifferentialPlot.h"
0002 #include "DQMOffline/RecoB/interface/EffPurFromHistos.h"
0003 #include "DQMOffline/RecoB/interface/Tools.h"
0004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0005 #include "TF1.h"
0006 
0007 #include "DQMServices/Core/interface/DQMStore.h"
0008 #include "FWCore/ServiceRegistry/interface/Service.h"
0009 
0010 #include "DQMOffline/RecoB/interface/HistoProviderDQM.h"
0011 
0012 #include <algorithm>
0013 #include <iostream>
0014 #include <sstream>
0015 using namespace std;
0016 
0017 BTagDifferentialPlot::BTagDifferentialPlot(double bEff,
0018                                            const ConstVarType& constVariable,
0019                                            const std::string& tagName,
0020                                            unsigned int mc)
0021     : fixedBEfficiency(bEff),
0022       noProcessing(false),
0023       processed(false),
0024       constVar(constVariable),
0025       constVariableName(""),
0026       diffVariableName(""),
0027       constVariableValue(999.9, 999.9),
0028       commonName("MisidForBEff_" + tagName + "_"),
0029       theDifferentialHistoB_d(nullptr),
0030       theDifferentialHistoB_u(nullptr),
0031       theDifferentialHistoB_s(nullptr),
0032       theDifferentialHistoB_c(nullptr),
0033       theDifferentialHistoB_b(nullptr),
0034       theDifferentialHistoB_g(nullptr),
0035       theDifferentialHistoB_ni(nullptr),
0036       theDifferentialHistoB_dus(nullptr),
0037       theDifferentialHistoB_dusg(nullptr),
0038       theDifferentialHistoB_pu(nullptr),
0039       mcPlots_(mc) {}
0040 
0041 BTagDifferentialPlot::~BTagDifferentialPlot() {}
0042 
0043 void BTagDifferentialPlot::plot(TCanvas& thePlotCanvas) {
0044   //   thePlotCanvas = new TCanvas( commonName,
0045   //                commonName,
0046   //                btppXCanvas, btppYCanvas);
0047   //
0048   //   if (!btppTitle) gStyle->SetOptTitle(0);
0049 
0050   if (!processed)
0051     return;
0052   //fixme:
0053   bool btppNI = false;
0054   bool btppColour = true;
0055 
0056   thePlotCanvas.SetFillColor(0);
0057   thePlotCanvas.cd(1);
0058   gPad->SetLogy(1);
0059   gPad->SetGridx(1);
0060   gPad->SetGridy(1);
0061 
0062   //  int col_b;
0063   int col_c;
0064   int col_g;
0065   int col_dus;
0066   int col_ni;
0067 
0068   //  int mStyle_b;
0069   int mStyle_c;
0070   int mStyle_g;
0071   int mStyle_dus;
0072   int mStyle_ni;
0073 
0074   // marker size(same for all)
0075   float mSize = 1.5;
0076 
0077   if (btppColour) {
0078     //    col_b    = 2;
0079     col_c = 6;
0080     col_g = 3;
0081     col_dus = 4;
0082     col_ni = 5;
0083     //    mStyle_b   = 20;
0084     mStyle_c = 20;
0085     mStyle_g = 20;
0086     mStyle_dus = 20;
0087     mStyle_ni = 20;
0088   } else {
0089     //    col_b    = 1;
0090     col_c = 1;
0091     col_g = 1;
0092     col_dus = 1;
0093     col_ni = 1;
0094     //    mStyle_b   = 12;
0095     mStyle_c = 22;
0096     mStyle_g = 29;
0097     mStyle_dus = 20;
0098     mStyle_ni = 27;
0099   }
0100 
0101   // for the moment: plot b(to see what the constant b-efficiency is), c, g, uds
0102   // b in red
0103   // No, do not plot b(because only visible for the soft leptons)
0104   // theDifferentialHistoB_b   -> GetXaxis()->SetTitle(diffVariableName);
0105   // theDifferentialHistoB_b   -> GetYaxis()->SetTitle("non b-jet efficiency");
0106   // theDifferentialHistoB_b   -> GetYaxis()->SetTitleOffset(1.25);
0107   // theDifferentialHistoB_b   -> SetMaximum(0.4);
0108   // theDifferentialHistoB_b   -> SetMinimum(1.e-4);
0109   // theDifferentialHistoB_b   -> SetMarkerColor(col_b);
0110   // theDifferentialHistoB_b   -> SetLineColor (col_b);
0111   // theDifferentialHistoB_b   -> SetMarkerSize(mSize);
0112   // theDifferentialHistoB_b   -> SetMarkerStyle(mStyle_b);
0113   // theDifferentialHistoB_b   -> SetStats(false);
0114   // theDifferentialHistoB_b   -> Draw("pe");
0115   // c in magenta
0116   theDifferentialHistoB_c->getTH1F()->SetMaximum(0.4);
0117   theDifferentialHistoB_c->getTH1F()->SetMinimum(1.e-4);
0118   theDifferentialHistoB_c->getTH1F()->SetMarkerColor(col_c);
0119   theDifferentialHistoB_c->getTH1F()->SetLineColor(col_c);
0120   theDifferentialHistoB_c->getTH1F()->SetMarkerSize(mSize);
0121   theDifferentialHistoB_c->getTH1F()->SetMarkerStyle(mStyle_c);
0122   theDifferentialHistoB_c->getTH1F()->SetStats(false);
0123   //  theDifferentialHistoB_c   -> Draw("peSame");
0124   theDifferentialHistoB_c->getTH1F()->Draw("pe");
0125   if (mcPlots_ > 2) {
0126     // uds in blue
0127     theDifferentialHistoB_dus->getTH1F()->SetMarkerColor(col_dus);
0128     theDifferentialHistoB_dus->getTH1F()->SetLineColor(col_dus);
0129     theDifferentialHistoB_dus->getTH1F()->SetMarkerSize(mSize);
0130     theDifferentialHistoB_dus->getTH1F()->SetMarkerStyle(mStyle_dus);
0131     theDifferentialHistoB_dus->getTH1F()->SetStats(false);
0132     theDifferentialHistoB_dus->getTH1F()->Draw("peSame");
0133     // g in green
0134     // only uds not to confuse
0135     theDifferentialHistoB_g->getTH1F()->SetMarkerColor(col_g);
0136     theDifferentialHistoB_g->getTH1F()->SetLineColor(col_g);
0137     theDifferentialHistoB_g->getTH1F()->SetMarkerSize(mSize);
0138     theDifferentialHistoB_g->getTH1F()->SetMarkerStyle(mStyle_g);
0139     theDifferentialHistoB_g->getTH1F()->SetStats(false);
0140     theDifferentialHistoB_g->getTH1F()->Draw("peSame");
0141   }
0142   // NI if wanted
0143   if (btppNI) {
0144     theDifferentialHistoB_ni->getTH1F()->SetMarkerColor(col_ni);
0145     theDifferentialHistoB_ni->getTH1F()->SetLineColor(col_ni);
0146     theDifferentialHistoB_ni->getTH1F()->SetMarkerSize(mSize);
0147     theDifferentialHistoB_ni->getTH1F()->SetMarkerStyle(mStyle_ni);
0148     theDifferentialHistoB_ni->getTH1F()->SetStats(false);
0149     theDifferentialHistoB_ni->getTH1F()->Draw("peSame");
0150   }
0151 }
0152 
0153 void BTagDifferentialPlot::epsPlot(const std::string& name) { plot(name, ".eps"); }
0154 
0155 void BTagDifferentialPlot::psPlot(const std::string& name) { plot(name, ".ps"); }
0156 
0157 void BTagDifferentialPlot::plot(const std::string& name, const std::string& ext) {
0158   if (!processed)
0159     return;
0160   TCanvas tc(commonName.c_str(), commonName.c_str());
0161   plot(tc);
0162   tc.Print((name + commonName + ext).c_str());
0163 }
0164 
0165 void BTagDifferentialPlot::process(DQMStore::IBooker& ibook) {
0166   setVariableName();  // also sets noProcessing if not OK
0167   if (noProcessing)
0168     return;
0169   bookHisto(ibook);
0170   fillHisto();
0171   processed = true;
0172 }
0173 
0174 void BTagDifferentialPlot::setVariableName() {
0175   if (constVar == constETA) {
0176     constVariableName = "eta";
0177     diffVariableName = "pt";
0178     constVariableValue =
0179         make_pair(theBinPlotters[0]->etaPtBin().getEtaMin(), theBinPlotters[0]->etaPtBin().getEtaMax());
0180   }
0181   if (constVar == constPT) {
0182     constVariableName = "pt";
0183     diffVariableName = "eta";
0184     constVariableValue = make_pair(theBinPlotters[0]->etaPtBin().getPtMin(), theBinPlotters[0]->etaPtBin().getPtMax());
0185   }
0186 }
0187 
0188 void BTagDifferentialPlot::bookHisto(DQMStore::IBooker& ibook) {
0189   // vector with ranges
0190   vector<float> variableRanges;
0191 
0192   for (vector<std::shared_ptr<JetTagPlotter>>::const_iterator iP = theBinPlotters.begin(); iP != theBinPlotters.end();
0193        ++iP) {
0194     const EtaPtBin& currentBin = (*iP)->etaPtBin();
0195     if (diffVariableName == "eta") {
0196       // only active bins in the variable on x-axis
0197       if (currentBin.getEtaActive()) {
0198         variableRanges.push_back(currentBin.getEtaMin());
0199         // also max if last one
0200         if (iP == --theBinPlotters.end())
0201           variableRanges.push_back(currentBin.getEtaMax());
0202       }
0203     }
0204     if (diffVariableName == "pt") {
0205       // only active bins in the variable on x-axis
0206       if (currentBin.getPtActive()) {
0207         variableRanges.push_back(currentBin.getPtMin());
0208         // also max if last one
0209         if (iP == --theBinPlotters.end())
0210           variableRanges.push_back(currentBin.getPtMax());
0211       }
0212     }
0213   }
0214 
0215   // to book histo with variable binning -> put into array
0216   int nBins = variableRanges.size() - 1;
0217   float* binArray = &variableRanges[0];
0218 
0219   // part of the name common to all flavours
0220   std::stringstream stream("");
0221   stream << fixedBEfficiency << "_Const_" << constVariableName << "_" << constVariableValue.first << "-";
0222   stream << constVariableValue.second << "_"
0223          << "_Vs_" << diffVariableName;
0224   commonName += stream.str();
0225   auto last = std::remove(commonName.begin(), commonName.end(), ' ');
0226   commonName.erase(last, commonName.end());
0227   std::replace(commonName.begin(), commonName.end(), '.', 'v');
0228 
0229   std::string label(commonName);
0230   HistoProviderDQM prov("Btag", label, ibook);
0231 
0232   theDifferentialHistoB_b = (prov.book1D("B_" + commonName, "B_" + commonName, nBins, binArray));
0233   theDifferentialHistoB_c = (prov.book1D("C_" + commonName, "C_" + commonName, nBins, binArray));
0234   theDifferentialHistoB_dusg = (prov.book1D("DUSG_" + commonName, "DUSG_" + commonName, nBins, binArray));
0235   theDifferentialHistoB_ni = (prov.book1D("NI_" + commonName, "NI_" + commonName, nBins, binArray));
0236   theDifferentialHistoB_pu = (prov.book1D("PU_" + commonName, "PU_" + commonName, nBins, binArray));
0237 
0238   if (mcPlots_ > 2) {
0239     theDifferentialHistoB_d = (prov.book1D("D_" + commonName, "D_" + commonName, nBins, binArray));
0240     theDifferentialHistoB_u = (prov.book1D("U_" + commonName, "U_" + commonName, nBins, binArray));
0241     theDifferentialHistoB_s = (prov.book1D("S_" + commonName, "S_" + commonName, nBins, binArray));
0242     theDifferentialHistoB_g = (prov.book1D("G_" + commonName, "G_" + commonName, nBins, binArray));
0243     theDifferentialHistoB_dus = (prov.book1D("DUS_" + commonName, "DUS_" + commonName, nBins, binArray));
0244   }
0245 }
0246 
0247 void BTagDifferentialPlot::fillHisto() {
0248   // loop over bins and find corresponding misid. in the MisIdVs..... histo
0249   for (vector<std::shared_ptr<JetTagPlotter>>::const_iterator iP = theBinPlotters.begin(); iP != theBinPlotters.end();
0250        ++iP) {
0251     const EtaPtBin& currentBin = (*iP)->etaPtBin();
0252     EffPurFromHistos& currentEffPurFromHistos = (*iP)->getEffPurFromHistos();
0253     //
0254     bool isActive = true;
0255     double valueXAxis = -999.99;
0256     // find right bin based on middle of the interval
0257     if (diffVariableName == "eta") {
0258       isActive = currentBin.getEtaActive();
0259       valueXAxis = 0.5 * (currentBin.getEtaMin() + currentBin.getEtaMax());
0260     } else if (diffVariableName == "pt") {
0261       isActive = currentBin.getPtActive();
0262       valueXAxis = 0.5 * (currentBin.getPtMin() + currentBin.getPtMax());
0263     } else {
0264       throw cms::Exception("Configuration")
0265           << "====>>>> BTagDifferentialPlot::fillHisto() : illegal diffVariableName = " << diffVariableName << endl;
0266     }
0267 
0268     // for the moment: ignore inactive bins
0269     //(maybe later: if a Bin is inactive -> set value to fill well below left edge of histogram to have it in the underflow)
0270 
0271     if (!isActive)
0272       continue;
0273 
0274     // to have less lines of code ....
0275     vector<pair<TH1F*, TH1F*>> effPurDifferentialPairs;
0276 
0277     // all flavours(b is a good cross check! must be constant and = fixed b-efficiency)
0278     // get histo; find the bin of the fixed b-efficiency in the histo and get misid; fill
0279 
0280     effPurDifferentialPairs.push_back(
0281         make_pair(currentEffPurFromHistos.getEffFlavVsBEff_b(), theDifferentialHistoB_b->getTH1F()));
0282     effPurDifferentialPairs.push_back(
0283         make_pair(currentEffPurFromHistos.getEffFlavVsBEff_c(), theDifferentialHistoB_c->getTH1F()));
0284     effPurDifferentialPairs.push_back(
0285         make_pair(currentEffPurFromHistos.getEffFlavVsBEff_dusg(), theDifferentialHistoB_dusg->getTH1F()));
0286     effPurDifferentialPairs.push_back(
0287         make_pair(currentEffPurFromHistos.getEffFlavVsBEff_ni(), theDifferentialHistoB_ni->getTH1F()));
0288     effPurDifferentialPairs.push_back(
0289         make_pair(currentEffPurFromHistos.getEffFlavVsBEff_pu(), theDifferentialHistoB_pu->getTH1F()));
0290     if (mcPlots_ > 2) {
0291       effPurDifferentialPairs.push_back(
0292           make_pair(currentEffPurFromHistos.getEffFlavVsBEff_d(), theDifferentialHistoB_d->getTH1F()));
0293       effPurDifferentialPairs.push_back(
0294           make_pair(currentEffPurFromHistos.getEffFlavVsBEff_u(), theDifferentialHistoB_u->getTH1F()));
0295       effPurDifferentialPairs.push_back(
0296           make_pair(currentEffPurFromHistos.getEffFlavVsBEff_s(), theDifferentialHistoB_s->getTH1F()));
0297       effPurDifferentialPairs.push_back(
0298           make_pair(currentEffPurFromHistos.getEffFlavVsBEff_g(), theDifferentialHistoB_g->getTH1F()));
0299       effPurDifferentialPairs.push_back(
0300           make_pair(currentEffPurFromHistos.getEffFlavVsBEff_dus(), theDifferentialHistoB_dus->getTH1F()));
0301     }
0302 
0303     for (vector<pair<TH1F*, TH1F*>>::const_iterator itP = effPurDifferentialPairs.begin();
0304          itP != effPurDifferentialPairs.end();
0305          ++itP) {
0306       TH1F* effPurHist = itP->first;
0307       TH1F* diffHist = itP->second;
0308       pair<double, double> mistag = getMistag(fixedBEfficiency, effPurHist);
0309       int iBinSet = diffHist->FindBin(valueXAxis);
0310       diffHist->SetBinContent(iBinSet, mistag.first);
0311       diffHist->SetBinError(iBinSet, mistag.second);
0312     }
0313   }
0314 }
0315 
0316 pair<double, double> BTagDifferentialPlot::getMistag(const double& fixedBEfficiency, TH1F* effPurHist) {
0317   int iBinGet = effPurHist->FindBin(fixedBEfficiency);
0318   double effForBEff = effPurHist->GetBinContent(iBinGet);
0319   double effForBEffErr = effPurHist->GetBinError(iBinGet);
0320 
0321   if (effForBEff == 0. && effForBEffErr == 0.) {
0322     // The bin was empty. Could be that it was not filled, as the scan-plot
0323     //  did not have an entry at the requested value, or that the curve
0324     // is above or below.
0325     // Fit a plynomial, and evaluate the mistag at the requested value.
0326     int fitStatus;
0327     //need our own copy for thread safety
0328     TF1 myfunc("myfunc", "pol4");
0329     try {
0330       fitStatus = effPurHist->Fit(&myfunc, "q");
0331     } catch (cms::Exception& iException) {
0332       return pair<double, double>(effForBEff, effForBEffErr);
0333     }
0334     if (fitStatus != 0) {
0335       edm::LogWarning("BTagDifferentialPlot") << "Fit failed to hisogram " << effPurHist->GetTitle()
0336                                               << ", perhaps because too few entries = " << effPurHist->GetEntries()
0337                                               << ". This bin will be missing in plots at fixed b efficiency.";
0338       //    } else {
0339       //      edm::LogInfo("BTagDifferentialPlot")<<"Fit OK to hisogram " << effPurHist->GetTitle() << " entries = " << effPurHist->GetEntries();
0340       return pair<double, double>(effForBEff, effForBEffErr);
0341     }
0342     effForBEff = myfunc.Eval(fixedBEfficiency);
0343     effPurHist->RecursiveRemove(&myfunc);
0344     //Error: first non-empty bin on the right and take its error
0345     for (int i = iBinGet + 1; i < effPurHist->GetNbinsX(); ++i) {
0346       if (effPurHist->GetBinContent(i) != 0) {
0347         effForBEffErr = effPurHist->GetBinError(i);
0348         break;
0349       }
0350     }
0351   }
0352 
0353   return pair<double, double>(effForBEff, effForBEffErr);
0354 }