CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Jet.py
Go to the documentation of this file.
2 from PhysicsTools.HeppyCore.utils.deltar import deltaPhi
3 import math
4 
5 loose_WP = [
6  (0, 2.5, -0.8),
7  (2.5, 2.75, -0.74),
8  (2.75, 3.0, -0.68),
9  (3.0, 5.0, -0.77),
10  ]
11 
12 # Working point 2 May 2013 (Phil via H2tau list)
13 loose_53X_WP = [
14  (0, 2.5, -0.63),
15  (2.5, 2.75, -0.60),
16  (2.75, 3.0, -0.55),
17  (3.0, 5.2, -0.45),
18  ]
19 
20 _btagWPs = {
21  "TCHEL": ("pfTrackCountingHighEffBJetTags", 1.7),
22  "TCHEM": ("pfTrackCountingHighEffBJetTags", 3.3),
23  "TCHPT": ("pfTrackCountingHighPurBJetTags", 3.41),
24  "JPL": ("pfJetProbabilityBJetTags", 0.275),
25  "JPM": ("pfJetProbabilityBJetTags", 0.545),
26  "JPT": ("pfJetProbabilityBJetTags", 0.790),
27  "CSVL": ("combinedSecondaryVertexBJetTags", 0.244),
28  "CSVM": ("combinedSecondaryVertexBJetTags", 0.679),
29  "CSVT": ("combinedSecondaryVertexBJetTags", 0.898),
30 ###https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation74X50ns
31  "CSVv2IVFL": ("pfCombinedInclusiveSecondaryVertexV2BJetTags", 0.605),
32  "CSVv2IVFM": ("pfCombinedInclusiveSecondaryVertexV2BJetTags", 0.890),
33  "CSVv2IVFT": ("pfCombinedInclusiveSecondaryVertexV2BJetTags", 0.990),
34  "CMVAL": ("pfCombinedMVABJetTags", 0.630), # for same b-jet efficiency of CSVv2IVFL on ttbar MC, jet pt > 30
35  "CMVAM": ("pfCombinedMVABJetTags", 0.732), # for same b-jet efficiency of CSVv2IVFM on ttbar MC, jet pt > 30
36  "CMVAT": ("pfCombinedMVABJetTags", 0.813), # for same b-jet efficiency of CSVv2IVFT on ttbar MC, jet pt > 30
37 
38 }
39 
41  def __init__(self, *args, **kwargs):
42  super(Jet, self).__init__(*args, **kwargs)
43  self._physObjInit()
44 
45  def _physObjInit(self):
47  self._recalibrated = False
48  self._leadingTrack = None
49  self._leadingTrackSearched = False
50 
51  def jetID(self,name=""):
52  if not self.isPFJet():
53  raise RuntimeError("jetID implemented only for PF Jets")
54  eta = abs(self.eta());
55  energy = (self.p4()*self.rawFactor()).energy();
56  chf = self.chargedHadronEnergy()/energy;
57  nhf = self.neutralHadronEnergy()/energy;
58  phf = self.neutralEmEnergy()/energy;
59  muf = self.muonEnergy()/energy;
60  elf = self.chargedEmEnergy()/energy;
61  chm = self.chargedHadronMultiplicity();
62  npr = self.chargedMultiplicity() + self.neutralMultiplicity();
63  npn = self.neutralMultiplicity();
64  #if npr != self.nConstituents():
65  # import pdb; pdb.set_trace()
66  if name == "POG_PFID":
67 
68  if self.jetID("PAG_monoID_Tight") and self.jetID("POG_PFID_Tight") : return 5;
69  if self.jetID("PAG_monoID_Loose") and self.jetID("POG_PFID_Tight") : return 4;
70  if self.jetID("POG_PFID_Tight") : return 3;
71  #elif self.jetID("POG_PFID_Medium") : return 2; commented this line because this working point doesn't exist anymore (as 12/05/15)
72  elif self.jetID("POG_PFID_Loose") : return 1;
73  else : return 0;
74 
75  # jetID from here: https://twiki.cern.ch/twiki/bin/viewauth/CMS/JetID#Recommendations_for_13_TeV_data
76  if name == "POG_PFID_Loose": return ((eta<3.0 and ((npr>1 and phf<0.99 and nhf<0.99) and (eta>2.4 or (elf<0.99 and chf>0 and chm>0)))) or (eta>3.0 and (phf<0.90 and npn>10)));
77  if name == "POG_PFID_Medium": return (npr>1 and phf<0.95 and nhf<0.95 and muf < 0.8) and (eta>2.4 or (elf<0.99 and chf>0 and chm>0));
78  if name == "POG_PFID_Tight": return ((eta<3.0 and ((npr>1 and phf<0.90 and nhf<0.90) and (eta>2.4 or (elf<0.99 and chf>0 and chm>0)))) or (eta>3.0 and (phf<0.90 and npn>10)));
79  if name == "VBFHBB_PFID_Loose": return (npr>1 and phf<0.99 and nhf<0.99);
80  if name == "VBFHBB_PFID_Medium": return (npr>1 and phf<0.99 and nhf<0.99) and ((eta<=2.4 and nhf<0.9 and phf<0.9 and elf<0.99 and muf<0.99 and chf>0 and chm>0) or eta>2.4);
81  if name == "VBFHBB_PFID_Tight": return (npr>1 and phf<0.99 and nhf<0.99) and ((eta<=2.4 and nhf<0.9 and phf<0.9 and elf<0.70 and muf<0.70 and chf>0 and chm>0) or eta>2.4);
82  raise RuntimeError("jetID '%s' not supported" % name)
83 
84  def looseJetId(self):
85  '''PF Jet ID (loose operation point) [method provided for convenience only]'''
86  return self.jetID("POG_PFID_Loose")
87 
88  def puMva(self, label="pileupJetId:fullDiscriminant"):
89  return self.userFloat(label)
90 
91  def puJetId(self, label="pileupJetId:fullDiscriminant"):
92  '''Full mva PU jet id'''
93 
94  puMva = self.puMva(label)
95  wp = loose_53X_WP
96  eta = abs(self.eta())
97 
98  for etamin, etamax, cut in wp:
99  if not(eta>=etamin and eta<etamax):
100  continue
101  return puMva>cut
102  return -99
103 
104  def rawFactor(self):
105  return self.jecFactor('Uncorrected') * self._rawFactorMultiplier
106 
107  def setRawFactor(self, factor):
108  self._rawFactorMultiplier = factor/self.jecFactor('Uncorrected')
109 
110  def corrFactor(self):
111  return 1.0/self.rawFactor()
112 
113  def setCorrP4(self,newP4):
114  self._recalibrated = True
115  corr = newP4.Pt() / (self.pt() * self.rawFactor())
116  self.setP4(newP4);
117  self.setRawFactor(1.0/corr);
118 
119  def l1corrFactor(self):
120  if hasattr(self, 'CorrFactor_L1'):
121  return self.CorrFactor_L1
122  if self._recalibrated:
123  raise RuntimeError("The jet was recalibrated, but without calculateSeparateCorrections. L1 is not available")
124  jecLevels = self.physObj.availableJECLevels()
125  for level in jecLevels:
126  if "L1" in level:
127  return self.physObj.jecFactor(level)/self.physObj.jecFactor('Uncorrected')
128  return 1.0 # Jet does not have any L1 correction
129 
130  def btag(self,name):
131  ret = self.bDiscriminator(name)
132  if ret == -1000 and name.startswith("pf"):
133  ret = self.bDiscriminator(name[2].lower()+name[3:])
134  return ret
135 
136  def btagWP(self,name):
137  global _btagWPs
138  (disc,val) = _btagWPs[name]
139  return self.btag(disc) > val
140 
141  def leadingTrack(self):
142  if self._leadingTrackSearched :
143  return self._leadingTrack
144  self._leadingTrackSearched = True
145  self._leadingTrack = max( self.daughterPtrVector() , key = lambda x : x.pt() if x.charge()!=0 else 0. )
146  if self._leadingTrack.charge()==0: #in case of "all neutral"
147  self._leadingTrack = None
148  return self._leadingTrack
149 
150  def leadTrackPt(self):
151  lt=self.leadingTrack()
152  if lt :
153  return lt.pt()
154  else :
155  return 0.
156  def qgl(self) :
157  if not hasattr(self,"qgl_value") :
158  if hasattr(self,"qgl_rho") : #check if qgl calculator is configured
159  self.computeQGvars()
160  self.qgl_value=self.qgl_calc(self,self.qgl_rho)
161  else :
162  self.qgl_value=-1. #if no qgl calculator configured
163 
164  return self.qgl_value
165 
166  def computeQGvars(self):
167  #return immediately if qgvars already computed or if qgl is disabled
168  if not hasattr(self,"qgl_rho") or getattr(self,"hasQGVvars",False) :
169  return self
170  self.hasQGvars = True
171 
172  jet = self
173  jet.mult = 0
174  sum_weight = 0.
175  sum_pt = 0.
176  sum_deta = 0.
177  sum_dphi = 0.
178  sum_deta2 = 0.
179  sum_detadphi = 0.
180  sum_dphi2 = 0.
181 
182 
183 
184  for ii in range(0, jet.numberOfDaughters()) :
185 
186  part = jet.daughter(ii)
187 
188  if part.charge() == 0 : # neutral particles
189 
190  if part.pt() < 1.: continue
191 
192  else : # charged particles
193 
194  if part.trackHighPurity()==False: continue
195  if part.fromPV()<=1: continue
196 
197 
198  jet.mult += 1
199 
200  deta = part.eta() - jet.eta()
201  dphi = deltaPhi(part.phi(), jet.phi())
202  partPt = part.pt()
203  weight = partPt*partPt
204  sum_weight += weight
205  sum_pt += partPt
206  sum_deta += deta*weight
207  sum_dphi += dphi*weight
208  sum_deta2 += deta*deta*weight
209  sum_detadphi += deta*dphi*weight
210  sum_dphi2 += dphi*dphi*weight
211 
212 
213 
214 
215  a = 0.
216  b = 0.
217  c = 0.
218 
219  if sum_weight > 0 :
220  jet.ptd = math.sqrt(sum_weight)/sum_pt
221  ave_deta = sum_deta/sum_weight
222  ave_dphi = sum_dphi/sum_weight
223  ave_deta2 = sum_deta2/sum_weight
224  ave_dphi2 = sum_dphi2/sum_weight
225  a = ave_deta2 - ave_deta*ave_deta
226  b = ave_dphi2 - ave_dphi*ave_dphi
227  c = -(sum_detadphi/sum_weight - ave_deta*ave_dphi)
228  else: jet.ptd = 0.
229 
230  delta = math.sqrt(math.fabs((a-b)*(a-b)+4.*c*c))
231 
232  if a+b-delta > 0: jet.axis2 = -math.log(math.sqrt(0.5*(a+b-delta)))
233  else: jet.axis2 = -1.
234  return jet
235 
236 
237 
239  pass
240 
def puMva
Definition: Jet.py:88
def looseJetId
Definition: Jet.py:84
def puJetId
Definition: Jet.py:91
_leadingTrack
Definition: Jet.py:48
def setRawFactor
Definition: Jet.py:107
def btag
Definition: Jet.py:130
_recalibrated
Definition: Jet.py:47
def qgl
Definition: Jet.py:156
def _physObjInit
Definition: Jet.py:45
def l1corrFactor
Definition: Jet.py:119
_rawFactorMultiplier
Definition: Jet.py:46
def leadingTrack
Definition: Jet.py:141
qgl_value
Definition: Jet.py:160
def __init__
Definition: Jet.py:41
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
def computeQGvars
Definition: Jet.py:166
def jetID
Definition: Jet.py:51
def leadTrackPt
Definition: Jet.py:150
def corrFactor
Definition: Jet.py:110
hasQGvars
Definition: Jet.py:170
def setCorrP4
Definition: Jet.py:113
_leadingTrackSearched
Definition: Jet.py:49
def rawFactor
Definition: Jet.py:104
def btagWP
Definition: Jet.py:136
Definition: Jet.py:40