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() #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 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)