CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
MT2Analyzer.py
Go to the documentation of this file.
1 import operator
2 import itertools
3 import copy
4 from math import *
5 
6 from ROOT import std
7 from ROOT import TLorentzVector, TVectorD
8 
9 from PhysicsTools.Heppy.analyzers.core.Analyzer import Analyzer
10 from PhysicsTools.HeppyCore.framework.event import Event
11 from PhysicsTools.HeppyCore.statistics.counter import Counter, Counters
12 from PhysicsTools.Heppy.analyzers.core.AutoHandle import AutoHandle
13 
14 import PhysicsTools.HeppyCore.framework.config as cfg
15 
16 from PhysicsTools.HeppyCore.utils.deltar import deltaR
17 
18 from ROOT.heppy import Hemisphere
19 from ROOT.heppy import ReclusterJets
20 
21 from ROOT.heppy import Davismt2
22 davismt2 = Davismt2()
23 
24 from ROOT.heppy import mt2w_bisect
25 mt2wSNT = mt2w_bisect.mt2w()
26 
27 import ROOT
28 
29 import os
30 
31 
32 class MT2Analyzer( Analyzer ):
33  def __init__(self, cfg_ana, cfg_comp, looperName ):
34  super(MT2Analyzer,self).__init__(cfg_ana,cfg_comp,looperName)
35 
36  def declareHandles(self):
37  super(MT2Analyzer, self).declareHandles()
38  #genJets
39  self.handles['genJets'] = AutoHandle( 'slimmedGenJets','std::vector<reco::GenJet>')
40 
41  def beginLoop(self, setup):
42  super(MT2Analyzer,self).beginLoop(setup)
43  self.counters.addCounter('pairs')
44  count = self.counters.counter('pairs')
45  count.register('all events')
46 
47  def computeMT2(self, visaVec, visbVec, metVec):
48 
49  import array
50  import numpy
51 
52  metVector = array.array('d',[0.,metVec.px(), metVec.py()])
53  visaVector = array.array('d',[0.,visaVec.px(), visaVec.py()])
54  visbVector = array.array('d',[0.,visbVec.px(), visbVec.py()])
55 
56  davismt2.set_momenta(visaVector,visbVector,metVector);
57  davismt2.set_mn(0);
58 
59  return davismt2.get_mt2()
60 
61  def getMT2AKT(self, event, TMPobjects40jc, met , postFix):
62 
63 #### get hemispheres via AntiKT -1 antikt, 1 kt, 0 CA
64  if len(TMPobjects40jc)>=2:
65 
66  objects = ROOT.std.vector(ROOT.reco.Particle.LorentzVector)()
67  for jet in TMPobjects40jc:
68  objects.push_back(jet.p4())
69 
70  hemisphereViaKt = ReclusterJets(objects, 1.,50.0)
71  groupingViaKt=hemisphereViaKt.getGroupingExclusive(2)
72 
73  if len(groupingViaKt)>=2:
74  setattr(event, "pseudoViaKtJet1"+postFix, ROOT.reco.Particle.LorentzVector(groupingViaKt[0]) )
75  setattr(event, "pseudoViaKtJet2"+postFix, ROOT.reco.Particle.LorentzVector(groupingViaKt[1]) )
76  return self.computeMT2(getattr(event,'pseudoViaKtJet1'+postFix), getattr(event,'pseudoViaKtJet2'+postFix), met)
77 
78  if not self.cfg_ana.doOnlyDefault:
79  hemisphereViaAKt = ReclusterJets(objects, -1.,50.0)
80  groupingViaAKt=hemisphereViaAKt.getGroupingExclusive(2)
81 
82  if len(groupingViaAKt)>=2:
83  setattr(event, "pseudoViaAKtJet1"+postFix, ROOT.reco.Particle.LorentzVector(groupingViaAKt[0]) )
84  setattr(event, "pseudoViaAKtJet2"+postFix, ROOT.reco.Particle.LorentzVector(groupingViaAKt[1]) )
85  setattr(event, "mt2ViaAKt"+postFix, self.computeMT2(getattr(event,'pseudoViaAKtJet1'+postFix), getattr(event,'pseudoViaAKtJet2'+postFix), met) )
86 
87  def getMT2Hemi(self, event, TMPobjects40jc, met, postFix):
88 
89  if len(TMPobjects40jc)>=2:
90 
91  pxvec = ROOT.std.vector(float)()
92  pyvec = ROOT.std.vector(float)()
93  pzvec = ROOT.std.vector(float)()
94  Evec = ROOT.std.vector(float)()
95  grouping = ROOT.std.vector(int)()
96 
97  for jet in TMPobjects40jc:
98  pxvec.push_back(jet.px())
99  pyvec.push_back(jet.py())
100  pzvec.push_back(jet.pz())
101  Evec.push_back(jet.energy())
102 
103  hemisphere = Hemisphere(pxvec, pyvec, pzvec, Evec, 2, 3)
104  grouping=hemisphere.getGrouping()
105 
106  pseudoJet1px = 0
107  pseudoJet1py = 0
108  pseudoJet1pz = 0
109  pseudoJet1energy = 0
110  multPSJ1 = 0
111 
112  pseudoJet2px = 0
113  pseudoJet2py = 0
114  pseudoJet2pz = 0
115  pseudoJet2energy = 0
116  multPSJ2 = 0
117 
118  for index in range(0, len(pxvec)):
119  if(grouping[index]==1):
120  pseudoJet1px += pxvec[index]
121  pseudoJet1py += pyvec[index]
122  pseudoJet1pz += pzvec[index]
123  pseudoJet1energy += Evec[index]
124  multPSJ1 += 1
125  if(grouping[index]==2):
126  pseudoJet2px += pxvec[index]
127  pseudoJet2py += pyvec[index]
128  pseudoJet2pz += pzvec[index]
129  pseudoJet2energy += Evec[index]
130  multPSJ2 += 1
131 
132  pseudoJet1pt2 = pseudoJet1px*pseudoJet1px + pseudoJet1py*pseudoJet1py
133  pseudoJet2pt2 = pseudoJet2px*pseudoJet2px + pseudoJet2py*pseudoJet2py
134 
135  if pseudoJet1pt2 >= pseudoJet2pt2:
136  setattr(event, "pseudoJet1"+postFix, ROOT.reco.Particle.LorentzVector( pseudoJet1px, pseudoJet1py, pseudoJet1pz, pseudoJet1energy ))
137  setattr(event, "pseudoJet2"+postFix, ROOT.reco.Particle.LorentzVector( pseudoJet2px, pseudoJet2py, pseudoJet2pz, pseudoJet2energy ))
138  setattr(event, "multPseudoJet1"+postFix, multPSJ1 )
139  setattr(event, "multPseudoJet2"+postFix, multPSJ2 )
140  else:
141  setattr(event, "pseudoJet2"+postFix, ROOT.reco.Particle.LorentzVector( pseudoJet1px, pseudoJet1py, pseudoJet1pz, pseudoJet1energy ))
142  setattr(event, "pseudoJet1"+postFix, ROOT.reco.Particle.LorentzVector( pseudoJet2px, pseudoJet2py, pseudoJet2pz, pseudoJet2energy ))
143  setattr(event, "multPseudoJet1"+postFix, multPSJ2 )
144  setattr(event, "multPseudoJet2"+postFix, multPSJ1 )
145 
146  return self.computeMT2(getattr(event,'pseudoJet1'+postFix), getattr(event,'pseudoJet2'+postFix), met)
147 
148 
149  def makeMT2(self, event):
150 # print '==> INSIDE THE PRINT MT2'
151 # print 'MET=',event.met.pt()
152 
153  import array
154  import numpy
155 
156 
157  objects40jc = [ j for j in event.cleanJets if j.pt() > 40 and abs(j.eta())<2.5 ]
158 
159 #### get hemispheres via AntiKT -1 antikt, 1 kt, 0 CA
160  if len(objects40jc)>=2:
161 
162  event.mt2ViaKt_had=self.getMT2AKT(event, objects40jc, event.met, "_had")
163 
164 ## ===> hadronic MT2 (as used in the SUS-13-019)
165 #### get hemispheres (seed 2: max inv mass, association method: default 3 = minimal lund distance)
166 
167  if len(objects40jc)>=2:
168 
169  event.mt2_had = self.getMT2Hemi(event,objects40jc, event.met, "_had")
170 
171 #### do same things for GEN
172 
173  if self.cfg_comp.isMC:
174  allGenJets = [ x for x in self.handles['genJets'].product() ]
175  objects40jc_Gen = [ j for j in allGenJets if j.pt() > 40 and abs(j.eta())<2.5 ]
176 
177  if len(objects40jc_Gen)>=2:
178  event.mt2_gen = self.getMT2Hemi(event,objects40jc_Gen, event.met.genMET(), "_gen")
179  else:
180  event.mt2_gen = -999.
181 
182 
183 ## ===> full MT2 (jets + leptons)
184 
185  objects10lc = [ l for l in event.selectedLeptons if l.pt() > 10 and abs(l.eta())<2.5 ]
186  if hasattr(event, 'selectedIsoCleanTrack'):
187  objects10lc = [ l for l in event.selectedLeptons if l.pt() > 10 and abs(l.eta())<2.5 ] + [ t for t in event.selectedIsoCleanTrack ]
188 
189  objects40j10lc = objects40jc + objects10lc
190 
191  objects40j10lc.sort(key = lambda obj : obj.pt(), reverse = True)
192 
193  if len(objects40j10lc)>=2:
194 
195  event.mt2 = self.getMT2Hemi(event,objects40j10lc,event.met,"") # no postfit since this is the nominal MT2
196 
197 ## ===> full gamma_MT2
198 
199  event.gamma_mt2=-999
200  event.pseudoJet1_gamma = ROOT.reco.Particle.LorentzVector( 0, 0, 0, 0 )
201  event.pseudoJet2_gamma = ROOT.reco.Particle.LorentzVector( 0, 0, 0, 0 )
202 
203  if hasattr(event, 'gamma_met'):
204 
205  gamma_objects40jc = [ j for j in event.gamma_cleanJets if j.pt() > 40 and abs(j.eta())<2.5 ]
206 
207  gamma_objects40j10lc = gamma_objects40jc + objects10lc
208 
209  gamma_objects40j10lc.sort(key = lambda obj : obj.pt(), reverse = True)
210 
211 ## if len(gamma_objects40j10lc)>=2:
212  if len(gamma_objects40jc)>=2:
213 
214  event.gamma_mt2 = self.getMT2Hemi(event,gamma_objects40jc,event.gamma_met,"_gamma")
215 
216 
217 ## ===> zll_MT2
218 
219  event.zll_mt2=-999
220  event.pseudoJet1_zll = ROOT.reco.Particle.LorentzVector( 0, 0, 0, 0 )
221  event.pseudoJet2_zll = ROOT.reco.Particle.LorentzVector( 0, 0, 0, 0 )
222 
223  if hasattr(event, 'zll_met'):
224 
225  csLeptons = [ l for l in event.selectedLeptons if l.pt() > 10 and abs(l.eta()) < 2.5 ]
226 
227  if len(csLeptons)==2 and len(objects40jc)>=2:
228 
229  event.zll_mt2 = self.getMT2Hemi(event,objects40jc,event.zll_met,"_zll")
230 
231 
232 #### do the mt2 with one or two b jets (medium CSV)
233  if len(event.bjetsMedium)>=2:
234 
235  event.mt2bb = self.computeMT2(event.bjetsMedium[0], event.bjetsMedium[1], event.met)
236 # print 'MT2bb(2b)',event.mt2bb
237  if len(event.bjetsMedium)==1:
238 
239  objects40jcCSV = [ j for j in event.cleanJets if j.pt() > 40 and abs(j.eta())<2.5 and j.p4()!=event.bjetsMedium[0].p4() ]
240  objects40jcCSV.sort(key = lambda l : l.btag('combinedInclusiveSecondaryVertexV2BJetTags'), reverse = True)
241 
242  if len(objects40jcCSV)>0:
243  event.mt2bb = self.computeMT2(event.bjetsMedium[0], objects40jcCSV[0], event.met)
244 ## print 'MT2bb(1b)',event.mt2bb
245 
246 ## ===> leptonic MT2 (as used in the SUS-13-025 )
247  if not self.cfg_ana.doOnlyDefault:
248  if len(event.selectedLeptons)>=2:
249  event.mt2lep = self.computeMT2(event.selectedLeptons[0], event.selectedLeptons[1], event.met)
250 
251 ###
252 
253  def process(self, event):
254  self.readCollections( event.input )
255 
256  event.mt2_gen=-999
257  event.mt2bb=-999
258  event.mt2lept=-999
259 
260  event.mt2_had=-999
261  event.pseudoJet1_had = ROOT.reco.Particle.LorentzVector( 0, 0, 0, 0 )
262  event.pseudoJet2_had = ROOT.reco.Particle.LorentzVector( 0, 0, 0, 0 )
263  event.multPseudoJet1_had=0
264  event.multPseudoJet2_had=0
265 
266  event.mt2=-999
267  event.pseudoJet1 = ROOT.reco.Particle.LorentzVector( 0, 0, 0, 0 )
268  event.pseudoJet2 = ROOT.reco.Particle.LorentzVector( 0, 0, 0, 0 )
269 
270  event.mt2ViaKt_had=-999
271  event.mt2ViaAKt_had=-999
272  event.pseudoViaKtJet1_had = ROOT.reco.Particle.LorentzVector( 0, 0, 0, 0 )
273  event.pseudoViaKtJet2_had = ROOT.reco.Particle.LorentzVector( 0, 0, 0, 0 )
274  event.pseudoViaAKtJet1_had = ROOT.reco.Particle.LorentzVector( 0, 0, 0, 0 )
275  event.pseudoViaAKtJet2_had = ROOT.reco.Particle.LorentzVector( 0, 0, 0, 0 )
276 
277  ###
278 
279  self.makeMT2(event)
280 
281 # print 'variables computed: MT=',event.mtw,'MT2=',event.mt2,'MT2W=',event.mt2w
282 # print 'pseudoJet1 px=',event.pseudoJet1.px(),' py=',event.pseudoJet1.py(),' pz=',event.pseudoJet1.pz()
283 # print 'pseudoJet2 px=',event.pseudoJet2.px(),' py=',event.pseudoJet2.py(),' pz=',event.pseudoJet2.pz()
284 
285  return True
286 
287 
288 
289 setattr(MT2Analyzer,"defaultConfig", cfg.Analyzer(
290  class_object = MT2Analyzer,
291  doOnlyDefault = True,
292  )
293 )
double p4[4]
Definition: TauolaWrapper.h:92
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
if(conf.exists("allCellsPositionCalc"))
tuple process
Definition: LaserDQM_cfg.py:3