def beginLoop(self): '''Automatically called by Looper, for all analyzers.''' self.declareHandles() self.counters = Counters() self.averages = Averages() self.mainLogger.warning( 'beginLoop ' + self.cfg_ana.name ) self.beginLoopCalled = True
def beginLoop(self): super(TauTauAnalyzer, self).beginLoop() self.counters = Counters() self.counters.addCounter('DiLepton') count = self.counters.counter('DiLepton') count.register('all events') count.register('> 0 di-lepton') count.register('lepton accept') count.register('third lepton veto') count.register('leg1 trig matched') count.register('leg2 trig matched') count.register('jet trig matched') count.register('leg1 offline cuts passed') count.register('leg2 offline cuts passed') count.register('{min:3.1f} < m < {max:3.1f}'.format( min=self.cfg_ana.m_min, max=self.cfg_ana.m_max)) count.register('exactly 1 di-lepton')
def beginLoop(self): super(TauTauAnalyzer,self).beginLoop() self.counters = Counters() self.counters.addCounter('DiLepton') count = self.counters.counter('DiLepton') count.register('all events') count.register('> 0 di-lepton') count.register('lepton accept') count.register('third lepton veto') count.register('leg1 trig matched') count.register('leg2 trig matched') count.register('jet trig matched') count.register('leg1 offline cuts passed') count.register('leg2 offline cuts passed') count.register('{min:3.1f} < m < {max:3.1f}'.format( min = self.cfg_ana.m_min, max = self.cfg_ana.m_max )) count.register('exactly 1 di-lepton')
class TauTauAnalyzer( DiLeptonAnalyzer ): DiObjectClass = TauTau LeptonClass = Tau def declareHandles(self): super(TauTauAnalyzer, self).declareHandles() #self.handles['diLeptons'] = AutoHandle( 'cmgDiTauCorSVFitFullSel' , 'std::vector<cmg::DiObject<cmg::Tau,cmg::Tau> >' ) ## old object #self.handles['mvametsigs'] = AutoHandle( 'mvaMETDiTau' , 'std::vector<cmg::METSignificance>' ) self.handles['diLeptons'] = AutoHandle( 'cmgDiTauCorSVFitFullSel' , 'std::vector<cmg::DiTauObject<cmg::Tau,cmg::Tau> >') ## new object by Jan self.handles['rawMET'] = AutoHandle( 'cmgPFMETRaw' , 'std::vector<cmg::BaseMET>' ) self.handles['jets'] = AutoHandle( 'cmgPFJetSel' , 'std::vector<cmg::PFJet>' ) self.handles['electrons'] = AutoHandle( 'cmgElectronSel' , 'std::vector<cmg::Electron>' ) self.handles['muons'] = AutoHandle( 'cmgMuonSel' , 'std::vector<cmg::Muon>' ) self.handles['triggerResults'] = AutoHandle( ('TriggerResults','','HLT') , 'edm::TriggerResults' ) self.handles['metSig'] = AutoHandle( 'pfMetSignificance' , 'cmg::METSignificance' ) self.handles['L1JetsCentral'] = AutoHandle( ('l1extraParticles','Central','RECO'), 'vector<l1extra::L1JetParticle>' ) self.handles['L1JetsTau'] = AutoHandle( ('l1extraParticles','Tau' ,'RECO'), 'vector<l1extra::L1JetParticle>' ) if self.cfg_comp.isMC and ("DY" in self.cfg_comp.name or "W" in self.cfg_comp.name or ("TTJets" in self.cfg_comp.name and 'emb' not in self.cfg_comp.name ) or "Higgs" in self.cfg_comp.name and not "WW" in self.cfg_comp.name and not "WZ" in self.cfg_comp.name): self.mchandles['genParticles'] = AutoHandle( 'genParticlesPruned','std::vector<reco::GenParticle>' ) if self.cfg_comp.isMC and "QCD" in self.cfg_comp.name: self.mchandles['generator'] = AutoHandle( 'generator','GenEventInfoProduct' ) if self.cfg_comp.isMC and ("DY" in self.cfg_comp.name or "W" in self.cfg_comp.name and not "WW" in self.cfg_comp.name and not "WZ" in self.cfg_comp.name and not "_new" in self.cfg_comp.name) : self.mchandles['source'] = AutoHandle('source','LHEEventProduct') #if self.cfg_comp.isEmb or self.cfg_comp.name == "TTJets_emb" : if 'emb' in self.cfg_comp.name : self.embhandles['genParticlesEmb'] = AutoHandle( ('genParticles','','EmbeddedRECO'),'std::vector<reco::GenParticle>' ) self.triggers = ['HLT_LooseIsoPFTau35_Trk20_Prong1_v6', 'HLT_LooseIsoPFTau35_Trk20_Prong1_MET70_v6' , 'HLT_LooseIsoPFTau35_Trk20_Prong1_MET75_v6' , 'HLT_DoubleMediumIsoPFTau30_Trk5_eta2p1_Jet30_v2' , 'HLT_DoubleMediumIsoPFTau30_Trk5_eta2p1_v2' , 'HLT_DoubleMediumIsoPFTau35_Trk5_eta2p1_v6' , 'HLT_DoubleMediumIsoPFTau35_Trk5_eta2p1_Prong1_v6' , ] self.triggersEmb = [ 'HLT_Mu17_Mu8_v16', 'HLT_Mu17_Mu8_v17', 'HLT_Mu17_Mu8_v18', 'HLT_Mu17_Mu8_v19', 'HLT_Mu17_Mu8_v21', 'HLT_Mu17_Mu8_v21', 'HLT_Mu17_Mu8_v22', ] self.triggers += self.triggersEmb ###### PT HIGGS REWEIGHTING if "HiggsGGH" in self.cfg_comp.name: masspoint = re.findall(r"(\d{2,3})", self.cfg_comp.name) masspoint = str(masspoint[0]) self.higgsPtWeightFile = TFile("$CMSSW_BASE/src/CMGTools/H2TauTau/data/weight_ptH_"+masspoint+"_8TeV.root") self.higgsPtWeightHistogramNom = self.higgsPtWeightFile.Get("Nominal") self.higgsPtWeightHistogramUp = self.higgsPtWeightFile.Get("Up") self.higgsPtWeightHistogramDown = self.higgsPtWeightFile.Get("Down") def beginLoop(self): super(TauTauAnalyzer,self).beginLoop() self.counters = Counters() self.counters.addCounter('DiLepton') count = self.counters.counter('DiLepton') count.register('all events') count.register('> 0 di-lepton') count.register('lepton accept') count.register('third lepton veto') count.register('leg1 trig matched') count.register('leg2 trig matched') count.register('jet trig matched') count.register('leg1 offline cuts passed') count.register('leg2 offline cuts passed') count.register('{min:3.1f} < m < {max:3.1f}'.format( min = self.cfg_ana.m_min, max = self.cfg_ana.m_max )) count.register('exactly 1 di-lepton') def bestDiLepton(self, diLeptons): '''Returns the best diLepton (the one with best isolation).''' iso = self.cfg_ana.isolation if iso == 'mva' : #### Tau ID MVA return max( [ (min(dilep.leg1().tauID("byRawIsoMVA"), dilep.leg2().tauID("byRawIsoMVA")), dilep) for dilep in diLeptons ] )[1] if iso == 'mva2' : #### Tau ID MVA2 return max( [ (min(dilep.leg1().tauID("byIsolationMVA2raw"), dilep.leg2().tauID("byIsolationMVA2raw")), dilep) for dilep in diLeptons ] )[1] if iso == 'db3h' : #### Tau ID deltaBeta 3 hits return min( [ (max(dilep.leg1().tauID("byCombinedIsolationDeltaBetaCorrRaw3Hits"), dilep.leg2().tauID("byCombinedIsolationDeltaBetaCorrRaw3Hits")), dilep) for dilep in diLeptons ] )[1] #### highest sum pt pair #return max( [ (dilep.sumPt(), dilep) for dilep in diLeptons ] )[1] def process(self, iEvent, event): # select signal dileptons with all cuts on both legs if 'TTJets_emb' in self.cfg_comp.name : self.cfg_comp.isEmbed = True self.readCollections( iEvent ) # trigger stuff could be put in a separate analyzer # event.triggerObject = self.handles['cmgTriggerObjectSel'].product()[0] event.diLeptons = self.buildDiLeptons( self.handles['diLeptons'].product(), event ) #event.leptons = self.buildLeptons( self.handles['leptons'].product(), event ) event.leptons = [] for diLepton in event.diLeptons: if not diLepton.leg1() in event.leptons: event.leptons += [diLepton.leg1()] if not diLepton.leg2() in event.leptons: event.leptons += [diLepton.leg2()] self.shiftEnergyScale(event) event.rawMET = self.handles['rawMET'].product() triggerResults = self.handles['triggerResults'].product() triggerNames = iEvent._event.triggerNames(triggerResults) #event.hltPath = [] for trig in self.triggers: index = triggerNames.triggerIndex(trig) if index >= triggerNames.size(): trigres = -1 else: trigres = triggerResults.accept(index) #event.hltPath.append(trig) setattr(event,trig,trigres) result = self.selectionSequence(event, fillCounter=True) # select non signal dileptons with loose cuts if result is False: selDiLeptons = [ diL for diL in event.diLeptonsTrigMatched if \ self.cfg_ana.m_min < diL.mass() and diL.mass() < self.cfg_ana.m_max and \ self.testLooseLeg( diL.leg1() ) and self.testLooseLeg( diL.leg2() ) and \ (self.testLeg( diL.leg1() ) or self.testLeg( diL.leg2() )) ] if len(selDiLeptons)==0: selDiLeptons = [ diL for diL in event.diLeptons if \ self.cfg_ana.m_min < diL.mass() and diL.mass() < self.cfg_ana.m_max and \ self.testLooseLeg( diL.leg1() ) and self.testLooseLeg( diL.leg2() ) and \ (self.testLeg( diL.leg1() ) or self.testLeg( diL.leg2() )) ] if len(selDiLeptons)==0: return False event.diLepton = self.bestDiLepton( selDiLeptons ) event.leg1 = event.diLepton.leg1() event.leg2 = event.diLepton.leg2() event.isSignal = False else: event.isSignal = True #if event.eventId in notPassed : # print 'diLeptons built, is Signal?', result # import pdb ; pdb.set_trace() #if len([event.diLepton])>1 : #import pdb ; pdb.set_trace() event.leg1.NewLooseAntiEleMVA3 = self.passAntiEMVA(iCat = event.diLepton.leg1().tauID("againstElectronMVA3category"), raw = event.diLepton.leg1().tauID("againstElectronMVA3raw"), WP = 0 ) event.leg2.NewLooseAntiEleMVA3 = self.passAntiEMVA(iCat = event.diLepton.leg2().tauID("againstElectronMVA3category"), raw = event.diLepton.leg2().tauID("againstElectronMVA3raw"), WP = 0 ) # count muons event.muons = [lep for lep in self.buildMuons(self.handles['muons'].product(),event) if self.testLegKine(lep, ptcut=10, etacut=2.4) and self.testLeg2ID(lep) and self.testLeg2Iso(lep, 0.3) ] # count electrons event.electrons = [electron for electron in self.buildElectrons(self.handles['electrons'].product(),event) if self.testLegKine(electron, ptcut=10, etacut=2.5) and electron.looseIdForTriLeptonVeto() and self.testVertex( electron ) and electron.relIsoAllChargedDB05() < 0.3] ####### what ID for veto means ####### http://cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/UserCode/CMG/CMGTools/RootTools/python/physicsobjects/HTauTauElectron.py?revision=1.10&view=markup #import pdb ; pdb.set_trace() if self.cfg_comp.isEmbed or "TTJets_emb" in self.cfg_comp.name : genParticles = self.embhandles['genParticlesEmb'].product() self.splitDYJets( event, genParticles, event.diLepton, require_status=False) if self.cfg_comp.isMC and ("DY" in self.cfg_comp.name or "W" in self.cfg_comp.name and not "WW" in self.cfg_comp.name and not "WZ" in self.cfg_comp.name and not "_new" in self.cfg_comp.name) : event.NUP = self.mchandles['source'].product().hepeup().NUP else: event.NUP = -1 event.genMatched = None if self.cfg_comp.isMC and ("DY" in self.cfg_comp.name or "Higgs" in self.cfg_comp.name): genParticles = self.mchandles['genParticles'].product() event.genParticles = map( GenParticle, genParticles) # useless now leg1DeltaR, leg2DeltaR = event.diLepton.match( event.genParticles ) event.leg1DeltaR = leg1DeltaR event.leg2DeltaR = leg2DeltaR if leg1DeltaR>-1 and leg1DeltaR < 0.3 and \ leg2DeltaR>-1 and leg2DeltaR < 0.3 : event.genMatched = True else: event.genMatched = False self.splitDYJets( event, genParticles, event.diLepton) event.isPhoton=False event.isElectron=False for gen in genParticles: if abs(gen.pdgId())==15 and abs(gen.mother().pdgId())==23 and (gen.mother().mass()<80 or gen.mother().mass()>100): event.isPhoton=True if abs(gen.pdgId())==13 and abs(gen.mother().pdgId())==23: event.isMuon=True if abs(gen.pdgId())==11 and abs(gen.mother().pdgId())==23: event.isElectron=True #import pdb ; pdb.set_trace() if self.cfg_comp.isMC and "W" in self.cfg_comp.name: genParticles = self.mchandles['genParticles'].product() event.genParticles = map( GenParticle, genParticles) genTaus = [] event.genMatched = False event.genMatchedElectron = False event.genMatchedMuon = False for gen in genParticles: if abs(gen.pdgId()) in [11,13,15] and abs(gen.mother().pdgId())==24: # W -> tau nu genTaus.append( gen ) if len(genTaus)>=1: dR2leg1Min, event.diLepton.leg1Gen = ( float('inf'), None) dR2leg2Min, event.diLepton.leg2Gen = ( float('inf'), None) for genTau in genTaus: dR2leg1 = deltaR2(event.diLepton.leg1().eta(), event.diLepton.leg1().phi(), genTau.eta(), genTau.phi() ) dR2leg2 = deltaR2(event.diLepton.leg2().eta(), event.diLepton.leg2().phi(), genTau.eta(), genTau.phi() ) if dR2leg1 < dR2leg1Min: dR2leg1Min, event.diLepton.leg1Gen = (dR2leg1, genTau) if dR2leg2 < dR2leg2Min: dR2leg2Min, event.diLepton.leg2Gen = (dR2leg2, genTau) leg1DeltaR = math.sqrt( dR2leg1Min ) leg2DeltaR = math.sqrt( dR2leg2Min ) if ((leg1DeltaR>-1 and leg1DeltaR < 0.1) or \ (leg2DeltaR>-1 and leg2DeltaR < 0.1)) and abs(genTau.pdgId())==11: event.genMatchedElectron = True if ((leg1DeltaR>-1 and leg1DeltaR < 0.1) or \ (leg2DeltaR>-1 and leg2DeltaR < 0.1)) and abs(genTau.pdgId())==13: event.genMatchedMuon = True if ((leg1DeltaR>-1 and leg1DeltaR < 0.1) or \ (leg2DeltaR>-1 and leg2DeltaR < 0.1)) and abs(genTau.pdgId())==15: event.genMatched = True event.isElectron=False event.isMuon=False event.isTau=False for gen in genParticles: if abs(gen.pdgId())==11 and abs(gen.mother().pdgId())==24: event.isElectron=True if abs(gen.pdgId())==13 and abs(gen.mother().pdgId())==24: event.isMuon=True if abs(gen.pdgId())==15 and abs(gen.mother().pdgId())==24: event.isTau=True #import pdb ; pdb.set_trace() if self.cfg_comp.isMC and "TTJets_emb" not in self.cfg_comp.name: genParticles = self.mchandles['genParticles'].product() event.genParticles = map( GenParticle, genParticles) genTaus = [] event.genMatched = 0 event.genMatchedElectron = 0 event.genMatchedMuon = 0 for gen in genParticles: if abs(gen.pdgId()) in [11,13,15] and abs(gen.mother().pdgId())==24: # W -> tau nu genTaus.append( gen ) if len(genTaus)>=1: dR2leg1Min, event.diLepton.leg1Gen = ( float('inf'), None) dR2leg2Min, event.diLepton.leg2Gen = ( float('inf'), None) for genTau in genTaus: dR2leg1 = deltaR2(event.diLepton.leg1().eta(), event.diLepton.leg1().phi(), genTau.eta(), genTau.phi() ) dR2leg2 = deltaR2(event.diLepton.leg2().eta(), event.diLepton.leg2().phi(), genTau.eta(), genTau.phi() ) if dR2leg1 < dR2leg1Min: dR2leg1Min, event.diLepton.leg1Gen = (dR2leg1, genTau) if dR2leg2 < dR2leg2Min: dR2leg2Min, event.diLepton.leg2Gen = (dR2leg2, genTau) leg1DeltaR = math.sqrt( dR2leg1Min ) leg2DeltaR = math.sqrt( dR2leg2Min ) if (leg1DeltaR>-1 and leg1DeltaR < 0.1) and abs(genTau.pdgId())==11: event.genMatchedElectron+=1 if (leg1DeltaR>-1 and leg1DeltaR < 0.1) and abs(genTau.pdgId())==13: event.genMatchedMuon+=1 if (leg1DeltaR>-1 and leg1DeltaR < 0.1) and abs(genTau.pdgId())==15: event.genMatched+=1 if (leg2DeltaR>-1 and leg2DeltaR < 0.1) and abs(genTau.pdgId())==11: event.genMatchedElectron+=1 if (leg2DeltaR>-1 and leg2DeltaR < 0.1) and abs(genTau.pdgId())==13: event.genMatchedMuon+=1 if (leg2DeltaR>-1 and leg2DeltaR < 0.1) and abs(genTau.pdgId())==15: event.genMatched+=1 event.isElectron=0 event.isMuon=0 event.isTau=0 for gen in genParticles: if abs(gen.pdgId())==11 and abs(gen.mother().pdgId())==24: event.isElectron+=1 if abs(gen.pdgId())==13 and abs(gen.mother().pdgId())==24: event.isMuon+=1 if abs(gen.pdgId())==15 and abs(gen.mother().pdgId())==24: event.isTau+=1 if self.cfg_comp.isMC and "QCD" in self.cfg_comp.name: generator = self.mchandles['generator'].product() event.generatorWeight = generator.weight() event.eventWeight *= event.generatorWeight #import pdb ; pdb.set_trace() if self.cfg_comp.isMC and "HiggsGGH" in self.cfg_comp.name: genParticles = self.mchandles['genParticles'].product() event.genParticles = map( GenParticle, genParticles) higgsPt=-1 for gen in genParticles: if abs(gen.pdgId())==25: higgsPt = gen.pt() break event.higgsPtWeightNom = self.higgsPtWeightHistogramNom.GetBinContent(self.higgsPtWeightHistogramNom.FindBin(higgsPt)) event.higgsPtWeightUp = self.higgsPtWeightHistogramUp.GetBinContent(self.higgsPtWeightHistogramUp.FindBin(higgsPt)) event.higgsPtWeightDown = self.higgsPtWeightHistogramDown.GetBinContent(self.higgsPtWeightHistogramDown.FindBin(higgsPt)) else : event.higgsPtWeightNom = 1. event.higgsPtWeightUp = 1. event.higgsPtWeightDown = 1. ## third lepton veto if len(event.muons)+len(event.electrons)> 0: return False if ("DY" in self.cfg_comp.name and event.isZtt) or "Higgs" in self.cfg_comp.name or (self.cfg_comp.isEmbed and event.isZtt): event.isRealTau = 1 else : event.isRealTau = 0 if not hasattr(event,'NJetWeight') : event.NJetWeight = 1. #import pdb ; pdb.set_trace() if ("DY" in self.cfg_comp.name and event.isZtt) or "Higgs" in self.cfg_comp.name or (self.cfg_comp.isEmbed and event.isZtt): if event.leg1.decayMode() == 0 : event.leg1.prongWeight = 0.88 else : event.leg1.prongWeight = 1. if event.leg2.decayMode() == 0 : event.leg2.prongWeight = 0.88 else : event.leg2.prongWeight = 1. #import pdb ; pdb.set_trace() #event.name = self.cfg_comp.name #import pdb ; pdb.set_trace() event.metsig = self.handles['metSig'].product() event.ntot = 1. # ngenevts = { 'W1Jets' : 23141598.* 1.0 , # 'W2Jets' : 34044921.* 1.0 , # 'W3Jets' : 15539503.* 0.997191011236, # 'W4Jets' : 13382803.* 0.996168582375, # #'WJets' : 18393090 * 1.0 , # 'WJets' : 57709905.* 1.0 , # 'HiggsGGH125' : 968134. * 1.0 , # 'HiggsVBF125' : 998836. * 1.0 , # 'TTJetsFullLept' : 12011428 * 1.0 , # 'TTJetsHadronic' : 31223821 * 1.0 , # 'TTJetsSemiLept' : 24953451 * 1.0 , # 'DYJets' : 30459503 * 1.0 , # 'HiggsSUSYBB' : 999976 * 1.0 , # 'HiggsSUSYGluGlu': 981688 * 1.0 , # 'HiggsSUSYBB' : 996960 * 1.0 , # 'HiggsSUSYGluGlu': 985800 * 1.0 , # } ngenevts = { 'HiggsSUSYGluGlu110': 1000348 * 0.990003 , } #import pdb ; pdb.set_trace() for name in ngenevts.keys() : if name in self.cfg_comp.name : event.ntot = ngenevts[name] return True def selectionSequence(self, event, fillCounter, leg1IsoCut=None, leg2IsoCut=None): if fillCounter: self.counters.counter('DiLepton').inc('all events') if len(event.diLeptons) == 0: return False if fillCounter: self.counters.counter('DiLepton').inc('> 0 di-lepton') # testing di-lepton itself selDiLeptons = event.diLeptons if not self.leptonAccept( event.leptons ): return False if fillCounter: self.counters.counter('DiLepton').inc('lepton accept') if not hasattr( event, 'hltPaths'): event.hltPaths = [] #import pdb ; pdb.set_trace() matching = {} for trig in event.hltPaths : matching.update({trig:[-99,-99,-99]}) # {trigName:leg1,leg2,jet} event.diLeptonsTrigMatched = [] for trig in event.hltPaths : if self.cfg_comp.isEmbed : continue ## no matching for the embed selDiLeptons = event.diLeptons if len(self.cfg_comp.triggers)>0: # trigger matching leg1 selDiLeptons = [diL for diL in selDiLeptons if self.trigMatched(event, diL.leg1(), 'leg1', trig)] if len(selDiLeptons) == 0: matching[trig][0]=0 else: if fillCounter: self.counters.counter('DiLepton').inc('leg1 trig matched') matching[trig][0]=1 if len(self.cfg_comp.triggers)>0: # trigger matching leg2 selDiLeptons = [diL for diL in selDiLeptons if self.trigMatched(event, diL.leg2(), 'leg2', trig)] if len(selDiLeptons) == 0: matching[trig][1]=0 else: if fillCounter: self.counters.counter('DiLepton').inc('leg2 trig matched') matching[trig][1]=1 if len(self.cfg_comp.triggers)>0 and len(self.cfg_ana.triggerMap[ trig ])>2: # trigger matching jet cmgJets = self.handles['jets'].product() jets=[] for cmgJet in cmgJets: jet = Jet( cmgJet ) if self.testJet( jet ): jets.append(jet) selDiLeptonsNew=[] for diL in selDiLeptons: cleanJets, dummy = cleanObjectCollection( jets, masks = [ diL.leg1(), diL.leg2() ], deltaRMin = 0.5 ) if len(cleanJets)>0 and self.trigMatched(event, cleanJets[0], 'jet', trig): selDiLeptonsNew += [diL] selDiLeptons = selDiLeptonsNew if len(selDiLeptons) == 0: matching[trig][2]=0 else: if fillCounter: self.counters.counter('DiLepton').inc('jet trig matched') matching[trig][2]=1 event.diLeptonsTrigMatched += selDiLeptons event.diLeptonsTrigMatched = set(event.diLeptonsTrigMatched) ### need unix style wild card to macth different trigger versions in data for trig in matching.keys() : if fnm(trig,'HLT_DoubleMediumIsoPFTau35_Trk*_eta2p1_v*') : event.l1TrigMatched_diTau = matching[trig][0] event.l2TrigMatched_diTau = matching[trig][1] if fnm(trig,'HLT_DoubleMediumIsoPFTau*_Trk*_eta2p1_Jet30_v*') : event.l1TrigMatched_diTauJet = matching[trig][0] event.l2TrigMatched_diTauJet = matching[trig][1] event.jetTrigMatched_diTauJet = matching[trig][2] # testing leg1 selDiLeptons = [ diL for diL in selDiLeptons if self.testLeg( diL.leg1() ) ] if len(selDiLeptons) == 0: return False else: if fillCounter: self.counters.counter('DiLepton').inc('leg1 offline cuts passed') # testing leg2 selDiLeptons = [ diL for diL in selDiLeptons if self.testLeg( diL.leg2() ) ] if len(selDiLeptons) == 0: return False else: if fillCounter: self.counters.counter('DiLepton').inc('leg2 offline cuts passed') # mass cut selDiLeptons = [ diL for diL in selDiLeptons if self.testMass(diL) ] if len(selDiLeptons)==0: return False else: if fillCounter: self.counters.counter('DiLepton').inc('{min:3.1f} < m < {max:3.1f}'.format( min = self.cfg_ana.m_min, max = self.cfg_ana.m_max )) # exactly one? if len(selDiLeptons)==0: return False elif len(selDiLeptons)==1: if fillCounter: self.counters.counter('DiLepton').inc('exactly 1 di-lepton') event.diLepton = self.bestDiLepton( selDiLeptons ) event.leg1 = event.diLepton.leg1() event.leg2 = event.diLepton.leg2() # match with L1 particles, whether Central Jets or Taus L1Taus = self.handles['L1JetsTau'].product() L1Jets = self.handles['L1JetsCentral'].product() L1dR1T, L1dR2T, index1T, index2T = self.match(event.diLepton, L1Taus) L1dR1J, L1dR2J, index1J, index2J = self.match(event.diLepton, L1Jets) if L1dR1T < L1dR1J and L1dR1T<=0.5 : if L1Taus[index1T].pt()>44. and abs(L1Taus[index1T].eta())<2.1 : event.leg1.L1particle = L1Taus[index1T] if L1dR1J < L1dR1T and L1dR1J<=0.5 : if L1Jets[index1J].pt()>64. : event.leg1.L1particle = L1Jets[index1J] if L1dR2T < L1dR2J and L1dR2T<=0.5 : if L1Taus[index2T].pt()>44. and abs(L1Taus[index2T].eta())<2.1 : event.leg2.L1particle = L1Taus[index2T] if L1dR2J < L1dR2T and L1dR2J<=0.5 : if L1Jets[index2J].pt()>64. : event.leg2.L1particle = L1Jets[index2J] ### require trigger bit in Embedded RecHit if self.cfg_comp.isEmbed : #if len(event.hltPath)==0 : return False if not event.hltPath : return False #import pdb ; pdb.set_trace() return True def testLeg(self, leg): leg_pt = self.cfg_ana.pt leg_eta = self.cfg_ana.eta iso = self.cfg_ana.isolation if iso == 'mva' : #### Tau ID MVA test_leg_iso = leg.tauID("byRawIsoMVA") > 0.5 # 0.884 if iso == 'mva2' : #### Tau ID MVA2 test_leg_iso = leg.tauID("byIsolationMVA2raw") > 0.5 # 0.90 if iso == 'db3h' : #### Tau ID deltaBeta 3 hits test_leg_iso = leg.tauID("byCombinedIsolationDeltaBetaCorrRaw3Hits") < 10. #15. return (test_leg_iso and \ leg.pt()>leg_pt and abs(leg.eta()) < leg_eta and \ leg.tauID("decayModeFinding") > 0.5 and \ leg.tauID("againstElectronLoose") > 0.5 and \ leg.tauID("againstMuonLoose") > 0.5) def testLooseLeg(self, leg): leg_pt = self.cfg_ana.pt leg_eta = self.cfg_ana.eta iso = self.cfg_ana.isolation if iso == 'mva' : #### Tau ID MVA test_leg_iso = leg.tauID("byRawIsoMVA") > 0.5 if iso == 'mva2' : #### Tau ID MVA2 test_leg_iso = leg.tauID("byIsolationMVA2raw") > 0.5 if iso == 'db3h' : #### Tau ID deltaBeta 3 hits test_leg_iso = leg.tauID("byCombinedIsolationDeltaBetaCorrRaw3Hits") < 10. #15. return (test_leg_iso and \ leg.pt()>leg_pt and abs(leg.eta()) < leg_eta and \ leg.tauID("decayModeFinding") > 0.5 and \ leg.tauID("againstElectronLoose") > 0.5 and \ leg.tauID("againstMuonLoose") > 0.5) def passAntiEMVA(self, iCat, raw, WP=0) : iCat = int(iCat) if iCat<0 : return False if iCat>15 : return True cutsLoose = [0.835,0.831,0.849,0.859,0.873,0.823,0.85 ,0.855,0.816,0.861,0.862,0.847,0.893,0.82 ,0.845,0.851] cutsMedium = [0.933,0.921,0.944,0.945,0.918,0.941,0.981,0.943,0.956,0.947,0.951,0.95 ,0.897,0.958,0.955,0.942] cutsTight = [ 0.96,0.968,0.971,0.972,0.969,0.959,0.981,0.965,0.975,0.972,0.974,0.971,0.897,0.971,0.961,0.97 ] cutsVeryTight = [0.978,0.98 ,0.982,0.985,0.977,0.974,0.989,0.977,0.986,0.983,0.984,0.983,0.971,0.987,0.977,0.981] cut = 0 if WP==0 : cut = cutsLoose[iCat] if WP==1 : cut = cutsMedium[iCat] if WP==2 : cut = cutsTight[iCat] if WP==3 : cut = cutsVeryTight[iCat] return (raw>cut) def muonIso(self, muon ): '''dbeta corrected pf isolation with all charged particles instead of charged hadrons''' return muon.relIsoAllChargedDB05() def testLeg2ID(self, muon): '''Tight muon selection, no isolation requirement''' return muon.tightId() and \ self.testVertex( muon ) def testLeg2Iso(self, muon, isocut): '''Tight muon selection, with isolation requirement''' if isocut is None: isocut = self.cfg_ana.iso2 return self.muonIso(muon)<isocut def testVertex(self, lepton): '''Tests vertex constraints, for mu and tau''' return abs(lepton.dxy()) < 0.045 and \ abs(lepton.dz()) < 0.2 def testMuonIDLoose(self, muon): '''Loose muon ID and kine, no isolation requirement, for lepton veto''' return muon.pt() > 15 and \ abs( muon.eta() ) < 2.4 and \ muon.isGlobalMuon() and \ muon.isTrackerMuon() and \ muon.sourcePtr().userFloat('isPFMuon') and \ abs(muon.dz()) < 0.2 def buildMuons(self, cmgLeptons, event): '''Build muons for veto, associate best vertex, select loose ID muons. The loose ID selection is done to ensure that the muon has an inner track.''' leptons = [] for index, lep in enumerate(cmgLeptons): pyl = Muon(lep) pyl.associatedVertex = event.goodVertices[0] if not self.testMuonIDLoose( pyl ): continue leptons.append( pyl ) return leptons def buildElectrons(self, cmgOtherLeptons, event): '''Build electrons for third lepton veto, associate best vertex. ''' otherLeptons = [] for index, lep in enumerate(cmgOtherLeptons): pyl = Electron(lep) pyl.associatedVertex = event.goodVertices[0] #COLINTLV check ID # if not self.testMuonIDLoose(pyl): # continue otherLeptons.append( pyl ) return otherLeptons def trigMatched(self, event, leg, legName, trigpath): '''Returns true if the leg is matched to a trigger object as defined in the triggerMap parameter''' if not hasattr( self.cfg_ana, 'triggerMap'): return True #path = event.hltPath this works if you have only one path path = trigpath #import pdb ; pdb.set_trace() triggerObjects = event.triggerObjects filters = self.cfg_ana.triggerMap[ path ] filter = None if legName == 'leg1': filter = filters[0] elif legName == 'leg2': filter = filters[1] elif legName == 'jet': filter = filters[2] else: raise ValueError( 'legName should be leg1 or leg2, not {leg}'.format( leg=legName ) ) # the default dR2Max value is 0.3^2 pdgIds = None if len(filter) == 2: filter, pdgIds = filter[0], filter[1] return triggerMatched(leg, triggerObjects, path, filter, dR2Max=0.5*0.5,dRMax=0.5, pdgIds=pdgIds ) def testJetID(self, jet): #jet.puJetIdPassed = jet.puJetId() jet.puJetIdPassed = jet.puJetId53X() jet.pfJetIdPassed = jet.looseJetId() #jet.pfJetIdPassed = jet.getSelection('cuts_looseJetId') if self.cfg_ana.relaxJetId: return True else: return jet.puJetIdPassed and jet.pfJetIdPassed def testJet( self, jet ): # 2 is loose pile-up jet id return jet.pt() > self.cfg_ana.jetPt and \ abs( jet.eta() ) < self.cfg_ana.jetEta and \ self.testJetID(jet) # jet.passPuJetId('full', 2) def match(self, myPair, genParticles): dR2leg1Min = 999. dR2leg2Min = 999. dR2leg1 = 999. dR2leg2 = 999. index1 = -99 index2 = -99 for index, genPart in enumerate(genParticles) : dR2leg1 = deltaR2(myPair.leg1().eta(), myPair.leg1().phi(), genPart.eta(), genPart.phi() ) dR2leg2 = deltaR2(myPair.leg2().eta(), myPair.leg2().phi(), genPart.eta(), genPart.phi() ) if dR2leg1 < dR2leg1Min: dR2leg1Min = dR2leg1 index1 = index if dR2leg2 < dR2leg2Min: dR2leg2Min = dR2leg2 index2 = index self.leg1DeltaR = math.sqrt( dR2leg1Min ) self.leg2DeltaR = math.sqrt( dR2leg2Min ) self.index1 = index1 self.index2 = index2 return (self.leg1DeltaR, self.leg2DeltaR, self.index1, self.index2) def splitDYJets( self, event, genParticles, myPair, require_status = True, bosons = [23,25,35,36]) : ## require_status: yes, status==3 for MCs, but status may vary for emb, therefore it is switched off ## PDG Id: e 11, mu 13, tau 15, Z 23, h 25, H 35, A 36, H+ 37 ## DYJets sample gets split by gen matching and ## Higgs samples are given a flag (isZtt) to require reco taus matched to gen taus ## flag to split DYJets into ZTT, ZL, ZJ event.isZtt = False ## two taus gen matched event.isZttj = False ## two taus that fail the matching event.isZee = False ## two electrons, both fake taus event.isZmm = False ## two muons, both fake taus event.isZttll = False ## ZTT->LL, both lepton fake taus event.isZj = False ## whatever else ## lists with the index of Z boson's daughters genTausFromZ = [] genMuonsFromZ = [] genElectronsFromZ = [] genLeptonsFromTaus = [] for index, gen in enumerate(genParticles): status = gen.status() id = gen.pdgId() motherId = 0 if gen.numberOfMothers()>0 : motherId = gen.mother().pdgId() if ((not require_status) or status==3) and abs(id)==15 and abs(motherId) in bosons : genTausFromZ.append(index) if ((not require_status) or status==3) and abs(id)==13 and abs(motherId) in bosons : genMuonsFromZ.append(index) if ((not require_status) or status==3) and abs(id)==11 and abs(motherId) in bosons : genElectronsFromZ.append(index) if ((not require_status) or status==3) and abs(id)==11 and abs(motherId)==15 : genLeptonsFromTaus.append(index) if ((not require_status) or status==3) and abs(id)==13 and abs(motherId)==15 : genLeptonsFromTaus.append(index) if abs(gen.pdgId()) in [23] : event.hasW = True if abs(gen.pdgId()) in [24] : event.hasZ = True if abs(gen.pdgId()) in [23, 25, 35, 36, 37] : event.genMass = gen.mass() if len(genTausFromZ) == 2 : ##### we don't match the embedded and therefore we don't match the DY->TT #event.isZtt = True ##### now we do 26/8/2013 leg1TauDR, leg2TauDR, dummy, dummy = self.match( myPair, [ genParticles[genTausFromZ[0]],genParticles[genTausFromZ[1]] ] ) if leg1TauDR < 0.3 : myPair.leg1().genl = genParticles[genTausFromZ[0]] if leg2TauDR < 0.3 : myPair.leg2().genl = genParticles[genTausFromZ[1]] if leg1TauDR < 0.3 and leg2TauDR < 0.3 : event.isZtt = True else : event.isZttj = True elif len(genMuonsFromZ) == 2 : leg1MuDR, leg2MuDR, dummy, dummy = self.match( myPair, [ genParticles[genMuonsFromZ[0]],genParticles[genMuonsFromZ[1]] ] ) if leg1MuDR < 0.3 : myPair.leg1().genl = genParticles[genMuonsFromZ[0]] if leg2MuDR < 0.3 : myPair.leg2().genl = genParticles[genMuonsFromZ[1]] if leg1MuDR < 0.3 and leg2MuDR < 0.3 : event.isZmm = True elif len(genElectronsFromZ) == 2 : leg1ElDR, leg2ElDR, dummy, dummy = self.match( myPair, [ genParticles[genElectronsFromZ[0]],genParticles[genElectronsFromZ[1]] ] ) if leg1ElDR < 0.3 : myPair.leg1().genl = genParticles[genElectronsFromZ[0]] if leg2ElDR < 0.3 : myPair.leg2().genl = genParticles[genElectronsFromZ[1]] if leg1ElDR < 0.3 and leg2ElDR < 0.3 : event.isZee = True elif len(genLeptonsFromTaus) == 2 : leg1LepDR, leg2LepDR, dummy, dummy = self.match( myPair, [ genParticles[genLeptonsFromTaus[0]],genParticles[genLeptonsFromTaus[1]] ] ) if leg1LepDR < 0.3 : myPair.leg1().genl = genParticles[genLeptonsFromTaus[0]] if leg2LepDR < 0.3 : myPair.leg2().genl = genParticles[genLeptonsFromTaus[1]] if leg1LepDR < 0.3 and leg2LepDR < 0.3 : event.isZttll = True ## needs to be rerun with all samples #if not(event.isZtt or event.isZee or event.isZmm or event.isZttll or event.isZttj) : if not(event.isZtt or event.isZee or event.isZmm) : event.isZj = True
class TauTauAnalyzer(DiLeptonAnalyzer): DiObjectClass = TauTau LeptonClass = Tau def declareHandles(self): super(TauTauAnalyzer, self).declareHandles() #self.handles['diLeptons'] = AutoHandle( 'cmgDiTauCorSVFitFullSel' , 'std::vector<cmg::DiObject<cmg::Tau,cmg::Tau> >' ) ## old object #self.handles['mvametsigs'] = AutoHandle( 'mvaMETDiTau' , 'std::vector<cmg::METSignificance>' ) self.handles['diLeptons'] = AutoHandle( 'cmgDiTauCorSVFitFullSel', 'std::vector<cmg::DiTauObject<cmg::Tau,cmg::Tau> >' ) ## new object by Jan self.handles['rawMET'] = AutoHandle('cmgPFMETRaw', 'std::vector<cmg::BaseMET>') self.handles['jets'] = AutoHandle('cmgPFJetSel', 'std::vector<cmg::PFJet>') self.handles['electrons'] = AutoHandle('cmgElectronSel', 'std::vector<cmg::Electron>') self.handles['muons'] = AutoHandle('cmgMuonSel', 'std::vector<cmg::Muon>') self.handles['triggerResults'] = AutoHandle( ('TriggerResults', '', 'HLT'), 'edm::TriggerResults') self.handles['metSig'] = AutoHandle('pfMetSignificance', 'cmg::METSignificance') self.handles['L1JetsCentral'] = AutoHandle( ('l1extraParticles', 'Central', 'RECO'), 'vector<l1extra::L1JetParticle>') self.handles['L1JetsTau'] = AutoHandle( ('l1extraParticles', 'Tau', 'RECO'), 'vector<l1extra::L1JetParticle>') if self.cfg_comp.isMC and ("DY" in self.cfg_comp.name or "W" in self.cfg_comp.name or ("TTJets" in self.cfg_comp.name and 'emb' not in self.cfg_comp.name) or "Higgs" in self.cfg_comp.name and not "WW" in self.cfg_comp.name and not "WZ" in self.cfg_comp.name): self.mchandles['genParticles'] = AutoHandle( 'genParticlesPruned', 'std::vector<reco::GenParticle>') if self.cfg_comp.isMC and "QCD" in self.cfg_comp.name: self.mchandles['generator'] = AutoHandle('generator', 'GenEventInfoProduct') if self.cfg_comp.isMC and ("DY" in self.cfg_comp.name or "W" in self.cfg_comp.name and not "WW" in self.cfg_comp.name and not "WZ" in self.cfg_comp.name and not "_new" in self.cfg_comp.name): self.mchandles['source'] = AutoHandle('source', 'LHEEventProduct') #if self.cfg_comp.isEmb or self.cfg_comp.name == "TTJets_emb" : if 'emb' in self.cfg_comp.name: self.embhandles['genParticlesEmb'] = AutoHandle( ('genParticles', '', 'EmbeddedRECO'), 'std::vector<reco::GenParticle>') self.triggers = [ 'HLT_LooseIsoPFTau35_Trk20_Prong1_v6', 'HLT_LooseIsoPFTau35_Trk20_Prong1_MET70_v6', 'HLT_LooseIsoPFTau35_Trk20_Prong1_MET75_v6', 'HLT_DoubleMediumIsoPFTau30_Trk5_eta2p1_Jet30_v2', 'HLT_DoubleMediumIsoPFTau30_Trk5_eta2p1_v2', 'HLT_DoubleMediumIsoPFTau35_Trk5_eta2p1_v6', 'HLT_DoubleMediumIsoPFTau35_Trk5_eta2p1_Prong1_v6', ] self.triggersEmb = [ 'HLT_Mu17_Mu8_v16', 'HLT_Mu17_Mu8_v17', 'HLT_Mu17_Mu8_v18', 'HLT_Mu17_Mu8_v19', 'HLT_Mu17_Mu8_v21', 'HLT_Mu17_Mu8_v21', 'HLT_Mu17_Mu8_v22', ] self.triggers += self.triggersEmb ###### PT HIGGS REWEIGHTING if "HiggsGGH" in self.cfg_comp.name: masspoint = re.findall(r"(\d{2,3})", self.cfg_comp.name) masspoint = str(masspoint[0]) self.higgsPtWeightFile = TFile( "$CMSSW_BASE/src/CMGTools/H2TauTau/data/weight_ptH_" + masspoint + "_8TeV.root") self.higgsPtWeightHistogramNom = self.higgsPtWeightFile.Get( "Nominal") self.higgsPtWeightHistogramUp = self.higgsPtWeightFile.Get("Up") self.higgsPtWeightHistogramDown = self.higgsPtWeightFile.Get( "Down") def beginLoop(self): super(TauTauAnalyzer, self).beginLoop() self.counters = Counters() self.counters.addCounter('DiLepton') count = self.counters.counter('DiLepton') count.register('all events') count.register('> 0 di-lepton') count.register('lepton accept') count.register('third lepton veto') count.register('leg1 trig matched') count.register('leg2 trig matched') count.register('jet trig matched') count.register('leg1 offline cuts passed') count.register('leg2 offline cuts passed') count.register('{min:3.1f} < m < {max:3.1f}'.format( min=self.cfg_ana.m_min, max=self.cfg_ana.m_max)) count.register('exactly 1 di-lepton') def bestDiLepton(self, diLeptons): '''Returns the best diLepton (the one with best isolation).''' iso = self.cfg_ana.isolation if iso == 'mva': #### Tau ID MVA return max([(min(dilep.leg1().tauID("byRawIsoMVA"), dilep.leg2().tauID("byRawIsoMVA")), dilep) for dilep in diLeptons])[1] if iso == 'mva2': #### Tau ID MVA2 return max([(min(dilep.leg1().tauID("byIsolationMVA2raw"), dilep.leg2().tauID("byIsolationMVA2raw")), dilep) for dilep in diLeptons])[1] if iso == 'db3h': #### Tau ID deltaBeta 3 hits return min([(max( dilep.leg1().tauID("byCombinedIsolationDeltaBetaCorrRaw3Hits"), dilep.leg2().tauID( "byCombinedIsolationDeltaBetaCorrRaw3Hits")), dilep) for dilep in diLeptons])[1] #### highest sum pt pair #return max( [ (dilep.sumPt(), dilep) for dilep in diLeptons ] )[1] def process(self, iEvent, event): # select signal dileptons with all cuts on both legs if 'TTJets_emb' in self.cfg_comp.name: self.cfg_comp.isEmbed = True self.readCollections(iEvent) # trigger stuff could be put in a separate analyzer # event.triggerObject = self.handles['cmgTriggerObjectSel'].product()[0] event.diLeptons = self.buildDiLeptons( self.handles['diLeptons'].product(), event) #event.leptons = self.buildLeptons( self.handles['leptons'].product(), event ) event.leptons = [] for diLepton in event.diLeptons: if not diLepton.leg1() in event.leptons: event.leptons += [diLepton.leg1()] if not diLepton.leg2() in event.leptons: event.leptons += [diLepton.leg2()] self.shiftEnergyScale(event) event.rawMET = self.handles['rawMET'].product() triggerResults = self.handles['triggerResults'].product() triggerNames = iEvent._event.triggerNames(triggerResults) #event.hltPath = [] for trig in self.triggers: index = triggerNames.triggerIndex(trig) if index >= triggerNames.size(): trigres = -1 else: trigres = triggerResults.accept(index) #event.hltPath.append(trig) setattr(event, trig, trigres) result = self.selectionSequence(event, fillCounter=True) # select non signal dileptons with loose cuts if result is False: selDiLeptons = [ diL for diL in event.diLeptonsTrigMatched if \ self.cfg_ana.m_min < diL.mass() and diL.mass() < self.cfg_ana.m_max and \ self.testLooseLeg( diL.leg1() ) and self.testLooseLeg( diL.leg2() ) and \ (self.testLeg( diL.leg1() ) or self.testLeg( diL.leg2() )) ] if len(selDiLeptons) == 0: selDiLeptons = [ diL for diL in event.diLeptons if \ self.cfg_ana.m_min < diL.mass() and diL.mass() < self.cfg_ana.m_max and \ self.testLooseLeg( diL.leg1() ) and self.testLooseLeg( diL.leg2() ) and \ (self.testLeg( diL.leg1() ) or self.testLeg( diL.leg2() )) ] if len(selDiLeptons) == 0: return False event.diLepton = self.bestDiLepton(selDiLeptons) event.leg1 = event.diLepton.leg1() event.leg2 = event.diLepton.leg2() event.isSignal = False else: event.isSignal = True #if event.eventId in notPassed : # print 'diLeptons built, is Signal?', result # import pdb ; pdb.set_trace() #if len([event.diLepton])>1 : #import pdb ; pdb.set_trace() event.leg1.NewLooseAntiEleMVA3 = self.passAntiEMVA( iCat=event.diLepton.leg1().tauID("againstElectronMVA3category"), raw=event.diLepton.leg1().tauID("againstElectronMVA3raw"), WP=0) event.leg2.NewLooseAntiEleMVA3 = self.passAntiEMVA( iCat=event.diLepton.leg2().tauID("againstElectronMVA3category"), raw=event.diLepton.leg2().tauID("againstElectronMVA3raw"), WP=0) # count muons event.muons = [ lep for lep in self.buildMuons(self.handles['muons'].product(), event) if self.testLegKine(lep, ptcut=10, etacut=2.4) and self.testLeg2ID(lep) and self.testLeg2Iso(lep, 0.3) ] # count electrons event.electrons = [ electron for electron in self.buildElectrons( self.handles['electrons'].product(), event) if self.testLegKine(electron, ptcut=10, etacut=2.5) and electron.looseIdForTriLeptonVeto() and self.testVertex( electron) and electron.relIsoAllChargedDB05() < 0.3 ] ####### what ID for veto means ####### http://cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/UserCode/CMG/CMGTools/RootTools/python/physicsobjects/HTauTauElectron.py?revision=1.10&view=markup #import pdb ; pdb.set_trace() if self.cfg_comp.isEmbed or "TTJets_emb" in self.cfg_comp.name: genParticles = self.embhandles['genParticlesEmb'].product() self.splitDYJets(event, genParticles, event.diLepton, require_status=False) if self.cfg_comp.isMC and ("DY" in self.cfg_comp.name or "W" in self.cfg_comp.name and not "WW" in self.cfg_comp.name and not "WZ" in self.cfg_comp.name and not "_new" in self.cfg_comp.name): event.NUP = self.mchandles['source'].product().hepeup().NUP else: event.NUP = -1 event.genMatched = None if self.cfg_comp.isMC and ("DY" in self.cfg_comp.name or "Higgs" in self.cfg_comp.name): genParticles = self.mchandles['genParticles'].product() event.genParticles = map(GenParticle, genParticles) # useless now leg1DeltaR, leg2DeltaR = event.diLepton.match(event.genParticles) event.leg1DeltaR = leg1DeltaR event.leg2DeltaR = leg2DeltaR if leg1DeltaR>-1 and leg1DeltaR < 0.3 and \ leg2DeltaR>-1 and leg2DeltaR < 0.3 : event.genMatched = True else: event.genMatched = False self.splitDYJets(event, genParticles, event.diLepton) event.isPhoton = False event.isElectron = False for gen in genParticles: if abs(gen.pdgId()) == 15 and abs( gen.mother().pdgId()) == 23 and ( gen.mother().mass() < 80 or gen.mother().mass() > 100): event.isPhoton = True if abs(gen.pdgId()) == 13 and abs(gen.mother().pdgId()) == 23: event.isMuon = True if abs(gen.pdgId()) == 11 and abs(gen.mother().pdgId()) == 23: event.isElectron = True #import pdb ; pdb.set_trace() if self.cfg_comp.isMC and "W" in self.cfg_comp.name: genParticles = self.mchandles['genParticles'].product() event.genParticles = map(GenParticle, genParticles) genTaus = [] event.genMatched = False event.genMatchedElectron = False event.genMatchedMuon = False for gen in genParticles: if abs(gen.pdgId()) in [11, 13, 15] and abs( gen.mother().pdgId()) == 24: # W -> tau nu genTaus.append(gen) if len(genTaus) >= 1: dR2leg1Min, event.diLepton.leg1Gen = (float('inf'), None) dR2leg2Min, event.diLepton.leg2Gen = (float('inf'), None) for genTau in genTaus: dR2leg1 = deltaR2(event.diLepton.leg1().eta(), event.diLepton.leg1().phi(), genTau.eta(), genTau.phi()) dR2leg2 = deltaR2(event.diLepton.leg2().eta(), event.diLepton.leg2().phi(), genTau.eta(), genTau.phi()) if dR2leg1 < dR2leg1Min: dR2leg1Min, event.diLepton.leg1Gen = (dR2leg1, genTau) if dR2leg2 < dR2leg2Min: dR2leg2Min, event.diLepton.leg2Gen = (dR2leg2, genTau) leg1DeltaR = math.sqrt(dR2leg1Min) leg2DeltaR = math.sqrt(dR2leg2Min) if ((leg1DeltaR>-1 and leg1DeltaR < 0.1) or \ (leg2DeltaR>-1 and leg2DeltaR < 0.1)) and abs(genTau.pdgId())==11: event.genMatchedElectron = True if ((leg1DeltaR>-1 and leg1DeltaR < 0.1) or \ (leg2DeltaR>-1 and leg2DeltaR < 0.1)) and abs(genTau.pdgId())==13: event.genMatchedMuon = True if ((leg1DeltaR>-1 and leg1DeltaR < 0.1) or \ (leg2DeltaR>-1 and leg2DeltaR < 0.1)) and abs(genTau.pdgId())==15: event.genMatched = True event.isElectron = False event.isMuon = False event.isTau = False for gen in genParticles: if abs(gen.pdgId()) == 11 and abs(gen.mother().pdgId()) == 24: event.isElectron = True if abs(gen.pdgId()) == 13 and abs(gen.mother().pdgId()) == 24: event.isMuon = True if abs(gen.pdgId()) == 15 and abs(gen.mother().pdgId()) == 24: event.isTau = True #import pdb ; pdb.set_trace() if self.cfg_comp.isMC and "TTJets_emb" not in self.cfg_comp.name: genParticles = self.mchandles['genParticles'].product() event.genParticles = map(GenParticle, genParticles) genTaus = [] event.genMatched = 0 event.genMatchedElectron = 0 event.genMatchedMuon = 0 for gen in genParticles: if abs(gen.pdgId()) in [11, 13, 15] and abs( gen.mother().pdgId()) == 24: # W -> tau nu genTaus.append(gen) if len(genTaus) >= 1: dR2leg1Min, event.diLepton.leg1Gen = (float('inf'), None) dR2leg2Min, event.diLepton.leg2Gen = (float('inf'), None) for genTau in genTaus: dR2leg1 = deltaR2(event.diLepton.leg1().eta(), event.diLepton.leg1().phi(), genTau.eta(), genTau.phi()) dR2leg2 = deltaR2(event.diLepton.leg2().eta(), event.diLepton.leg2().phi(), genTau.eta(), genTau.phi()) if dR2leg1 < dR2leg1Min: dR2leg1Min, event.diLepton.leg1Gen = (dR2leg1, genTau) if dR2leg2 < dR2leg2Min: dR2leg2Min, event.diLepton.leg2Gen = (dR2leg2, genTau) leg1DeltaR = math.sqrt(dR2leg1Min) leg2DeltaR = math.sqrt(dR2leg2Min) if (leg1DeltaR > -1 and leg1DeltaR < 0.1) and abs( genTau.pdgId()) == 11: event.genMatchedElectron += 1 if (leg1DeltaR > -1 and leg1DeltaR < 0.1) and abs( genTau.pdgId()) == 13: event.genMatchedMuon += 1 if (leg1DeltaR > -1 and leg1DeltaR < 0.1) and abs( genTau.pdgId()) == 15: event.genMatched += 1 if (leg2DeltaR > -1 and leg2DeltaR < 0.1) and abs( genTau.pdgId()) == 11: event.genMatchedElectron += 1 if (leg2DeltaR > -1 and leg2DeltaR < 0.1) and abs( genTau.pdgId()) == 13: event.genMatchedMuon += 1 if (leg2DeltaR > -1 and leg2DeltaR < 0.1) and abs( genTau.pdgId()) == 15: event.genMatched += 1 event.isElectron = 0 event.isMuon = 0 event.isTau = 0 for gen in genParticles: if abs(gen.pdgId()) == 11 and abs(gen.mother().pdgId()) == 24: event.isElectron += 1 if abs(gen.pdgId()) == 13 and abs(gen.mother().pdgId()) == 24: event.isMuon += 1 if abs(gen.pdgId()) == 15 and abs(gen.mother().pdgId()) == 24: event.isTau += 1 if self.cfg_comp.isMC and "QCD" in self.cfg_comp.name: generator = self.mchandles['generator'].product() event.generatorWeight = generator.weight() event.eventWeight *= event.generatorWeight #import pdb ; pdb.set_trace() if self.cfg_comp.isMC and "HiggsGGH" in self.cfg_comp.name: genParticles = self.mchandles['genParticles'].product() event.genParticles = map(GenParticle, genParticles) higgsPt = -1 for gen in genParticles: if abs(gen.pdgId()) == 25: higgsPt = gen.pt() break event.higgsPtWeightNom = self.higgsPtWeightHistogramNom.GetBinContent( self.higgsPtWeightHistogramNom.FindBin(higgsPt)) event.higgsPtWeightUp = self.higgsPtWeightHistogramUp.GetBinContent( self.higgsPtWeightHistogramUp.FindBin(higgsPt)) event.higgsPtWeightDown = self.higgsPtWeightHistogramDown.GetBinContent( self.higgsPtWeightHistogramDown.FindBin(higgsPt)) else: event.higgsPtWeightNom = 1. event.higgsPtWeightUp = 1. event.higgsPtWeightDown = 1. ## third lepton veto if len(event.muons) + len(event.electrons) > 0: return False if ("DY" in self.cfg_comp.name and event.isZtt) or "Higgs" in self.cfg_comp.name or ( self.cfg_comp.isEmbed and event.isZtt): event.isRealTau = 1 else: event.isRealTau = 0 if not hasattr(event, 'NJetWeight'): event.NJetWeight = 1. #import pdb ; pdb.set_trace() if ("DY" in self.cfg_comp.name and event.isZtt) or "Higgs" in self.cfg_comp.name or ( self.cfg_comp.isEmbed and event.isZtt): if event.leg1.decayMode() == 0: event.leg1.prongWeight = 0.88 else: event.leg1.prongWeight = 1. if event.leg2.decayMode() == 0: event.leg2.prongWeight = 0.88 else: event.leg2.prongWeight = 1. #import pdb ; pdb.set_trace() #event.name = self.cfg_comp.name #import pdb ; pdb.set_trace() event.metsig = self.handles['metSig'].product() event.ntot = 1. # ngenevts = { 'W1Jets' : 23141598.* 1.0 , # 'W2Jets' : 34044921.* 1.0 , # 'W3Jets' : 15539503.* 0.997191011236, # 'W4Jets' : 13382803.* 0.996168582375, # #'WJets' : 18393090 * 1.0 , # 'WJets' : 57709905.* 1.0 , # 'HiggsGGH125' : 968134. * 1.0 , # 'HiggsVBF125' : 998836. * 1.0 , # 'TTJetsFullLept' : 12011428 * 1.0 , # 'TTJetsHadronic' : 31223821 * 1.0 , # 'TTJetsSemiLept' : 24953451 * 1.0 , # 'DYJets' : 30459503 * 1.0 , # 'HiggsSUSYBB' : 999976 * 1.0 , # 'HiggsSUSYGluGlu': 981688 * 1.0 , # 'HiggsSUSYBB' : 996960 * 1.0 , # 'HiggsSUSYGluGlu': 985800 * 1.0 , # } ngenevts = { 'HiggsSUSYGluGlu110': 1000348 * 0.990003, } #import pdb ; pdb.set_trace() for name in ngenevts.keys(): if name in self.cfg_comp.name: event.ntot = ngenevts[name] return True def selectionSequence(self, event, fillCounter, leg1IsoCut=None, leg2IsoCut=None): if fillCounter: self.counters.counter('DiLepton').inc('all events') if len(event.diLeptons) == 0: return False if fillCounter: self.counters.counter('DiLepton').inc('> 0 di-lepton') # testing di-lepton itself selDiLeptons = event.diLeptons if not self.leptonAccept(event.leptons): return False if fillCounter: self.counters.counter('DiLepton').inc('lepton accept') if not hasattr(event, 'hltPaths'): event.hltPaths = [] #import pdb ; pdb.set_trace() matching = {} for trig in event.hltPaths: matching.update({trig: [-99, -99, -99]}) # {trigName:leg1,leg2,jet} event.diLeptonsTrigMatched = [] for trig in event.hltPaths: if self.cfg_comp.isEmbed: continue ## no matching for the embed selDiLeptons = event.diLeptons if len(self.cfg_comp.triggers) > 0: # trigger matching leg1 selDiLeptons = [ diL for diL in selDiLeptons if self.trigMatched(event, diL.leg1(), 'leg1', trig) ] if len(selDiLeptons) == 0: matching[trig][0] = 0 else: if fillCounter: self.counters.counter('DiLepton').inc( 'leg1 trig matched') matching[trig][0] = 1 if len(self.cfg_comp.triggers) > 0: # trigger matching leg2 selDiLeptons = [ diL for diL in selDiLeptons if self.trigMatched(event, diL.leg2(), 'leg2', trig) ] if len(selDiLeptons) == 0: matching[trig][1] = 0 else: if fillCounter: self.counters.counter('DiLepton').inc( 'leg2 trig matched') matching[trig][1] = 1 if len(self.cfg_comp.triggers) > 0 and len( self.cfg_ana.triggerMap[trig]) > 2: # trigger matching jet cmgJets = self.handles['jets'].product() jets = [] for cmgJet in cmgJets: jet = Jet(cmgJet) if self.testJet(jet): jets.append(jet) selDiLeptonsNew = [] for diL in selDiLeptons: cleanJets, dummy = cleanObjectCollection( jets, masks=[diL.leg1(), diL.leg2()], deltaRMin=0.5) if len(cleanJets) > 0 and self.trigMatched( event, cleanJets[0], 'jet', trig): selDiLeptonsNew += [diL] selDiLeptons = selDiLeptonsNew if len(selDiLeptons) == 0: matching[trig][2] = 0 else: if fillCounter: self.counters.counter('DiLepton').inc( 'jet trig matched') matching[trig][2] = 1 event.diLeptonsTrigMatched += selDiLeptons event.diLeptonsTrigMatched = set(event.diLeptonsTrigMatched) ### need unix style wild card to macth different trigger versions in data for trig in matching.keys(): if fnm(trig, 'HLT_DoubleMediumIsoPFTau35_Trk*_eta2p1_v*'): event.l1TrigMatched_diTau = matching[trig][0] event.l2TrigMatched_diTau = matching[trig][1] if fnm(trig, 'HLT_DoubleMediumIsoPFTau*_Trk*_eta2p1_Jet30_v*'): event.l1TrigMatched_diTauJet = matching[trig][0] event.l2TrigMatched_diTauJet = matching[trig][1] event.jetTrigMatched_diTauJet = matching[trig][2] # testing leg1 selDiLeptons = [ diL for diL in selDiLeptons if self.testLeg(diL.leg1()) ] if len(selDiLeptons) == 0: return False else: if fillCounter: self.counters.counter('DiLepton').inc( 'leg1 offline cuts passed') # testing leg2 selDiLeptons = [ diL for diL in selDiLeptons if self.testLeg(diL.leg2()) ] if len(selDiLeptons) == 0: return False else: if fillCounter: self.counters.counter('DiLepton').inc( 'leg2 offline cuts passed') # mass cut selDiLeptons = [diL for diL in selDiLeptons if self.testMass(diL)] if len(selDiLeptons) == 0: return False else: if fillCounter: self.counters.counter('DiLepton').inc( '{min:3.1f} < m < {max:3.1f}'.format( min=self.cfg_ana.m_min, max=self.cfg_ana.m_max)) # exactly one? if len(selDiLeptons) == 0: return False elif len(selDiLeptons) == 1: if fillCounter: self.counters.counter('DiLepton').inc('exactly 1 di-lepton') event.diLepton = self.bestDiLepton(selDiLeptons) event.leg1 = event.diLepton.leg1() event.leg2 = event.diLepton.leg2() # match with L1 particles, whether Central Jets or Taus L1Taus = self.handles['L1JetsTau'].product() L1Jets = self.handles['L1JetsCentral'].product() L1dR1T, L1dR2T, index1T, index2T = self.match(event.diLepton, L1Taus) L1dR1J, L1dR2J, index1J, index2J = self.match(event.diLepton, L1Jets) if L1dR1T < L1dR1J and L1dR1T <= 0.5: if L1Taus[index1T].pt() > 44. and abs(L1Taus[index1T].eta()) < 2.1: event.leg1.L1particle = L1Taus[index1T] if L1dR1J < L1dR1T and L1dR1J <= 0.5: if L1Jets[index1J].pt() > 64.: event.leg1.L1particle = L1Jets[index1J] if L1dR2T < L1dR2J and L1dR2T <= 0.5: if L1Taus[index2T].pt() > 44. and abs(L1Taus[index2T].eta()) < 2.1: event.leg2.L1particle = L1Taus[index2T] if L1dR2J < L1dR2T and L1dR2J <= 0.5: if L1Jets[index2J].pt() > 64.: event.leg2.L1particle = L1Jets[index2J] ### require trigger bit in Embedded RecHit if self.cfg_comp.isEmbed: #if len(event.hltPath)==0 : return False if not event.hltPath: return False #import pdb ; pdb.set_trace() return True def testLeg(self, leg): leg_pt = self.cfg_ana.pt leg_eta = self.cfg_ana.eta iso = self.cfg_ana.isolation if iso == 'mva': #### Tau ID MVA test_leg_iso = leg.tauID("byRawIsoMVA") > 0.5 # 0.884 if iso == 'mva2': #### Tau ID MVA2 test_leg_iso = leg.tauID("byIsolationMVA2raw") > 0.5 # 0.90 if iso == 'db3h': #### Tau ID deltaBeta 3 hits test_leg_iso = leg.tauID( "byCombinedIsolationDeltaBetaCorrRaw3Hits") < 10. #15. return (test_leg_iso and \ leg.pt()>leg_pt and abs(leg.eta()) < leg_eta and \ leg.tauID("decayModeFinding") > 0.5 and \ leg.tauID("againstElectronLoose") > 0.5 and \ leg.tauID("againstMuonLoose") > 0.5) def testLooseLeg(self, leg): leg_pt = self.cfg_ana.pt leg_eta = self.cfg_ana.eta iso = self.cfg_ana.isolation if iso == 'mva': #### Tau ID MVA test_leg_iso = leg.tauID("byRawIsoMVA") > 0.5 if iso == 'mva2': #### Tau ID MVA2 test_leg_iso = leg.tauID("byIsolationMVA2raw") > 0.5 if iso == 'db3h': #### Tau ID deltaBeta 3 hits test_leg_iso = leg.tauID( "byCombinedIsolationDeltaBetaCorrRaw3Hits") < 10. #15. return (test_leg_iso and \ leg.pt()>leg_pt and abs(leg.eta()) < leg_eta and \ leg.tauID("decayModeFinding") > 0.5 and \ leg.tauID("againstElectronLoose") > 0.5 and \ leg.tauID("againstMuonLoose") > 0.5) def passAntiEMVA(self, iCat, raw, WP=0): iCat = int(iCat) if iCat < 0: return False if iCat > 15: return True cutsLoose = [ 0.835, 0.831, 0.849, 0.859, 0.873, 0.823, 0.85, 0.855, 0.816, 0.861, 0.862, 0.847, 0.893, 0.82, 0.845, 0.851 ] cutsMedium = [ 0.933, 0.921, 0.944, 0.945, 0.918, 0.941, 0.981, 0.943, 0.956, 0.947, 0.951, 0.95, 0.897, 0.958, 0.955, 0.942 ] cutsTight = [ 0.96, 0.968, 0.971, 0.972, 0.969, 0.959, 0.981, 0.965, 0.975, 0.972, 0.974, 0.971, 0.897, 0.971, 0.961, 0.97 ] cutsVeryTight = [ 0.978, 0.98, 0.982, 0.985, 0.977, 0.974, 0.989, 0.977, 0.986, 0.983, 0.984, 0.983, 0.971, 0.987, 0.977, 0.981 ] cut = 0 if WP == 0: cut = cutsLoose[iCat] if WP == 1: cut = cutsMedium[iCat] if WP == 2: cut = cutsTight[iCat] if WP == 3: cut = cutsVeryTight[iCat] return (raw > cut) def muonIso(self, muon): '''dbeta corrected pf isolation with all charged particles instead of charged hadrons''' return muon.relIsoAllChargedDB05() def testLeg2ID(self, muon): '''Tight muon selection, no isolation requirement''' return muon.tightId() and \ self.testVertex( muon ) def testLeg2Iso(self, muon, isocut): '''Tight muon selection, with isolation requirement''' if isocut is None: isocut = self.cfg_ana.iso2 return self.muonIso(muon) < isocut def testVertex(self, lepton): '''Tests vertex constraints, for mu and tau''' return abs(lepton.dxy()) < 0.045 and \ abs(lepton.dz()) < 0.2 def testMuonIDLoose(self, muon): '''Loose muon ID and kine, no isolation requirement, for lepton veto''' return muon.pt() > 15 and \ abs( muon.eta() ) < 2.4 and \ muon.isGlobalMuon() and \ muon.isTrackerMuon() and \ muon.sourcePtr().userFloat('isPFMuon') and \ abs(muon.dz()) < 0.2 def buildMuons(self, cmgLeptons, event): '''Build muons for veto, associate best vertex, select loose ID muons. The loose ID selection is done to ensure that the muon has an inner track.''' leptons = [] for index, lep in enumerate(cmgLeptons): pyl = Muon(lep) pyl.associatedVertex = event.goodVertices[0] if not self.testMuonIDLoose(pyl): continue leptons.append(pyl) return leptons def buildElectrons(self, cmgOtherLeptons, event): '''Build electrons for third lepton veto, associate best vertex. ''' otherLeptons = [] for index, lep in enumerate(cmgOtherLeptons): pyl = Electron(lep) pyl.associatedVertex = event.goodVertices[0] #COLINTLV check ID # if not self.testMuonIDLoose(pyl): # continue otherLeptons.append(pyl) return otherLeptons def trigMatched(self, event, leg, legName, trigpath): '''Returns true if the leg is matched to a trigger object as defined in the triggerMap parameter''' if not hasattr(self.cfg_ana, 'triggerMap'): return True #path = event.hltPath this works if you have only one path path = trigpath #import pdb ; pdb.set_trace() triggerObjects = event.triggerObjects filters = self.cfg_ana.triggerMap[path] filter = None if legName == 'leg1': filter = filters[0] elif legName == 'leg2': filter = filters[1] elif legName == 'jet': filter = filters[2] else: raise ValueError( 'legName should be leg1 or leg2, not {leg}'.format( leg=legName)) # the default dR2Max value is 0.3^2 pdgIds = None if len(filter) == 2: filter, pdgIds = filter[0], filter[1] return triggerMatched(leg, triggerObjects, path, filter, dR2Max=0.5 * 0.5, dRMax=0.5, pdgIds=pdgIds) def testJetID(self, jet): #jet.puJetIdPassed = jet.puJetId() jet.puJetIdPassed = jet.puJetId53X() jet.pfJetIdPassed = jet.looseJetId() #jet.pfJetIdPassed = jet.getSelection('cuts_looseJetId') if self.cfg_ana.relaxJetId: return True else: return jet.puJetIdPassed and jet.pfJetIdPassed def testJet(self, jet): # 2 is loose pile-up jet id return jet.pt() > self.cfg_ana.jetPt and \ abs( jet.eta() ) < self.cfg_ana.jetEta and \ self.testJetID(jet) # jet.passPuJetId('full', 2) def match(self, myPair, genParticles): dR2leg1Min = 999. dR2leg2Min = 999. dR2leg1 = 999. dR2leg2 = 999. index1 = -99 index2 = -99 for index, genPart in enumerate(genParticles): dR2leg1 = deltaR2(myPair.leg1().eta(), myPair.leg1().phi(), genPart.eta(), genPart.phi()) dR2leg2 = deltaR2(myPair.leg2().eta(), myPair.leg2().phi(), genPart.eta(), genPart.phi()) if dR2leg1 < dR2leg1Min: dR2leg1Min = dR2leg1 index1 = index if dR2leg2 < dR2leg2Min: dR2leg2Min = dR2leg2 index2 = index self.leg1DeltaR = math.sqrt(dR2leg1Min) self.leg2DeltaR = math.sqrt(dR2leg2Min) self.index1 = index1 self.index2 = index2 return (self.leg1DeltaR, self.leg2DeltaR, self.index1, self.index2) def splitDYJets(self, event, genParticles, myPair, require_status=True, bosons=[23, 25, 35, 36]): ## require_status: yes, status==3 for MCs, but status may vary for emb, therefore it is switched off ## PDG Id: e 11, mu 13, tau 15, Z 23, h 25, H 35, A 36, H+ 37 ## DYJets sample gets split by gen matching and ## Higgs samples are given a flag (isZtt) to require reco taus matched to gen taus ## flag to split DYJets into ZTT, ZL, ZJ event.isZtt = False ## two taus gen matched event.isZttj = False ## two taus that fail the matching event.isZee = False ## two electrons, both fake taus event.isZmm = False ## two muons, both fake taus event.isZttll = False ## ZTT->LL, both lepton fake taus event.isZj = False ## whatever else ## lists with the index of Z boson's daughters genTausFromZ = [] genMuonsFromZ = [] genElectronsFromZ = [] genLeptonsFromTaus = [] for index, gen in enumerate(genParticles): status = gen.status() id = gen.pdgId() motherId = 0 if gen.numberOfMothers() > 0: motherId = gen.mother().pdgId() if ((not require_status) or status == 3) and abs(id) == 15 and abs(motherId) in bosons: genTausFromZ.append(index) if ((not require_status) or status == 3) and abs(id) == 13 and abs(motherId) in bosons: genMuonsFromZ.append(index) if ((not require_status) or status == 3) and abs(id) == 11 and abs(motherId) in bosons: genElectronsFromZ.append(index) if ((not require_status) or status == 3) and abs(id) == 11 and abs(motherId) == 15: genLeptonsFromTaus.append(index) if ((not require_status) or status == 3) and abs(id) == 13 and abs(motherId) == 15: genLeptonsFromTaus.append(index) if abs(gen.pdgId()) in [23]: event.hasW = True if abs(gen.pdgId()) in [24]: event.hasZ = True if abs(gen.pdgId()) in [23, 25, 35, 36, 37]: event.genMass = gen.mass() if len(genTausFromZ) == 2: ##### we don't match the embedded and therefore we don't match the DY->TT #event.isZtt = True ##### now we do 26/8/2013 leg1TauDR, leg2TauDR, dummy, dummy = self.match( myPair, [genParticles[genTausFromZ[0]], genParticles[genTausFromZ[1]]]) if leg1TauDR < 0.3: myPair.leg1().genl = genParticles[genTausFromZ[0]] if leg2TauDR < 0.3: myPair.leg2().genl = genParticles[genTausFromZ[1]] if leg1TauDR < 0.3 and leg2TauDR < 0.3: event.isZtt = True else: event.isZttj = True elif len(genMuonsFromZ) == 2: leg1MuDR, leg2MuDR, dummy, dummy = self.match( myPair, [ genParticles[genMuonsFromZ[0]], genParticles[genMuonsFromZ[1]] ]) if leg1MuDR < 0.3: myPair.leg1().genl = genParticles[genMuonsFromZ[0]] if leg2MuDR < 0.3: myPair.leg2().genl = genParticles[genMuonsFromZ[1]] if leg1MuDR < 0.3 and leg2MuDR < 0.3: event.isZmm = True elif len(genElectronsFromZ) == 2: leg1ElDR, leg2ElDR, dummy, dummy = self.match( myPair, [ genParticles[genElectronsFromZ[0]], genParticles[genElectronsFromZ[1]] ]) if leg1ElDR < 0.3: myPair.leg1().genl = genParticles[genElectronsFromZ[0]] if leg2ElDR < 0.3: myPair.leg2().genl = genParticles[genElectronsFromZ[1]] if leg1ElDR < 0.3 and leg2ElDR < 0.3: event.isZee = True elif len(genLeptonsFromTaus) == 2: leg1LepDR, leg2LepDR, dummy, dummy = self.match( myPair, [ genParticles[genLeptonsFromTaus[0]], genParticles[genLeptonsFromTaus[1]] ]) if leg1LepDR < 0.3: myPair.leg1().genl = genParticles[genLeptonsFromTaus[0]] if leg2LepDR < 0.3: myPair.leg2().genl = genParticles[genLeptonsFromTaus[1]] if leg1LepDR < 0.3 and leg2LepDR < 0.3: event.isZttll = True ## needs to be rerun with all samples #if not(event.isZtt or event.isZee or event.isZmm or event.isZttll or event.isZttj) : if not (event.isZtt or event.isZee or event.isZmm): event.isZj = True
class TauTauAnalyzer( DiLeptonAnalyzer ): DiObjectClass = TauTau LeptonClass = Tau def declareHandles(self): super(TauTauAnalyzer, self).declareHandles() # print 'TauTauAnalyzer.declareHandles' self.handles['diLeptons'] = AutoHandle( 'cmgDiTauCorSVFitFullSel', 'std::vector<cmg::DiObject<cmg::Tau,cmg::Tau>>' ) self.handles['rawMET'] = AutoHandle( 'cmgPFMETRaw', 'std::vector<cmg::BaseMET>' ) self.handles['triggerResults'] = AutoHandle( ('TriggerResults','','HLT'), 'edm::TriggerResults' ) self.triggers=['HLT_LooseIsoPFTau35_Trk20_Prong1_v6', 'HLT_LooseIsoPFTau35_Trk20_Prong1_MET70_v6', 'HLT_LooseIsoPFTau35_Trk20_Prong1_MET75_v6', 'HLT_DoubleMediumIsoPFTau30_Trk5_eta2p1_Jet30_v2', 'HLT_DoubleMediumIsoPFTau30_Trk5_eta2p1_v2', 'HLT_DoubleMediumIsoPFTau35_Trk5_eta2p1_v6', 'HLT_DoubleMediumIsoPFTau35_Trk5_eta2p1_Prong1_v6'] #self.handles['leptons'] = AutoHandle( # 'cmgTauSel', # 'std::vector<cmg::Tau>' # ) if self.cfg_comp.isMC and ("DY" in self.cfg_comp.name or "W" in self.cfg_comp.name or "TTJets" in self.cfg_comp.name or "Higgs" in self.cfg_comp.name): self.mchandles['genParticles'] = AutoHandle( 'genParticlesPruned', 'std::vector<reco::GenParticle>' ) if self.cfg_comp.isMC and "QCD" in self.cfg_comp.name: self.mchandles['generator'] = AutoHandle( 'generator', 'GenEventInfoProduct' ) #COLIN this collection does not exist ## if self.cfg_comp.isEmbed: ## self.handles['genParticles'] = AutoHandle( 'genParticles', ## 'std::vector<reco::GenParticle>' ) if "Higgsgg" in self.cfg_comp.name: masspoint=self.cfg_comp.name[7:10] self.higgsPtWeightFile=TFile("$CMSSW_BASE/src/CMGTools/H2TauTau/data/weight_ptH_"+masspoint+".root") self.higgsPtWeightHistogram=self.higgsPtWeightFile.Get("powheg_weight/weight_hqt_fehipro_fit_"+masspoint) self.handles['electrons'] = AutoHandle( 'cmgElectronSel', 'std::vector<cmg::Electron>' ) self.handles['muons'] = AutoHandle( 'cmgMuonSel', 'std::vector<cmg::Muon>' ) if self.cfg_comp.isMC and ("WJets" in self.cfg_comp.name or "W0Jets" in self.cfg_comp.name or "W1Jets" in self.cfg_comp.name or "W2Jets" in self.cfg_comp.name or "W3Jets" in self.cfg_comp.name or "W4Jets" in self.cfg_comp.name or "DYJets" in self.cfg_comp.name or "DY0Jets" in self.cfg_comp.name or "DY1Jets" in self.cfg_comp.name or "DY2Jets" in self.cfg_comp.name or "DY3Jets" in self.cfg_comp.name or "DY4Jets" in self.cfg_comp.name): self.mchandles['source'] = AutoHandle( 'source', 'LHEEventProduct' ) #self.handles['jets'] = AutoHandle( self.cfg_ana.jetCol, # 'std::vector<cmg::PFJet>' ) self.handles['jets'] = AutoHandle( 'cmgPFJetSel', 'std::vector<cmg::PFJet>' ) def beginLoop(self): super(TauTauAnalyzer,self).beginLoop() self.counters = Counters() self.counters.addCounter('DiLepton') count = self.counters.counter('DiLepton') count.register('all events') count.register('> 0 di-lepton') # count.register('di-lepton cut string ok') count.register('lepton accept') count.register('third lepton veto') count.register('leg1 trig matched') count.register('leg2 trig matched') count.register('jet trig matched') count.register('leg1 offline cuts passed') count.register('leg2 offline cuts passed') count.register('{min:3.1f} < m < {max:3.1f}'.format( min = self.cfg_ana.m_min, max = self.cfg_ana.m_max )) count.register('exactly 1 di-lepton') def bestDiLepton(self, diLeptons): '''Returns the best diLepton (the one with best isolation).''' return max( [ (min(dilep.leg1().tauID("byRawIsoMVA"), dilep.leg2().tauID("byRawIsoMVA")), dilep) for dilep in diLeptons ] )[1] #return max( [ (dilep.sumPt(), dilep) for dilep in diLeptons ] )[1] def process(self, iEvent, event): # select signal dileptons with all cuts on both legs self.readCollections( iEvent ) # trigger stuff could be put in a separate analyzer # event.triggerObject = self.handles['cmgTriggerObjectSel'].product()[0] event.diLeptons = self.buildDiLeptons( self.handles['diLeptons'].product(), event ) #event.leptons = self.buildLeptons( self.handles['leptons'].product(), event ) event.leptons = [] for diLepton in event.diLeptons: if not diLepton.leg1() in event.leptons: event.leptons += [diLepton.leg1()] if not diLepton.leg2() in event.leptons: event.leptons += [diLepton.leg2()] self.shiftEnergyScale(event) if hasattr(self.cfg_ana,'HCP_matching'): event.triggerObjects=[] result = self.selectionSequence(event, fillCounter=True) #if event.eventId in [212391570,227704571,254997006,34410222]: # print "found event" # print eventId,result event.rawMET=self.handles['rawMET'].product() triggerResults=self.handles['triggerResults'].product() triggerNames = iEvent._event.triggerNames(triggerResults) for trig in self.triggers: index=triggerNames.triggerIndex(trig) if index>=triggerNames.size(): trigres=-1 else: trigres=triggerResults.accept(index) setattr(event,trig,trigres) if hasattr(self.cfg_ana,'HCP_matching'): event.l1TrigMatched=True event.l2TrigMatched=True # select non signal dileptons with loose cuts if result is False: # Post-Preapproval version if hasattr(self.cfg_ana,'HCP_matching'): selDiLeptons = [ diL for diL in event.diLeptons if \ self.cfg_ana.m_min < diL.mass() and diL.mass() < self.cfg_ana.m_max and \ self.testNonLeg( diL.leg1() ) and self.testNonLeg( diL.leg2() ) and \ (self.testLeg( diL.leg1() ) or self.testLeg( diL.leg2() )) ] else: selDiLeptons = [ diL for diL in event.diLeptonsTrigMatched if \ self.cfg_ana.m_min < diL.mass() and diL.mass() < self.cfg_ana.m_max and \ self.testNonLeg( diL.leg1() ) and self.testNonLeg( diL.leg2() ) and \ (self.testLeg( diL.leg1() ) or self.testLeg( diL.leg2() )) ] if len(selDiLeptons)==0: selDiLeptons = [ diL for diL in event.diLeptons if \ self.cfg_ana.m_min < diL.mass() and diL.mass() < self.cfg_ana.m_max and \ self.testNonLeg( diL.leg1() ) and self.testNonLeg( diL.leg2() ) and \ (self.testLeg( diL.leg1() ) or self.testLeg( diL.leg2() )) ] # loose reference version #selDiLeptons = [ diL for diL in event.diLeptonsTrigMatched if \ # self.cfg_ana.m_min < diL.mass() and diL.mass() < self.cfg_ana.m_max and \ # self.testLooseLeg( diL.leg1() ) and self.testLooseLeg( diL.leg2() ) and \ # (self.testLeg( diL.leg1() ) or self.testLeg( diL.leg2() )) ] # std. medium iso version #selDiLeptons = [ diL for diL in event.diLeptonsTrigMatched if \ # self.cfg_ana.m_min < diL.mass() and diL.mass() < self.cfg_ana.m_max and \ # self.testNonLeg( diL.leg1() ) and self.testNonLeg( diL.leg2() ) and \ # (self.testStdMediumLeg( diL.leg1() ) or self.testStdMediumLeg( diL.leg2() )) ] # std. tight iso version #selDiLeptons = [ diL for diL in event.diLeptonsTrigMatched if \ # self.cfg_ana.m_min < diL.mass() and diL.mass() < self.cfg_ana.m_max and \ # self.testLooseStdLeg( diL.leg1() ) and self.testLooseStdLeg( diL.leg2() ) and \ # (self.testStdTightLeg( diL.leg1() ) or self.testStdTightLeg( diL.leg2() )) ] # relax cuts completely #if len(selDiLeptons)==0: # selDiLeptons=event.diLeptons if len(selDiLeptons)==0: return False event.diLepton = self.bestDiLepton( selDiLeptons ) event.leg1 = event.diLepton.leg1() event.leg2 = event.diLepton.leg2() event.isSignal = False else: event.isSignal = True # count muons event.muons = [lep for lep in self.buildMuons(self.handles['muons'].product(),event) if self.testLegKine(lep, ptcut=10, etacut=2.4) and self.testLeg2ID(lep) and self.testLeg2Iso(lep, 0.3) ] # count electrons event.electrons = [electron for electron in self.buildElectrons(self.handles['electrons'].product(),event) if self.testLegKine(electron, ptcut=10, etacut=2.5) and \ electron.looseIdForTriLeptonVeto() and \ self.testVertex( electron ) and \ electron.relIsoAllChargedDB05() < 0.3] # if len(event.muons)+len(event.electrons) > 0: # return False if self.cfg_comp.isMC and ("WJets" in self.cfg_comp.name or "W0Jets" in self.cfg_comp.name or "W1Jets" in self.cfg_comp.name or "W2Jets" in self.cfg_comp.name or "W3Jets" in self.cfg_comp.name or "W4Jets" in self.cfg_comp.name or "DYJets" in self.cfg_comp.name or "DY0Jets" in self.cfg_comp.name or "DY1Jets" in self.cfg_comp.name or "DY2Jets" in self.cfg_comp.name or "DY3Jets" in self.cfg_comp.name or "DY4Jets" in self.cfg_comp.name): event.NUP = self.mchandles['source'].product().hepeup().NUP else: event.NUP = -1 event.genMatched = None if self.cfg_comp.isMC and ("DY" in self.cfg_comp.name or "Higgs" in self.cfg_comp.name): genParticles = self.mchandles['genParticles'].product() event.genParticles = map( GenParticle, genParticles) leg1DeltaR, leg2DeltaR = event.diLepton.match( event.genParticles ) event.leg1DeltaR=leg1DeltaR event.leg2DeltaR=leg2DeltaR if leg1DeltaR>-1 and leg1DeltaR < 0.1 and \ leg2DeltaR>-1 and leg2DeltaR < 0.1: event.genMatched = True else: event.genMatched = False event.isPhoton=False event.isElectron=False for gen in genParticles: if abs(gen.pdgId())==15 and abs(gen.mother().pdgId())==23 and (gen.mother().mass()<80 or gen.mother().mass()>100): event.isPhoton=True if abs(gen.pdgId())==13 and abs(gen.mother().pdgId())==23: event.isMuon=True if abs(gen.pdgId())==11 and abs(gen.mother().pdgId())==23: event.isElectron=True if abs(gen.pdgId()) in [23, 25, 35, 36, 37]: event.genMass=gen.mass() if abs(gen.pdgId()) in [23]: event.hasW=True if abs(gen.pdgId()) in [24]: event.hasZ=True if self.cfg_comp.isMC and "W" in self.cfg_comp.name: genParticles = self.mchandles['genParticles'].product() event.genParticles = map( GenParticle, genParticles) genTaus = [] event.genMatched = False event.genMatchedElectron = False event.genMatchedMuon = False for gen in genParticles: if abs(gen.pdgId()) in [11,13,15] and abs(gen.mother().pdgId())==24: # W -> tau nu genTaus.append( gen ) if len(genTaus)>=1: dR2leg1Min, event.diLepton.leg1Gen = ( float('inf'), None) dR2leg2Min, event.diLepton.leg2Gen = ( float('inf'), None) for genTau in genTaus: dR2leg1 = deltaR2(event.diLepton.leg1().eta(), event.diLepton.leg1().phi(), genTau.eta(), genTau.phi() ) dR2leg2 = deltaR2(event.diLepton.leg2().eta(), event.diLepton.leg2().phi(), genTau.eta(), genTau.phi() ) if dR2leg1 < dR2leg1Min: dR2leg1Min, event.diLepton.leg1Gen = (dR2leg1, genTau) if dR2leg2 < dR2leg2Min: dR2leg2Min, event.diLepton.leg2Gen = (dR2leg2, genTau) leg1DeltaR = math.sqrt( dR2leg1Min ) leg2DeltaR = math.sqrt( dR2leg2Min ) if ((leg1DeltaR>-1 and leg1DeltaR < 0.1) or \ (leg2DeltaR>-1 and leg2DeltaR < 0.1)) and abs(genTau.pdgId())==11: event.genMatchedElectron = True if ((leg1DeltaR>-1 and leg1DeltaR < 0.1) or \ (leg2DeltaR>-1 and leg2DeltaR < 0.1)) and abs(genTau.pdgId())==13: event.genMatchedMuon = True if ((leg1DeltaR>-1 and leg1DeltaR < 0.1) or \ (leg2DeltaR>-1 and leg2DeltaR < 0.1)) and abs(genTau.pdgId())==15: event.genMatched = True event.isElectron=False event.isMuon=False event.isTau=False for gen in genParticles: if abs(gen.pdgId())==11 and abs(gen.mother().pdgId())==24: event.isElectron=True if abs(gen.pdgId())==13 and abs(gen.mother().pdgId())==24: event.isMuon=True if abs(gen.pdgId())==15 and abs(gen.mother().pdgId())==24: event.isTau=True if self.cfg_comp.isMC and "TTJets" in self.cfg_comp.name: genParticles = self.mchandles['genParticles'].product() event.genParticles = map( GenParticle, genParticles) genTaus = [] event.genMatched = 0 event.genMatchedElectron = 0 event.genMatchedMuon = 0 for gen in genParticles: if abs(gen.pdgId()) in [11,13,15] and abs(gen.mother().pdgId())==24: # W -> tau nu genTaus.append( gen ) if len(genTaus)>=1: dR2leg1Min, event.diLepton.leg1Gen = ( float('inf'), None) dR2leg2Min, event.diLepton.leg2Gen = ( float('inf'), None) for genTau in genTaus: dR2leg1 = deltaR2(event.diLepton.leg1().eta(), event.diLepton.leg1().phi(), genTau.eta(), genTau.phi() ) dR2leg2 = deltaR2(event.diLepton.leg2().eta(), event.diLepton.leg2().phi(), genTau.eta(), genTau.phi() ) if dR2leg1 < dR2leg1Min: dR2leg1Min, event.diLepton.leg1Gen = (dR2leg1, genTau) if dR2leg2 < dR2leg2Min: dR2leg2Min, event.diLepton.leg2Gen = (dR2leg2, genTau) leg1DeltaR = math.sqrt( dR2leg1Min ) leg2DeltaR = math.sqrt( dR2leg2Min ) if (leg1DeltaR>-1 and leg1DeltaR < 0.1) and abs(genTau.pdgId())==11: event.genMatchedElectron+=1 if (leg1DeltaR>-1 and leg1DeltaR < 0.1) and abs(genTau.pdgId())==13: event.genMatchedMuon+=1 if (leg1DeltaR>-1 and leg1DeltaR < 0.1) and abs(genTau.pdgId())==15: event.genMatched+=1 if (leg2DeltaR>-1 and leg2DeltaR < 0.1) and abs(genTau.pdgId())==11: event.genMatchedElectron+=1 if (leg2DeltaR>-1 and leg2DeltaR < 0.1) and abs(genTau.pdgId())==13: event.genMatchedMuon+=1 if (leg2DeltaR>-1 and leg2DeltaR < 0.1) and abs(genTau.pdgId())==15: event.genMatched+=1 event.isElectron=0 event.isMuon=0 event.isTau=0 for gen in genParticles: if abs(gen.pdgId())==11 and abs(gen.mother().pdgId())==24: event.isElectron+=1 if abs(gen.pdgId())==13 and abs(gen.mother().pdgId())==24: event.isMuon+=1 if abs(gen.pdgId())==15 and abs(gen.mother().pdgId())==24: event.isTau+=1 if self.cfg_comp.isMC and "Higgsgg" in self.cfg_comp.name: genParticles = self.mchandles['genParticles'].product() event.genParticles = map( GenParticle, genParticles) higgsPt=-1 for gen in genParticles: if abs(gen.pdgId())==25: higgsPt = gen.pt() break event.higgsPtWeight = self.higgsPtWeightHistogram.GetBinContent(self.higgsPtWeightHistogram.FindBin(higgsPt)) #event.eventWeight *= event.higgsPtWeight if self.cfg_comp.isMC and "QCD" in self.cfg_comp.name: generator = self.mchandles['generator'].product() event.generatorWeight = generator.weight() event.eventWeight *= event.generatorWeight #COLIN: no genParticle collection present in embedded samples diTau files... ## if self.cfg_comp.isEmbed: ## genParticles = self.handles['genParticles'].product() ## event.genParticles = map( GenParticle, genParticles) ## for gen in genParticles: ## if abs(gen.pdgId()) in [23]: ## event.genMass=gen.mass() return True # trigger: debug it and make sure that trigger matching is working # build trigger list for data # build trigger map # 3rd lepton veto: # look for electron or muon that pass loose id # none of them def selectionSequence(self, event, fillCounter, leg1IsoCut=None, leg2IsoCut=None): if fillCounter: self.counters.counter('DiLepton').inc('all events') # if not self.triggerList.triggerPassed(event.triggerObject): # return False # self.counters.counter('DiLepton').inc('trigger passed ') # if event.eventId == 155035: # import pdb; pdb.set_trace() if len(event.diLeptons) == 0: return False if fillCounter: self.counters.counter('DiLepton').inc('> 0 di-lepton') # testing di-lepton itself selDiLeptons = event.diLeptons # selDiLeptons = self.selectDiLeptons( selDiLeptons ) if not self.leptonAccept( event.leptons ): return False if fillCounter: self.counters.counter('DiLepton').inc('lepton accept') if len(self.cfg_comp.triggers)>0: # trigger matching leg1 selDiLeptons = [diL for diL in selDiLeptons if \ self.trigMatched(event, diL.leg1(), 'leg1')] if len(selDiLeptons) == 0: event.l1TrigMatched=False if hasattr(self.cfg_ana,'HCP_matching'): return False else: if fillCounter: self.counters.counter('DiLepton').inc('leg1 trig matched') event.l1TrigMatched=True if len(self.cfg_comp.triggers)>0: # trigger matching leg2 selDiLeptons = [diL for diL in selDiLeptons if \ self.trigMatched(event, diL.leg2(), 'leg2')] if len(selDiLeptons) == 0: event.l2TrigMatched=False if hasattr(self.cfg_ana,'HCP_matching'): return False else: if fillCounter: self.counters.counter('DiLepton').inc('leg2 trig matched') event.l2TrigMatched=True if len(self.cfg_comp.triggers)>0 and len(self.cfg_ana.triggerMap[ event.hltPath ])>2: # trigger matching jet cmgJets = self.handles['jets'].product() jets=[] for cmgJet in cmgJets: jet = Jet( cmgJet ) if self.testJet( jet ): jets.append(jet) selDiLeptonsNew=[] for diL in selDiLeptons: cleanJets, dummy = cleanObjectCollection( jets, masks = [ diL.leg1(), diL.leg2() ], deltaRMin = 0.5 ) if len(cleanJets)>0 and self.trigMatched(event, cleanJets[0], 'jet'): selDiLeptonsNew+=[diL] selDiLeptons=selDiLeptonsNew if len(selDiLeptons) == 0: event.jetTrigMatched=False if hasattr(self.cfg_ana,'HCP_matching'): return False else: if fillCounter: self.counters.counter('DiLepton').inc('jet trig matched') event.jetTrigMatched=True event.diLeptonsTrigMatched = selDiLeptons # testing leg1 selDiLeptons = [ diL for diL in selDiLeptons if \ self.testLeg1( diL.leg1(), leg1IsoCut ) ] if len(selDiLeptons) == 0: return False else: if fillCounter: self.counters.counter('DiLepton').inc('leg1 offline cuts passed') # testing leg2 selDiLeptons = [ diL for diL in selDiLeptons if \ self.testLeg2( diL.leg2(), leg2IsoCut ) ] if len(selDiLeptons) == 0: return False else: if fillCounter: self.counters.counter('DiLepton').inc('leg2 offline cuts passed') # mass cut selDiLeptons = [ diL for diL in selDiLeptons if \ self.testMass(diL) ] if len(selDiLeptons)==0: return False else: if fillCounter: self.counters.counter('DiLepton').inc( '{min:3.1f} < m < {max:3.1f}'.format( min = self.cfg_ana.m_min, max = self.cfg_ana.m_max ) ) # exactly one? if len(selDiLeptons)==0: return False elif len(selDiLeptons)==1: if fillCounter: self.counters.counter('DiLepton').inc('exactly 1 di-lepton') event.diLepton = self.bestDiLepton( selDiLeptons ) event.leg1 = event.diLepton.leg1() event.leg2 = event.diLepton.leg2() return True def testLeg1(self, leg, iso=None): #return True #return self.testNonLeg(leg) return self.testLeg(leg) #return self.testStdMediumLeg(leg) #return self.testStdTightLeg(leg) def testLeg2(self, leg, iso=None): #return True #return self.testNonLeg(leg) return self.testLeg(leg) #return self.testStdMediumLeg(leg) #return self.testStdTightLeg(leg) def testLeg(self, leg): return (leg.pt()>45 and abs(leg.eta())<2.1 and \ leg.tauID("decayModeFinding")>0.5 and \ leg.tauID("byMediumIsoMVA")>0.5 and \ leg.tauID("againstElectronLoose")>0.5 and \ leg.tauID("againstMuonLoose")>0.5) def testStdMediumLeg(self, leg): return (leg.pt()>45 and abs(leg.eta())<2.1 and \ leg.tauID("decayModeFinding")>0.5 and \ leg.tauID("byMediumCombinedIsolationDeltaBetaCorr")>0.5 and \ leg.tauID("againstElectronLoose")>0.5 and \ leg.tauID("againstMuonLoose")>0.5) def testStdTightLeg(self, leg): return (leg.pt()>45 and abs(leg.eta())<2.1 and \ leg.tauID("decayModeFinding")>0.5 and \ leg.tauID("byTightCombinedIsolationDeltaBetaCorr")>0.5 and \ leg.tauID("againstElectronLoose")>0.5 and \ leg.tauID("againstMuonLoose")>0.5) #def selectDiLeptons(self, diLeptons, cutString=None): # selDiLeptons = [ diL for diL in diLeptons if \ # (diL.leg1().tauID("byTightIsoMVA")>0.5 or diL.leg2().tauID("byTightIsoMVA")>0.5)] # if len(selDiLeptons) > 0: # self.counters.counter('DiLepton').inc( 'di-lepton cut string ok') # return selDiLeptons def testLooseLeg(self, leg): return (leg.pt()>45 and abs(leg.eta())<2.1 and \ leg.tauID("decayModeFinding")>0.5 and \ leg.tauID("byRawIsoMVA")>0.5 and \ #leg.tauID("byRawIsoMVA")>0.795 and \ leg.tauID("againstElectronLoose")>0.5 and \ leg.tauID("againstMuonLoose")>0.5) def testLooseStdLeg(self, leg): return (leg.pt()>45 and abs(leg.eta())<2.1 and \ leg.tauID("decayModeFinding")>0.5 and \ leg.tauID("byLooseCombinedIsolationDeltaBetaCorr")>0.5 and \ leg.tauID("againstElectronLoose")>0.5 and \ leg.tauID("againstMuonLoose")>0.5) def testNonLeg(self, leg): return (leg.pt()>45 and abs(leg.eta())<2.1 and \ leg.tauID("decayModeFinding")>0.5 and \ leg.tauID("againstElectronLoose")>0.5 and \ leg.tauID("againstMuonLoose")>0.5) def muonIso(self, muon ): '''dbeta corrected pf isolation with all charged particles instead of charged hadrons''' return muon.relIsoAllChargedDB05() def testLeg2ID(self, muon): '''Tight muon selection, no isolation requirement''' return muon.tightId() and \ self.testVertex( muon ) def testLeg2Iso(self, muon, isocut): '''Tight muon selection, with isolation requirement''' if isocut is None: isocut = self.cfg_ana.iso2 return self.muonIso(muon)<isocut def testVertex(self, lepton): '''Tests vertex constraints, for mu and tau''' return abs(lepton.dxy()) < 0.045 and \ abs(lepton.dz()) < 0.2 def testMuonIDLoose(self, muon): '''Loose muon ID and kine, no isolation requirement, for lepton veto''' return muon.pt() > 15 and \ abs( muon.eta() ) < 2.4 and \ muon.isGlobalMuon() and \ muon.isTrackerMuon() and \ muon.sourcePtr().userFloat('isPFMuon') and \ abs(muon.dz()) < 0.2 # self.testVertex( muon ) def buildMuons(self, cmgLeptons, event): '''Build muons for veto, associate best vertex, select loose ID muons. The loose ID selection is done to ensure that the muon has an inner track.''' leptons = [] for index, lep in enumerate(cmgLeptons): pyl = Muon(lep) pyl.associatedVertex = event.goodVertices[0] if not self.testMuonIDLoose( pyl ): continue leptons.append( pyl ) return leptons def buildElectrons(self, cmgOtherLeptons, event): '''Build electrons for third lepton veto, associate best vertex. ''' otherLeptons = [] for index, lep in enumerate(cmgOtherLeptons): pyl = Electron(lep) pyl.associatedVertex = event.goodVertices[0] #COLINTLV check ID # if not self.testMuonIDLoose(pyl): # continue otherLeptons.append( pyl ) return otherLeptons def trigMatched(self, event, leg, legName): '''Returns true if the leg is matched to a trigger object as defined in the triggerMap parameter''' if not hasattr( self.cfg_ana, 'triggerMap'): return True path = event.hltPath triggerObjects = event.triggerObjects filters = self.cfg_ana.triggerMap[ path ] filter = None if legName == 'leg1': filter = filters[0] elif legName == 'leg2': filter = filters[1] elif legName == 'jet': filter = filters[2] else: raise ValueError( 'legName should be leg1 or leg2, not {leg}'.format( leg=legName ) ) # the dR2Max value is 0.3^2 pdgIds = None if len(filter) == 2: filter, pdgIds = filter[0], filter[1] return triggerMatched(leg, triggerObjects, path, filter, # dR2Max=0.089999, dR2Max=0.25, pdgIds=pdgIds ) def testJetID(self, jet): jet.puJetIdPassed = jet.puJetId() jet.pfJetIdPassed = jet.looseJetId() #jet.pfJetIdPassed = jet.getSelection('cuts_looseJetId') if self.cfg_ana.relaxJetId: return True else: return jet.puJetIdPassed and jet.pfJetIdPassed def testJet( self, jet ): # 2 is loose pile-up jet id return jet.pt() > self.cfg_ana.jetPt and \ abs( jet.eta() ) < self.cfg_ana.jetEta and \ self.testJetID(jet)
class TauTauAnalyzer(DiLeptonAnalyzer): DiObjectClass = TauTau LeptonClass = Tau def declareHandles(self): super(TauTauAnalyzer, self).declareHandles() #self.handles['diLeptons'] = AutoHandle( 'cmgDiTauCorSVFitFullSel' , 'std::vector<cmg::DiObject<cmg::Tau,cmg::Tau> >' ) ## old object self.handles['diLeptons'] = AutoHandle( 'cmgDiTauCorSVFitFullSel', 'std::vector<cmg::DiTauObject<cmg::Tau,cmg::Tau> >' ) ## new object by Jan self.handles['rawMET'] = AutoHandle('cmgPFMETRaw', 'std::vector<cmg::BaseMET>') self.handles['jets'] = AutoHandle('cmgPFJetSel', 'std::vector<cmg::PFJet>') self.handles['electrons'] = AutoHandle('cmgElectronSel', 'std::vector<cmg::Electron>') self.handles['muons'] = AutoHandle('cmgMuonSel', 'std::vector<cmg::Muon>') self.handles['triggerResults'] = AutoHandle( ('TriggerResults', '', 'HLT'), 'edm::TriggerResults') self.handles['metSig'] = AutoHandle('pfMetSignificance', 'cmg::METSignificance') #self.handles['mvametsigs'] = AutoHandle( 'mvaMETDiTau' , 'std::vector<cmg::METSignificance>' ) if self.cfg_comp.isMC and ("DY" in self.cfg_comp.name or "W" in self.cfg_comp.name or "TTJets" in self.cfg_comp.name or "Higgs" in self.cfg_comp.name and not "WW" in self.cfg_comp.name and not "WZ" in self.cfg_comp.name): self.mchandles['genParticles'] = AutoHandle( 'genParticlesPruned', 'std::vector<reco::GenParticle>') if self.cfg_comp.isMC and "QCD" in self.cfg_comp.name: self.mchandles['generator'] = AutoHandle('generator', 'GenEventInfoProduct') if self.cfg_comp.isMC and ("DY" in self.cfg_comp.name or "W" in self.cfg_comp.name and not "WW" in self.cfg_comp.name and not "WZ" in self.cfg_comp.name): self.mchandles['source'] = AutoHandle('source', 'LHEEventProduct') self.triggers = [ 'HLT_LooseIsoPFTau35_Trk20_Prong1_v6', 'HLT_LooseIsoPFTau35_Trk20_Prong1_MET70_v6', 'HLT_LooseIsoPFTau35_Trk20_Prong1_MET75_v6', 'HLT_DoubleMediumIsoPFTau30_Trk5_eta2p1_Jet30_v2', 'HLT_DoubleMediumIsoPFTau30_Trk5_eta2p1_v2', 'HLT_DoubleMediumIsoPFTau35_Trk5_eta2p1_v6', 'HLT_DoubleMediumIsoPFTau35_Trk5_eta2p1_Prong1_v6', ] self.triggersEmb = [ 'HLT_Mu17_Mu8_v16', 'HLT_Mu17_Mu8_v17', 'HLT_Mu17_Mu8_v18', 'HLT_Mu17_Mu8_v19', 'HLT_Mu17_Mu8_v21', 'HLT_Mu17_Mu8_v21', 'HLT_Mu17_Mu8_v22', ] self.triggers += self.triggersEmb ###### PT HIGGS REWEIGHTING if "HiggsGGH" in self.cfg_comp.name: masspoint = re.findall(r"(\d{2,3})", self.cfg_comp.name) masspoint = str(masspoint[0]) self.higgsPtWeightFile = TFile( "$CMSSW_BASE/src/CMGTools/H2TauTau/data/weight_ptH_" + masspoint + "_8TeV.root") self.higgsPtWeightHistogramNom = self.higgsPtWeightFile.Get( "Nominal") self.higgsPtWeightHistogramUp = self.higgsPtWeightFile.Get("Up") self.higgsPtWeightHistogramDown = self.higgsPtWeightFile.Get( "Down") def beginLoop(self): super(TauTauAnalyzer, self).beginLoop() self.counters = Counters() self.counters.addCounter('DiLepton') count = self.counters.counter('DiLepton') count.register('all events') count.register('> 0 di-lepton') count.register('lepton accept') count.register('third lepton veto') count.register('leg1 trig matched') count.register('leg2 trig matched') count.register('jet trig matched') count.register('leg1 offline cuts passed') count.register('leg2 offline cuts passed') count.register('{min:3.1f} < m < {max:3.1f}'.format( min=self.cfg_ana.m_min, max=self.cfg_ana.m_max)) count.register('exactly 1 di-lepton') def bestDiLepton(self, diLeptons): '''Returns the best diLepton (the one with best isolation).''' iso = self.cfg_ana.isolation if iso == 'mva': #### Tau ID MVA return max([(min(dilep.leg1().tauID("byRawIsoMVA"), dilep.leg2().tauID("byRawIsoMVA")), dilep) for dilep in diLeptons])[1] if iso == 'mva2': #### Tau ID MVA2 return max([(min(dilep.leg1().tauID("byIsolationMVA2raw"), dilep.leg2().tauID("byIsolationMVA2raw")), dilep) for dilep in diLeptons])[1] if iso == 'db3h': #### Tau ID deltaBeta 3 hits return min([(max( dilep.leg1().tauID("byCombinedIsolationDeltaBetaCorrRaw3Hits"), dilep.leg2().tauID( "byCombinedIsolationDeltaBetaCorrRaw3Hits")), dilep) for dilep in diLeptons])[1] #### highest sum pt pair #return max( [ (dilep.sumPt(), dilep) for dilep in diLeptons ] )[1] def process(self, iEvent, event): # select signal dileptons with all cuts on both legs self.readCollections(iEvent) # trigger stuff could be put in a separate analyzer # event.triggerObject = self.handles['cmgTriggerObjectSel'].product()[0] #if event.eventId in notPassed : # print 'before anything' # import pdb ; pdb.set_trace() event.diLeptons = self.buildDiLeptons( self.handles['diLeptons'].product(), event) #event.leptons = self.buildLeptons( self.handles['leptons'].product(), event ) event.leptons = [] for diLepton in event.diLeptons: if not diLepton.leg1() in event.leptons: event.leptons += [diLepton.leg1()] if not diLepton.leg2() in event.leptons: event.leptons += [diLepton.leg2()] self.shiftEnergyScale(event) result = self.selectionSequence(event, fillCounter=True) event.rawMET = self.handles['rawMET'].product() triggerResults = self.handles['triggerResults'].product() triggerNames = iEvent._event.triggerNames(triggerResults) for trig in self.triggers: index = triggerNames.triggerIndex(trig) if index >= triggerNames.size(): trigres = -1 else: trigres = triggerResults.accept(index) setattr(event, trig, trigres) # select non signal dileptons with loose cuts if result is False: selDiLeptons = [ diL for diL in event.diLeptonsTrigMatched if \ self.cfg_ana.m_min < diL.mass() and diL.mass() < self.cfg_ana.m_max and \ self.testLooseLeg( diL.leg1() ) and self.testLooseLeg( diL.leg2() ) and \ (self.testLeg( diL.leg1() ) or self.testLeg( diL.leg2() )) ] if len(selDiLeptons) == 0: selDiLeptons = [ diL for diL in event.diLeptons if \ self.cfg_ana.m_min < diL.mass() and diL.mass() < self.cfg_ana.m_max and \ self.testLooseLeg( diL.leg1() ) and self.testLooseLeg( diL.leg2() ) and \ (self.testLeg( diL.leg1() ) or self.testLeg( diL.leg2() )) ] if len(selDiLeptons) == 0: return False event.diLepton = self.bestDiLepton(selDiLeptons) event.leg1 = event.diLepton.leg1() event.leg2 = event.diLepton.leg2() event.isSignal = False else: event.isSignal = True #if event.eventId in notPassed : # print 'diLeptons built, is Signal?', result # import pdb ; pdb.set_trace() #if len([event.diLepton])>1 : #import pdb ; pdb.set_trace() event.leg1.NewLooseAntiEleMVA3 = self.passAntiEMVA( iCat=event.diLepton.leg1().tauID("againstElectronMVA3category"), raw=event.diLepton.leg1().tauID("againstElectronMVA3raw"), WP=0) event.leg2.NewLooseAntiEleMVA3 = self.passAntiEMVA( iCat=event.diLepton.leg2().tauID("againstElectronMVA3category"), raw=event.diLepton.leg2().tauID("againstElectronMVA3raw"), WP=0) # count muons event.muons = [ lep for lep in self.buildMuons(self.handles['muons'].product(), event) if self.testLegKine(lep, ptcut=10, etacut=2.4) and self.testLeg2ID(lep) and self.testLeg2Iso(lep, 0.3) ] # count electrons event.electrons = [ electron for electron in self.buildElectrons( self.handles['electrons'].product(), event) if self.testLegKine(electron, ptcut=10, etacut=2.5) and electron.looseIdForTriLeptonVeto() and self.testVertex( electron) and electron.relIsoAllChargedDB05() < 0.3 ] ####### what ID for veto means ####### http://cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/UserCode/CMG/CMGTools/RootTools/python/physicsobjects/HTauTauElectron.py?revision=1.10&view=markup if self.cfg_comp.isMC and ("DY" in self.cfg_comp.name or "W" in self.cfg_comp.name and not "WW" in self.cfg_comp.name and not "WZ" in self.cfg_comp.name): event.NUP = self.mchandles['source'].product().hepeup().NUP else: event.NUP = -1 event.genMatched = None if self.cfg_comp.isMC and ("DY" in self.cfg_comp.name or "Higgs" in self.cfg_comp.name): genParticles = self.mchandles['genParticles'].product() event.genParticles = map(GenParticle, genParticles) leg1DeltaR, leg2DeltaR = event.diLepton.match(event.genParticles) event.leg1DeltaR = leg1DeltaR event.leg2DeltaR = leg2DeltaR if leg1DeltaR>-1 and leg1DeltaR < 0.1 and \ leg2DeltaR>-1 and leg2DeltaR < 0.1: event.genMatched = True else: event.genMatched = False event.isPhoton = False event.isElectron = False for gen in genParticles: if abs(gen.pdgId()) == 15 and abs( gen.mother().pdgId()) == 23 and ( gen.mother().mass() < 80 or gen.mother().mass() > 100): event.isPhoton = True if abs(gen.pdgId()) == 13 and abs(gen.mother().pdgId()) == 23: event.isMuon = True if abs(gen.pdgId()) == 11 and abs(gen.mother().pdgId()) == 23: event.isElectron = True if abs(gen.pdgId()) in [23, 25, 35, 36, 37]: event.genMass = gen.mass() if abs(gen.pdgId()) in [23]: event.hasW = True if abs(gen.pdgId()) in [24]: event.hasZ = True if self.cfg_comp.isMC and "W" in self.cfg_comp.name: genParticles = self.mchandles['genParticles'].product() event.genParticles = map(GenParticle, genParticles) genTaus = [] event.genMatched = False event.genMatchedElectron = False event.genMatchedMuon = False for gen in genParticles: if abs(gen.pdgId()) in [11, 13, 15] and abs( gen.mother().pdgId()) == 24: # W -> tau nu genTaus.append(gen) if len(genTaus) >= 1: dR2leg1Min, event.diLepton.leg1Gen = (float('inf'), None) dR2leg2Min, event.diLepton.leg2Gen = (float('inf'), None) for genTau in genTaus: dR2leg1 = deltaR2(event.diLepton.leg1().eta(), event.diLepton.leg1().phi(), genTau.eta(), genTau.phi()) dR2leg2 = deltaR2(event.diLepton.leg2().eta(), event.diLepton.leg2().phi(), genTau.eta(), genTau.phi()) if dR2leg1 < dR2leg1Min: dR2leg1Min, event.diLepton.leg1Gen = (dR2leg1, genTau) if dR2leg2 < dR2leg2Min: dR2leg2Min, event.diLepton.leg2Gen = (dR2leg2, genTau) leg1DeltaR = math.sqrt(dR2leg1Min) leg2DeltaR = math.sqrt(dR2leg2Min) if ((leg1DeltaR>-1 and leg1DeltaR < 0.1) or \ (leg2DeltaR>-1 and leg2DeltaR < 0.1)) and abs(genTau.pdgId())==11: event.genMatchedElectron = True if ((leg1DeltaR>-1 and leg1DeltaR < 0.1) or \ (leg2DeltaR>-1 and leg2DeltaR < 0.1)) and abs(genTau.pdgId())==13: event.genMatchedMuon = True if ((leg1DeltaR>-1 and leg1DeltaR < 0.1) or \ (leg2DeltaR>-1 and leg2DeltaR < 0.1)) and abs(genTau.pdgId())==15: event.genMatched = True event.isElectron = False event.isMuon = False event.isTau = False for gen in genParticles: if abs(gen.pdgId()) == 11 and abs(gen.mother().pdgId()) == 24: event.isElectron = True if abs(gen.pdgId()) == 13 and abs(gen.mother().pdgId()) == 24: event.isMuon = True if abs(gen.pdgId()) == 15 and abs(gen.mother().pdgId()) == 24: event.isTau = True if self.cfg_comp.isMC and "TTJets" in self.cfg_comp.name: genParticles = self.mchandles['genParticles'].product() event.genParticles = map(GenParticle, genParticles) genTaus = [] event.genMatched = 0 event.genMatchedElectron = 0 event.genMatchedMuon = 0 for gen in genParticles: if abs(gen.pdgId()) in [11, 13, 15] and abs( gen.mother().pdgId()) == 24: # W -> tau nu genTaus.append(gen) if len(genTaus) >= 1: dR2leg1Min, event.diLepton.leg1Gen = (float('inf'), None) dR2leg2Min, event.diLepton.leg2Gen = (float('inf'), None) for genTau in genTaus: dR2leg1 = deltaR2(event.diLepton.leg1().eta(), event.diLepton.leg1().phi(), genTau.eta(), genTau.phi()) dR2leg2 = deltaR2(event.diLepton.leg2().eta(), event.diLepton.leg2().phi(), genTau.eta(), genTau.phi()) if dR2leg1 < dR2leg1Min: dR2leg1Min, event.diLepton.leg1Gen = (dR2leg1, genTau) if dR2leg2 < dR2leg2Min: dR2leg2Min, event.diLepton.leg2Gen = (dR2leg2, genTau) leg1DeltaR = math.sqrt(dR2leg1Min) leg2DeltaR = math.sqrt(dR2leg2Min) if (leg1DeltaR > -1 and leg1DeltaR < 0.1) and abs( genTau.pdgId()) == 11: event.genMatchedElectron += 1 if (leg1DeltaR > -1 and leg1DeltaR < 0.1) and abs( genTau.pdgId()) == 13: event.genMatchedMuon += 1 if (leg1DeltaR > -1 and leg1DeltaR < 0.1) and abs( genTau.pdgId()) == 15: event.genMatched += 1 if (leg2DeltaR > -1 and leg2DeltaR < 0.1) and abs( genTau.pdgId()) == 11: event.genMatchedElectron += 1 if (leg2DeltaR > -1 and leg2DeltaR < 0.1) and abs( genTau.pdgId()) == 13: event.genMatchedMuon += 1 if (leg2DeltaR > -1 and leg2DeltaR < 0.1) and abs( genTau.pdgId()) == 15: event.genMatched += 1 event.isElectron = 0 event.isMuon = 0 event.isTau = 0 for gen in genParticles: if abs(gen.pdgId()) == 11 and abs(gen.mother().pdgId()) == 24: event.isElectron += 1 if abs(gen.pdgId()) == 13 and abs(gen.mother().pdgId()) == 24: event.isMuon += 1 if abs(gen.pdgId()) == 15 and abs(gen.mother().pdgId()) == 24: event.isTau += 1 if self.cfg_comp.isMC and "QCD" in self.cfg_comp.name: generator = self.mchandles['generator'].product() event.generatorWeight = generator.weight() event.eventWeight *= event.generatorWeight if self.cfg_comp.isMC and "HiggsGGH" in self.cfg_comp.name: genParticles = self.mchandles['genParticles'].product() event.genParticles = map(GenParticle, genParticles) higgsPt = -1 for gen in genParticles: if abs(gen.pdgId()) == 25: higgsPt = gen.pt() break event.higgsPtWeightNom = self.higgsPtWeightHistogramNom.GetBinContent( self.higgsPtWeightHistogramNom.FindBin(higgsPt)) event.higgsPtWeightUp = self.higgsPtWeightHistogramUp.GetBinContent( self.higgsPtWeightHistogramUp.FindBin(higgsPt)) event.higgsPtWeightDown = self.higgsPtWeightHistogramDown.GetBinContent( self.higgsPtWeightHistogramDown.FindBin(higgsPt)) else: event.higgsPtWeightNom = 1. event.higgsPtWeightUp = 1. event.higgsPtWeightDown = 1. ## third lepton veto if len(event.muons) > 0 + len(event.electrons) > 0: ## FOR SYNCHING!!! return False if "DY" in self.cfg_comp.name or "Higgs" in self.cfg_comp.name or self.cfg_comp.isEmbed: event.isRealTau = 1 else: event.isRealTau = 0 if not hasattr(event, 'NJetWeight'): event.NJetWeight = 1. #event.name = self.cfg_comp.name #import pdb ; pdb.set_trace() event.metsig = self.handles['metSig'].product() return True def selectionSequence(self, event, fillCounter, leg1IsoCut=None, leg2IsoCut=None): if fillCounter: self.counters.counter('DiLepton').inc('all events') if len(event.diLeptons) == 0: return False if fillCounter: self.counters.counter('DiLepton').inc('> 0 di-lepton') # testing di-lepton itself selDiLeptons = event.diLeptons if not self.leptonAccept(event.leptons): return False if fillCounter: self.counters.counter('DiLepton').inc('lepton accept') ## for embedded no hltPaths (for now) if not hasattr(event, 'hltPaths'): event.hltPaths = [] matching = {} for trig in event.hltPaths: matching.update({trig: [-99, -99, -99]}) # {trigName:leg1,leg2,jet} event.diLeptonsTrigMatched = [] for trig in event.hltPaths: if self.cfg_comp.isEmbed: continue ## no matching for the embed selDiLeptons = event.diLeptons if len(self.cfg_comp.triggers) > 0: # trigger matching leg1 selDiLeptons = [ diL for diL in selDiLeptons if self.trigMatched(event, diL.leg1(), 'leg1', trig) ] if len(selDiLeptons) == 0: matching[trig][0] = 0 else: if fillCounter: self.counters.counter('DiLepton').inc( 'leg1 trig matched') matching[trig][0] = 1 if len(self.cfg_comp.triggers) > 0: # trigger matching leg2 selDiLeptons = [ diL for diL in selDiLeptons if self.trigMatched(event, diL.leg2(), 'leg2', trig) ] if len(selDiLeptons) == 0: matching[trig][1] = 0 else: if fillCounter: self.counters.counter('DiLepton').inc( 'leg2 trig matched') matching[trig][1] = 1 if len(self.cfg_comp.triggers) > 0 and len( self.cfg_ana.triggerMap[trig]) > 2: # trigger matching jet cmgJets = self.handles['jets'].product() jets = [] for cmgJet in cmgJets: jet = Jet(cmgJet) if self.testJet(jet): jets.append(jet) selDiLeptonsNew = [] for diL in selDiLeptons: cleanJets, dummy = cleanObjectCollection( jets, masks=[diL.leg1(), diL.leg2()], deltaRMin=0.5) if len(cleanJets) > 0 and self.trigMatched( event, cleanJets[0], 'jet', trig): selDiLeptonsNew += [diL] selDiLeptons = selDiLeptonsNew if len(selDiLeptons) == 0: matching[trig][2] = 0 else: if fillCounter: self.counters.counter('DiLepton').inc( 'jet trig matched') matching[trig][2] = 1 event.diLeptonsTrigMatched += selDiLeptons event.diLeptonsTrigMatched = set(event.diLeptonsTrigMatched) ### need unix style wild card to macth different trigger versions in data for trig in matching.keys(): if fnm(trig, 'HLT_DoubleMediumIsoPFTau35_Trk*_eta2p1_v*'): event.l1TrigMatched_diTau = matching[trig][0] event.l2TrigMatched_diTau = matching[trig][1] if fnm(trig, 'HLT_DoubleMediumIsoPFTau*_Trk*_eta2p1_Jet30_v*'): event.l1TrigMatched_diTauJet = matching[trig][0] event.l2TrigMatched_diTauJet = matching[trig][1] event.jetTrigMatched_diTauJet = matching[trig][2] # testing leg1 selDiLeptons = [ diL for diL in selDiLeptons if self.testLeg(diL.leg1()) ] if len(selDiLeptons) == 0: return False else: if fillCounter: self.counters.counter('DiLepton').inc( 'leg1 offline cuts passed') # testing leg2 selDiLeptons = [ diL for diL in selDiLeptons if self.testLeg(diL.leg2()) ] if len(selDiLeptons) == 0: return False else: if fillCounter: self.counters.counter('DiLepton').inc( 'leg2 offline cuts passed') # mass cut selDiLeptons = [diL for diL in selDiLeptons if self.testMass(diL)] if len(selDiLeptons) == 0: return False else: if fillCounter: self.counters.counter('DiLepton').inc( '{min:3.1f} < m < {max:3.1f}'.format( min=self.cfg_ana.m_min, max=self.cfg_ana.m_max)) # exactly one? if len(selDiLeptons) == 0: return False elif len(selDiLeptons) == 1: if fillCounter: self.counters.counter('DiLepton').inc('exactly 1 di-lepton') event.diLepton = self.bestDiLepton(selDiLeptons) event.leg1 = event.diLepton.leg1() event.leg2 = event.diLepton.leg2() ### require trigger bit in Embedded RecHit if self.cfg_comp.isEmbed: if not event.hltPath: return False if "DY" in self.cfg_comp.name or "Higgs" in self.cfg_comp.name or self.cfg_comp.isEmbed: if event.leg1.decayMode() == 0: event.leg1.prongWeight = 0.88 else: event.leg1.prongWeight = 1. if event.leg2.decayMode() == 0: event.leg2.prongWeight = 0.88 else: event.leg2.prongWeight = 1. #import pdb ; pdb.set_trace() return True def testLeg(self, leg): leg_pt = self.cfg_ana.pt leg_eta = self.cfg_ana.eta iso = self.cfg_ana.isolation if iso == 'mva': #### Tau ID MVA test_leg_iso = leg.tauID("byRawIsoMVA") > 0.5 # 0.884 if iso == 'mva2': #### Tau ID MVA2 test_leg_iso = leg.tauID("byIsolationMVA2raw") > 0.5 # 0.90 if iso == 'db3h': #### Tau ID deltaBeta 3 hits test_leg_iso = leg.tauID( "byCombinedIsolationDeltaBetaCorrRaw3Hits") < 10. #15. return (test_leg_iso and \ leg.pt()>leg_pt and abs(leg.eta()) < leg_eta and \ leg.tauID("decayModeFinding") > 0.5 and \ leg.tauID("againstElectronLoose") > -0.5 and \ leg.tauID("againstMuonLoose") > -0.5) def testLooseLeg(self, leg): leg_pt = self.cfg_ana.pt leg_eta = self.cfg_ana.eta iso = self.cfg_ana.isolation if iso == 'mva': #### Tau ID MVA test_leg_iso = leg.tauID("byRawIsoMVA") > 0.5 if iso == 'mva2': #### Tau ID MVA2 test_leg_iso = leg.tauID("byIsolationMVA2raw") > 0.5 if iso == 'db3h': #### Tau ID deltaBeta 3 hits test_leg_iso = leg.tauID( "byCombinedIsolationDeltaBetaCorrRaw3Hits") < 10. #15. return (test_leg_iso and \ leg.pt()>leg_pt and abs(leg.eta()) < leg_eta and \ leg.tauID("decayModeFinding") > 0.5 and \ leg.tauID("againstElectronLoose") > -0.5 and \ leg.tauID("againstMuonLoose") > -0.5) def passAntiEMVA(self, iCat, raw, WP=0): iCat = int(iCat) if iCat < 0: return False if iCat > 15: return True cutsLoose = [ 0.835, 0.831, 0.849, 0.859, 0.873, 0.823, 0.85, 0.855, 0.816, 0.861, 0.862, 0.847, 0.893, 0.82, 0.845, 0.851 ] cutsMedium = [ 0.933, 0.921, 0.944, 0.945, 0.918, 0.941, 0.981, 0.943, 0.956, 0.947, 0.951, 0.95, 0.897, 0.958, 0.955, 0.942 ] cutsTight = [ 0.96, 0.968, 0.971, 0.972, 0.969, 0.959, 0.981, 0.965, 0.975, 0.972, 0.974, 0.971, 0.897, 0.971, 0.961, 0.97 ] cutsVeryTight = [ 0.978, 0.98, 0.982, 0.985, 0.977, 0.974, 0.989, 0.977, 0.986, 0.983, 0.984, 0.983, 0.971, 0.987, 0.977, 0.981 ] cut = 0 if WP == 0: cut = cutsLoose[iCat] if WP == 1: cut = cutsMedium[iCat] if WP == 2: cut = cutsTight[iCat] if WP == 3: cut = cutsVeryTight[iCat] return (raw > cut) def muonIso(self, muon): '''dbeta corrected pf isolation with all charged particles instead of charged hadrons''' return muon.relIsoAllChargedDB05() def testLeg2ID(self, muon): '''Tight muon selection, no isolation requirement''' return muon.tightId() and \ self.testVertex( muon ) def testLeg2Iso(self, muon, isocut): '''Tight muon selection, with isolation requirement''' if isocut is None: isocut = self.cfg_ana.iso2 return self.muonIso(muon) < isocut def testVertex(self, lepton): '''Tests vertex constraints, for mu and tau''' return abs(lepton.dxy()) < 0.045 and \ abs(lepton.dz()) < 0.2 def testMuonIDLoose(self, muon): '''Loose muon ID and kine, no isolation requirement, for lepton veto''' return muon.pt() > 15 and \ abs( muon.eta() ) < 2.4 and \ muon.isGlobalMuon() and \ muon.isTrackerMuon() and \ muon.sourcePtr().userFloat('isPFMuon') and \ abs(muon.dz()) < 0.2 def buildMuons(self, cmgLeptons, event): '''Build muons for veto, associate best vertex, select loose ID muons. The loose ID selection is done to ensure that the muon has an inner track.''' leptons = [] for index, lep in enumerate(cmgLeptons): pyl = Muon(lep) pyl.associatedVertex = event.goodVertices[0] if not self.testMuonIDLoose(pyl): continue leptons.append(pyl) return leptons def buildElectrons(self, cmgOtherLeptons, event): '''Build electrons for third lepton veto, associate best vertex. ''' otherLeptons = [] for index, lep in enumerate(cmgOtherLeptons): pyl = Electron(lep) pyl.associatedVertex = event.goodVertices[0] #COLINTLV check ID # if not self.testMuonIDLoose(pyl): # continue otherLeptons.append(pyl) return otherLeptons def trigMatched(self, event, leg, legName, trigpath): '''Returns true if the leg is matched to a trigger object as defined in the triggerMap parameter''' if not hasattr(self.cfg_ana, 'triggerMap'): return True #path = event.hltPath this works if you have only one path path = trigpath #import pdb ; pdb.set_trace() triggerObjects = event.triggerObjects filters = self.cfg_ana.triggerMap[path] filter = None if legName == 'leg1': filter = filters[0] elif legName == 'leg2': filter = filters[1] elif legName == 'jet': filter = filters[2] else: raise ValueError( 'legName should be leg1 or leg2, not {leg}'.format( leg=legName)) # the default dR2Max value is 0.3^2 pdgIds = None if len(filter) == 2: filter, pdgIds = filter[0], filter[1] return triggerMatched(leg, triggerObjects, path, filter, dR2Max=0.5 * 0.5, dRMax=0.5, pdgIds=pdgIds) def testJetID(self, jet): #jet.puJetIdPassed = jet.puJetId() jet.puJetIdPassed = jet.puJetId53X() jet.pfJetIdPassed = jet.looseJetId() #jet.pfJetIdPassed = jet.getSelection('cuts_looseJetId') if self.cfg_ana.relaxJetId: return True else: return jet.puJetIdPassed and jet.pfJetIdPassed def testJet(self, jet): # 2 is loose pile-up jet id return jet.pt() > self.cfg_ana.jetPt and \ abs( jet.eta() ) < self.cfg_ana.jetEta and \ self.testJetID(jet)
class Analyzer(object): '''Base Analyzer class. Used in Looper.''' def __init__(self, cfg_ana, cfg_comp, looperName ): '''Create an analyzer. cfg_ana: configuration parameters for this analyzer (e.g. a pt cut) cfg_comp: configuration parameters for the data or MC component (e.g. DYJets) looperName: name of the Looper which runs this analyzer. See Looper and Config for more information. You should inherit from this class. Interesting examples of child analyzers are: DiLeptonAnalyzer, TauMuAnalyzer, VertexAnalyzer, H2TauTauEventSorter. ''' self.name = cfg_ana.name self.verbose = cfg_ana.verbose self.cfg_ana = cfg_ana self.cfg_comp = cfg_comp self.looperName = looperName self.dirName = '/'.join( [self.looperName, self.name] ) os.mkdir( self.dirName ) # this is the main logger corresponding to the looper. # each analyzer could also declare its own logger self.mainLogger = logging.getLogger( looperName ) self.beginLoopCalled = False def declareHandles(self): self.handles = {} self.mchandles = {} self.embhandles = {} def beginLoop(self): '''Automatically called by Looper, for all analyzers.''' self.declareHandles() self.counters = Counters() self.averages = Averages() self.mainLogger.warning( 'beginLoop ' + self.cfg_ana.name ) self.beginLoopCalled = True def endLoop(self): '''Automatically called by Looper, for all analyzers.''' #print self.cfg_ana self.mainLogger.warning( '' ) self.mainLogger.warning( str(self) ) self.mainLogger.warning( '' ) def process(self, iEvent, event ): '''Automatically called by Looper, for all analyzers. each analyzer in the sequence will be passed the same event instance. each analyzer can access, modify, and store event information, of any type.''' print self.cfg_ana.name self.readCollections( iEvent ) def readCollections(self, iEvent ): '''You must call this function at the beginning of the process function of your child analyzer.''' # if not self.beginLoopCalled: # # necessary in case the user calls process to go straight to a given event, before looping # self.beginLoop() for str,handle in self.handles.iteritems(): handle.Load( iEvent ) if self.cfg_comp.isMC: for str,handle in self.mchandles.iteritems(): handle.Load( iEvent ) if self.cfg_comp.isEmbed: for str,handle in self.embhandles.iteritems(): handle.Load( iEvent ) def write(self): '''Called by Looper.write, for all analyzers. Just overload it if you have histograms to write.''' # print 'writing not implemented for', self.cfg_ana.name self.counters.write( self.dirName ) self.averages.write( self.dirName ) def __str__(self): '''A multipurpose printout. Should do the job for most analyzers.''' ana = str( self.cfg_ana ) count = '' ave = '' if hasattr(self, 'counters') and len( self.counters.counters ) > 0: count = '\n'.join(map(str, self.counters.counters)) if hasattr(self, 'averages') and len( self.averages ) > 0: ave = '\n'.join(map(str, self.averages)) return '\n'.join( [ana, count, ave] )
class TauTauAnalyzer( DiLeptonAnalyzer ): DiObjectClass = TauTau LeptonClass = Tau def declareHandles(self): super(TauTauAnalyzer, self).declareHandles() #self.handles['diLeptons'] = AutoHandle( 'cmgDiTauCorSVFitFullSel' , 'std::vector<cmg::DiObject<cmg::Tau,cmg::Tau> >' ) ## old object self.handles['diLeptons'] = AutoHandle( 'cmgDiTauCorSVFitFullSel' , 'std::vector<cmg::DiTauObject<cmg::Tau,cmg::Tau> >') ## new object by Jan self.handles['rawMET'] = AutoHandle( 'cmgPFMETRaw' , 'std::vector<cmg::BaseMET>' ) self.handles['jets'] = AutoHandle( 'cmgPFJetSel' , 'std::vector<cmg::PFJet>' ) self.handles['electrons'] = AutoHandle( 'cmgElectronSel' , 'std::vector<cmg::Electron>' ) self.handles['muons'] = AutoHandle( 'cmgMuonSel' , 'std::vector<cmg::Muon>' ) self.handles['triggerResults'] = AutoHandle( ('TriggerResults','','HLT'), 'edm::TriggerResults' ) self.handles['metSig'] = AutoHandle( 'pfMetSignificance' , 'cmg::METSignificance' ) #self.handles['mvametsigs'] = AutoHandle( 'mvaMETDiTau' , 'std::vector<cmg::METSignificance>' ) if self.cfg_comp.isMC and ("DY" in self.cfg_comp.name or "W" in self.cfg_comp.name or "TTJets" in self.cfg_comp.name or "Higgs" in self.cfg_comp.name and not "WW" in self.cfg_comp.name and not "WZ" in self.cfg_comp.name): self.mchandles['genParticles'] = AutoHandle( 'genParticlesPruned','std::vector<reco::GenParticle>' ) if self.cfg_comp.isMC and "QCD" in self.cfg_comp.name: self.mchandles['generator'] = AutoHandle( 'generator','GenEventInfoProduct' ) if self.cfg_comp.isMC and ("DY" in self.cfg_comp.name or "W" in self.cfg_comp.name and not "WW" in self.cfg_comp.name and not "WZ" in self.cfg_comp.name) : self.mchandles['source'] = AutoHandle('source','LHEEventProduct') self.triggers = ['HLT_LooseIsoPFTau35_Trk20_Prong1_v6', 'HLT_LooseIsoPFTau35_Trk20_Prong1_MET70_v6' , 'HLT_LooseIsoPFTau35_Trk20_Prong1_MET75_v6' , 'HLT_DoubleMediumIsoPFTau30_Trk5_eta2p1_Jet30_v2' , 'HLT_DoubleMediumIsoPFTau30_Trk5_eta2p1_v2' , 'HLT_DoubleMediumIsoPFTau35_Trk5_eta2p1_v6' , 'HLT_DoubleMediumIsoPFTau35_Trk5_eta2p1_Prong1_v6' , ] self.triggersEmb = [ 'HLT_Mu17_Mu8_v16', 'HLT_Mu17_Mu8_v17', 'HLT_Mu17_Mu8_v18', 'HLT_Mu17_Mu8_v19', 'HLT_Mu17_Mu8_v21', 'HLT_Mu17_Mu8_v21', 'HLT_Mu17_Mu8_v22', ] self.triggers += self.triggersEmb ###### PT HIGGS REWEIGHTING if "HiggsGGH" in self.cfg_comp.name: masspoint = re.findall(r"(\d{2,3})", self.cfg_comp.name) masspoint = str(masspoint[0]) self.higgsPtWeightFile = TFile("$CMSSW_BASE/src/CMGTools/H2TauTau/data/weight_ptH_"+masspoint+"_8TeV.root") self.higgsPtWeightHistogramNom = self.higgsPtWeightFile.Get("Nominal") self.higgsPtWeightHistogramUp = self.higgsPtWeightFile.Get("Up") self.higgsPtWeightHistogramDown = self.higgsPtWeightFile.Get("Down") def beginLoop(self): super(TauTauAnalyzer,self).beginLoop() self.counters = Counters() self.counters.addCounter('DiLepton') count = self.counters.counter('DiLepton') count.register('all events') count.register('> 0 di-lepton') count.register('lepton accept') count.register('third lepton veto') count.register('leg1 trig matched') count.register('leg2 trig matched') count.register('jet trig matched') count.register('leg1 offline cuts passed') count.register('leg2 offline cuts passed') count.register('{min:3.1f} < m < {max:3.1f}'.format( min = self.cfg_ana.m_min, max = self.cfg_ana.m_max )) count.register('exactly 1 di-lepton') def bestDiLepton(self, diLeptons): '''Returns the best diLepton (the one with best isolation).''' iso = self.cfg_ana.isolation if iso == 'mva' : #### Tau ID MVA return max( [ (min(dilep.leg1().tauID("byRawIsoMVA"), dilep.leg2().tauID("byRawIsoMVA")), dilep) for dilep in diLeptons ] )[1] if iso == 'mva2' : #### Tau ID MVA2 return max( [ (min(dilep.leg1().tauID("byIsolationMVA2raw"), dilep.leg2().tauID("byIsolationMVA2raw")), dilep) for dilep in diLeptons ] )[1] if iso == 'db3h' : #### Tau ID deltaBeta 3 hits return min( [ (max(dilep.leg1().tauID("byCombinedIsolationDeltaBetaCorrRaw3Hits"), dilep.leg2().tauID("byCombinedIsolationDeltaBetaCorrRaw3Hits")), dilep) for dilep in diLeptons ] )[1] #### highest sum pt pair #return max( [ (dilep.sumPt(), dilep) for dilep in diLeptons ] )[1] def process(self, iEvent, event): # select signal dileptons with all cuts on both legs self.readCollections( iEvent ) # trigger stuff could be put in a separate analyzer # event.triggerObject = self.handles['cmgTriggerObjectSel'].product()[0] #if event.eventId in notPassed : # print 'before anything' # import pdb ; pdb.set_trace() event.diLeptons = self.buildDiLeptons( self.handles['diLeptons'].product(), event ) #event.leptons = self.buildLeptons( self.handles['leptons'].product(), event ) event.leptons = [] for diLepton in event.diLeptons: if not diLepton.leg1() in event.leptons: event.leptons += [diLepton.leg1()] if not diLepton.leg2() in event.leptons: event.leptons += [diLepton.leg2()] self.shiftEnergyScale(event) result = self.selectionSequence(event, fillCounter=True) event.rawMET = self.handles['rawMET'].product() triggerResults = self.handles['triggerResults'].product() triggerNames = iEvent._event.triggerNames(triggerResults) for trig in self.triggers: index = triggerNames.triggerIndex(trig) if index >= triggerNames.size(): trigres = -1 else: trigres = triggerResults.accept(index) setattr(event,trig,trigres) # select non signal dileptons with loose cuts if result is False: selDiLeptons = [ diL for diL in event.diLeptonsTrigMatched if \ self.cfg_ana.m_min < diL.mass() and diL.mass() < self.cfg_ana.m_max and \ self.testLooseLeg( diL.leg1() ) and self.testLooseLeg( diL.leg2() ) and \ (self.testLeg( diL.leg1() ) or self.testLeg( diL.leg2() )) ] if len(selDiLeptons)==0: selDiLeptons = [ diL for diL in event.diLeptons if \ self.cfg_ana.m_min < diL.mass() and diL.mass() < self.cfg_ana.m_max and \ self.testLooseLeg( diL.leg1() ) and self.testLooseLeg( diL.leg2() ) and \ (self.testLeg( diL.leg1() ) or self.testLeg( diL.leg2() )) ] if len(selDiLeptons)==0: return False event.diLepton = self.bestDiLepton( selDiLeptons ) event.leg1 = event.diLepton.leg1() event.leg2 = event.diLepton.leg2() event.isSignal = False else: event.isSignal = True #if event.eventId in notPassed : # print 'diLeptons built, is Signal?', result # import pdb ; pdb.set_trace() #if len([event.diLepton])>1 : #import pdb ; pdb.set_trace() event.leg1.NewLooseAntiEleMVA3 = self.passAntiEMVA(iCat = event.diLepton.leg1().tauID("againstElectronMVA3category"), raw = event.diLepton.leg1().tauID("againstElectronMVA3raw"), WP = 0 ) event.leg2.NewLooseAntiEleMVA3 = self.passAntiEMVA(iCat = event.diLepton.leg2().tauID("againstElectronMVA3category"), raw = event.diLepton.leg2().tauID("againstElectronMVA3raw"), WP = 0 ) # count muons event.muons = [lep for lep in self.buildMuons(self.handles['muons'].product(),event) if self.testLegKine(lep, ptcut=10, etacut=2.4) and self.testLeg2ID(lep) and self.testLeg2Iso(lep, 0.3) ] # count electrons event.electrons = [electron for electron in self.buildElectrons(self.handles['electrons'].product(),event) if self.testLegKine(electron, ptcut=10, etacut=2.5) and electron.looseIdForTriLeptonVeto() and self.testVertex( electron ) and electron.relIsoAllChargedDB05() < 0.3] ####### what ID for veto means ####### http://cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/UserCode/CMG/CMGTools/RootTools/python/physicsobjects/HTauTauElectron.py?revision=1.10&view=markup if self.cfg_comp.isMC and ("DY" in self.cfg_comp.name or "W" in self.cfg_comp.name and not "WW" in self.cfg_comp.name and not "WZ" in self.cfg_comp.name) : event.NUP = self.mchandles['source'].product().hepeup().NUP else: event.NUP = -1 event.genMatched = None if self.cfg_comp.isMC and ("DY" in self.cfg_comp.name or "Higgs" in self.cfg_comp.name): genParticles = self.mchandles['genParticles'].product() event.genParticles = map( GenParticle, genParticles) leg1DeltaR, leg2DeltaR = event.diLepton.match( event.genParticles ) event.leg1DeltaR=leg1DeltaR event.leg2DeltaR=leg2DeltaR if leg1DeltaR>-1 and leg1DeltaR < 0.1 and \ leg2DeltaR>-1 and leg2DeltaR < 0.1: event.genMatched = True else: event.genMatched = False event.isPhoton=False event.isElectron=False for gen in genParticles: if abs(gen.pdgId())==15 and abs(gen.mother().pdgId())==23 and (gen.mother().mass()<80 or gen.mother().mass()>100): event.isPhoton=True if abs(gen.pdgId())==13 and abs(gen.mother().pdgId())==23: event.isMuon=True if abs(gen.pdgId())==11 and abs(gen.mother().pdgId())==23: event.isElectron=True if abs(gen.pdgId()) in [23, 25, 35, 36, 37]: event.genMass=gen.mass() if abs(gen.pdgId()) in [23]: event.hasW=True if abs(gen.pdgId()) in [24]: event.hasZ=True if self.cfg_comp.isMC and "W" in self.cfg_comp.name: genParticles = self.mchandles['genParticles'].product() event.genParticles = map( GenParticle, genParticles) genTaus = [] event.genMatched = False event.genMatchedElectron = False event.genMatchedMuon = False for gen in genParticles: if abs(gen.pdgId()) in [11,13,15] and abs(gen.mother().pdgId())==24: # W -> tau nu genTaus.append( gen ) if len(genTaus)>=1: dR2leg1Min, event.diLepton.leg1Gen = ( float('inf'), None) dR2leg2Min, event.diLepton.leg2Gen = ( float('inf'), None) for genTau in genTaus: dR2leg1 = deltaR2(event.diLepton.leg1().eta(), event.diLepton.leg1().phi(), genTau.eta(), genTau.phi() ) dR2leg2 = deltaR2(event.diLepton.leg2().eta(), event.diLepton.leg2().phi(), genTau.eta(), genTau.phi() ) if dR2leg1 < dR2leg1Min: dR2leg1Min, event.diLepton.leg1Gen = (dR2leg1, genTau) if dR2leg2 < dR2leg2Min: dR2leg2Min, event.diLepton.leg2Gen = (dR2leg2, genTau) leg1DeltaR = math.sqrt( dR2leg1Min ) leg2DeltaR = math.sqrt( dR2leg2Min ) if ((leg1DeltaR>-1 and leg1DeltaR < 0.1) or \ (leg2DeltaR>-1 and leg2DeltaR < 0.1)) and abs(genTau.pdgId())==11: event.genMatchedElectron = True if ((leg1DeltaR>-1 and leg1DeltaR < 0.1) or \ (leg2DeltaR>-1 and leg2DeltaR < 0.1)) and abs(genTau.pdgId())==13: event.genMatchedMuon = True if ((leg1DeltaR>-1 and leg1DeltaR < 0.1) or \ (leg2DeltaR>-1 and leg2DeltaR < 0.1)) and abs(genTau.pdgId())==15: event.genMatched = True event.isElectron=False event.isMuon=False event.isTau=False for gen in genParticles: if abs(gen.pdgId())==11 and abs(gen.mother().pdgId())==24: event.isElectron=True if abs(gen.pdgId())==13 and abs(gen.mother().pdgId())==24: event.isMuon=True if abs(gen.pdgId())==15 and abs(gen.mother().pdgId())==24: event.isTau=True if self.cfg_comp.isMC and "TTJets" in self.cfg_comp.name: genParticles = self.mchandles['genParticles'].product() event.genParticles = map( GenParticle, genParticles) genTaus = [] event.genMatched = 0 event.genMatchedElectron = 0 event.genMatchedMuon = 0 for gen in genParticles: if abs(gen.pdgId()) in [11,13,15] and abs(gen.mother().pdgId())==24: # W -> tau nu genTaus.append( gen ) if len(genTaus)>=1: dR2leg1Min, event.diLepton.leg1Gen = ( float('inf'), None) dR2leg2Min, event.diLepton.leg2Gen = ( float('inf'), None) for genTau in genTaus: dR2leg1 = deltaR2(event.diLepton.leg1().eta(), event.diLepton.leg1().phi(), genTau.eta(), genTau.phi() ) dR2leg2 = deltaR2(event.diLepton.leg2().eta(), event.diLepton.leg2().phi(), genTau.eta(), genTau.phi() ) if dR2leg1 < dR2leg1Min: dR2leg1Min, event.diLepton.leg1Gen = (dR2leg1, genTau) if dR2leg2 < dR2leg2Min: dR2leg2Min, event.diLepton.leg2Gen = (dR2leg2, genTau) leg1DeltaR = math.sqrt( dR2leg1Min ) leg2DeltaR = math.sqrt( dR2leg2Min ) if (leg1DeltaR>-1 and leg1DeltaR < 0.1) and abs(genTau.pdgId())==11: event.genMatchedElectron+=1 if (leg1DeltaR>-1 and leg1DeltaR < 0.1) and abs(genTau.pdgId())==13: event.genMatchedMuon+=1 if (leg1DeltaR>-1 and leg1DeltaR < 0.1) and abs(genTau.pdgId())==15: event.genMatched+=1 if (leg2DeltaR>-1 and leg2DeltaR < 0.1) and abs(genTau.pdgId())==11: event.genMatchedElectron+=1 if (leg2DeltaR>-1 and leg2DeltaR < 0.1) and abs(genTau.pdgId())==13: event.genMatchedMuon+=1 if (leg2DeltaR>-1 and leg2DeltaR < 0.1) and abs(genTau.pdgId())==15: event.genMatched+=1 event.isElectron=0 event.isMuon=0 event.isTau=0 for gen in genParticles: if abs(gen.pdgId())==11 and abs(gen.mother().pdgId())==24: event.isElectron+=1 if abs(gen.pdgId())==13 and abs(gen.mother().pdgId())==24: event.isMuon+=1 if abs(gen.pdgId())==15 and abs(gen.mother().pdgId())==24: event.isTau+=1 if self.cfg_comp.isMC and "QCD" in self.cfg_comp.name: generator = self.mchandles['generator'].product() event.generatorWeight = generator.weight() event.eventWeight *= event.generatorWeight if self.cfg_comp.isMC and "HiggsGGH" in self.cfg_comp.name: genParticles = self.mchandles['genParticles'].product() event.genParticles = map( GenParticle, genParticles) higgsPt=-1 for gen in genParticles: if abs(gen.pdgId())==25: higgsPt = gen.pt() break event.higgsPtWeightNom = self.higgsPtWeightHistogramNom.GetBinContent(self.higgsPtWeightHistogramNom.FindBin(higgsPt)) event.higgsPtWeightUp = self.higgsPtWeightHistogramUp.GetBinContent(self.higgsPtWeightHistogramUp.FindBin(higgsPt)) event.higgsPtWeightDown = self.higgsPtWeightHistogramDown.GetBinContent(self.higgsPtWeightHistogramDown.FindBin(higgsPt)) else : event.higgsPtWeightNom = 1. event.higgsPtWeightUp = 1. event.higgsPtWeightDown = 1. ## third lepton veto if len(event.muons)>0+len(event.electrons) > 0: ## FOR SYNCHING!!! return False if "DY" in self.cfg_comp.name or "Higgs" in self.cfg_comp.name or self.cfg_comp.isEmbed: event.isRealTau = 1 else : event.isRealTau = 0 if not hasattr(event,'NJetWeight') : event.NJetWeight = 1. #event.name = self.cfg_comp.name #import pdb ; pdb.set_trace() event.metsig = self.handles['metSig'].product() return True def selectionSequence(self, event, fillCounter, leg1IsoCut=None, leg2IsoCut=None): if fillCounter: self.counters.counter('DiLepton').inc('all events') if len(event.diLeptons) == 0: return False if fillCounter: self.counters.counter('DiLepton').inc('> 0 di-lepton') # testing di-lepton itself selDiLeptons = event.diLeptons if not self.leptonAccept( event.leptons ): return False if fillCounter: self.counters.counter('DiLepton').inc('lepton accept') ## for embedded no hltPaths (for now) if not hasattr( event, 'hltPaths'): event.hltPaths = [] matching = {} for trig in event.hltPaths : matching.update({trig:[-99,-99,-99]}) # {trigName:leg1,leg2,jet} event.diLeptonsTrigMatched = [] for trig in event.hltPaths : if self.cfg_comp.isEmbed : continue ## no matching for the embed selDiLeptons = event.diLeptons if len(self.cfg_comp.triggers)>0: # trigger matching leg1 selDiLeptons = [diL for diL in selDiLeptons if self.trigMatched(event, diL.leg1(), 'leg1', trig)] if len(selDiLeptons) == 0: matching[trig][0]=0 else: if fillCounter: self.counters.counter('DiLepton').inc('leg1 trig matched') matching[trig][0]=1 if len(self.cfg_comp.triggers)>0: # trigger matching leg2 selDiLeptons = [diL for diL in selDiLeptons if self.trigMatched(event, diL.leg2(), 'leg2', trig)] if len(selDiLeptons) == 0: matching[trig][1]=0 else: if fillCounter: self.counters.counter('DiLepton').inc('leg2 trig matched') matching[trig][1]=1 if len(self.cfg_comp.triggers)>0 and len(self.cfg_ana.triggerMap[ trig ])>2: # trigger matching jet cmgJets = self.handles['jets'].product() jets=[] for cmgJet in cmgJets: jet = Jet( cmgJet ) if self.testJet( jet ): jets.append(jet) selDiLeptonsNew=[] for diL in selDiLeptons: cleanJets, dummy = cleanObjectCollection( jets, masks = [ diL.leg1(), diL.leg2() ], deltaRMin = 0.5 ) if len(cleanJets)>0 and self.trigMatched(event, cleanJets[0], 'jet', trig): selDiLeptonsNew += [diL] selDiLeptons = selDiLeptonsNew if len(selDiLeptons) == 0: matching[trig][2]=0 else: if fillCounter: self.counters.counter('DiLepton').inc('jet trig matched') matching[trig][2]=1 event.diLeptonsTrigMatched += selDiLeptons event.diLeptonsTrigMatched = set(event.diLeptonsTrigMatched) ### need unix style wild card to macth different trigger versions in data for trig in matching.keys() : if fnm(trig,'HLT_DoubleMediumIsoPFTau35_Trk*_eta2p1_v*') : event.l1TrigMatched_diTau = matching[trig][0] event.l2TrigMatched_diTau = matching[trig][1] if fnm(trig,'HLT_DoubleMediumIsoPFTau*_Trk*_eta2p1_Jet30_v*') : event.l1TrigMatched_diTauJet = matching[trig][0] event.l2TrigMatched_diTauJet = matching[trig][1] event.jetTrigMatched_diTauJet = matching[trig][2] # testing leg1 selDiLeptons = [ diL for diL in selDiLeptons if self.testLeg( diL.leg1() ) ] if len(selDiLeptons) == 0: return False else: if fillCounter: self.counters.counter('DiLepton').inc('leg1 offline cuts passed') # testing leg2 selDiLeptons = [ diL for diL in selDiLeptons if self.testLeg( diL.leg2() ) ] if len(selDiLeptons) == 0: return False else: if fillCounter: self.counters.counter('DiLepton').inc('leg2 offline cuts passed') # mass cut selDiLeptons = [ diL for diL in selDiLeptons if self.testMass(diL) ] if len(selDiLeptons)==0: return False else: if fillCounter: self.counters.counter('DiLepton').inc('{min:3.1f} < m < {max:3.1f}'.format( min = self.cfg_ana.m_min, max = self.cfg_ana.m_max )) # exactly one? if len(selDiLeptons)==0: return False elif len(selDiLeptons)==1: if fillCounter: self.counters.counter('DiLepton').inc('exactly 1 di-lepton') event.diLepton = self.bestDiLepton( selDiLeptons ) event.leg1 = event.diLepton.leg1() event.leg2 = event.diLepton.leg2() ### require trigger bit in Embedded RecHit if self.cfg_comp.isEmbed : if not event.hltPath : return False if "DY" in self.cfg_comp.name or "Higgs" in self.cfg_comp.name or self.cfg_comp.isEmbed: if event.leg1.decayMode() == 0 : event.leg1.prongWeight = 0.88 else : event.leg1.prongWeight = 1. if event.leg2.decayMode() == 0 : event.leg2.prongWeight = 0.88 else : event.leg2.prongWeight = 1. #import pdb ; pdb.set_trace() return True def testLeg(self, leg): leg_pt = self.cfg_ana.pt leg_eta = self.cfg_ana.eta iso = self.cfg_ana.isolation if iso == 'mva' : #### Tau ID MVA test_leg_iso = leg.tauID("byRawIsoMVA") > 0.5 # 0.884 if iso == 'mva2' : #### Tau ID MVA2 test_leg_iso = leg.tauID("byIsolationMVA2raw") > 0.5 # 0.90 if iso == 'db3h' : #### Tau ID deltaBeta 3 hits test_leg_iso = leg.tauID("byCombinedIsolationDeltaBetaCorrRaw3Hits") < 10. #15. return (test_leg_iso and \ leg.pt()>leg_pt and abs(leg.eta()) < leg_eta and \ leg.tauID("decayModeFinding") > 0.5 and \ leg.tauID("againstElectronLoose") > -0.5 and \ leg.tauID("againstMuonLoose") > -0.5) def testLooseLeg(self, leg): leg_pt = self.cfg_ana.pt leg_eta = self.cfg_ana.eta iso = self.cfg_ana.isolation if iso == 'mva' : #### Tau ID MVA test_leg_iso = leg.tauID("byRawIsoMVA") > 0.5 if iso == 'mva2' : #### Tau ID MVA2 test_leg_iso = leg.tauID("byIsolationMVA2raw") > 0.5 if iso == 'db3h' : #### Tau ID deltaBeta 3 hits test_leg_iso = leg.tauID("byCombinedIsolationDeltaBetaCorrRaw3Hits") < 10. #15. return (test_leg_iso and \ leg.pt()>leg_pt and abs(leg.eta()) < leg_eta and \ leg.tauID("decayModeFinding") > 0.5 and \ leg.tauID("againstElectronLoose") > -0.5 and \ leg.tauID("againstMuonLoose") > -0.5) def passAntiEMVA(self, iCat, raw, WP=0) : iCat = int(iCat) if iCat<0 : return False if iCat>15 : return True cutsLoose = [0.835,0.831,0.849,0.859,0.873,0.823,0.85 ,0.855,0.816,0.861,0.862,0.847,0.893,0.82 ,0.845,0.851] cutsMedium = [0.933,0.921,0.944,0.945,0.918,0.941,0.981,0.943,0.956,0.947,0.951,0.95 ,0.897,0.958,0.955,0.942] cutsTight = [ 0.96,0.968,0.971,0.972,0.969,0.959,0.981,0.965,0.975,0.972,0.974,0.971,0.897,0.971,0.961,0.97 ] cutsVeryTight = [0.978,0.98 ,0.982,0.985,0.977,0.974,0.989,0.977,0.986,0.983,0.984,0.983,0.971,0.987,0.977,0.981] cut = 0 if WP==0 : cut = cutsLoose[iCat] if WP==1 : cut = cutsMedium[iCat] if WP==2 : cut = cutsTight[iCat] if WP==3 : cut = cutsVeryTight[iCat] return (raw>cut) def muonIso(self, muon ): '''dbeta corrected pf isolation with all charged particles instead of charged hadrons''' return muon.relIsoAllChargedDB05() def testLeg2ID(self, muon): '''Tight muon selection, no isolation requirement''' return muon.tightId() and \ self.testVertex( muon ) def testLeg2Iso(self, muon, isocut): '''Tight muon selection, with isolation requirement''' if isocut is None: isocut = self.cfg_ana.iso2 return self.muonIso(muon)<isocut def testVertex(self, lepton): '''Tests vertex constraints, for mu and tau''' return abs(lepton.dxy()) < 0.045 and \ abs(lepton.dz()) < 0.2 def testMuonIDLoose(self, muon): '''Loose muon ID and kine, no isolation requirement, for lepton veto''' return muon.pt() > 15 and \ abs( muon.eta() ) < 2.4 and \ muon.isGlobalMuon() and \ muon.isTrackerMuon() and \ muon.sourcePtr().userFloat('isPFMuon') and \ abs(muon.dz()) < 0.2 def buildMuons(self, cmgLeptons, event): '''Build muons for veto, associate best vertex, select loose ID muons. The loose ID selection is done to ensure that the muon has an inner track.''' leptons = [] for index, lep in enumerate(cmgLeptons): pyl = Muon(lep) pyl.associatedVertex = event.goodVertices[0] if not self.testMuonIDLoose( pyl ): continue leptons.append( pyl ) return leptons def buildElectrons(self, cmgOtherLeptons, event): '''Build electrons for third lepton veto, associate best vertex. ''' otherLeptons = [] for index, lep in enumerate(cmgOtherLeptons): pyl = Electron(lep) pyl.associatedVertex = event.goodVertices[0] #COLINTLV check ID # if not self.testMuonIDLoose(pyl): # continue otherLeptons.append( pyl ) return otherLeptons def trigMatched(self, event, leg, legName, trigpath): '''Returns true if the leg is matched to a trigger object as defined in the triggerMap parameter''' if not hasattr( self.cfg_ana, 'triggerMap'): return True #path = event.hltPath this works if you have only one path path = trigpath #import pdb ; pdb.set_trace() triggerObjects = event.triggerObjects filters = self.cfg_ana.triggerMap[ path ] filter = None if legName == 'leg1': filter = filters[0] elif legName == 'leg2': filter = filters[1] elif legName == 'jet': filter = filters[2] else: raise ValueError( 'legName should be leg1 or leg2, not {leg}'.format( leg=legName ) ) # the default dR2Max value is 0.3^2 pdgIds = None if len(filter) == 2: filter, pdgIds = filter[0], filter[1] return triggerMatched(leg, triggerObjects, path, filter, dR2Max=0.5*0.5,dRMax=0.5, pdgIds=pdgIds ) def testJetID(self, jet): #jet.puJetIdPassed = jet.puJetId() jet.puJetIdPassed = jet.puJetId53X() jet.pfJetIdPassed = jet.looseJetId() #jet.pfJetIdPassed = jet.getSelection('cuts_looseJetId') if self.cfg_ana.relaxJetId: return True else: return jet.puJetIdPassed and jet.pfJetIdPassed def testJet( self, jet ): # 2 is loose pile-up jet id return jet.pt() > self.cfg_ana.jetPt and \ abs( jet.eta() ) < self.cfg_ana.jetEta and \ self.testJetID(jet)