CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
BTagWeightCalculator.py
Go to the documentation of this file.
1 import ROOT
2 import numpy as np
3 
5  def __init__(self, fn_hf, fn_lf) :
6  self.pdfs = {}
7 
8  self.pt_bins_hf = np.array([20, 30, 40, 60, 100, 160, 10000])
9  self.eta_bins_hf = np.array([0, 2.41])
10 
11  self.pt_bins_lf = np.array([20, 30, 40, 60, 10000])
12  self.eta_bins_lf = np.array([0, 0.8, 1.6, 2.41])
13 
14  self.btag = "pfCombinedInclusiveSecondaryVertexV2BJetTags"
15  self.init(fn_hf, fn_lf)
16 
17  def getBin(self, bvec, val):
18  return int(bvec.searchsorted(val) - 1)
19 
20  def init(self, fn_hf, fn_lf) :
21  print "[BTagWeightCalculator]: Initializing from files", fn_hf, fn_lf
22 
23  self.pdfs["hf"] = self.getHistosFromFile(fn_hf)
24  self.pdfs["lf"] = self.getHistosFromFile(fn_lf)
25 
26  return True
27 
28  def getHistosFromFile(self, fn):
29  ret = {}
30  tf = ROOT.TFile(fn)
31  if not tf or tf.IsZombie():
32  raise FileError("Could not open file {0}".format(fn))
33  ROOT.gROOT.cd()
34  for k in tf.GetListOfKeys():
35  kn = k.GetName()
36  if not (kn.startswith("csv_ratio") or kn.startswith("c_csv_ratio") ):
37  continue
38  spl = kn.split("_")
39  is_c = 1 if kn.startswith("c_csv_ratio") else 0
40 
41  if spl[2+is_c] == "all":
42  ptbin = -1
43  etabin = -1
44  kind = "all"
45  syst = "nominal"
46  else:
47  ptbin = int(spl[2+is_c][2:])
48  etabin = int(spl[3+is_c][3:])
49  kind = spl[4+is_c]
50  if len(spl)==(6+is_c):
51  syst = spl[5+is_c]
52  else:
53  syst = "nominal"
54  ret[(ptbin, etabin, kind, syst)] = k.ReadObj().Clone()
55  return ret
56 
57  def calcJetWeight(self, jet, kind, systematic):
58  pt = jet.pt()
59  aeta = abs(jet.eta())
60  fl = abs(jet.hadronFlavour())
61  csv = jet.btag(self.btag)
62 
63  is_b = (fl == 5)
64  is_c = (fl == 4)
65  is_l = (fl < 4)
66 
67  if is_b and not (systematic in ["JESUp", "JESDown", "LFUp", "LFDown",
68  "Stats1Up", "Stats1Down", "Stats2Up", "Stats2Down",
69  "nominal"]):
70  return 1.0
71  if is_c and not (systematic in ["cErr1Up", "cErr1Down", "cErr2Up", "cErr2Down",
72  "nominal"]):
73  return 1.0
74  if is_l and not (systematic in ["JESUp", "JESDown", "HFUp", "HFDown",
75  "Stats1Up", "Stats1Down", "Stats2Up", "Stats2Down",
76  "nominal"]):
77  return 1.0
78 
79 
80  if is_b or is_c:
81  ptbin = self.getBin(self.pt_bins_hf, pt)
82  etabin = self.getBin(self.eta_bins_hf, aeta)
83  else:
84  ptbin = self.getBin(self.pt_bins_lf, pt)
85  etabin = self.getBin(self.eta_bins_lf, aeta)
86 
87  if ptbin < 0 or etabin < 0:
88  return 1.0
89 
90  k = (ptbin, etabin, kind, systematic)
91  hdict = self.pdfs["lf"]
92  if is_b or is_c:
93  hdict = self.pdfs["hf"]
94  h = hdict.get(k, None)
95  if not h:
96  return 1.0
97 
98  csvbin = 1
99  if csv>=0:
100  csvbin = h.FindBin(csv)
101 
102  if csvbin <= 0 or csvbin > h.GetNbinsX():
103  return 1.0
104 
105  w = h.GetBinContent(csvbin)
106  return w
107 
108  def calcEventWeight(self, jets, kind, systematic):
109  weights = np.array(
110  [self.calcJetWeight(jet, kind, systematic)
111  for jet in jets]
112  )
113 
114  wtot = np.prod(weights)
115  return wtot
Abs< T >::type abs(const T &t)
Definition: Abs.h:22