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  if name == "PAG_monoID_Loose": return (eta<3.0 and chf>0.05 and nhf<0.7 and phf<0.8);
83  if name == "PAG_monoID_Tight": return (eta<3.0 and chf>0.2 and nhf<0.7 and phf<0.7);
84 
85  raise RuntimeError, "jetID '%s' not supported" % name
86 
87  def looseJetId(self):
88  '''PF Jet ID (loose operation point) [method provided for convenience only]'''
89  return self.jetID("POG_PFID_Loose")
90 
91  def puMva(self, label="pileupJetId:fullDiscriminant"):
92  return self.userFloat(label)
93 
94  def puJetId(self, label="pileupJetId:fullDiscriminant"):
95  '''Full mva PU jet id'''
96 
97  puMva = self.puMva(label)
98  wp = loose_53X_WP
99  eta = abs(self.eta())
100 
101  for etamin, etamax, cut in wp:
102  if not(eta>=etamin and eta<etamax):
103  continue
104  return puMva>cut
105  return -99
106 
107  def rawFactor(self):
108  return self.jecFactor('Uncorrected') * self._rawFactorMultiplier
109 
110  def setRawFactor(self, factor):
111  self._rawFactorMultiplier = factor/self.jecFactor('Uncorrected')
112 
113  def corrFactor(self):
114  return 1.0/self.rawFactor()
115 
116  def setCorrP4(self,newP4):
117  self._recalibrated = True
118  corr = newP4.Pt() / (self.pt() * self.rawFactor())
119  self.setP4(newP4);
120  self.setRawFactor(1.0/corr);
121 
122  def l1corrFactor(self):
123  if hasattr(self, 'CorrFactor_L1'):
124  return self.CorrFactor_L1
125  if self._recalibrated:
126  raise RuntimeError, "The jet was recalibrated, but without calculateSeparateCorrections. L1 is not available"
127  jecLevels = self.physObj.availableJECLevels()
128  for level in jecLevels:
129  if "L1" in level:
130  return self.physObj.jecFactor(level)/self.physObj.jecFactor('Uncorrected')
131  return 1.0 # Jet does not have any L1 correction
132 
133  def btag(self,name):
134  ret = self.bDiscriminator(name)
135  if ret == -1000 and name.startswith("pf"):
136  ret = self.bDiscriminator(name[2].lower()+name[3:])
137  return ret
138 
139  def btagWP(self,name):
140  global _btagWPs
141  (disc,val) = _btagWPs[name]
142  return self.btag(disc) > val
143 
144  def leadingTrack(self):
145  if self._leadingTrackSearched :
146  return self._leadingTrack
147  self._leadingTrackSearched = True
148  self._leadingTrack = max( self.daughterPtrVector() , key = lambda x : x.pt() if x.charge()!=0 else 0. )
149  if self._leadingTrack.charge()==0: #in case of "all neutral"
150  self._leadingTrack = None
151  return self._leadingTrack
152 
153  def leadTrackPt(self):
154  lt=self.leadingTrack()
155  if lt :
156  return lt.pt()
157  else :
158  return 0.
159  def qgl(self) :
160  if not hasattr(self,"qgl_value") :
161  if hasattr(self,"qgl_rho") : #check if qgl calculator is configured
162  self.computeQGvars()
163  self.qgl_value=self.qgl_calc(self,self.qgl_rho)
164  else :
165  self.qgl_value=-1. #if no qgl calculator configured
166 
167  return self.qgl_value
168 
169  def computeQGvars(self):
170  #return immediately if qgvars already computed or if qgl is disabled
171  if not hasattr(self,"qgl_rho") or getattr(self,"hasQGVvars",False) :
172  return self
173  self.hasQGvars = True
174 
175  jet = self
176  jet.mult = 0
177  sum_weight = 0.
178  sum_pt = 0.
179  sum_deta = 0.
180  sum_dphi = 0.
181  sum_deta2 = 0.
182  sum_detadphi = 0.
183  sum_dphi2 = 0.
184 
185 
186 
187  for ii in range(0, jet.numberOfDaughters()) :
188 
189  part = jet.daughter(ii)
190 
191  if part.charge() == 0 : # neutral particles
192 
193  if part.pt() < 1.: continue
194 
195  else : # charged particles
196 
197  if part.trackHighPurity()==False: continue
198  if part.fromPV()<=1: continue
199 
200 
201  jet.mult += 1
202 
203  deta = part.eta() - jet.eta()
204  dphi = deltaPhi(part.phi(), jet.phi())
205  partPt = part.pt()
206  weight = partPt*partPt
207  sum_weight += weight
208  sum_pt += partPt
209  sum_deta += deta*weight
210  sum_dphi += dphi*weight
211  sum_deta2 += deta*deta*weight
212  sum_detadphi += deta*dphi*weight
213  sum_dphi2 += dphi*dphi*weight
214 
215 
216 
217 
218  a = 0.
219  b = 0.
220  c = 0.
221 
222  if sum_weight > 0 :
223  jet.ptd = math.sqrt(sum_weight)/sum_pt
224  ave_deta = sum_deta/sum_weight
225  ave_dphi = sum_dphi/sum_weight
226  ave_deta2 = sum_deta2/sum_weight
227  ave_dphi2 = sum_dphi2/sum_weight
228  a = ave_deta2 - ave_deta*ave_deta
229  b = ave_dphi2 - ave_dphi*ave_dphi
230  c = -(sum_detadphi/sum_weight - ave_deta*ave_dphi)
231  else: jet.ptd = 0.
232 
233  delta = math.sqrt(math.fabs((a-b)*(a-b)+4.*c*c))
234 
235  if a+b-delta > 0: jet.axis2 = -math.log(math.sqrt(0.5*(a+b-delta)))
236  else: jet.axis2 = -1.
237  return jet
238 
239 
240 
242  pass
243 
def puMva
Definition: Jet.py:91
def looseJetId
Definition: Jet.py:87
def puJetId
Definition: Jet.py:94
_leadingTrack
Definition: Jet.py:48
def setRawFactor
Definition: Jet.py:110
def btag
Definition: Jet.py:133
_recalibrated
Definition: Jet.py:47
def qgl
Definition: Jet.py:159
def _physObjInit
Definition: Jet.py:45
def l1corrFactor
Definition: Jet.py:122
_rawFactorMultiplier
Definition: Jet.py:46
def leadingTrack
Definition: Jet.py:144
qgl_value
Definition: Jet.py:163
def __init__
Definition: Jet.py:41
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
def computeQGvars
Definition: Jet.py:169
def jetID
Definition: Jet.py:51
def leadTrackPt
Definition: Jet.py:153
def corrFactor
Definition: Jet.py:113
hasQGvars
Definition: Jet.py:173
def setCorrP4
Definition: Jet.py:116
_leadingTrackSearched
Definition: Jet.py:49
def rawFactor
Definition: Jet.py:107
def btagWP
Definition: Jet.py:139
Definition: Jet.py:40