def __init__(self, name, dataType, **kwargs): year = kwargs.get('year', 2017 ) doZpt = kwargs.get('doZpt', 'DY' in name ) channel = 'mumu' self.name = name self.year = year self.out = TreeProducerMuMu(name) self.isData = dataType=='data' self.doZpt = doZpt setYear(year) self.vlooseIso = getVLooseTauIso(year) if year==2016: self.trigger = lambda e: e.HLT_IsoMu22 or e.HLT_IsoMu22_eta2p1 or e.HLT_IsoTkMu22 or e.HLT_IsoTkMu22_eta2p1 #or e.HLT_IsoMu19_eta2p1_LooseIsoPFTau20_SingleL1 self.muon1CutPt = 23 else: self.trigger = lambda e: e.HLT_IsoMu24 or e.HLT_IsoMu27 self.muon1CutPt = 25 self.muon2CutPt = 15 if not self.isData: self.muSFs = MuonSFs(year=year) self.puTool = PileupWeightTool(year=year) self.btagTool = BTagWeightTool('CSVv2','medium',channel='mutau',year=year) self.btagTool_deep = BTagWeightTool('DeepCSV','medium',channel='mutau',year=year) if self.doZpt: self.recoilTool = RecoilCorrectionTool(year=year) self.csvv2_wp = BTagWPs('CSVv2',year=year) self.deepcsv_wp = BTagWPs('DeepCSV',year=year) self.Nocut = 0 self.Trigger = 1 self.GoodMuons = 2 self.GoodSecondMuon = 3 self.GoodDiLepton = 4 self.TotalWeighted = 15 self.TotalWeighted_no0PU = 16 self.out.cutflow.GetXaxis().SetBinLabel(1+self.Nocut, "no cut" ) self.out.cutflow.GetXaxis().SetBinLabel(1+self.Trigger, "trigger" ) self.out.cutflow.GetXaxis().SetBinLabel(1+self.GoodMuons, "muon object" ) self.out.cutflow.GetXaxis().SetBinLabel(1+self.GoodSecondMuon, "second muon object" ) self.out.cutflow.GetXaxis().SetBinLabel(1+self.GoodDiLepton, "mumu pair" ) self.out.cutflow.GetXaxis().SetBinLabel(1+self.TotalWeighted, "no cut, weighted" ) self.out.cutflow.GetXaxis().SetBinLabel(1+self.TotalWeighted_no0PU, "no cut, weighted, PU>0" ) self.out.cutflow.GetXaxis().SetLabelSize(0.041)
def __init__(self, name, dataType, **kwargs): self.name = name self.out = TreeProducerMuMu(name) self.isData = dataType == 'data' self.year = kwargs.get('year', 2017) self.tes = kwargs.get('tes', 1.0) self.ltf = kwargs.get('ltf', 1.0) self.inZmassWindow = kwargs.get('ZmassWindow', True) self.doZpt = kwargs.get('doZpt', 'DY' in name) self.doRecoil = kwargs.get( 'doRecoil', ('DY' in name or re.search(r"W\d?Jets", name)) and self.year > 2016) self.doTTpt = kwargs.get('doTTpt', 'TT' in name) self.doTight = kwargs.get('doTight', self.tes != 1 or self.ltf != 1) self.channel = 'mumu' year, channel = self.year, self.channel self.vlooseIso = getVLooseTauIso(year) self.filter = getMETFilters(year, self.isData) if year == 2016: self.trigger = lambda e: e.HLT_IsoMu22 or e.HLT_IsoMu22_eta2p1 or e.HLT_IsoTkMu22 or e.HLT_IsoTkMu22_eta2p1 #or e.HLT_IsoMu19_eta2p1_LooseIsoPFTau20_SingleL1 self.muon1CutPt = lambda e: 23 elif year == 2017: self.trigger = lambda e: e.HLT_IsoMu24 or e.HLT_IsoMu27 #or e.HLT_IsoMu20_eta2p1_LooseChargedIsoPFTau27_eta2p1_CrossL1 self.muon1CutPt = lambda e: 25 if e.HLT_IsoMu24 else 28 else: self.trigger = lambda e: e.HLT_IsoMu24 or e.HLT_IsoMu27 #or e.HLT_IsoMu20_eta2p1_LooseChargedIsoPFTau27_eta2p1_CrossL1 self.muon1CutPt = lambda e: 25 self.muon2CutPt = 15 if not self.isData: self.muSFs = MuonSFs(year=year) self.puTool = PileupWeightTool(year=year) self.btagTool = BTagWeightTool('DeepCSV', 'medium', channel='mutau', year=year) if self.doZpt: self.zptTool = ZptCorrectionTool(year=year) if self.doRecoil: self.recoilTool = RecoilCorrectionTool(year=year) self.deepcsv_wp = BTagWPs('DeepCSV', year=year) self.Nocut = 0 self.Trigger = 1 self.GoodMuons = 2 self.GoodSecondMuon = 3 self.GoodDiLepton = 4 self.TotalWeighted = 15 self.TotalWeighted_no0PU = 16 self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Nocut, "no cut") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Trigger, "trigger") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodMuons, "muon object") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodSecondMuon, "second muon object") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodDiLepton, "mumu pair") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.TotalWeighted, "no cut, weighted") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.TotalWeighted_no0PU, "no cut, weighted, PU>0") self.out.cutflow.GetXaxis().SetLabelSize(0.041)
class MuMuProducer(Module): def __init__(self, name, dataType, **kwargs): self.name = name self.out = TreeProducerMuMu(name) self.isData = dataType == 'data' self.year = kwargs.get('year', 2017) self.tes = kwargs.get('tes', 1.0) self.ltf = kwargs.get('ltf', 1.0) self.inZmassWindow = kwargs.get('ZmassWindow', True) self.doZpt = kwargs.get('doZpt', 'DY' in name) self.doRecoil = kwargs.get( 'doRecoil', ('DY' in name or re.search(r"W\d?Jets", name)) and self.year > 2016) self.doTTpt = kwargs.get('doTTpt', 'TT' in name) self.doTight = kwargs.get('doTight', self.tes != 1 or self.ltf != 1) self.channel = 'mumu' year, channel = self.year, self.channel self.vlooseIso = getVLooseTauIso(year) self.filter = getMETFilters(year, self.isData) if year == 2016: self.trigger = lambda e: e.HLT_IsoMu22 or e.HLT_IsoMu22_eta2p1 or e.HLT_IsoTkMu22 or e.HLT_IsoTkMu22_eta2p1 #or e.HLT_IsoMu19_eta2p1_LooseIsoPFTau20_SingleL1 self.muon1CutPt = lambda e: 23 elif year == 2017: self.trigger = lambda e: e.HLT_IsoMu24 or e.HLT_IsoMu27 #or e.HLT_IsoMu20_eta2p1_LooseChargedIsoPFTau27_eta2p1_CrossL1 self.muon1CutPt = lambda e: 25 if e.HLT_IsoMu24 else 28 else: self.trigger = lambda e: e.HLT_IsoMu24 or e.HLT_IsoMu27 #or e.HLT_IsoMu20_eta2p1_LooseChargedIsoPFTau27_eta2p1_CrossL1 self.muon1CutPt = lambda e: 25 self.muon2CutPt = 15 if not self.isData: self.muSFs = MuonSFs(year=year) self.puTool = PileupWeightTool(year=year) self.btagTool = BTagWeightTool('DeepCSV', 'medium', channel='mutau', year=year) if self.doZpt: self.zptTool = ZptCorrectionTool(year=year) if self.doRecoil: self.recoilTool = RecoilCorrectionTool(year=year) self.deepcsv_wp = BTagWPs('DeepCSV', year=year) self.Nocut = 0 self.Trigger = 1 self.GoodMuons = 2 self.GoodSecondMuon = 3 self.GoodDiLepton = 4 self.TotalWeighted = 15 self.TotalWeighted_no0PU = 16 self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Nocut, "no cut") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Trigger, "trigger") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodMuons, "muon object") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodSecondMuon, "second muon object") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodDiLepton, "mumu pair") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.TotalWeighted, "no cut, weighted") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.TotalWeighted_no0PU, "no cut, weighted, PU>0") self.out.cutflow.GetXaxis().SetLabelSize(0.041) def beginJob(self): pass def endJob(self): if not self.isData: self.btagTool.setDirectory(self.out.outputfile, 'btag') self.out.endJob() def beginFile(self, inputFile, outputFile, inputTree, wrappedOutputTree): sys.stdout.flush() checkBranches(inputTree) def endFile(self, inputFile, outputFile, inputTree, wrappedOutputTree): pass def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" sys.stdout.flush() ##################################### self.out.cutflow.Fill(self.Nocut) if self.isData: self.out.cutflow.Fill(self.TotalWeighted, 1.) if event.PV_npvs > 0: self.out.cutflow.Fill(self.TotalWeighted_no0PU, 1.) else: return False else: self.out.cutflow.Fill(self.TotalWeighted, event.genWeight) self.out.pileup.Fill(event.Pileup_nTrueInt) if event.Pileup_nTrueInt > 0: self.out.cutflow.Fill(self.TotalWeighted_no0PU, event.genWeight) else: return False ##################################### if not self.trigger(event): return False ##################################### self.out.cutflow.Fill(self.Trigger) ##################################### idx_goodmuons = [] for imuon in range(event.nMuon): if event.Muon_pt[imuon] < self.muon2CutPt: continue # lower pT cut if abs(event.Muon_eta[imuon]) > 2.4: continue if abs(event.Muon_dz[imuon]) > 0.2: continue if abs(event.Muon_dxy[imuon]) > 0.045: continue if event.Muon_pfRelIso04_all[imuon] > 0.15: continue if not event.Muon_mediumId[imuon]: continue idx_goodmuons.append(imuon) if len(idx_goodmuons) < 1: return False ##################################### self.out.cutflow.Fill(self.GoodMuons) ##################################### if not any(event.Muon_pt[i] > self.muon1CutPt(event) for i in idx_goodmuons) or len(idx_goodmuons) < 2: # higher pT cut return False ##################################### self.out.cutflow.Fill(self.GoodSecondMuon) ##################################### muons = Collection(event, 'Muon') dileptons = [] for idx1 in idx_goodmuons: for idx2 in idx_goodmuons: if idx1 >= idx2: continue muon1 = muons[idx1].p4() muon2 = muons[idx2].p4() if muon1.DeltaR(muon2) < 0.5: continue if self.inZmassWindow and not (70 < (muon1 + muon2).M() < 110): continue # Z mass dilepton = DiLeptonBasicClass(idx1, event.Muon_pt[idx1], event.Muon_pfRelIso04_all[idx1], idx2, event.Muon_pt[idx2], event.Muon_pfRelIso04_all[idx2]) dileptons.append(dilepton) if len(dileptons) == 0: return False dilepton = bestDiLepton(dileptons) muon1 = muons[dilepton.id1].p4() muon2 = muons[dilepton.id2].p4() ##################################### self.out.cutflow.Fill(self.GoodDiLepton) ##################################### # JETS jetIds = [] bjetIds = [] jets = Collection(event, 'Jet') nfjets = 0 ncjets = 0 nbtag = 0 for ijet in range(event.nJet): if event.Jet_pt[ijet] < 20: continue # 20 for tau -> j fake measurement if abs(event.Jet_eta[ijet]) > 4.7: continue if muon1.DeltaR(jets[ijet].p4()) < 0.5: continue if muon2.DeltaR(jets[ijet].p4()) < 0.5: continue jetIds.append(ijet) if abs(event.Jet_eta[ijet]) > 2.4: nfjets += 1 else: ncjets += 1 if event.Jet_btagDeepB[ijet] > self.deepcsv_wp.medium: nbtag += 1 bjetIds.append(ijet) if not self.isData and event.Muon_pfRelIso04_all[ dilepton.id1] < 0.50 and event.Muon_pfRelIso04_all[ dilepton.id2] < 0.50: self.btagTool.fillEfficiencies(event, jetIds) # VETOS self.out.extramuon_veto[0], self.out.extraelec_veto[ 0], self.out.dilepton_veto[0] = extraLeptonVetos( event, [dilepton.id1, dilepton.id2], [-1], self.channel) self.out.lepton_vetos[0] = self.out.extramuon_veto[ 0] or self.out.extraelec_veto[0] or self.out.dilepton_veto[0] # EVENT self.out.isData[0] = self.isData self.out.run[0] = event.run self.out.lumi[0] = event.luminosityBlock self.out.event[0] = event.event & 0xffffffffffffffff ###self.out.puppimet[0] = event.PuppiMET_pt ###self.out.puppimetphi[0] = event.PuppiMET_phi ###self.out.metsignificance[0] = event.MET_significance ###self.out.metcovXX[0] = event.MET_covXX ###self.out.metcovXY[0] = event.MET_covXY ###self.out.metcovYY[0] = event.MET_covYY self.out.npvs[0] = event.PV_npvs self.out.npvsGood[0] = event.PV_npvsGood self.out.metfilter[0] = self.filter(event) if not self.isData: self.out.genPartFlav_1[0] = ord( event.Muon_genPartFlav[dilepton.id1]) self.out.genPartFlav_2[0] = ord( event.Muon_genPartFlav[dilepton.id2]) self.out.genmet[0] = event.GenMET_pt self.out.genmetphi[0] = event.GenMET_phi self.out.nPU[0] = event.Pileup_nPU self.out.nTrueInt[0] = event.Pileup_nTrueInt try: self.out.LHE_Njets[0] = event.LHE_Njets except RuntimeError: self.out.LHE_Njets[0] = -1 # MUON 1 self.out.pt_1[0] = event.Muon_pt[dilepton.id1] self.out.eta_1[0] = event.Muon_eta[dilepton.id1] self.out.phi_1[0] = event.Muon_phi[dilepton.id1] self.out.m_1[0] = event.Muon_mass[dilepton.id1] self.out.dxy_1[0] = event.Muon_dxy[dilepton.id1] self.out.dz_1[0] = event.Muon_dz[dilepton.id1] self.out.q_1[0] = event.Muon_charge[dilepton.id1] self.out.pfRelIso04_all_1[0] = event.Muon_pfRelIso04_all[dilepton.id1] # MUON 2 self.out.pt_2[0] = event.Muon_pt[dilepton.id2] self.out.eta_2[0] = event.Muon_eta[dilepton.id2] self.out.phi_2[0] = event.Muon_phi[dilepton.id2] self.out.m_2[0] = event.Muon_mass[dilepton.id2] self.out.dxy_2[0] = event.Muon_dxy[dilepton.id2] self.out.dz_2[0] = event.Muon_dz[dilepton.id2] self.out.q_2[0] = event.Muon_charge[dilepton.id2] self.out.pfRelIso04_all_2[0] = event.Muon_pfRelIso04_all[dilepton.id2] # TAU for jet -> tau fake rate measurement maxId = -1 maxPt = 20 taus = Collection(event, 'Tau') for itau in range(event.nTau): if event.Tau_pt[itau] < maxPt: continue if muon1.DeltaR(taus[itau].p4()) < 0.5: continue if muon2.DeltaR(taus[itau].p4()) < 0.5: continue if abs(event.Tau_eta[itau]) > 2.3: continue if abs(event.Tau_dz[itau]) > 0.2: continue if event.Tau_decayMode[itau] not in [0, 1, 10, 11]: continue if abs(event.Tau_charge[itau]) != 1: continue if ord(event.Tau_idAntiEle[itau]) < 1: continue # VLoose if ord(event.Tau_idAntiMu[itau]) < 1: continue # Loose #if not self.vlooseIso(event,itau): continue maxId = itau maxPt = event.Tau_pt[itau] if maxId > -1: self.out.pt_3[0] = event.Tau_pt[maxId] self.out.eta_3[0] = event.Tau_eta[maxId] self.out.m_3[0] = event.Tau_mass[maxId] self.out.decayMode_3[0] = event.Tau_decayMode[maxId] self.out.idAntiEle_3[0] = ord(event.Tau_idAntiEle[maxId]) self.out.idAntiMu_3[0] = ord(event.Tau_idAntiMu[maxId]) self.out.idMVAoldDM_3[0] = ord(event.Tau_idMVAoldDM[maxId]) self.out.idMVAoldDM2017v1_3[0] = ord( event.Tau_idMVAoldDM2017v1[maxId]) self.out.idMVAoldDM2017v2_3[0] = ord( event.Tau_idMVAoldDM2017v2[maxId]) self.out.idMVAnewDM2017v2_3[0] = ord( event.Tau_idMVAnewDM2017v2[maxId]) self.out.idIso_3[0] = Tau_idIso(event, maxId) if not self.isData: self.out.genPartFlav_3[0] = genmatch( event, maxId) #ord(event.Tau_genPartFlav[maxId]) else: self.out.pt_3[0] = -1 self.out.eta_3[0] = -9 self.out.m_3[0] = -1 self.out.decayMode_3[0] = -1 self.out.idAntiEle_3[0] = -1 self.out.idAntiMu_3[0] = -1 self.out.idMVAoldDM_3[0] = -1 self.out.idMVAoldDM2017v1_3[0] = -1 self.out.idMVAoldDM2017v2_3[0] = -1 self.out.idMVAnewDM2017v2_3[0] = -1 self.out.idIso_3[0] = -1 self.out.genPartFlav_3[0] = -1 # WEIGHTS met = TLorentzVector() met.SetPxPyPzE(event.MET_pt * cos(event.MET_phi), event.MET_pt * sin(event.MET_phi), 0, event.MET_pt) if not self.isData: if self.doRecoil: boson, boson_vis = getBoson(event) self.recoilTool.CorrectTByMeanResolution( met, boson, boson_vis, len(jetIds)) event.MET_pt = met.Pt() event.MET_phi = met.Phi() self.out.m_genboson[0] = boson.M() self.out.pt_genboson[0] = boson.Pt() if self.doZpt: self.out.zptweight[0] = self.zptTool.getZptWeight( boson.Pt(), boson.M()) elif self.doZpt: zboson = getZBoson(event) self.out.m_genboson[0] = zboson.M() self.out.pt_genboson[0] = zboson.Pt() self.out.zptweight[0] = self.zptTool.getZptWeight( zboson.Pt(), zboson.M()) elif self.doTTpt: toppt1, toppt2 = getTTPt(event) self.out.ttptweight[0] = getTTptWeight(toppt1, toppt2) self.out.genweight[0] = event.genWeight self.out.puweight[0] = self.puTool.getWeight(event.Pileup_nTrueInt) self.out.trigweight[0] = self.muSFs.getTriggerSF( self.out.pt_1[0], self.out.eta_1[0]) self.out.idisoweight_1[0] = self.muSFs.getIdIsoSF( self.out.pt_1[0], self.out.eta_1[0]) self.out.idisoweight_2[0] = self.muSFs.getIdIsoSF( self.out.pt_2[0], self.out.eta_2[0]) self.out.btagweight[0] = self.btagTool.getWeight(event, jetIds) self.out.weight[0] = self.out.genweight[0] * self.out.puweight[ 0] * self.out.trigweight[0] * self.out.idisoweight_1[ 0] * self.out.idisoweight_2[0] # JETS self.out.njets[0] = len(jetIds) self.out.njets50[0] = len([j for j in jetIds if event.Jet_pt[j] > 50]) self.out.nfjets[0] = nfjets self.out.ncjets[0] = ncjets self.out.nbtag[0] = nbtag if len(jetIds) > 0: self.out.jpt_1[0] = event.Jet_pt[jetIds[0]] self.out.jeta_1[0] = event.Jet_eta[jetIds[0]] self.out.jphi_1[0] = event.Jet_phi[jetIds[0]] self.out.jdeepb_1[0] = event.Jet_btagDeepB[jetIds[0]] else: self.out.jpt_1[0] = -9. self.out.jeta_1[0] = -9. self.out.jphi_1[0] = -9. self.out.jdeepb_1[0] = -9. if len(jetIds) > 1: self.out.jpt_2[0] = event.Jet_pt[jetIds[1]] self.out.jeta_2[0] = event.Jet_eta[jetIds[1]] self.out.jphi_2[0] = event.Jet_phi[jetIds[1]] self.out.jdeepb_2[0] = event.Jet_btagDeepB[jetIds[1]] else: self.out.jpt_2[0] = -9. self.out.jeta_2[0] = -9. self.out.jphi_2[0] = -9. self.out.jdeepb_2[0] = -9. if len(bjetIds) > 0: self.out.bpt_1[0] = event.Jet_pt[bjetIds[0]] self.out.beta_1[0] = event.Jet_eta[bjetIds[0]] else: self.out.bpt_1[0] = -9. self.out.beta_1[0] = -9. if len(bjetIds) > 1: self.out.bpt_2[0] = event.Jet_pt[bjetIds[1]] self.out.beta_2[0] = event.Jet_eta[bjetIds[1]] else: self.out.bpt_2[0] = -9. self.out.beta_2[0] = -9. self.out.met[0] = event.MET_pt self.out.metphi[0] = event.MET_phi self.out.pfmt_1[0] = sqrt( 2 * self.out.pt_1[0] * event.MET_pt * (1 - cos(deltaPhi(self.out.phi_1[0], event.MET_phi)))) self.out.pfmt_2[0] = sqrt( 2 * self.out.pt_2[0] * event.MET_pt * (1 - cos(deltaPhi(self.out.phi_2[0], event.MET_phi)))) self.out.m_vis[0] = (muon1 + muon2).M() self.out.pt_ll[0] = (muon1 + muon2).Pt() self.out.dR_ll[0] = muon1.DeltaR(muon2) self.out.dphi_ll[0] = deltaPhi(self.out.phi_1[0], self.out.phi_2[0]) self.out.deta_ll[0] = abs(self.out.eta_1[0] - self.out.eta_2[0]) # PZETA leg1 = TVector3(muon1.Px(), muon1.Py(), 0.) leg2 = TVector3(muon2.Px(), muon2.Py(), 0.) zetaAxis = TVector3(leg1.Unit() + leg2.Unit()).Unit() pzeta_vis = leg1 * zetaAxis + leg2 * zetaAxis pzeta_miss = met.Vect() * zetaAxis self.out.pzetamiss[0] = pzeta_miss self.out.pzetavis[0] = pzeta_vis self.out.dzeta[0] = pzeta_miss - 0.85 * pzeta_vis self.out.tree.Fill() return True
def beginFile(self, inputFile, outputFile, inputTree, wrappedOutputTree): self.out = wrappedOutputTree self.out.branch("isMC", "I") self.out.branch("is2016", "I") self.out.branch("is2017", "I") self.out.branch("is2018", "I") self.out.branch("is4m", "I") self.out.branch("is4e", "I") self.out.branch("is2e2m", "I") self.out.branch("isDoubleElectronTrigger", "I") self.out.branch("isDoubleMuonTrigger", "I") self.out.branch("isMuonElectronTrigger", "I") self.out.branch("passedMETFilters", "I") self.out.branch("nCleanElectron", "I") self.out.branch("nCleanMuon", "I") self.out.branch("nCleanTau", "I") self.out.branch("nCleanPhoton", "I") self.out.branch("nCleanJet", "I") self.out.branch("nCleanBTagJet", "I") self.out.branch("HT30", "F") self.out.branch("iLepton1", "I") self.out.branch("iLepton2", "I") self.out.branch("iLepton3", "I") self.out.branch("iLepton4", "I") self.out.branch("Z1_pt", "F") self.out.branch("Z1_eta", "F") self.out.branch("Z1_phi", "F") self.out.branch("Z1_mass", "F") self.out.branch("Z1_dEta", "F") self.out.branch("Z1_dPhi", "F") self.out.branch("Z1_dR", "F") self.out.branch("Z2_pt", "F") self.out.branch("Z2_eta", "F") self.out.branch("Z2_phi", "F") self.out.branch("Z2_mass", "F") self.out.branch("Z2_dEta", "F") self.out.branch("Z2_dPhi", "F") self.out.branch("Z2_dR", "F") self.out.branch("H_pt", "F") self.out.branch("H_eta", "F") self.out.branch("H_phi", "F") self.out.branch("H_mass", "F") self.out.branch("H_dEta", "F") self.out.branch("H_dPhi", "F") self.out.branch("H_dR", "F") self.out.branch("cosThetaStar", "F") self.out.branch("cosTheta1", "F") self.out.branch("cosTheta2", "F") self.out.branch("phi", "F") self.out.branch("phi1", "F") #self.out.branch("genCosThetaStar", "F") #self.out.branch("genCosTheta1", "F") #self.out.branch("genPhi1", "F") self.out.branch("lumiWeight", "F") self.out.branch("lheWeight", "F") self.out.branch("stitchWeight", "F") self.out.branch("puWeight", "F") self.out.branch("topWeight", "F") self.out.branch("qcdnloWeight", "F") self.out.branch("qcdnnloWeight", "F") self.out.branch("ewknloWeight", "F") self.out.branch("triggerWeight", "F") self.out.branch("leptonWeight", "F") self.out.branch("eventWeightLumi", "F") self.fileName = inputFile.GetName() self.sampleName = getNameFromFile(self.fileName) self.isMC = not "Run201" in self.fileName if self.verbose >= 0: print "+ Opening file", self.fileName # b-tagging working points for DeepCSV # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation2016Legacy # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation94X # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation102X if "Run2016" in self.fileName or "Summer16" in self.fileName: self.year = 2016 self.lumi = 35920. self.btagLoose = 0.2217 #0.0614 self.btagMedium = 0.6321 #0.3093 self.btagTight = 0.8953 #0.7221 elif "Run2017" in self.fileName or "Fall17" in self.fileName: self.year = 2017 self.lumi = 41530. self.btagLoose = 0.1522 #0.0521 self.btagMedium = 0.4941 #0.3033 self.btagTight = 0.8001 #0.7489 elif "Run2018" in self.fileName or "Autumn18" in self.fileName: self.year = 2018 self.lumi = 59740. self.btagLoose = 0.1241 #0.0494 self.btagMedium = 0.4184 #0.2770 self.btagTight = 0.7527 #0.7264 else: if self.verbose >= 0: print "- Unknown year, aborting module" import sys sys.exit() self.xs = XS[self.sampleName] if self.sampleName in XS else 0. self.nevents = EV[self.sampleName] if self.sampleName in EV else 0. self.xsWeight = self.xs / self.nevents if self.nevents > 0 else 1. self.lumiWeight = self.xsWeight * self.lumi if self.isMC else 1. self.isLO = abs( self.nevents % 1 ) < 1.e-6 # if True, the event count is integer, so the weight should be normalized (+1) if self.verbose >= 1: print "+ Module parameters: isMC", self.isMC, ", year", self.year, ", lumi", self.lumi, "pb" if self.verbose >= 1: print "+ Sample", self.sampleName, ", XS", self.xs, ", events", self.nevents if self.verbose >= 1: print "+ Weight", self.lumiWeight if self.isMC and self.isLO and self.verbose >= 1: print "+ Sample is LO, gen weight will be set to 1" # self.puTool = PileupWeightTool(year = year) if self.isMC else None self.DoubleElectronTriggers = [ "HLT_Ele23_Ele12_CaloIdL_TrackIdL_IsoVL", "HLT_Ele23_Ele12_CaloIdL_TrackIdL_IsoVL_DZ", "HLT_DoubleEle33_CaloIdL_MW", "HLT_Ele16_Ele12_Ele8_CaloIdL_TrackIdL" ] self.DoubleMuonTriggers = [ "HLT_Mu17_TrkIsoVVL_Mu8_TrkIsoVVL", "HLT_Mu17_TrkIsoVVL_Mu8_TrkIsoVVL_DZ_Mass3p8", "HLT_Mu17_TrkIsoVVL_Mu8_TrkIsoVVL_DZ_Mass8", "HLT_TripleMu_12_10_5", "HLT_TripleMu_10_5_5_DZ" ] self.MuonElectronTriggers = [ "HLT_Mu8_TrkIsoVVL_Ele23_CaloIdL_TrackIdL_IsoVL", "HLT_Mu8_TrkIsoVVL_Ele23_CaloIdL_TrackIdL_IsoVL_DZ", "HLT_Mu23_TrkIsoVVL_Ele12_CaloIdL_TrackIdL_IsoVL", "HLT_Mu23_TrkIsoVVL_Ele12_CaloIdL_TrackIdL_IsoVL_DZ", "HLT_Mu12_TrkIsoVVL_Ele23_CaloIdL_TrackIdL_IsoVL_DZ", "HLT_Mu8_DiEle12_CaloIdL_TrackIdL", "HLT_Mu8_DiEle12_CaloIdL_TrackIdL_DZ", "HLT_DiMu9_Ele9_CaloIdL_TrackIdL", "HLT_DiMu9_Ele9_CaloIdL_TrackIdL_DZ" ] if self.isMC: self.muSFs = MuonSFs(year=self.year) self.elSFs = ElectronSFs(year=self.year) self.puTool = PileupWeightTool(year=self.year)
def beginFile(self, inputFile, outputFile, inputTree, wrappedOutputTree): self.out = wrappedOutputTree self.out.branch("iSkim", "I") self.out.branch("isMC", "I") self.out.branch("isSingleMuIsoTrigger", "I") self.out.branch("isSingleMuTrigger", "I") self.out.branch("isDoubleMuonTrigger", "I") self.out.branch("isSingleEleIsoTrigger", "I") self.out.branch("isSingleEleTrigger", "I") self.out.branch("passedMETFilters", "I") self.out.branch("nCleanElectron", "I") self.out.branch("nCleanMuon", "I") self.out.branch("nCleanJet", "I") self.out.branch("Z_mass", "F") self.out.branch("Z_pt", "F") self.out.branch("W_mass", "F") self.out.branch("W_tmass", "F") self.out.branch("W_pt", "F") self.out.branch("ll_dEta", "F") self.out.branch("ll_dPhi", "F") self.out.branch("ll_dR", "F") self.out.branch("Wqq_mass", "F") self.out.branch("Tlvb1_mass", "F") self.out.branch("Tlvb2_mass", "F") self.out.branch("Tqqb1_mass", "F") self.out.branch("Tqqb2_mass", "F") self.out.branch("jj_mass", "F") self.out.branch("jj_pt", "F") self.out.branch("jj_dEta", "F") self.out.branch("jj_dPhi", "F") self.out.branch("jj_dR", "F") self.out.branch("nj_mass", "F") self.out.branch("vis_mass", "F") self.out.branch("lljj_mass", "F") self.out.branch("minMuonIso", "F") self.out.branch("maxMuonIso", "F") self.out.branch("minMuonMetDPhi", "F") self.out.branch("maxMuonMetDPhi", "F") self.out.branch("minMuonJetDR", "F") self.out.branch("HT30", "F") self.out.branch("nj20", "I") self.out.branch("nj30", "I") self.out.branch("nj40", "I") self.out.branch("nBJet", "I") self.out.branch("CSV1", "F") self.out.branch("CSV2", "F") self.out.branch("CSV3", "F") self.out.branch("CSV4", "F") self.out.branch("iCSV1", "I") self.out.branch("iCSV2", "I") self.out.branch("iCSV3", "I") self.out.branch("iCSV4", "I") self.out.branch("lumiWeight", "F") self.out.branch("lheWeight", "F") self.out.branch("stitchWeight", "F") self.out.branch("puWeight", "F") self.out.branch("topWeight", "F") self.out.branch("qcdnloWeight", "F") self.out.branch("qcdnnloWeight", "F") self.out.branch("ewknloWeight", "F") self.out.branch("triggerWeight", "F") self.out.branch("leptonWeight", "F") self.out.branch("eventWeightLumi", "F") self.fileName = inputFile.GetName() self.sampleName = getNameFromFile(self.fileName) self.isMC = not "Run201" in self.fileName print "+ Opening file", self.fileName # b-tagging working points for DeepCSV # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation2016Legacy # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation94X # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation102X if "Run2016" in self.fileName or "Summer16" in self.fileName: self.year = 2016 self.lumi = 35920. self.btagLoose = 0.2217 #0.0614 self.btagMedium = 0.6321 #0.3093 self.btagTight = 0.8953 #0.7221 elif "Run2017" in self.fileName or "Fall17" in self.fileName: self.year = 2017 self.lumi = 41530. self.btagLoose = 0.1522 #0.0521 self.btagMedium = 0.4941 #0.3033 self.btagTight = 0.8001 #0.7489 elif "Run2018" in self.fileName or "Autumn18" in self.fileName: self.year = 2018 self.lumi = 59740. self.btagLoose = 0.1241 #0.0494 self.btagMedium = 0.4184 #0.2770 self.btagTight = 0.7527 #0.7264 else: print "- Unknown year, aborting module" import sys sys.exit() self.xs = XS[self.sampleName] if self.sampleName in XS else 0. self.nevents = EV[self.sampleName] if self.sampleName in EV else 0. self.xsWeight = self.xs / self.nevents if self.nevents > 0 else 1. self.lumiWeight = self.xsWeight * self.lumi if self.isMC else 1. self.isLO = abs( self.nevents % 1 ) < 1.e-6 # if True, the event count is integer, so the weight should be normalized (+1) print "+ Module parameters: isMC", self.isMC, ", year", self.year, ", lumi", self.lumi, "pb" print "+ Sample", self.sampleName, ( "is LO" if self.isLO else "is not LO"), ", XS", self.xs, ", events", self.nevents print "+ Weight", self.lumiWeight if self.isMC and self.isLO: print "+ Sample is LO, gen weight will be set to 1" # self.puTool = PileupWeightTool(year = year) if self.isMC else None self.SingleMuIsoTriggers = [ "HLT_IsoMu24", "HLT_IsoTkMu24", "HLT_IsoMu27", "HLT_IsoTkMu27" ] self.SingleMuTriggers = [ "HLT_Mu50", "HLT_TkMu50", "HLT_Mu100", "HLT_TkMu100" ] self.DoubleMuonTriggers = [ "HLT_Mu17_Mu8", "HLT_Mu17_Mu8_DZ", "HLT_Mu17_TkMu8_DZ" ] self.SingleEleIsoTriggers = [ "HLT_Ele27_WPTight_Gsf", "HLT_Ele27_WPLoose_Gsf", "HLT_Ele32_WPTight_Gsf", "HLT_Ele35_WPTight_Gsf" ] self.SingleEleTriggers = [ "HLT_Ele105_CaloIdVT_GsfTrkIdT", "HLT_Ele115_CaloIdVT_GsfTrkIdT", "HLT_Photon175", "HLT_Photon200" ] if self.isMC: self.muSFs = MuonSFs(year=self.year) self.elSFs = ElectronSFs(year=self.year) self.puTool = PileupWeightTool(year=self.year) # self.btagToolAK8 = BTagWeightTool('CSVv2','AK8','loose',sigma='central',channel='ll',year=year) # self.btagToolAK4 = BTagWeightTool('CSVv2','AK4','loose',sigma='central',channel='ll',year=year) # self.btagToolAK8_deep = BTagWeightTool('DeepCSV','AK8','loose',sigma='central',channel='ll',year=year) # self.btagToolAK8_deep_up = BTagWeightTool('DeepCSV','AK8','loose',sigma='up',channel='ll',year=year) # self.btagToolAK8_deep_down = BTagWeightTool('DeepCSV','AK8','loose',sigma='down',channel='ll',year=year) # self.btagToolAK4_deep = BTagWeightTool('DeepCSV','AK4','loose',sigma='central',channel='ll',year=year) # self.btagToolAK4_deep_up = BTagWeightTool('DeepCSV','AK4','loose',sigma='up',channel='ll',year=year) # self.btagToolAK4_deep_down = BTagWeightTool('DeepCSV','AK4','loose',sigma='down',channel='ll',year=year) if 'DYJetsToLL_M-50' in self.fileName: self.VptCorr = DYCorrection('DYJetsToLL') elif 'ZJetsToNuNu' in self.fileName: self.VptCorr = DYCorrection('ZJetsToNuNu') elif 'WJetsToLNu' in self.fileName: self.VptCorr = DYCorrection('WJetsToLNu') else: self.VptCorr = None
class SameSign(Module): def __init__(self): self.writeHistFile = True def beginJob(self, histFile=None, histDirName=None): Module.beginJob(self, histFile, histDirName) self.event = 0 self.hists = {} self.hists["Events"] = ROOT.TH1F("Events", "Events", 1, 0, 1) # self.addObject(self.h_events) # self.h_events.SetDirectory def endJob(self): Module.endJob(self) print "+ Module ended successfully," #, self.h_events.GetEntries(), "events analyzed" pass def beginFile(self, inputFile, outputFile, inputTree, wrappedOutputTree): self.out = wrappedOutputTree self.out.branch("iSkim", "I") self.out.branch("isMC", "I") self.out.branch("isSingleMuIsoTrigger", "I") self.out.branch("isSingleMuTrigger", "I") self.out.branch("isDoubleMuonTrigger", "I") self.out.branch("isSingleEleIsoTrigger", "I") self.out.branch("isSingleEleTrigger", "I") self.out.branch("passedMETFilters", "I") self.out.branch("nCleanElectron", "I") self.out.branch("nCleanMuon", "I") self.out.branch("nCleanJet", "I") self.out.branch("Z_mass", "F") self.out.branch("Z_pt", "F") self.out.branch("W_mass", "F") self.out.branch("W_tmass", "F") self.out.branch("W_pt", "F") self.out.branch("ll_dEta", "F") self.out.branch("ll_dPhi", "F") self.out.branch("ll_dR", "F") self.out.branch("Wqq_mass", "F") self.out.branch("Tlvb1_mass", "F") self.out.branch("Tlvb2_mass", "F") self.out.branch("Tqqb1_mass", "F") self.out.branch("Tqqb2_mass", "F") self.out.branch("jj_mass", "F") self.out.branch("jj_pt", "F") self.out.branch("jj_dEta", "F") self.out.branch("jj_dPhi", "F") self.out.branch("jj_dR", "F") self.out.branch("nj_mass", "F") self.out.branch("vis_mass", "F") self.out.branch("lljj_mass", "F") self.out.branch("minMuonIso", "F") self.out.branch("maxMuonIso", "F") self.out.branch("minMuonMetDPhi", "F") self.out.branch("maxMuonMetDPhi", "F") self.out.branch("minMuonJetDR", "F") self.out.branch("HT30", "F") self.out.branch("nj20", "I") self.out.branch("nj30", "I") self.out.branch("nj40", "I") self.out.branch("nBJet", "I") self.out.branch("CSV1", "F") self.out.branch("CSV2", "F") self.out.branch("CSV3", "F") self.out.branch("CSV4", "F") self.out.branch("iCSV1", "I") self.out.branch("iCSV2", "I") self.out.branch("iCSV3", "I") self.out.branch("iCSV4", "I") self.out.branch("lumiWeight", "F") self.out.branch("lheWeight", "F") self.out.branch("stitchWeight", "F") self.out.branch("puWeight", "F") self.out.branch("topWeight", "F") self.out.branch("qcdnloWeight", "F") self.out.branch("qcdnnloWeight", "F") self.out.branch("ewknloWeight", "F") self.out.branch("triggerWeight", "F") self.out.branch("leptonWeight", "F") self.out.branch("eventWeightLumi", "F") self.fileName = inputFile.GetName() self.sampleName = getNameFromFile(self.fileName) self.isMC = not "Run201" in self.fileName print "+ Opening file", self.fileName # b-tagging working points for DeepCSV # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation2016Legacy # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation94X # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation102X if "Run2016" in self.fileName or "Summer16" in self.fileName: self.year = 2016 self.lumi = 35920. self.btagLoose = 0.2217 #0.0614 self.btagMedium = 0.6321 #0.3093 self.btagTight = 0.8953 #0.7221 elif "Run2017" in self.fileName or "Fall17" in self.fileName: self.year = 2017 self.lumi = 41530. self.btagLoose = 0.1522 #0.0521 self.btagMedium = 0.4941 #0.3033 self.btagTight = 0.8001 #0.7489 elif "Run2018" in self.fileName or "Autumn18" in self.fileName: self.year = 2018 self.lumi = 59740. self.btagLoose = 0.1241 #0.0494 self.btagMedium = 0.4184 #0.2770 self.btagTight = 0.7527 #0.7264 else: print "- Unknown year, aborting module" import sys sys.exit() self.xs = XS[self.sampleName] if self.sampleName in XS else 0. self.nevents = EV[self.sampleName] if self.sampleName in EV else 0. self.xsWeight = self.xs / self.nevents if self.nevents > 0 else 1. self.lumiWeight = self.xsWeight * self.lumi if self.isMC else 1. self.isLO = abs( self.nevents % 1 ) < 1.e-6 # if True, the event count is integer, so the weight should be normalized (+1) print "+ Module parameters: isMC", self.isMC, ", year", self.year, ", lumi", self.lumi, "pb" print "+ Sample", self.sampleName, ( "is LO" if self.isLO else "is not LO"), ", XS", self.xs, ", events", self.nevents print "+ Weight", self.lumiWeight if self.isMC and self.isLO: print "+ Sample is LO, gen weight will be set to 1" # self.puTool = PileupWeightTool(year = year) if self.isMC else None self.SingleMuIsoTriggers = [ "HLT_IsoMu24", "HLT_IsoTkMu24", "HLT_IsoMu27", "HLT_IsoTkMu27" ] self.SingleMuTriggers = [ "HLT_Mu50", "HLT_TkMu50", "HLT_Mu100", "HLT_TkMu100" ] self.DoubleMuonTriggers = [ "HLT_Mu17_Mu8", "HLT_Mu17_Mu8_DZ", "HLT_Mu17_TkMu8_DZ" ] self.SingleEleIsoTriggers = [ "HLT_Ele27_WPTight_Gsf", "HLT_Ele27_WPLoose_Gsf", "HLT_Ele32_WPTight_Gsf", "HLT_Ele35_WPTight_Gsf" ] self.SingleEleTriggers = [ "HLT_Ele105_CaloIdVT_GsfTrkIdT", "HLT_Ele115_CaloIdVT_GsfTrkIdT", "HLT_Photon175", "HLT_Photon200" ] if self.isMC: self.muSFs = MuonSFs(year=self.year) self.elSFs = ElectronSFs(year=self.year) self.puTool = PileupWeightTool(year=self.year) # self.btagToolAK8 = BTagWeightTool('CSVv2','AK8','loose',sigma='central',channel='ll',year=year) # self.btagToolAK4 = BTagWeightTool('CSVv2','AK4','loose',sigma='central',channel='ll',year=year) # self.btagToolAK8_deep = BTagWeightTool('DeepCSV','AK8','loose',sigma='central',channel='ll',year=year) # self.btagToolAK8_deep_up = BTagWeightTool('DeepCSV','AK8','loose',sigma='up',channel='ll',year=year) # self.btagToolAK8_deep_down = BTagWeightTool('DeepCSV','AK8','loose',sigma='down',channel='ll',year=year) # self.btagToolAK4_deep = BTagWeightTool('DeepCSV','AK4','loose',sigma='central',channel='ll',year=year) # self.btagToolAK4_deep_up = BTagWeightTool('DeepCSV','AK4','loose',sigma='up',channel='ll',year=year) # self.btagToolAK4_deep_down = BTagWeightTool('DeepCSV','AK4','loose',sigma='down',channel='ll',year=year) if 'DYJetsToLL_M-50' in self.fileName: self.VptCorr = DYCorrection('DYJetsToLL') elif 'ZJetsToNuNu' in self.fileName: self.VptCorr = DYCorrection('ZJetsToNuNu') elif 'WJetsToLNu' in self.fileName: self.VptCorr = DYCorrection('WJetsToLNu') else: self.VptCorr = None def endFile(self, inputFile, outputFile, inputTree, wrappedOutputTree): outputFile.mkdir("Hists") outputFile.cd("Hists") for histname, hist in self.hists.iteritems(): hist.Write() outputFile.cd("..") print "+ File closed successfully" pass def analyze(self, event): iSkim = 0 eventWeightLumi, lheWeight, stitchWeight, puWeight, qcdnloWeight, qcdnnloWeight, ewknloWeight, topWeight = 1., 1., 1., 1., 1., 1., 1., 1. triggerWeight, leptonWeight = 1., 1. MinMuonIso, MaxMuonIso, MinMuonMetDPhi, MaxMuonMetDPhi, MinMuonJetDR = -1., -1., -1., -1., -1. mZ, mW, mT, ptZ, ptW = -1., -1., -1., -1., -1. dEtaLL, dPhiLL, dRLL = -1., -1., -1. mJJ, ptJJ, dEtaJJ, dPhiJJ, dRJJ = -1., -1., -1., -1., -1. mLLJJ, mNJ = -1., -1. mHadW, mLepTop1, mLepTop2, mHadTop1, mHadTop2 = -1., -1., -1., -1., -1. isSingleMuIsoTrigger, isSingleMuTrigger, isDoubleMuonTrigger, isSingleEleIsoTrigger, isSingleEleTrigger = False, False, False, False, False for t in self.SingleMuIsoTriggers: if hasattr(event, t) and getattr(event, t): isSingleMuIsoTrigger = True for t in self.SingleMuTriggers: if hasattr(event, t) and getattr(event, t): isSingleMuTrigger = True for t in self.DoubleMuonTriggers: if hasattr(event, t) and getattr(event, t): isDoubleMuonTrigger = True for t in self.SingleEleIsoTriggers: if hasattr(event, t) and getattr(event, t): isSingleEleIsoTrigger = True for t in self.SingleEleTriggers: if hasattr(event, t) and getattr(event, t): isSingleEleTrigger = True lheWeight = 1. if self.isMC: # Event weight if not self.isLO and hasattr(event, "LHEWeight_originalXWGTUP"): lheWeight = event.LHEWeight_originalXWGTUP GenVpt = self.VptCorr.getGenVpt( event) if not self.VptCorr is None else 0. # MC stitching weight # W+jets inclusive and exclusive if 'WJetsToLNu_TuneCUETP8M1_13TeV-amcatnloFXFX-pythia8' in self.fileName and 'Summer16' in self.fileName: if event.LHE_Vpt > 100.: stitchWeight = 0. # Z+jets and Z+gamma if self.fileName.startswith( 'ZGTo2LG_TuneCUETP8M1') or self.fileName.startswith( 'ZGToLLG_01J_5f_TuneCP5') or self.fileName.startswith( 'DYJetsToLL_M-50_Tune'): nGenPhotons = 0 photonPtTh = 15. if self.fileName.startswith( 'ZGTo2LG_TuneCUETP8M1') or self.fileName.startswith( 'DYJetsToLL_M-50_TuneCUETP8M1') else 20. for i in range(event.nGenPart): if GenPart_pdgId[i] == 22 and TMath.Odd( GenPart_statusFlags[i] ) and GenPart_pt > photonPtTh: nGenPhotons += 1 if self.fileName.startswith('ZG') and nGenPhotons <= 0: stitchWeight = 0. if self.fileName.startswith( 'DYJetsToLL_M-50') and nGenPhotons >= 1: stitchWeight = 0. # PU weight puWeight = self.puTool.getWeight(event.Pileup_nTrueInt) # Higher order correction weights if not self.VptCorr is None: if not 'amcatnlo' in self.fileName: qcdnloWeight = self.VptCorr.getWeightQCDNLO(GenVpt) qcdnnloWeight = self.VptCorr.getWeightQCDNNLO(GenVpt) ewknloWeight = self.VptCorr.getWeightEWKNLO(GenVpt) if 'TTTo' in self.fileName: Top1_pt, Top2_pt = getTTPt(event) topWeight = getTTptWeight(Top1_pt, Top2_pt) self.hists["Events"].Fill(0, lheWeight) # electrons = Collection(event, "Electron") # muons = Collection(event, "Muon") # jets = Collection(event, "Jet") # eventSum = ROOT.TLorentzVector() # #select events with at least 2 muons # if len(muons) >=2 : # for lep in muons : #loop on muons # eventSum += lep.p4() # for lep in electrons : #loop on electrons # eventSum += lep.p4() # for j in jets : #loop on jets # eventSum += j.p4() # Clean collections # Electrons cleanElectron = [] for i in range(event.nElectron): if event.Electron_pt[i] > 10. and event.Electron_cutBased[i] >= 2: p4 = TLorentzVector() p4.SetPtEtaPhiM(event.Electron_pt[i], event.Electron_eta[i], event.Electron_phi[i], event.Electron_mass[i]) cleanElectron.append(p4) # Muons cleanMuon = [] for i in range(event.nMuon): if event.Muon_pt[i] > 10. and event.Muon_mediumId[ i] and event.Muon_pfRelIso03_all[i] < 0.15: p4 = TLorentzVector() p4.SetPtEtaPhiM(event.Muon_pt[i], event.Muon_eta[i], event.Muon_phi[i], event.Muon_mass[i]) cleanMuon.append(p4) # Jets and Event variables cleanJet, cleanBJet, cleanNonBJet = [], [], [] HT30, Nj20, Nj30, Nj40, nBJet = 0., 0, 0, 0, 0 CSVs = [] twoJets, allJets = TLorentzVector(), TLorentzVector() for i in range(event.nJet): if event.Jet_jetId[i] >= 6 and abs(event.Jet_eta[i]) < 2.5: p4 = TLorentzVector() p4.SetPtEtaPhiM(event.Jet_pt[i], event.Jet_eta[i], event.Jet_phi[i], event.Jet_mass[i]) # remove overlaps with electrons and muons cleanFromLeptons = True for e in range(len(cleanElectron)): if cleanElectron[e].DeltaR(p4) < 0.4: cleanFromLeptons = False for m in range(len(cleanMuon)): if cleanMuon[m].DeltaR(p4) < 0.4: cleanFromLeptons = False # fill variables if cleanFromLeptons: if event.Jet_pt[i] > 20.: Nj20 += 1 if event.Jet_pt[i] > 30.: HT30 += event.Jet_pt[i] Nj30 += 1 cleanJet.append(p4) if event.Jet_btagDeepB[i] >= self.btagMedium: cleanBJet.append(p4) else: cleanNonBJet.append(p4) CSVs.append([i, event.Jet_btagDeepB[i]]) if len(cleanJet) < 2: twoJets += p4 allJets += p4 if event.Jet_pt[i] > 40.: Nj40 += 1 # b-tag ranking nBJet = len(cleanBJet) CSV1, CSV2, CSV3, CSV4, iCSV1, iCSV2, iCSV3, iCSV4 = 0., 0., 0., 0., -1, -1, -1, -1 CSVs.sort(key=lambda x: x[1], reverse=True) if len(CSVs) > 0: iCSV1, CSV1 = CSVs[0][0], CSVs[0][1] if len(CSVs) > 1: iCSV2, CSV2 = CSVs[1][0], CSVs[1][1] if len(CSVs) > 2: iCSV3, CSV3 = CSVs[2][0], CSVs[2][1] if len(CSVs) > 3: iCSV4, CSV4 = CSVs[3][0], CSVs[3][1] if len(cleanJet) >= 2: mJJ = (cleanJet[0] + cleanJet[1]).M() ptJJ = (cleanJet[0] + cleanJet[1]).Pt() dEtaJJ = abs(cleanJet[0].Eta() - cleanJet[1].Eta()) dPhiJJ = abs(cleanJet[0].DeltaPhi(cleanJet[1])) dRJJ = cleanJet[0].DeltaR(cleanJet[1]) mNJ = allJets.M() Lepton1, Lepton2, Lepton3, Neutrino, MET, LLJJ, Vis = TLorentzVector( ), TLorentzVector(), TLorentzVector(), TLorentzVector( ), TLorentzVector(), TLorentzVector(), TLorentzVector() MET.SetPtEtaPhiM(event.MET_pt, 0., event.MET_phi, 0.) # Categorization: # iSkim = 1: 2 muons (OS or SS) # iSkim = 2: 1 muon and 1 electron (no OS requirement) # iSkim = 3: 3 muons (assumed that they are not 3 same-sign) # iSkim = 4: 2 muons (OS) and 1 electron # iSkim = 5: 1 muons, 3 jets, >= 1 btag # iSkim = 6: 2 electrons # case 3a: 3 lepton CR (3mu) if iSkim == 0 and event.nMuon >= 3: if (isSingleMuIsoTrigger or isSingleMuTrigger) and event.Muon_pt[ 0] > 27. and event.Muon_pt[1] > 15. and event.Muon_pt[ 2] > 15. and event.Muon_mediumId[ 0] and event.Muon_mediumId[ 1] and event.Muon_mediumId[2]: Lepton1.SetPtEtaPhiM(event.Muon_pt[0], event.Muon_eta[0], event.Muon_phi[0], event.Muon_mass[0]) Lepton2.SetPtEtaPhiM(event.Muon_pt[1], event.Muon_eta[1], event.Muon_phi[1], event.Muon_mass[1]) Lepton3.SetPtEtaPhiM(event.Muon_pt[2], event.Muon_eta[2], event.Muon_phi[2], event.Muon_mass[2]) if event.Muon_charge[0] * event.Muon_charge[1] < 0: mll = (Lepton1 + Lepton2).M() ptll = (Lepton1 + Lepton2).Pt() detall = abs(Lepton1.Eta() - Lepton2.Eta()) dphill = abs(Lepton1.DeltaPhi(Lepton2)) drll = Lepton1.DeltaR(Lepton2) else: mll = (Lepton1 + Lepton3).M() ptll = (Lepton1 + Lepton3).Pt() detall = abs(Lepton1.Eta() - Lepton3.Eta()) dphill = abs(Lepton1.DeltaPhi(Lepton3)) drll = Lepton1.DeltaR(Lepton3) if mll > 15.: iSkim = 3 # Variables mZ, ptZ = mll, ptll dEtaLL, dPhiLL, dRLL = detall, dphill, drll MinMuonIso = min( min(event.Muon_pfRelIso03_all[0], event.Muon_pfRelIso03_all[1]), event.Muon_pfRelIso03_all[2]) MaxMuonIso = max( max(event.Muon_pfRelIso03_all[0], event.Muon_pfRelIso03_all[1]), event.Muon_pfRelIso03_all[2]) MinMuonMetDPhi = min( min(abs(Lepton1.DeltaPhi(MET)), abs(Lepton2.DeltaPhi(MET))), abs(Lepton3.DeltaPhi(MET))) MaxMuonMetDPhi = max( max(abs(Lepton1.DeltaPhi(MET)), abs(Lepton2.DeltaPhi(MET))), abs(Lepton3.DeltaPhi(MET))) MinMuonJetDR = min( min(getMinMuonJetDR(cleanJet, Lepton1), getMinMuonJetDR(cleanJet, Lepton2)), getMinMuonJetDR(cleanJet, Lepton3)) LLJJ = twoJets + Lepton1 + Lepton2 Vis = allJets + Lepton1 + Lepton2 + Lepton3 # Weights if self.isMC: triggerWeight = self.muSFs.getTriggerSF( event.Muon_pt[0], event.Muon_eta[0]) IdSF1 = self.muSFs.getIdSF(event.Muon_pt[0], event.Muon_eta[0], 2) IsoSF1 = self.muSFs.getIsoSF(event.Muon_pt[0], event.Muon_eta[0]) IdSF2 = self.muSFs.getIdSF(event.Muon_pt[1], event.Muon_eta[1], 2) IsoSF2 = self.muSFs.getIsoSF(event.Muon_pt[1], event.Muon_eta[1]) IdSF3 = self.muSFs.getIdSF(event.Muon_pt[2], event.Muon_eta[2], 2) IsoSF3 = self.muSFs.getIsoSF(event.Muon_pt[2], event.Muon_eta[2]) leptonWeight = IdSF1 * IsoSF1 * IdSF2 * IsoSF2 * IdSF3 * IsoSF3 # case 3b: 3 lepton CR (2mu 1e) if iSkim == 0 and event.nMuon >= 2 and event.nElectron >= 1: if (isSingleMuIsoTrigger or isSingleMuTrigger) and event.Muon_pt[ 0] > 27. and event.Muon_pt[1] > 15. and event.Electron_pt[ 0] > 15. and event.Muon_mediumId[ 0] and event.Muon_mediumId[ 1] and event.Electron_cutBased[ 0] >= 2 and event.Muon_charge[ 0] * event.Muon_charge[1] < 0: Lepton1.SetPtEtaPhiM(event.Muon_pt[0], event.Muon_eta[0], event.Muon_phi[0], event.Muon_mass[0]) Lepton2.SetPtEtaPhiM(event.Muon_pt[1], event.Muon_eta[1], event.Muon_phi[1], event.Muon_mass[1]) Lepton3.SetPtEtaPhiM(event.Electron_pt[0], event.Electron_eta[0], event.Electron_phi[0], event.Electron_mass[0]) mll = (Lepton1 + Lepton2).M() ptll = (Lepton1 + Lepton2).Pt() if mll > 15.: iSkim = 4 # Variables mZ, ptZ = mll, ptll dEtaLL = abs(Lepton1.Eta() - Lepton2.Eta()) dPhiLL = abs(Lepton1.DeltaPhi(Lepton2)) dRLL = Lepton1.DeltaR(Lepton2) MinMuonIso = min(event.Muon_pfRelIso03_all[0], event.Muon_pfRelIso03_all[1]) MaxMuonIso = max(event.Muon_pfRelIso03_all[0], event.Muon_pfRelIso03_all[1]) MinMuonMetDPhi = min( min(abs(Lepton1.DeltaPhi(MET)), abs(Lepton2.DeltaPhi(MET))), abs(Lepton3.DeltaPhi(MET))) MaxMuonMetDPhi = max( max(abs(Lepton1.DeltaPhi(MET)), abs(Lepton2.DeltaPhi(MET))), abs(Lepton3.DeltaPhi(MET))) MinMuonJetDR = min(getMinMuonJetDR(cleanJet, Lepton1), getMinMuonJetDR(cleanJet, Lepton2)) LLJJ = twoJets + Lepton1 + Lepton2 Vis = allJets + Lepton1 + Lepton2 + Lepton3 # Weights if self.isMC: triggerWeight = self.muSFs.getTriggerSF( event.Muon_pt[0], event.Muon_eta[0]) IdSF1 = self.muSFs.getIdSF(event.Muon_pt[0], event.Muon_eta[0], 2) IsoSF1 = self.muSFs.getIsoSF(event.Muon_pt[0], event.Muon_eta[0]) IdSF2 = self.muSFs.getIdSF(event.Muon_pt[1], event.Muon_eta[1], 2) IsoSF2 = self.muSFs.getIsoSF(event.Muon_pt[1], event.Muon_eta[1]) IdIsoSF3 = self.elSFs.getIdIsoSF( event.Electron_pt[0], event.Electron_eta[0]) leptonWeight = IdSF1 * IsoSF1 * IdSF2 * IsoSF2 * IdIsoSF3 # case 1: Z->mumu CR (2 mu) if iSkim == 0 and event.nMuon >= 2: if (isSingleMuIsoTrigger or isSingleMuTrigger) and event.Muon_pt[ 0] > 27. and event.Muon_pt[1] > 7. and event.Muon_mediumId[ 0] and event.Muon_mediumId[1]: Lepton1.SetPtEtaPhiM(event.Muon_pt[0], event.Muon_eta[0], event.Muon_phi[0], event.Muon_mass[0]) Lepton2.SetPtEtaPhiM(event.Muon_pt[1], event.Muon_eta[1], event.Muon_phi[1], event.Muon_mass[1]) mll = (Lepton1 + Lepton2).M() ptll = (Lepton1 + Lepton2).Pt() if mll > 15.: iSkim = 1 # Variables mZ, ptZ = mll, ptll dEtaLL = abs(Lepton1.Eta() - Lepton2.Eta()) dPhiLL = abs(Lepton1.DeltaPhi(Lepton2)) dRLL = Lepton1.DeltaR(Lepton2) MinMuonIso = min(event.Muon_pfRelIso03_all[0], event.Muon_pfRelIso03_all[1]) MaxMuonIso = max(event.Muon_pfRelIso03_all[0], event.Muon_pfRelIso03_all[1]) MinMuonMetDPhi = min(abs(Lepton1.DeltaPhi(MET)), abs(Lepton2.DeltaPhi(MET))) MaxMuonMetDPhi = max(abs(Lepton1.DeltaPhi(MET)), abs(Lepton2.DeltaPhi(MET))) MinMuonJetDR = min(getMinMuonJetDR(cleanJet, Lepton1), getMinMuonJetDR(cleanJet, Lepton2)) LLJJ = twoJets + Lepton1 + Lepton2 Vis = allJets + Lepton1 + Lepton2 # Weights if self.isMC: triggerWeight = self.muSFs.getTriggerSF( event.Muon_pt[0], event.Muon_eta[0]) IdSF1 = self.muSFs.getIdSF(event.Muon_pt[0], event.Muon_eta[0], 2) IdSF2 = self.muSFs.getIdSF(event.Muon_pt[1], event.Muon_eta[1], 2) IsoSF1 = self.muSFs.getIsoSF(event.Muon_pt[0], event.Muon_eta[0]) IsoSF2 = self.muSFs.getIsoSF(event.Muon_pt[1], event.Muon_eta[1]) leptonWeight = IdSF1 * IdSF2 * IsoSF1 * IsoSF2 # case 4: Z->ee CR (2 electrons) if iSkim == 0 and event.nElectron >= 2: if isSingleEleIsoTrigger and event.Electron_pt[ 0] > 35. and event.Electron_pt[ 1] > 10. and event.Electron_cutBased[ 0] > 0 and event.Electron_cutBased[1] > 0: Lepton1.SetPtEtaPhiM(event.Electron_pt[0], event.Electron_eta[0], event.Electron_phi[0], event.Electron_mass[0]) Lepton2.SetPtEtaPhiM(event.Electron_pt[1], event.Electron_eta[1], event.Electron_phi[1], event.Electron_mass[1]) mll = (Lepton1 + Lepton2).M() ptll = (Lepton1 + Lepton2).Pt() if mll > 15.: iSkim = 6 # Variables mZ, ptZ = mll, ptll dEtaLL = abs(Lepton1.Eta() - Lepton2.Eta()) dPhiLL = abs(Lepton1.DeltaPhi(Lepton2)) dRLL = Lepton1.DeltaR(Lepton2) MinMuonIso = event.Electron_pfRelIso03_all[0] MaxMuonIso = event.Electron_pfRelIso03_all[0] MinMuonMetDPhi = min(abs(Lepton1.DeltaPhi(MET)), abs(Lepton2.DeltaPhi(MET))) MaxMuonMetDPhi = max(abs(Lepton1.DeltaPhi(MET)), abs(Lepton2.DeltaPhi(MET))) MinMuonJetDR = min(getMinMuonJetDR(cleanJet, Lepton1), getMinMuonJetDR(cleanJet, Lepton2)) LLJJ = twoJets + Lepton1 + Lepton2 Vis = allJets + Lepton1 + Lepton2 # Weights if self.isMC: triggerWeight = self.elSFs.getTriggerSF( event.Electron_pt[0], event.Electron_eta[0]) leptonWeight = self.elSFs.getIdIsoSF( event.Electron_pt[0], event.Electron_eta[0]) * self.elSFs.getIdIsoSF( event.Electron_pt[1], event.Electron_eta[1]) # case 2: ttbar and Z OF CR (1 muon and 1 electron) if iSkim == 0 and event.nMuon >= 1 and event.nElectron >= 1: if (isSingleMuIsoTrigger or isSingleMuTrigger ) and event.Muon_pt[0] > 27. and event.Electron_pt[ 0] > 20. and event.Muon_mediumId[ 0] and event.Electron_cutBased[0] >= 2: Lepton1.SetPtEtaPhiM(event.Muon_pt[0], event.Muon_eta[0], event.Muon_phi[0], event.Muon_mass[0]) Lepton2.SetPtEtaPhiM(event.Electron_pt[0], event.Electron_eta[0], event.Electron_phi[0], event.Electron_mass[0]) mll = (Lepton1 + Lepton2).M() ptll = (Lepton1 + Lepton2).Pt() if mll > 15.: iSkim = 2 # Variables mZ, ptZ = mll, ptll dEtaLL = abs(Lepton1.Eta() - Lepton2.Eta()) dPhiLL = abs(Lepton1.DeltaPhi(Lepton2)) dRLL = Lepton1.DeltaR(Lepton2) MinMuonIso = event.Muon_pfRelIso03_all[0] MaxMuonIso = event.Muon_pfRelIso03_all[0] MinMuonMetDPhi = abs(Lepton1.DeltaPhi(MET)) MaxMuonMetDPhi = abs(Lepton1.DeltaPhi(MET)) MinMuonJetDR = min(getMinMuonJetDR(cleanJet, Lepton1), getMinMuonJetDR(cleanJet, Lepton2)) LLJJ = twoJets + Lepton1 + Lepton2 Vis = allJets + Lepton1 + Lepton2 # Weights if self.isMC: triggerWeight = self.muSFs.getTriggerSF( Lepton1.Pt(), Lepton1.Eta()) IdSF1 = self.muSFs.getIdSF(event.Muon_pt[0], event.Muon_eta[0], 2) IsoSF1 = self.muSFs.getIsoSF(event.Muon_pt[0], event.Muon_eta[0]) IdIsoSF2 = self.elSFs.getIdIsoSF( event.Electron_pt[0], event.Electron_eta[0]) leptonWeight = IdSF1 * IsoSF1 * IdIsoSF2 # case 4: ttbar CR (1 muon and >= 3 jets) if iSkim == 0 and event.nMuon >= 1: if (isSingleMuIsoTrigger or isSingleMuTrigger ) and event.Muon_pt[0] > 27. and event.Muon_mediumId[ 0] and event.Muon_pfRelIso03_all[0] < 0.15: Lepton1.SetPtEtaPhiM(event.Muon_pt[0], event.Muon_eta[0], event.Muon_phi[0], event.Muon_mass[0]) pzN = recoverNeutrinoPz(Lepton1, MET) Neutrino.SetPxPyPzE(MET.Px(), MET.Py(), pzN, MET.Pt()) mW = (Lepton1 + Neutrino).M() ptW = (Lepton1 + Neutrino).Pt() mT = math.sqrt(2. * Lepton1.Pt() * MET.Pt() * (1. - math.cos(Lepton1.DeltaPhi(MET)))) if Nj30 >= 3: # and nBJet >= 1: iSkim = 5 # Variables MinMuonIso = event.Muon_pfRelIso03_all[0] MaxMuonIso = event.Muon_pfRelIso03_all[0] MinMuonMetDPhi = abs(Lepton1.DeltaPhi(MET)) MaxMuonMetDPhi = abs(Lepton1.DeltaPhi(MET)) MinMuonJetDR = getMinMuonJetDR(cleanJet, Lepton1) LLJJ = twoJets + Lepton1 Vis = allJets + Lepton1 # W and Top reconstruction if len(cleanBJet) >= 2: mLepTop1 = (Lepton1 + Neutrino + cleanBJet[0]).M() mLepTop2 = (Lepton1 + Neutrino + cleanBJet[1]).M() elif len(cleanBJet) >= 1: mLepTop1 = (Lepton1 + Neutrino + cleanBJet[0]).M() mHadTop2 = mHadTop1 if len(cleanNonBJet) >= 2: mHadW = (cleanNonBJet[0] + cleanNonBJet[1]).M() if len(cleanBJet) >= 2: mHadTop1 = (cleanNonBJet[0] + cleanNonBJet[1] + cleanBJet[0]).M() mHadTop2 = (cleanNonBJet[0] + cleanNonBJet[1] + cleanBJet[1]).M() elif len(cleanBJet) >= 1: mHadTop1 = (cleanNonBJet[0] + cleanNonBJet[1] + cleanBJet[0]).M() mHadTop2 = mHadTop1 # Weights if self.isMC: triggerWeight = self.muSFs.getTriggerSF( Lepton1.Pt(), Lepton1.Eta()) IdSF1 = self.muSFs.getIdSF(event.Muon_pt[0], event.Muon_eta[0], 2) IsoSF1 = self.muSFs.getIsoSF(event.Muon_pt[0], event.Muon_eta[0]) leptonWeight = IdSF1 * IsoSF1 passedMETFilters = True filters = [ "Flag_goodVertices", "Flag_globalSuperTightHalo2016Filter", "Flag_BadPFMuonFilter", "Flag_EcalDeadCellTriggerPrimitiveFilter", "Flag_HBHENoiseFilter", "Flag_HBHENoiseIsoFilter", "Flag_ecalBadCalibFilter", "Flag_ecalBadCalibFilterV2" ] if not self.isMC: filters += ["Flag_eeBadScFilter"] for f in filters: if hasattr(event, f) and getattr(event, f) == False: passedMETFilters = False # try: ## if event.Flag_goodVertices: print "Flag_goodVertices" ## if event.Flag_globalSuperTightHalo2016Filter: print "Flag_globalSuperTightHalo2016Filter" ## if event.Flag_BadPFMuonFilter: print "Flag_BadPFMuonFilter" ## if event.Flag_EcalDeadCellTriggerPrimitiveFilter: print "Flag_EcalDeadCellTriggerPrimitiveFilter" ## if event.Flag_HBHENoiseFilter: print "Flag_HBHENoiseFilter" ## if event.Flag_HBHENoiseIsoFilter: print "Flag_HBHENoiseIsoFilter" ### if (self.isMC or event.Flag_eeBadScFilter): print "Flag_eeBadScFilter" ## if event.Flag_ecalBadCalibFilter: print "Flag_ecalBadCalibFilterV2" # if event.Flag_goodVertices and event.Flag_globalSuperTightHalo2016Filter and event.Flag_BadPFMuonFilter and event.Flag_EcalDeadCellTriggerPrimitiveFilter and event.Flag_HBHENoiseFilter and event.Flag_HBHENoiseIsoFilter: # and event.Flag_ecalBadCalibFilter: #and (self.isMC or event.Flag_eeBadScFilter): FIXME # passedMETFilters = True ## if not self.isMC: ## if not event.Flag_eeBadScFilter: ## passedMETFilters = False # except: # passedMETFilters = False if iSkim == 0: return False if self.isMC: eventWeightLumi = self.lumiWeight * lheWeight * puWeight * topWeight * qcdnloWeight * qcdnnloWeight * ewknloWeight * triggerWeight * leptonWeight self.out.fillBranch("iSkim", iSkim) self.out.fillBranch("isMC", self.isMC) self.out.fillBranch("isSingleMuIsoTrigger", isSingleMuIsoTrigger) self.out.fillBranch("isSingleMuTrigger", isSingleMuTrigger) self.out.fillBranch("isDoubleMuonTrigger", isDoubleMuonTrigger) self.out.fillBranch("isSingleEleIsoTrigger", isSingleEleIsoTrigger) self.out.fillBranch("isSingleEleTrigger", isSingleEleTrigger) self.out.fillBranch("passedMETFilters", passedMETFilters) self.out.fillBranch("nCleanElectron", len(cleanElectron)) self.out.fillBranch("nCleanMuon", len(cleanMuon)) self.out.fillBranch("nCleanJet", len(cleanJet)) self.out.fillBranch("Z_mass", mZ) self.out.fillBranch("Z_pt", ptZ) self.out.fillBranch("W_mass", mW) self.out.fillBranch("W_tmass", mT) self.out.fillBranch("W_pt", ptW) self.out.fillBranch("ll_dEta", dEtaLL) self.out.fillBranch("ll_dPhi", dPhiLL) self.out.fillBranch("ll_dR", dRLL) self.out.fillBranch("Wqq_mass", mHadW) self.out.fillBranch("Tlvb1_mass", mLepTop1) self.out.fillBranch("Tlvb2_mass", mLepTop2) self.out.fillBranch("Tqqb1_mass", mHadTop1) self.out.fillBranch("Tqqb2_mass", mHadTop2) self.out.fillBranch("jj_mass", mJJ) self.out.fillBranch("jj_pt", ptJJ) self.out.fillBranch("jj_dEta", dEtaJJ) self.out.fillBranch("jj_dPhi", dPhiJJ) self.out.fillBranch("jj_dR", dRJJ) self.out.fillBranch("nj_mass", mNJ) self.out.fillBranch("vis_mass", Vis.M()) self.out.fillBranch("lljj_mass", LLJJ.M()) self.out.fillBranch("minMuonIso", MinMuonIso) self.out.fillBranch("maxMuonIso", MaxMuonIso) self.out.fillBranch("minMuonMetDPhi", MinMuonMetDPhi) self.out.fillBranch("maxMuonMetDPhi", MaxMuonMetDPhi) self.out.fillBranch("minMuonJetDR", MinMuonJetDR) self.out.fillBranch("HT30", HT30) self.out.fillBranch("nj20", Nj20) self.out.fillBranch("nj30", Nj30) self.out.fillBranch("nj40", Nj40) self.out.fillBranch("nBJet", nBJet) self.out.fillBranch("CSV1", CSV1) self.out.fillBranch("CSV2", CSV2) self.out.fillBranch("CSV3", CSV3) self.out.fillBranch("CSV4", CSV4) self.out.fillBranch("iCSV1", iCSV1) self.out.fillBranch("iCSV2", iCSV2) self.out.fillBranch("iCSV3", iCSV3) self.out.fillBranch("iCSV4", iCSV4) self.out.fillBranch("lumiWeight", self.lumiWeight) self.out.fillBranch("lheWeight", lheWeight) self.out.fillBranch("stitchWeight", stitchWeight) self.out.fillBranch("puWeight", puWeight) self.out.fillBranch("topWeight", topWeight) self.out.fillBranch("qcdnloWeight", qcdnloWeight) self.out.fillBranch("qcdnnloWeight", qcdnnloWeight) self.out.fillBranch("ewknloWeight", ewknloWeight) self.out.fillBranch("triggerWeight", triggerWeight) self.out.fillBranch("leptonWeight", leptonWeight) self.out.fillBranch("eventWeightLumi", eventWeightLumi) return True
def beginFile(self, inputFile, outputFile, inputTree, wrappedOutputTree): self.out = wrappedOutputTree self.out.branch("isMC", "I") self.out.branch("is2016", "I") self.out.branch("is2017", "I") self.out.branch("is2018", "I") self.out.branch("isSingleMuonTrigger", "I") self.out.branch("isSingleMuonPhotonTrigger", "I") self.out.branch("isSingleMuonNoFiltersPhotonTrigger", "I") self.out.branch("isDoubleMuonTrigger", "I") self.out.branch("isDoubleMuonPhotonTrigger", "I") self.out.branch("isJPsiTrigger", "I") self.out.branch("isDisplacedTrigger", "I") self.out.branch("passedMETFilters", "I") self.out.branch("nCleanElectron", "I") self.out.branch("nCleanMuon", "I") self.out.branch("nCleanTau", "I") self.out.branch("nCleanPhoton", "I") self.out.branch("nCleanJet", "I") self.out.branch("nCleanBTagJet", "I") self.out.branch("HT30", "F") self.out.branch("iPhoton", "I") self.out.branch("iMuon1", "I") self.out.branch("iMuon2", "I") self.out.branch("Muon1_pt", "F") self.out.branch("Muon1_eta", "F") self.out.branch("Muon2_pt", "F") self.out.branch("Muon2_eta", "F") self.out.branch("Muon1_pfRelIso03_all", "F") self.out.branch("Muon2_pfRelIso03_all", "F") self.out.branch("Muon1_mediumId", "I") self.out.branch("Muon2_mediumId", "I") self.out.branch("Muon1_ip3d", "F") self.out.branch("Muon2_ip3d", "F") self.out.branch("minMuonIso", "F") self.out.branch("maxMuonIso", "F") self.out.branch("minMuonTrkIso", "F") self.out.branch("maxMuonTrkIso", "F") self.out.branch("Muon12_diffdxy", "F") self.out.branch("Muon12_diffdz", "F") self.out.branch("Muon12_signdxy", "F") self.out.branch("Muon12_signdz", "F") self.out.branch("Photon1_pt", "F") self.out.branch("Photon1_eta", "F") self.out.branch("Photon1_mvaID_WP80", "I") self.out.branch("Photon1_pfRelIso03_all", "F") self.out.branch("JPsi_pt", "F") self.out.branch("JPsi_eta", "F") self.out.branch("JPsi_phi", "F") self.out.branch("JPsi_mass", "F") self.out.branch("JPsi_dEta", "F") self.out.branch("JPsi_dPhi", "F") self.out.branch("JPsi_dR", "F") self.out.branch("H_pt", "F") self.out.branch("H_eta", "F") self.out.branch("H_phi", "F") self.out.branch("H_mass", "F") self.out.branch("H_dEta", "F") self.out.branch("H_dPhi", "F") self.out.branch("H_dR", "F") self.out.branch("minMuonMetDPhi", "F") self.out.branch("maxMuonMetDPhi", "F") self.out.branch("photonMetDPhi", "F") self.out.branch("metPlusPhotonDPhi", "F") self.out.branch("cosThetaStar", "F") self.out.branch("cosTheta1", "F") self.out.branch("phi1", "F") self.out.branch("genCosThetaStar", "F") self.out.branch("genCosTheta1", "F") self.out.branch("genPhi1", "F") self.out.branch("lumiWeight", "F") self.out.branch("lheWeight", "F") self.out.branch("stitchWeight", "F") self.out.branch("puWeight", "F") self.out.branch("topWeight", "F") self.out.branch("qcdnloWeight", "F") self.out.branch("qcdnnloWeight", "F") self.out.branch("ewknloWeight", "F") self.out.branch("triggerWeight", "F") self.out.branch("leptonWeight", "F") self.out.branch("eventWeightLumi", "F") self.fileName = inputFile.GetName() self.sampleName = getNameFromFile(self.fileName) self.isMC = not "Run201" in self.fileName if self.verbose >= 0: print "+ Opening file", self.fileName self.thMuons = [10., 3.] self.thPhoton = [10.] # b-tagging working points for DeepCSV # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation2016Legacy # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation94X # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation102X if "Run2016" in self.fileName or "UL16" in self.fileName or "Summer16" in self.fileName: self.year = 2016 self.lumi = 35920. self.btagLoose = 0.2217 #0.0614 self.btagMedium = 0.6321 #0.3093 self.btagTight = 0.8953 #0.7221 elif "Run2017" in self.fileName or "UL17" in self.fileName or "Fall17" in self.fileName: self.year = 2017 self.lumi = 41530. self.btagLoose = 0.1522 #0.0521 self.btagMedium = 0.4941 #0.3033 self.btagTight = 0.8001 #0.7489 elif "Run2018" in self.fileName or "UL18" in self.fileName or "Autumn18" in self.fileName: self.year = 2018 self.lumi = 59740. self.btagLoose = 0.1241 #0.0494 self.btagMedium = 0.4184 #0.2770 self.btagTight = 0.7527 #0.7264 else: if self.verbose >= 0: print "- Unknown year, aborting module" import sys sys.exit() self.xs = XS[self.sampleName] if self.sampleName in XS else 0. self.nevents = EV[self.sampleName] if self.sampleName in EV else 0. self.xsWeight = self.xs / self.nevents if self.nevents > 0 else 1. self.lumiWeight = self.xsWeight * self.lumi if self.isMC else 1. self.isLO = abs(self.nevents % 1) < 1.e-6 # if True, the event count is integer, so the weight should be normalized (+1) self.isSignal = ('JPsiG' in self.sampleName) if self.verbose >= 1: print "+ Module parameters: isMC", self.isMC, ", year", self.year, ", lumi", self.lumi, "pb" if self.verbose >= 1: print "+ Sample", self.sampleName, ", XS", self.xs, ", events", self.nevents if self.verbose >= 1: print "+ Weight", self.lumiWeight if self.isMC and self.isLO and self.verbose >= 1: print "+ Sample is LO, gen weight will be set to 1" # self.puTool = PileupWeightTool(year = year) if self.isMC else None self.SingleMuonTriggers = ["HLT_IsoMu27"] self.SingleMuonPhotonTriggers = ["HLT_Mu17_Photon30_CaloIdL_L1ISO", "HLT_Mu17_Photon30_IsoCaloId", "HLT_Mu17_Photon30_CaloIdL"] # 27.13 in 2017 self.SingleMuonNoFiltersPhotonTriggers = ["HLT_Mu38NoFiltersNoVtxDisplaced_Photon38_CaloIdL", "HLT_Mu38NoFiltersNoVtx_Photon38_CaloIdL", "HLT_Mu43NoFiltersNoVtx_Photon43_CaloIdL"] self.DoubleMuonTriggers = ["HLT_Mu17_Mu8", "HLT_Mu17_Mu8_DZ", "HLT_Mu17_TkMu8_DZ", "HLT_Mu17_TrkIsoVVL_Mu8_TrkIsoVVL_DZ_Mass", "HLT_Mu37_TkMu27", ] #, "HLT_DoubleMu33NoFiltersNoVtxDisplaced"] self.DoubleMuonPhotonTriggers = ["HLT_DoubleMu20_7_Mass0to30_Photon23"] self.JPsiTriggers = ["HLT_Dimuon16_Jpsi", "HLT_Dimuon18_PsiPrime", "HLT_Dimuon18_PsiPrime_noCorrL1", "HLT_Dimuon25_Jpsi", "HLT_Dimuon25_Jpsi_noCorrL1", "HLT_Dimuon20_Jpsi", ] self.DisplacedTriggers = ["HLT_DoubleMu4_JpsiTrk_Displaced", "HLT_DoubleMu4_PsiPrimeTrk_Displaced"] if self.isMC: self.muSFs = MuonSFs(year = self.year) self.elSFs = ElectronSFs(year = self.year) self.puTool = PileupWeightTool(year = self.year)
class MuMuProducer(Module): def __init__(self, name, dataType, **kwargs): year = kwargs.get('year', 2017 ) doZpt = kwargs.get('doZpt', 'DY' in name ) channel = 'mumu' self.name = name self.year = year self.out = TreeProducerMuMu(name) self.isData = dataType=='data' self.doZpt = doZpt setYear(year) self.vlooseIso = getVLooseTauIso(year) if year==2016: self.trigger = lambda e: e.HLT_IsoMu22 or e.HLT_IsoMu22_eta2p1 or e.HLT_IsoTkMu22 or e.HLT_IsoTkMu22_eta2p1 #or e.HLT_IsoMu19_eta2p1_LooseIsoPFTau20_SingleL1 self.muon1CutPt = 23 else: self.trigger = lambda e: e.HLT_IsoMu24 or e.HLT_IsoMu27 self.muon1CutPt = 25 self.muon2CutPt = 15 if not self.isData: self.muSFs = MuonSFs(year=year) self.puTool = PileupWeightTool(year=year) self.btagTool = BTagWeightTool('CSVv2','medium',channel='mutau',year=year) self.btagTool_deep = BTagWeightTool('DeepCSV','medium',channel='mutau',year=year) if self.doZpt: self.recoilTool = RecoilCorrectionTool(year=year) self.csvv2_wp = BTagWPs('CSVv2',year=year) self.deepcsv_wp = BTagWPs('DeepCSV',year=year) self.Nocut = 0 self.Trigger = 1 self.GoodMuons = 2 self.GoodSecondMuon = 3 self.GoodDiLepton = 4 self.TotalWeighted = 15 self.TotalWeighted_no0PU = 16 self.out.cutflow.GetXaxis().SetBinLabel(1+self.Nocut, "no cut" ) self.out.cutflow.GetXaxis().SetBinLabel(1+self.Trigger, "trigger" ) self.out.cutflow.GetXaxis().SetBinLabel(1+self.GoodMuons, "muon object" ) self.out.cutflow.GetXaxis().SetBinLabel(1+self.GoodSecondMuon, "second muon object" ) self.out.cutflow.GetXaxis().SetBinLabel(1+self.GoodDiLepton, "mumu pair" ) self.out.cutflow.GetXaxis().SetBinLabel(1+self.TotalWeighted, "no cut, weighted" ) self.out.cutflow.GetXaxis().SetBinLabel(1+self.TotalWeighted_no0PU, "no cut, weighted, PU>0" ) self.out.cutflow.GetXaxis().SetLabelSize(0.041) def beginJob(self): pass def endJob(self): self.out.outputfile.Write() self.out.outputfile.Close() def beginFile(self, inputFile, outputFile, inputTree, wrappedOutputTree): pass def endFile(self, inputFile, outputFile, inputTree, wrappedOutputTree): pass def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" ##################################### self.out.cutflow.Fill(self.Nocut) if self.isData: self.out.cutflow.Fill(self.TotalWeighted, 1.) if event.PV_npvs>0: self.out.cutflow.Fill(self.TotalWeighted_no0PU, 1.) else: return False else: self.out.cutflow.Fill(self.TotalWeighted, event.genWeight) self.out.pileup.Fill(event.Pileup_nTrueInt) if event.Pileup_nTrueInt>0: self.out.cutflow.Fill(self.TotalWeighted_no0PU, event.genWeight) else: return False ##################################### if not self.trigger(event): return False ##################################### self.out.cutflow.Fill(self.Trigger) ##################################### idx_goodmuons = [ ] for imuon in range(event.nMuon): if event.Muon_pt[imuon] < self.muon2CutPt: continue # lower pT cut if abs(event.Muon_eta[imuon]) > 2.4: continue if abs(event.Muon_dz[imuon]) > 0.2: continue if abs(event.Muon_dxy[imuon]) > 0.045: continue if event.Muon_pfRelIso04_all[imuon] > 0.15: continue if not event.Muon_mediumId[imuon]: continue idx_goodmuons.append(imuon) if len(idx_goodmuons) < 1: return False ##################################### self.out.cutflow.Fill(self.GoodMuons) ##################################### if not any(event.Muon_pt[i]>self.muon1CutPt for i in idx_goodmuons) or len(idx_goodmuons)<2: # higher pT cut return False ##################################### self.out.cutflow.Fill(self.GoodSecondMuon) ##################################### muons = Collection(event, 'Muon') dileptons = [ ] for idx1 in idx_goodmuons: for idx2 in idx_goodmuons: if idx1 >= idx2: continue muon1 = muons[idx1].p4() muon2 = muons[idx2].p4() if muon1.DeltaR(muon2) < 0.5: continue if not (70<(muon1+muon2).M()<110): continue # Z mass dilepton = DiLeptonBasicClass(idx1, event.Muon_pt[idx1], event.Muon_pfRelIso04_all[idx1], idx2, event.Muon_pt[idx2], event.Muon_pfRelIso04_all[idx2]) dileptons.append(dilepton) if len(dileptons)==0: return False dilepton = bestDiLepton(dileptons) muon1 = muons[dilepton.id1].p4() muon2 = muons[dilepton.id2].p4() ##################################### self.out.cutflow.Fill(self.GoodDiLepton) ##################################### # JETS jetIds = [ ] bjetIds = [ ] jets = Collection(event, 'Jet') nfjets = 0 ncjets = 0 nbtag = 0 for ijet in range(event.nJet): if event.Jet_pt[ijet] < 20: continue # 20 for tau -> j fake measurement if abs(event.Jet_eta[ijet]) > 4.7: continue if muon1.DeltaR(jets[ijet].p4()) < 0.5: continue if muon2.DeltaR(jets[ijet].p4()) < 0.5: continue jetIds.append(ijet) if abs(event.Jet_eta[ijet]) > 2.4: nfjets += 1 else: ncjets += 1 if event.Jet_btagDeepB[ijet] > self.deepcsv_wp.medium: nbtag += 1 bjetIds.append(ijet) if not self.isData and event.Muon_pfRelIso04_all[dilepton.id1]<0.50 and event.Muon_pfRelIso04_all[dilepton.id2]<0.50: self.btagTool.fillEfficiencies(event,jetIds) self.btagTool_deep.fillEfficiencies(event,jetIds) #eventSum = ROOT.TLorentzVector() # #for lep in muons : # eventSum += lep.p4() #for lep in electrons : # eventSum += lep.p4() #for j in filter(self.jetSel,jets): # eventSum += j.p4() # MUONS self.out.pt_1[0] = event.Muon_pt[dilepton.id1] self.out.eta_1[0] = event.Muon_eta[dilepton.id1] self.out.phi_1[0] = event.Muon_phi[dilepton.id1] self.out.m_1[0] = event.Muon_mass[dilepton.id1] self.out.dxy_1[0] = event.Muon_dxy[dilepton.id1] self.out.dz_1[0] = event.Muon_dz[dilepton.id1] self.out.q_1[0] = event.Muon_charge[dilepton.id1] self.out.pfRelIso04_all_1[0] = event.Muon_pfRelIso04_all[dilepton.id1] self.out.pt_2[0] = event.Muon_pt[dilepton.id2] self.out.eta_2[0] = event.Muon_eta[dilepton.id2] self.out.phi_2[0] = event.Muon_phi[dilepton.id2] self.out.m_2[0] = event.Muon_mass[dilepton.id2] self.out.dxy_2[0] = event.Muon_dxy[dilepton.id2] self.out.dz_2[0] = event.Muon_dz[dilepton.id2] self.out.q_2[0] = event.Muon_charge[dilepton.id2] self.out.pfRelIso04_all_2[0] = event.Muon_pfRelIso04_all[dilepton.id2] if not self.isData: self.out.genPartFlav_1[0] = ord(event.Muon_genPartFlav[dilepton.id1]) self.out.genPartFlav_2[0] = ord(event.Muon_genPartFlav[dilepton.id2]) # TAU maxId = -1 maxPt = 20 taus = Collection(event, 'Tau') for itau in range(event.nTau): if event.Tau_pt[itau] < maxPt: continue if muon1.DeltaR(taus[itau].p4())<0.5: continue if muon2.DeltaR(taus[itau].p4())<0.5: continue if abs(event.Tau_eta[itau])>2.3: continue if abs(event.Tau_dz[itau])>0.2: continue if event.Tau_decayMode[itau] not in [0,1,10,11]: continue if abs(event.Tau_charge[itau])!=1: continue if ord(event.Tau_idAntiEle[itau])<1: continue # VLoose if ord(event.Tau_idAntiMu[itau])<1: continue # Loose #if not self.vlooseIso(event,itau): continue maxId = itau maxPt = event.Tau_pt[itau] if maxId>-1: self.out.pt_3[0] = event.Tau_pt[maxId] self.out.eta_3[0] = event.Tau_eta[maxId] self.out.m_3[0] = event.Tau_mass[maxId] self.out.decayMode_3[0] = event.Tau_decayMode[maxId] self.out.idAntiEle_3[0] = ord(event.Tau_idAntiEle[maxId]) self.out.idAntiMu_3[0] = ord(event.Tau_idAntiMu[maxId]) self.out.idMVAoldDM_3[0] = ord(event.Tau_idMVAoldDM[maxId]) self.out.idMVAoldDM2017v1_3[0] = ord(event.Tau_idMVAoldDM2017v1[maxId]) self.out.idMVAoldDM2017v2_3[0] = ord(event.Tau_idMVAoldDM2017v2[maxId]) self.out.idMVAnewDM2017v2_3[0] = ord(event.Tau_idMVAnewDM2017v2[maxId]) self.out.idIso_3[0] = Tau_idIso(event,maxId) if not self.isData: self.out.genPartFlav_3[0] = ord(event.Tau_genPartFlav[maxId]) else: self.out.pt_3[0] = -1 self.out.eta_3[0] = -9 self.out.m_3[0] = -1 self.out.decayMode_3[0] = -1 self.out.idAntiEle_3[0] = -1 self.out.idAntiMu_3[0] = -1 self.out.idMVAoldDM_3[0] = -1 self.out.idMVAoldDM2017v1_3[0] = -1 self.out.idMVAoldDM2017v2_3[0] = -1 self.out.idMVAnewDM2017v2_3[0] = -1 self.out.idIso_3[0] = -1 self.out.genPartFlav_3[0] = -1 # EVENT self.out.isData[0] = self.isData self.out.run[0] = event.run self.out.luminosityBlock[0] = event.luminosityBlock self.out.event[0] = event.event & 0xffffffffffffffff self.out.met[0] = event.MET_pt self.out.metphi[0] = event.MET_phi ###self.out.puppimet[0] = event.PuppiMET_pt ###self.out.puppimetphi[0] = event.PuppiMET_phi ###self.out.metsignificance[0] = event.MET_significance ###self.out.metcovXX[0] = event.MET_covXX ###self.out.metcovXY[0] = event.MET_covXY ###self.out.metcovYY[0] = event.MET_covYY ###self.out.fixedGridRhoFastjetAll[0] = event.fixedGridRhoFastjetAll self.out.npvs[0] = event.PV_npvs self.out.npvsGood[0] = event.PV_npvsGood if not self.isData: self.out.genmet[0] = event.GenMET_pt self.out.genmetphi[0] = event.GenMET_phi self.out.nPU[0] = event.Pileup_nPU self.out.nTrueInt[0] = event.Pileup_nTrueInt try: self.out.LHE_Njets[0] = event.LHE_Njets except RuntimeError: self.out.LHE_Njets[0] = -1 # JETS self.out.njets[0] = len(jetIds) self.out.njets50[0] = len([j for j in jetIds if event.Jet_pt[j]>50]) self.out.nfjets[0] = nfjets self.out.ncjets[0] = ncjets self.out.nbtag[0] = nbtag if len(jetIds)>0: self.out.jpt_1[0] = event.Jet_pt[jetIds[0]] self.out.jeta_1[0] = event.Jet_eta[jetIds[0]] self.out.jphi_1[0] = event.Jet_phi[jetIds[0]] self.out.jcsvv2_1[0] = event.Jet_btagCSVV2[jetIds[0]] self.out.jdeepb_1[0] = event.Jet_btagDeepB[jetIds[0]] else: self.out.jpt_1[0] = -9. self.out.jeta_1[0] = -9. self.out.jphi_1[0] = -9. self.out.jcsvv2_1[0] = -9. self.out.jdeepb_1[0] = -9. if len(jetIds)>1: self.out.jpt_2[0] = event.Jet_pt[jetIds[1]] self.out.jeta_2[0] = event.Jet_eta[jetIds[1]] self.out.jphi_2[0] = event.Jet_phi[jetIds[1]] self.out.jcsvv2_2[0] = event.Jet_btagCSVV2[jetIds[1]] self.out.jdeepb_2[0] = event.Jet_btagDeepB[jetIds[1]] else: self.out.jpt_2[0] = -9. self.out.jeta_2[0] = -9. self.out.jphi_2[0] = -9. self.out.jcsvv2_2[0] = -9. self.out.jdeepb_2[0] = -9. if len(bjetIds)>0: self.out.bpt_1[0] = event.Jet_pt[bjetIds[0]] self.out.beta_1[0] = event.Jet_eta[bjetIds[0]] else: self.out.bpt_1[0] = -9. self.out.beta_1[0] = -9. if len(bjetIds)>1: self.out.bpt_2[0] = event.Jet_pt[bjetIds[1]] self.out.beta_2[0] = event.Jet_eta[bjetIds[1]] else: self.out.bpt_2[0] = -9. self.out.beta_2[0] = -9. self.out.njets[0] = len(jetIds) self.out.nfjets[0] = nfjets self.out.ncjets[0] = ncjets self.out.nbtag[0] = nbtag self.out.pfmt_1[0] = math.sqrt( 2 * self.out.pt_1[0] * self.out.met[0] * ( 1 - math.cos(deltaPhi(self.out.phi_1[0], self.out.metphi[0])) ) ); self.out.pfmt_2[0] = math.sqrt( 2 * self.out.pt_2[0] * self.out.met[0] * ( 1 - math.cos(deltaPhi(self.out.phi_2[0], self.out.metphi[0])) ) ); self.out.m_vis[0] = (muon1 + muon2).M() self.out.pt_ll[0] = (muon1 + muon2).Pt() self.out.dR_ll[0] = muon1.DeltaR(muon2) self.out.dphi_ll[0] = deltaPhi(self.out.phi_1[0], self.out.phi_2[0]) # PZETA leg1 = ROOT.TVector3(muon1.Px(), muon1.Py(), 0.) leg2 = ROOT.TVector3(muon2.Px(), muon2.Py(), 0.) met_tlv = ROOT.TLorentzVector() met_tlv.SetPxPyPzE(self.out.met[0]*math.cos(self.out.metphi[0]), self.out.met[0]*math.cos(self.out.metphi[0]), 0, self.out.met[0]) metleg = met_tlv.Vect() zetaAxis = ROOT.TVector3(leg1.Unit() + leg2.Unit()).Unit() pzetaVis = leg1*zetaAxis + leg2*zetaAxis pzetaMET = metleg*zetaAxis self.out.pzetamiss[0] = pzetaMET self.out.pzetavis[0] = pzetaVis self.out.dzeta[0] = pzetaMET - 0.85*pzetaVis # VETOS self.out.extramuon_veto[0], self.out.extraelec_veto[0], self.out.dilepton_veto[0] = extraLeptonVetos(event, [dilepton.id1, dilepton.id2], [-1], self.name) # WEIGHTS if not self.isData: if self.doZpt: zboson = getZPTMass(event) self.out.m_genboson[0] = zboson.M() self.out.pt_genboson[0] = zboson.Pt() self.out.zptweight[0] = self.recoilTool.getZptWeight(zboson.Pt(),zboson.M()) self.out.genweight[0] = event.genWeight self.out.puweight[0] = self.puTool.getWeight(event.Pileup_nTrueInt) self.out.trigweight[0] = self.muSFs.getTriggerSF(self.out.pt_1[0],self.out.eta_1[0]) self.out.idisoweight_1[0] = self.muSFs.getIdIsoSF(self.out.pt_1[0],self.out.eta_1[0]) self.out.idisoweight_2[0] = self.muSFs.getIdIsoSF(self.out.pt_2[0],self.out.eta_2[0]) self.out.btagweight[0] = self.btagTool.getWeight(event,jetIds) self.out.btagweight_deep[0] = self.btagTool_deep.getWeight(event,jetIds) self.out.weight[0] = self.out.genweight[0]*self.out.puweight[0]*self.out.trigweight[0]*self.out.idisoweight_1[0]*self.out.idisoweight_2[0] self.out.tree.Fill() return True
class MuTauProducer(Module): def __init__(self, name, dataType, **kwargs): year = kwargs.get('year', 2017) tes = kwargs.get('tes', 1.0) channel = 'mutau' self.name = name self.year = year self.tes = tes self.out = TreeProducerMuTau(name) self.isData = dataType == 'data' self.doZpt = 'DY' in self.name setYear(year) self.vlooseIso = getVLooseTauIso(year) if year == 2016: self.trigger = lambda e: e.HLT_IsoMu22 or e.HLT_IsoMu22_eta2p1 or e.HLT_IsoTkMu22 or e.HLT_IsoTkMu22_eta2p1 #or e.HLT_IsoMu19_eta2p1_LooseIsoPFTau20_SingleL1 self.muonCutPt = 23 else: self.trigger = lambda e: e.HLT_IsoMu24 or e.HLT_IsoMu27 self.muonCutPt = 25 self.tauCutPt = 20 if not self.isData: self.muSFs = MuonSFs(year=year) self.puTool = PileupWeightTool(year=year) self.ltfSFs = LeptonTauFakeSFs('tight', 'vloose', year=year) self.btagTool = BTagWeightTool('CSVv2', 'medium', channel=channel, year=year) self.btagTool_deep = BTagWeightTool('DeepCSV', 'medium', channel=channel, year=year) if self.doZpt: self.recoilTool = RecoilCorrectionTool(year=year) self.csvv2_wp = BTagWPs('CSVv2', year=year) self.deepcsv_wp = BTagWPs('DeepCSV', year=year) self.Nocut = 0 self.Trigger = 1 self.GoodMuons = 2 self.GoodTaus = 3 self.GoodDiLepton = 4 self.TotalWeighted = 15 self.TotalWeighted_no0PU = 16 self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Nocut, "no cut") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Trigger, "trigger") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodMuons, "muon object") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodTaus, "tau object") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodDiLepton, "mutau pair") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.TotalWeighted, "no cut, weighted") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.TotalWeighted_no0PU, "no cut, weighted, PU>0") self.out.cutflow.GetXaxis().SetLabelSize(0.041) def beginJob(self): pass def endJob(self): if not self.isData: self.btagTool.setDirectory(self.out.outputfile, 'btag') self.btagTool_deep.setDirectory(self.out.outputfile, 'btag') self.out.outputfile.Write() self.out.outputfile.Close() def beginFile(self, inputFile, outputFile, inputTree, wrappedOutputTree): pass def endFile(self, inputFile, outputFile, inputTree, wrappedOutputTree): pass def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" ##################################### self.out.cutflow.Fill(self.Nocut) if self.isData: self.out.cutflow.Fill(self.TotalWeighted, 1.) if event.PV_npvs > 0: self.out.cutflow.Fill(self.TotalWeighted_no0PU, 1.) else: return False else: self.out.cutflow.Fill(self.TotalWeighted, event.genWeight) self.out.pileup.Fill(event.Pileup_nTrueInt) if event.Pileup_nTrueInt > 0: self.out.cutflow.Fill(self.TotalWeighted_no0PU, event.genWeight) else: return False ##################################### if not self.trigger(event): return False ##################################### self.out.cutflow.Fill(self.Trigger) ##################################### idx_goodmuons = [] for imuon in range(event.nMuon): if event.Muon_pt[imuon] < self.muonCutPt: continue if abs(event.Muon_eta[imuon]) > 2.4: continue if abs(event.Muon_dz[imuon]) > 0.2: continue if abs(event.Muon_dxy[imuon]) > 0.045: continue if not event.Muon_mediumId[imuon]: continue #if event.Muon_pfRelIso04_all[imuon]>0.50: continue idx_goodmuons.append(imuon) if len(idx_goodmuons) == 0: return False ##################################### self.out.cutflow.Fill(self.GoodMuons) ##################################### idx_goodtaus = [] for itau in range(event.nTau): if self.tes != 1.0: event.Tau_pt[itau] *= self.tes event.Tau_mass[itau] *= self.tes if event.Tau_pt[itau] < self.tauCutPt: continue if abs(event.Tau_eta[itau]) > 2.3: continue if abs(event.Tau_dz[itau]) > 0.2: continue if event.Tau_decayMode[itau] not in [0, 1, 10]: continue if abs(event.Tau_charge[itau]) != 1: continue ###if ord(event.Tau_idAntiEle[itau])<1: continue ###if ord(event.Tau_idAntiMu[itau])<1: continue if not self.vlooseIso(event, itau): continue idx_goodtaus.append(itau) if len(idx_goodtaus) == 0: return False ##################################### self.out.cutflow.Fill(self.GoodTaus) ##################################### muons = Collection(event, 'Muon') taus = Collection(event, 'Tau') ltaus = [] for idx1 in idx_goodmuons: for idx2 in idx_goodtaus: if taus[idx2].p4().DeltaR(muons[idx1].p4()) < 0.5: continue ltau = LeptonTauPair(idx1, event.Muon_pt[idx1], event.Muon_pfRelIso04_all[idx1], idx2, event.Tau_pt[idx2], event.Tau_rawMVAoldDM2017v2[idx2]) ltaus.append(ltau) if len(ltaus) == 0: return False ltau = bestDiLepton(ltaus) muon = muons[ltau.id1].p4() tau = taus[ltau.id2].p4() #print 'chosen tau1 (idx, pt) = ', ltau.id1, ltau.tau1_pt, 'check', muon.Pt() #print 'chosen tau2 (idx, pt) = ', ltau.id2, ltau.tau2_pt, 'check', tau.Pt() ##################################### self.out.cutflow.Fill(self.GoodDiLepton) ##################################### # JETS jetIds = [] bjetIds = [] jets = Collection(event, 'Jet') nfjets = 0 ncjets = 0 nbtag = 0 for ijet in range(event.nJet): if event.Jet_pt[ijet] < 30: continue if abs(event.Jet_eta[ijet]) > 4.7: continue if muon.DeltaR(jets[ijet].p4()) < 0.5: continue if tau.DeltaR(jets[ijet].p4()) < 0.5: continue jetIds.append(ijet) if abs(event.Jet_eta[ijet]) > 2.4: nfjets += 1 else: ncjets += 1 if event.Jet_btagDeepB[ijet] > self.deepcsv_wp.medium: nbtag += 1 bjetIds.append(ijet) if not self.isData and self.vlooseIso( event, ltau.id2) and event.Muon_pfRelIso04_all[ltau.id1] < 0.50: self.btagTool.fillEfficiencies(event, jetIds) self.btagTool_deep.fillEfficiencies(event, jetIds) #eventSum = ROOT.TLorentzVector() # #for lep in muons : # eventSum += lep.p4() #for lep in electrons : # eventSum += lep.p4() #for j in filter(self.jetSel,jets): # eventSum += j.p4() # MUON self.out.pt_1[0] = event.Muon_pt[ltau.id1] self.out.eta_1[0] = event.Muon_eta[ltau.id1] self.out.phi_1[0] = event.Muon_phi[ltau.id1] self.out.m_1[0] = event.Muon_mass[ltau.id1] self.out.dxy_1[0] = event.Muon_dxy[ltau.id1] self.out.dz_1[0] = event.Muon_dz[ltau.id1] self.out.q_1[0] = event.Muon_charge[ltau.id1] self.out.pfRelIso04_all_1[0] = event.Muon_pfRelIso04_all[ltau.id1] # TAU self.out.pt_2[0] = event.Tau_pt[ltau.id2] self.out.eta_2[0] = event.Tau_eta[ltau.id2] self.out.phi_2[0] = event.Tau_phi[ltau.id2] self.out.m_2[0] = event.Tau_mass[ltau.id2] self.out.dxy_2[0] = event.Tau_dxy[ltau.id2] self.out.dz_2[0] = event.Tau_dz[ltau.id2] self.out.leadTkPtOverTauPt_2[0] = event.Tau_leadTkPtOverTauPt[ltau.id2] self.out.chargedIso_2[0] = event.Tau_chargedIso[ltau.id2] self.out.neutralIso_2[0] = event.Tau_neutralIso[ltau.id2] self.out.photonsOutsideSignalCone_2[ 0] = event.Tau_photonsOutsideSignalCone[ltau.id2] self.out.puCorr_2[0] = event.Tau_puCorr[ltau.id2] self.out.rawAntiEle_2[0] = event.Tau_rawAntiEle[ltau.id2] self.out.rawIso_2[0] = event.Tau_rawIso[ltau.id2] self.out.q_2[0] = event.Tau_charge[ltau.id2] self.out.decayMode_2[0] = event.Tau_decayMode[ltau.id2] ###self.out.rawAntiEleCat_2[0] = event.Tau_rawAntiEleCat[ltau.id2] self.out.idAntiEle_2[0] = ord(event.Tau_idAntiEle[ltau.id2]) self.out.idAntiMu_2[0] = ord(event.Tau_idAntiMu[ltau.id2]) self.out.idDecayMode_2[0] = event.Tau_idDecayMode[ltau.id2] self.out.idDecayModeNewDMs_2[0] = event.Tau_idDecayModeNewDMs[ltau.id2] self.out.rawMVAoldDM_2[0] = event.Tau_rawMVAoldDM[ltau.id2] self.out.rawMVAoldDM2017v1_2[0] = event.Tau_rawMVAoldDM2017v1[ltau.id2] self.out.rawMVAoldDM2017v2_2[0] = event.Tau_rawMVAoldDM2017v2[ltau.id2] self.out.rawMVAnewDM2017v2_2[0] = event.Tau_rawMVAnewDM2017v2[ltau.id2] self.out.idMVAoldDM_2[0] = ord(event.Tau_idMVAoldDM[ltau.id2]) self.out.idMVAoldDM2017v1_2[0] = ord( event.Tau_idMVAoldDM2017v1[ltau.id2]) self.out.idMVAoldDM2017v2_2[0] = ord( event.Tau_idMVAoldDM2017v2[ltau.id2]) self.out.idMVAnewDM2017v2_2[0] = ord( event.Tau_idMVAnewDM2017v2[ltau.id2]) # GENERATOR if not self.isData: self.out.genPartFlav_1[0] = ord(event.Muon_genPartFlav[ltau.id1]) self.out.genPartFlav_2[0] = ord(event.Tau_genPartFlav[ltau.id2]) genvistau = Collection(event, 'GenVisTau') dRmax = 1000 gendm = -1 genpt = -1 geneta = -1 genphi = -1 for igvt in range(event.nGenVisTau): dR = genvistau[igvt].p4().DeltaR(tau) if dR < 0.5 and dR < dRmax: dRmax = dR gendm = event.GenVisTau_status[igvt] genpt = event.GenVisTau_pt[igvt] geneta = event.GenVisTau_eta[igvt] genphi = event.GenVisTau_phi[igvt] self.out.gendecayMode_2[0] = gendm self.out.genvistaupt_2[0] = genpt self.out.genvistaueta_2[0] = geneta self.out.genvistauphi_2[0] = genphi # EVENT self.out.isData[0] = self.isData self.out.run[0] = event.run self.out.luminosityBlock[0] = event.luminosityBlock self.out.event[0] = event.event & 0xffffffffffffffff self.out.met[0] = event.MET_pt self.out.metphi[0] = event.MET_phi ###self.out.puppimet[0] = event.PuppiMET_pt ###self.out.puppimetphi[0] = event.PuppiMET_phi ###self.out.metsignificance[0] = event.MET_significance ###self.out.metcovXX[0] = event.MET_covXX ###self.out.metcovXY[0] = event.MET_covXY ###self.out.metcovYY[0] = event.MET_covYY ###self.out.fixedGridRhoFastjetAll[0] = event.fixedGridRhoFastjetAll self.out.npvs[0] = event.PV_npvs self.out.npvsGood[0] = event.PV_npvsGood if not self.isData: self.out.genmet[0] = event.GenMET_pt self.out.genmetphi[0] = event.GenMET_phi self.out.nPU[0] = event.Pileup_nPU self.out.nTrueInt[0] = event.Pileup_nTrueInt try: self.out.LHE_Njets[0] = event.LHE_Njets except RuntimeError: self.out.LHE_Njets[0] = -1 # JETS self.out.njets[0] = len(jetIds) self.out.njets50[0] = len([j for j in jetIds if event.Jet_pt[j] > 50]) self.out.nfjets[0] = nfjets self.out.ncjets[0] = ncjets self.out.nbtag[0] = nbtag if len(jetIds) > 0: self.out.jpt_1[0] = event.Jet_pt[jetIds[0]] self.out.jeta_1[0] = event.Jet_eta[jetIds[0]] self.out.jphi_1[0] = event.Jet_phi[jetIds[0]] self.out.jcsvv2_1[0] = event.Jet_btagCSVV2[jetIds[0]] self.out.jdeepb_1[0] = event.Jet_btagDeepB[jetIds[0]] else: self.out.jpt_1[0] = -9. self.out.jeta_1[0] = -9. self.out.jphi_1[0] = -9. self.out.jcsvv2_1[0] = -9. self.out.jdeepb_1[0] = -9. if len(jetIds) > 1: self.out.jpt_2[0] = event.Jet_pt[jetIds[1]] self.out.jeta_2[0] = event.Jet_eta[jetIds[1]] self.out.jphi_2[0] = event.Jet_phi[jetIds[1]] self.out.jcsvv2_2[0] = event.Jet_btagCSVV2[jetIds[1]] self.out.jdeepb_2[0] = event.Jet_btagDeepB[jetIds[1]] else: self.out.jpt_2[0] = -9. self.out.jeta_2[0] = -9. self.out.jphi_2[0] = -9. self.out.jcsvv2_2[0] = -9. self.out.jdeepb_2[0] = -9. if len(bjetIds) > 0: self.out.bpt_1[0] = event.Jet_pt[bjetIds[0]] self.out.beta_1[0] = event.Jet_eta[bjetIds[0]] else: self.out.bpt_1[0] = -9. self.out.beta_1[0] = -9. if len(bjetIds) > 1: self.out.bpt_2[0] = event.Jet_pt[bjetIds[1]] self.out.beta_2[0] = event.Jet_eta[bjetIds[1]] else: self.out.bpt_2[0] = -9. self.out.beta_2[0] = -9. self.out.pfmt_1[0] = math.sqrt( 2 * self.out.pt_1[0] * self.out.met[0] * (1 - math.cos(deltaPhi(self.out.phi_1[0], self.out.metphi[0])))) self.out.pfmt_2[0] = math.sqrt( 2 * self.out.pt_2[0] * self.out.met[0] * (1 - math.cos(deltaPhi(self.out.phi_2[0], self.out.metphi[0])))) self.out.m_vis[0] = (muon + tau).M() self.out.pt_ll[0] = (muon + tau).Pt() self.out.dR_ll[0] = muon.DeltaR(tau) self.out.dphi_ll[0] = deltaPhi(self.out.phi_1[0], self.out.phi_2[0]) # PZETA leg1 = ROOT.TVector3(muon.Px(), muon.Py(), 0.) leg2 = ROOT.TVector3(tau.Px(), tau.Py(), 0.) met_tlv = ROOT.TLorentzVector() met_tlv.SetPxPyPzE(self.out.met[0] * math.cos(self.out.metphi[0]), self.out.met[0] * math.cos(self.out.metphi[0]), 0, self.out.met[0]) metleg = met_tlv.Vect() zetaAxis = ROOT.TVector3(leg1.Unit() + leg2.Unit()).Unit() pzetaVis = leg1 * zetaAxis + leg2 * zetaAxis pzetaMET = metleg * zetaAxis self.out.pzetamiss[0] = pzetaMET self.out.pzetavis[0] = pzetaVis self.out.dzeta[0] = pzetaMET - 0.85 * pzetaVis # VETOS self.out.extramuon_veto[0], self.out.extraelec_veto[ 0], self.out.dilepton_veto[0] = extraLeptonVetos( event, [ltau.id1], [-1], self.name) # WEIGHTS if not self.isData: if self.doZpt: zboson = getZPTMass(event) self.out.m_genboson[0] = zboson.M() self.out.pt_genboson[0] = zboson.Pt() self.out.zptweight[0] = self.recoilTool.getZptWeight( zboson.Pt(), zboson.M()) self.out.genweight[0] = event.genWeight self.out.puweight[0] = self.puTool.getWeight(event.Pileup_nTrueInt) self.out.trigweight[0] = self.muSFs.getTriggerSF( self.out.pt_1[0], self.out.eta_1[0]) self.out.idisoweight_1[0] = self.muSFs.getIdIsoSF( self.out.pt_1[0], self.out.eta_1[0]) self.out.idisoweight_2[0] = self.ltfSFs.getSF( self.out.genPartFlav_2[0], self.out.eta_2[0]) self.out.btagweight[0] = self.btagTool.getWeight(event, jetIds) self.out.btagweight_deep[0] = self.btagTool_deep.getWeight( event, jetIds) self.out.weight[0] = self.out.genweight[0] * self.out.puweight[ 0] * self.out.trigweight[0] * self.out.idisoweight_1[ 0] * self.out.idisoweight_2[0] self.out.tree.Fill() return True