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, filelist): self.name = name self.out = TreeProducer(name) self.sample = filelist if DataType == 'data': self.isData = True self.isMC = False else: self.isData = False self.isMC = True if not self.isData: self.puTool = PileupWeightTool(year=2017) self.btagTool = BTagWeightTool('CSVv2', 'medium', channel='mutau', year=2017)
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)
class HZZ4L(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["Nevents"] = ROOT.TH1F("Nevents", "Nevents", 1, 0, 1) #self.hists["Acceptance"] = ROOT.TH1F("Acceptance", "Acceptance", 5, -0.5, 4.5) #self.hists["genH_pt"] = ROOT.TH1F("genH_pt", ";generator H p_{T} (GeV)", 100, 0., 100.) #self.hists["genH_eta"] = ROOT.TH1F("genH_eta", ";generator H #eta", 100, -5., 5.) #self.hists["genH_phi"] = ROOT.TH1F("genH_phi", ";generator H #phi", 100, -3.15, 3.15) #self.hists["genH_mass"] = ROOT.TH1F("genH_mass", ";generator H mass", 300, 0., 150.) #self.hists["genJPsi_pt"] = ROOT.TH1F("genJPsi_pt", ";generator J/#Psi p_{T} (GeV)", 100, 0., 100.) #self.hists["genJPsi_eta"] = ROOT.TH1F("genJPsi_eta", ";generator J/#Psi #eta", 100, -5., 5.) #self.hists["genJPsi_phi"] = ROOT.TH1F("genJPsi_phi", ";generator J/#Psi #phi", 100, -3.15, 3.15) #self.hists["genJPsi_mass"] = ROOT.TH1F("genJPsi_mass", ";generator J/#Psi mass", 200, 0., 4.) #self.hists["genPhoton_pt"] = ROOT.TH1F("genPhoton_pt", ";generator #gamma p_{T} (GeV)", 100, 0., 100.) #self.hists["genPhoton_eta"] = ROOT.TH1F("genPhoton_eta", ";generator #gamma #eta", 100, -5., 5.) #self.hists["genMuon1_pt"] = ROOT.TH1F("genMuon1_pt", ";generator #mu^{-} p_{T} (GeV)", 100, 0., 100.) #self.hists["genMuon1_eta"] = ROOT.TH1F("genMuon1_eta", ";generator #mu^{-} #eta", 100, -5., 5.) #self.hists["genMuon2_pt"] = ROOT.TH1F("genMuon2_pt", ";generator #mu^{+} p_{T} (GeV)", 100, 0., 100.) #self.hists["genMuon2_eta"] = ROOT.TH1F("genMuon2_eta", ";generator #mu^{+} #eta", 100, -5., 5.) #self.hists["genCosThetaStar"] = ROOT.TH1F("genCosThetaStar", ";cos #theta^{*}", 100, -1., 1.) #self.hists["genCosTheta1"] = ROOT.TH1F("genCosTheta1", ";cos #theta_{1}", 100, -1., 1.) #self.hists["genPhi1"] = ROOT.TH1F("genPhi1", ";#Phi_{1}", 100, -3.1415, 3.1415) #self.hists["genCosThetaStarZtoMM"] = ROOT.TH1F("genCosThetaStarZtoMM", ";cos #theta^{*}", 100, -1., 1.) self.hists["Cutflow"] = ROOT.TH1F("Cutflow", "Cutflow", 10, -0.5, 9.5) self.hists["Cutflow"].GetXaxis().SetBinLabel(1, "All events") self.hists["Cutflow"].GetXaxis().SetBinLabel(2, "Acceptance") # self.addObject(self.h_events) # self.h_events.SetDirectory self.verbose = -1 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("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 endFile(self, inputFile, outputFile, inputTree, wrappedOutputTree): outputFile.mkdir("Hists") outputFile.cd("Hists") for histname, hist in self.hists.iteritems(): hist.Write() outputFile.cd("..") if self.verbose >= 0: print "+ File closed successfully" pass def analyze(self, event): eventWeightLumi, lheWeight, stitchWeight, puWeight, qcdnloWeight, qcdnnloWeight, ewknloWeight, topWeight = 1., 1., 1., 1., 1., 1., 1., 1. triggerWeight, leptonWeight = 1., 1. isDoubleElectronTrigger, isDoubleMuonTrigger, isMuonElectronTrigger = False, False, False nCleanElectron, nCleanMuon, nCleanTau, nCleanPhoton, nCleanJet, nCleanBTagJet, HT30 = 0, 0, 0, 0, 0, 0, 0 cosThetaStar, cosTheta1, cosTheta2, phi, phi1 = -2., -2., -2., -4., -4. is4e, is4m, is2e2m = False, False, False for t in self.DoubleElectronTriggers: if hasattr(event, t) and getattr(event, t): isDoubleElectronTrigger = True for t in self.DoubleMuonTriggers: if hasattr(event, t) and getattr(event, t): isDoubleMuonTrigger = True for t in self.MuonElectronTriggers: if hasattr(event, t) and getattr(event, t): isMuonElectronTrigger = True lheWeight = 1. if self.isMC: # Event weight if not self.isLO and hasattr(event, "LHEWeight_originalXWGTUP"): lheWeight = event.LHEWeight_originalXWGTUP # PU weight puWeight = self.puTool.getWeight(event.Pileup_nTrueInt) self.hists["Cutflow"].Fill(1, lheWeight) cleanElectrons, cleanMuons = [], [] # Electrons for i in range(event.nElectron): if event.Electron_pt[i] > 7. and abs( event.Electron_eta[i] ) < 2.5 and event.Electron_mvaFall17V2Iso_WP90[i] and abs( event.Electron_dxy[i]) < 0.5 and abs( event.Electron_dz[i] ) < 1.0 and event.Electron_sip3d[i] < 4.: cleanElectrons += [i] # Muons for i in range(event.nMuon): if event.Muon_pt[i] > 5. and abs(event.Muon_eta[i]) < 2.4 and abs( event.Muon_dxy[i]) < 0.5 and abs( event.Muon_dz[i]) < 1.0 and event.Muon_looseId[ i] and event.Muon_pfRelIso03_all[ i] < 0.35 and event.Muon_sip3d[i] < 4.: cleanMuons += [i] il1, il2, il3, il4 = -1, -1, -1, -1 l1, l2, l3, l4, z1, z2 = TLorentzVector(), TLorentzVector( ), TLorentzVector(), TLorentzVector(), TLorentzVector( ), TLorentzVector() lm1, lp1, lm2, lp2 = TLorentzVector(), TLorentzVector( ), TLorentzVector(), TLorentzVector() # ZZ -> 4mu if len(cleanMuons) >= 4: # Try to reconstruct Z1 for i in range(len(cleanMuons)): for j in range(len(cleanMuons)): if i == j or (il1 >= 0 and il2 >= 0): continue if event.Muon_charge[i] * event.Muon_charge[j] > 0: continue l1.SetPtEtaPhiM(event.Muon_pt[i], event.Muon_eta[i], event.Muon_phi[i], event.Muon_mass[i]) l2.SetPtEtaPhiM(event.Muon_pt[j], event.Muon_eta[j], event.Muon_phi[j], event.Muon_mass[j]) if 40 < (l1 + l2).M() < 120.: z1, il1, il2 = (l1 + l2), i, j lm1, lp1 = (l1, l2) if event.Muon_charge[i] < 0 else (l2, l1) # Look for Z2 for i in range(len(cleanMuons)): for j in range(len(cleanMuons)): if i == j or i == il1 or j == il1 or i == il2 or j == il2 or ( il3 >= 0 and il4 >= 0): continue if event.Muon_charge[i] * event.Muon_charge[j] > 0: continue l3.SetPtEtaPhiM(event.Muon_pt[i], event.Muon_eta[i], event.Muon_phi[i], event.Muon_mass[i]) l4.SetPtEtaPhiM(event.Muon_pt[j], event.Muon_eta[j], event.Muon_phi[j], event.Muon_mass[j]) if (l3 + l4).M() > 4.: z2, il3, il4 = (l3 + l4), i, j lm2, lp2 = (l3, l4) if event.Muon_charge[i] < 0 else (l4, l3) if il1 >= 0 and il2 >= 0 and il3 >= 0 and il4 >= 0 and isDoubleMuonTrigger: is4m = True # ZZ -> 4e elif len(cleanElectrons) >= 4: # Try to reconstruct Z1 for i in range(len(cleanElectrons)): for j in range(len(cleanElectrons)): if i == j or (il1 >= 0 and il2 >= 0): continue if event.Electron_charge[i] * event.Electron_charge[j] > 0: continue l1.SetPtEtaPhiM(event.Electron_pt[i], event.Electron_eta[i], event.Electron_phi[i], event.Electron_mass[i]) l2.SetPtEtaPhiM(event.Electron_pt[j], event.Electron_eta[j], event.Electron_phi[j], event.Electron_mass[j]) if 40 < (l1 + l2).M() < 120.: z1, il1, il2 = (l1 + l2), i, j lm1, lp1 = (l1, l2) if event.Muon_charge[i] < 0 else (l2, l1) # Look for Z2 for i in range(len(cleanElectrons)): for j in range(len(cleanElectrons)): if i == j or i == il1 or j == il1 or i == il2 or j == il2 or ( il3 >= 0 and il4 >= 0): continue if event.Electron_charge[i] * event.Electron_charge[j] > 0: continue l3.SetPtEtaPhiM(event.Electron_pt[i], event.Electron_eta[i], event.Electron_phi[i], event.Electron_mass[i]) l4.SetPtEtaPhiM(event.Electron_pt[j], event.Electron_eta[j], event.Electron_phi[j], event.Electron_mass[j]) if (l3 + l4).M() > 4.: z2, il3, il4 = (l3 + l4), i, j lm2, lp2 = (l3, l4) if event.Muon_charge[i] < 0 else (l4, l3) if il1 >= 0 and il2 >= 0 and il3 >= 0 and il4 >= 0 and isDoubleElectronTrigger: is4e = True # ZZ -> 2e2mu elif len(cleanMuons) >= 2 and len(cleanElectrons) >= 2: # Try to reconstruct Z1 (mumu) for i in range(len(cleanMuons)): for j in range(len(cleanMuons)): if i == j or (il1 >= 0 and il2 >= 0): continue if event.Muon_charge[i] * event.Muon_charge[j] > 0: continue l1.SetPtEtaPhiM(event.Muon_pt[i], event.Muon_eta[i], event.Muon_phi[i], event.Muon_mass[i]) l2.SetPtEtaPhiM(event.Muon_pt[j], event.Muon_eta[j], event.Muon_phi[j], event.Muon_mass[j]) if (l1 + l2).M() > 4.: z1, il1, il2 = (l1 + l2), i, j lm1, lp1 = (l1, l2) if event.Muon_charge[i] < 0 else (l2, l1) # Look for Z2 (ee) for i in range(len(cleanElectrons)): for j in range(len(cleanElectrons)): if i == j or (il3 >= 0 and il3 >= 0): continue if event.Electron_charge[i] * event.Electron_charge[j] > 0: continue l3.SetPtEtaPhiM(event.Electron_pt[i], event.Electron_eta[i], event.Electron_phi[i], event.Electron_mass[i]) l4.SetPtEtaPhiM(event.Electron_pt[j], event.Electron_eta[j], event.Electron_phi[j], event.Electron_mass[j]) if (l3 + l4).M() > 4.: z2, il3, il4 = (l3 + l4), i, j lm2, lp2 = (l3, l4) if event.Muon_charge[i] < 0 else (l4, l3) # Swap Z1 and Z2 if needed if z2.M() > z1.M(): z1, z2 = z2, z1 l1, l2, l3, l4 = l3, l4, l1, l2 lm1, lp1, lm2, lp2 = lm2, lp2, lm1, lp1 il1, il2, il3, il4 = il3, il4, il1, il2 if il1 >= 0 and il2 >= 0 and il3 >= 0 and il4 >= 0 and ( 40. < z1.M() < 120.) and z2.M() > 4. and ( isDoubleElectronTrigger or isDoubleMuonTrigger or isMuonElectronTrigger): is2e2m = True if not is4m and not is4e and not is2e2m: if self.verbose >= 2: print "- No ZZ candidate reconstructed" return False self.hists["Cutflow"].Fill(2, lheWeight) h = z1 + z2 z1_pt = z1.Pt() z1_eta = z1.Eta() z1_phi = z1.Phi() z1_mass = z1.M() z1_dEta = abs(l1.Eta() - l2.Eta()) z1_dPhi = abs(l1.DeltaPhi(l2)) z1_dR = l1.DeltaR(l2) z2_pt = z2.Pt() z2_eta = z2.Eta() z2_phi = z2.Phi() z2_mass = z2.M() z2_dEta = abs(l3.Eta() - l4.Eta()) z2_dPhi = abs(l3.DeltaPhi(l4)) z2_dR = l3.DeltaR(l4) h_pt = h.Pt() h_eta = h.Eta() h_phi = h.Phi() h_mass = h.M() h_dEta = abs(z1.Eta() - z2.Eta()) h_dPhi = abs(z1.DeltaPhi(z2)) h_dR = z1.DeltaR(z2) cosThetaStar = self.returnCosThetaStar(h, z1) cosTheta1 = self.returnCosTheta1(z1, lp1, lm1, z2) cosTheta2 = self.returnCosTheta1(z2, lp2, lm2, z1) phi = self.returnPhi(h, lp1, lm1, lp2, lm2) phi1 = self.returnPhi1(h, lp1, lm1) # Weights if self.isMC: if is4e: triggerWeight = 0.982 / 0.991 elif is4m: triggerWeight = 1.000 / 0.997 elif is2e2m: triggerWeight = 0.983 / 0.995 # 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 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 ### Event variables ### # Muons nCleanMuon = len(cleanMuons) # Electrons nCleanElectron = len(cleanElectrons) # Taus for i in range(event.nTau): if event.Tau_pt[i] > 20. and abs( event.Tau_eta[i]) < 2.5 and event.Tau_idDeepTau2017v2p1VSe[ i] >= 16 and event.Tau_idDeepTau2017v2p1VSmu[ i] >= 8 and event.Tau_idDeepTau2017v2p1VSjet[ i] >= 16 and event.Tau_rawIsodR03[i] < 0.15: nCleanTau += 1 # Photons for i in range(event.nPhoton): if event.Photon_pt[i] > 15. and abs( event.Photon_eta[i]) < 2.5 and event.Photon_pfRelIso03_all[ i] < 0.15 and event.Photon_mvaID_WP90[i]: nCleanPhoton += 1 # Jets and Event variables for i in range(event.nJet): if event.Jet_jetId[i] >= 6 and abs(event.Jet_eta[i]) < 2.5: HT30 += event.Jet_pt[i] nCleanJet += 1 if event.Jet_btagDeepB[i] >= self.btagMedium: nCleanBTagJet += 1 if self.isMC: eventWeightLumi = self.lumiWeight * lheWeight * puWeight * topWeight * qcdnloWeight * qcdnnloWeight * ewknloWeight * triggerWeight * leptonWeight self.out.fillBranch("isMC", self.isMC) self.out.fillBranch("is2016", (self.year == 2016)) self.out.fillBranch("is2017", (self.year == 2017)) self.out.fillBranch("is2018", (self.year == 2018)) self.out.fillBranch("is4m", is4m) self.out.fillBranch("is4e", is4e) self.out.fillBranch("is2e2m", is2e2m) self.out.fillBranch("isDoubleElectronTrigger", isDoubleElectronTrigger) self.out.fillBranch("isDoubleMuonTrigger", isDoubleMuonTrigger) self.out.fillBranch("isMuonElectronTrigger", isMuonElectronTrigger) self.out.fillBranch("passedMETFilters", passedMETFilters) self.out.fillBranch("nCleanElectron", nCleanElectron) self.out.fillBranch("nCleanMuon", nCleanMuon) self.out.fillBranch("nCleanTau", nCleanTau) self.out.fillBranch("nCleanPhoton", nCleanPhoton) self.out.fillBranch("nCleanJet", nCleanJet) self.out.fillBranch("nCleanBTagJet", nCleanBTagJet) self.out.fillBranch("HT30", HT30) self.out.fillBranch("iLepton1", il1) self.out.fillBranch("iLepton2", il2) self.out.fillBranch("iLepton3", il3) self.out.fillBranch("iLepton4", il4) self.out.fillBranch("Z1_pt", z1_pt) self.out.fillBranch("Z1_eta", z1_eta) self.out.fillBranch("Z1_phi", z1_phi) self.out.fillBranch("Z1_mass", z1_mass) self.out.fillBranch("Z1_dEta", z1_dEta) self.out.fillBranch("Z1_dPhi", z1_dPhi) self.out.fillBranch("Z1_dR", z1_dR) self.out.fillBranch("Z2_pt", z2_pt) self.out.fillBranch("Z2_eta", z2_eta) self.out.fillBranch("Z2_phi", z2_phi) self.out.fillBranch("Z2_mass", z2_mass) self.out.fillBranch("Z2_dEta", z2_dEta) self.out.fillBranch("Z2_dPhi", z2_dPhi) self.out.fillBranch("Z2_dR", z2_dR) self.out.fillBranch("H_pt", h_pt) self.out.fillBranch("H_eta", h_eta) self.out.fillBranch("H_phi", h_phi) self.out.fillBranch("H_mass", h_mass) self.out.fillBranch("H_dEta", h_dEta) self.out.fillBranch("H_dPhi", h_dPhi) self.out.fillBranch("H_dR", h_dR) self.out.fillBranch("cosThetaStar", cosThetaStar) self.out.fillBranch("cosTheta1", cosTheta1) self.out.fillBranch("cosTheta2", cosTheta2) self.out.fillBranch("phi", phi) self.out.fillBranch("phi1", phi1) #self.out.fillBranch("genCosThetaStar", genCosThetaStar) #self.out.fillBranch("genCosTheta1", genCosTheta1) #self.out.fillBranch("genPhi1", genPhi1) 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) if self.verbose >= 2: print "+ Tree filled" return True def returnCosThetaStar(self, theH, theJPsi): h, j = TLorentzVector(theH), TLorentzVector(theJPsi) # Boost the Z to the A rest frame j.Boost(-h.BoostVector()) value = j.CosTheta() if value != value or math.isinf(value): return -2. return value def returnCosTheta1(self, theJPsi, theL1, theL2, thePhoton): j, l1, l2, g = TLorentzVector(theJPsi), TLorentzVector( theL1), TLorentzVector(theL2), TLorentzVector(thePhoton) # Boost objects to the JPsi rest frame l1.Boost(-j.BoostVector()) l2.Boost(-j.BoostVector()) g.Boost(-j.BoostVector()) # cos theta = Gamma dot L1 / (|Gamma|*|L1|) value = g.Vect().Dot(l1.Vect()) / ( (g.Vect().Mag()) * (l1.Vect().Mag()) ) if g.Vect().Mag() > 0. and l1.Vect().Mag() > 0. else -2 if value != value or math.isinf(value): return -2. return value def returnPhi1(self, theH, theL1, theL2): h, l1, l2 = TLorentzVector(theH), TLorentzVector( theL1), TLorentzVector(theL2) beamAxis = TVector3(0., 0., 1.) # Boost objects to the A rest frame l1.Boost(-h.BoostVector()) l2.Boost(-h.BoostVector()) # Reconstruct JPsi in H rest frame j = l1 + l2 # Build unit vectors orthogonal to the decay planes Zplane = TVector3(l1.Vect().Cross(l2.Vect())) # L1 x L2 Bplane = TVector3(beamAxis.Cross( j.Vect())) # Beam x JPsi, beam/JPsi plane if Zplane.Mag() == 0. or Bplane.Mag() == 0.: return -4. Zplane.SetMag(1.) Bplane.SetMag(1.) # Sign of Phi1 sgn = j.Vect().Dot(Zplane.Cross(Bplane)) sgn /= abs(sgn) if abs(Zplane.Dot(Bplane)) > 1.: return -5. value = sgn * math.acos(Zplane.Dot(Bplane)) if value != value or math.isinf(value): return -5. return value def returnPhi(self, theH, theL1, theL2, theL3, theL4): h, l1, l2, l3, l4 = TLorentzVector(theH), TLorentzVector( theL1), TLorentzVector(theL2), TLorentzVector( theL3), TLorentzVector(theL4) # Boost objects to the A rest frame l1.Boost(-h.BoostVector()) l2.Boost(-h.BoostVector()) l3.Boost(-h.BoostVector()) l4.Boost(-h.BoostVector()) # Build unit vectors orthogonal to the decay planes Zplane = l1.Vect().Cross(l2.Vect()) # L1 x L2 Hplane = l3.Vect().Cross(l4.Vect()) # B1 x B2 Zplane.SetMag(1.) Hplane.SetMag(1.) # Sign of Phi z1 = l1 + l2 sgn = 1 if z1.Vect().Dot(Zplane.Cross(Hplane)) > 0 else -1 value = sgn * math.acos(Zplane.Dot(Hplane)) if value != value or math.isinf(value): return -5. return value
def __init__(self, name, dataType, **kwargs): year = kwargs.get('year', 2017) tes = kwargs.get('tes', 1.0) channel = 'eletau' self.name = name self.year = year self.tes = tes self.out = TreeProducerEleTau(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_Ele25_eta2p1_WPTight_Gsf or e.HLT_Ele45_WPLoose_Gsf_L1JetTauSeeded #or e.HLT_Ele24_eta2p1_WPLoose_Gsf_LooseIsoPFTau20_SingleL1 or e.HLT_Ele24_eta2p1_WPLoose_Gsf_LooseIsoPFTau20 or e.HLT_Ele24_eta2p1_WPLoose_Gsf_LooseIsoPFTau30 self.electronCutPt = 26 else: # HLT_Ele32_WPTight_Gsf_L1DoubleEG # HLT_Ele32_WPTight_Gsf self.trigger = lambda e: e.HLT_Ele35_WPTight_Gsf or e.HLT_Ele32_WPTight_Gsf self.electronCutPt = 36 self.tauCutPt = 20 if not self.isData: self.eleSFs = ElectronSFs(year=year) self.puTool = PileupWeightTool(year=year) self.ltfSFs = LeptonTauFakeSFs('loose', 'tight', 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.GoodElectrons = 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.GoodElectrons, "electron object") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodTaus, "tau object") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodDiLepton, "eletau 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 EleTauProducer(Module): def __init__(self, name, dataType, **kwargs): year = kwargs.get('year', 2017) tes = kwargs.get('tes', 1.0) channel = 'eletau' self.name = name self.year = year self.tes = tes self.out = TreeProducerEleTau(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_Ele25_eta2p1_WPTight_Gsf or e.HLT_Ele45_WPLoose_Gsf_L1JetTauSeeded #or e.HLT_Ele24_eta2p1_WPLoose_Gsf_LooseIsoPFTau20_SingleL1 or e.HLT_Ele24_eta2p1_WPLoose_Gsf_LooseIsoPFTau20 or e.HLT_Ele24_eta2p1_WPLoose_Gsf_LooseIsoPFTau30 self.electronCutPt = 26 else: # HLT_Ele32_WPTight_Gsf_L1DoubleEG # HLT_Ele32_WPTight_Gsf self.trigger = lambda e: e.HLT_Ele35_WPTight_Gsf or e.HLT_Ele32_WPTight_Gsf self.electronCutPt = 36 self.tauCutPt = 20 if not self.isData: self.eleSFs = ElectronSFs(year=year) self.puTool = PileupWeightTool(year=year) self.ltfSFs = LeptonTauFakeSFs('loose', 'tight', 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.GoodElectrons = 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.GoodElectrons, "electron object") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodTaus, "tau object") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodDiLepton, "eletau 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)""" #electrons = Collection(event, "Electron") ##################################### 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) 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_goodelectrons = [] for ielectron in range(event.nElectron): if event.Electron_pt[ielectron] < self.electronCutPt: continue if abs(event.Electron_eta[ielectron]) > 2.1: continue if abs(event.Electron_dz[ielectron]) > 0.2: continue if abs(event.Electron_dxy[ielectron]) > 0.045: continue if event.Electron_convVeto[ielectron] != 1: continue if ord(event.Electron_lostHits[ielectron]) > 1: continue if getvar(event, 'Electron_mvaFall17Iso_WP80')[ielectron] < 0.5: continue idx_goodelectrons.append(ielectron) if len(idx_goodelectrons) == 0: return False ##################################### self.out.cutflow.Fill(self.GoodElectrons) ##################################### idx_goodtaus = [] for itau in range(event.nTau): 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) ##################################### electrons = Collection(event, 'Electron') taus = Collection(event, 'Tau') ltaus = [] for idx1 in idx_goodelectrons: for idx2 in idx_goodtaus: dR = taus[idx2].p4().DeltaR(electrons[idx1].p4()) if dR < 0.5: continue ltau = LeptonTauPair(idx1, event.Electron_pt[idx1], event.Electron_pfRelIso03_all[idx1], idx2, event.Tau_pt[idx2], event.Tau_rawMVAoldDM2017v2[idx2]) ltaus.append(ltau) if len(ltaus) == 0: return False ltau = bestDiLepton(ltaus) electron = electrons[ltau.id1].p4() tau = taus[ltau.id2].p4() #print 'chosen tau1 (idx, pt) = ', ltau.id1, ltau.tau1_pt, 'check', electron.p4().Pt() #print 'chosen tau2 (idx, pt) = ', ltau.id2, ltau.tau2_pt, 'check', tau.p4().Pt() ##################################### self.out.cutflow.Fill(self.GoodDiLepton) ##################################### 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 electron.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.Electron_pfRelIso03_all[ltau.id1] < 0.50: self.btagTool.fillEfficiencies(event, jetIds) self.btagTool_deep.fillEfficiencies(event, jetIds) #eventSum = ROOT.TLorentzVector() # #for lep in electrons : # eventSum += lep.p4() #for lep in electrons : # eventSum += lep.p4() #for j in filter(self.jetSel,jets): # eventSum += j.p4() # ELECTRON self.out.pt_1[0] = event.Electron_pt[ltau.id1] self.out.eta_1[0] = event.Electron_eta[ltau.id1] self.out.phi_1[0] = event.Electron_phi[ltau.id1] self.out.m_1[0] = event.Electron_mass[ltau.id1] self.out.dxy_1[0] = event.Electron_dxy[ltau.id1] self.out.dz_1[0] = event.Electron_dz[ltau.id1] self.out.q_1[0] = event.Electron_charge[ltau.id1] self.out.pfRelIso03_all_1[0] = event.Electron_pfRelIso03_all[ltau.id1] self.out.cutBased_1[0] = event.Electron_cutBased[ltau.id1] self.out.mvaFall17Iso_1[0] = getvar(event, 'Electron_mvaFall17Iso')[ltau.id1] self.out.mvaFall17Iso_WP80_1[0] = getvar( event, 'Electron_mvaFall17Iso_WP80')[ltau.id1] self.out.mvaFall17Iso_WP90_1[0] = getvar( event, 'Electron_mvaFall17Iso_WP90')[ltau.id1] self.out.mvaFall17Iso_WPL_1[0] = getvar( event, 'Electron_mvaFall17Iso_WPL')[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.rawMVAnewDM2017v2_2[0] = event.Tau_rawMVAnewDM2017v2[ltau.id2] self.out.rawMVAoldDM2017v1_2[0] = event.Tau_rawMVAoldDM2017v1[ltau.id2] self.out.rawMVAoldDM2017v2_2[0] = event.Tau_rawMVAoldDM2017v2[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 #print type(event.Tau_genPartFlav[ltau.id2]) if not self.isData: self.out.genPartFlav_1[0] = ord( event.Electron_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 self.out.genWeight[0] = event.genWeight 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] = (electron + tau).M() self.out.pt_ll[0] = (electron + tau).Pt() self.out.dR_ll[0] = electron.DeltaR(tau) self.out.dphi_ll[0] = deltaPhi(self.out.phi_1[0], self.out.phi_2[0]) # PZETA leg1 = ROOT.TVector3(electron.Px(), electron.Py(), 0.) leg2 = ROOT.TVector3(tau.Px(), tau.Py(), 0.) met_tlv = ROOT.TLorentzVector() 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, [-1], [ltau.id1], 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.eleSFs.getTriggerSF( self.out.pt_1[0], self.out.eta_1[0]) self.out.idisoweight_1[0] = self.eleSFs.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
def __init__(self, name, dataType, **kwargs): self.name = name self.out = TreeProducerEleTau(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.jtf = kwargs.get('jtf', 1.0) 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 = 'eletau' year, channel = self.year, self.channel self.vlooseIso = getVLooseTauIso(year) if year == 2016: self.trigger = lambda e: e.HLT_Ele25_eta2p1_WPTight_Gsf or e.HLT_Ele27_WPTight_Gsf #or e.HLT_Ele45_WPLoose_Gsf_L1JetTauSeeded #or e.HLT_Ele24_eta2p1_WPLoose_Gsf_LooseIsoPFTau20_SingleL1 or e.HLT_Ele24_eta2p1_WPLoose_Gsf_LooseIsoPFTau20 or e.HLT_Ele24_eta2p1_WPLoose_Gsf_LooseIsoPFTau30 self.eleCutPt = 26 elif year == 2017: self.trigger = lambda e: e.HLT_Ele35_WPTight_Gsf or e.HLT_Ele32_WPTight_Gsf_L1DoubleEG or e.HLT_Ele32_WPTight_Gsf self.eleCutPt = 36 else: self.trigger = lambda e: e.HLT_Ele32_WPTight_Gsf or e.HLT_Ele35_WPTight_Gsf self.eleCutPt = 33 self.tauCutPt = 20 if not self.isData: self.eleSFs = ElectronSFs(year=year) self.puTool = PileupWeightTool(year=year) self.ltfSFs = LeptonTauFakeSFs('loose', 'tight', 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.GoodElectrons = 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.GoodElectrons, "electron object") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodTaus, "tau object") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodDiLepton, "eletau 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 EleTauProducer(Module): def __init__(self, name, dataType, **kwargs): self.name = name self.out = TreeProducerEleTau(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.jtf = kwargs.get('jtf', 1.0) 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 = 'eletau' year, channel = self.year, self.channel self.vlooseIso = getVLooseTauIso(year) if year == 2016: self.trigger = lambda e: e.HLT_Ele25_eta2p1_WPTight_Gsf or e.HLT_Ele27_WPTight_Gsf #or e.HLT_Ele45_WPLoose_Gsf_L1JetTauSeeded #or e.HLT_Ele24_eta2p1_WPLoose_Gsf_LooseIsoPFTau20_SingleL1 or e.HLT_Ele24_eta2p1_WPLoose_Gsf_LooseIsoPFTau20 or e.HLT_Ele24_eta2p1_WPLoose_Gsf_LooseIsoPFTau30 self.eleCutPt = 26 elif year == 2017: self.trigger = lambda e: e.HLT_Ele35_WPTight_Gsf or e.HLT_Ele32_WPTight_Gsf_L1DoubleEG or e.HLT_Ele32_WPTight_Gsf self.eleCutPt = 36 else: self.trigger = lambda e: e.HLT_Ele32_WPTight_Gsf or e.HLT_Ele35_WPTight_Gsf self.eleCutPt = 33 self.tauCutPt = 20 if not self.isData: self.eleSFs = ElectronSFs(year=year) self.puTool = PileupWeightTool(year=year) self.ltfSFs = LeptonTauFakeSFs('loose', 'tight', 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.GoodElectrons = 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.GoodElectrons, "electron object") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodTaus, "tau object") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodDiLepton, "eletau 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) 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_goodelectrons = [] for ielectron in range(event.nElectron): if event.Electron_pt[ielectron] < self.eleCutPt: continue if abs(event.Electron_eta[ielectron]) > 2.1: continue if abs(event.Electron_dz[ielectron]) > 0.2: continue if abs(event.Electron_dxy[ielectron]) > 0.045: continue if event.Electron_convVeto[ielectron] != 1: continue if ord(event.Electron_lostHits[ielectron]) > 1: continue if event.Electron_mvaFall17V2Iso_WP80[ielectron] < 0.5: continue idx_goodelectrons.append(ielectron) if len(idx_goodelectrons) == 0: return False ##################################### self.out.cutflow.Fill(self.GoodElectrons) ##################################### Tau_genmatch = {} # bug in Tau_genPartFlav idx_goodtaus = [] for itau in range(event.nTau): if not self.vlooseIso(event, itau): 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 not self.isData: Tau_genmatch[itau] = genmatch(event, itau) #if self.tes!=1.0 and Tau_genmatch[itau]==5: # event.Tau_pt[itau] *= self.tes # event.Tau_mass[itau] *= self.tes #elif self.ltf!=1.0 and 0<Tau_genmatch[itau]<5: # event.Tau_pt[itau] *= self.ltf # event.Tau_mass[itau] *= self.ltf #elif self.jtf!=1.0 and Tau_genmatch[itau]==0: # event.Tau_pt[itau] *= self.jtf # event.Tau_mass[itau] *= self.jtf if event.Tau_pt[itau] < self.tauCutPt: continue ###if ord(event.Tau_idAntiEle[itau])<1: continue ###if ord(event.Tau_idAntiMu[itau])<1: continue idx_goodtaus.append(itau) if len(idx_goodtaus) == 0: return False ##################################### self.out.cutflow.Fill(self.GoodTaus) ##################################### electrons = Collection(event, 'Electron') taus = Collection(event, 'Tau') ltaus = [] for idx1 in idx_goodelectrons: for idx2 in idx_goodtaus: dR = taus[idx2].p4().DeltaR(electrons[idx1].p4()) if dR < 0.5: continue ltau = LeptonTauPair(idx1, event.Electron_pt[idx1], event.Electron_pfRelIso03_all[idx1], idx2, event.Tau_pt[idx2], event.Tau_rawMVAoldDM2017v2[idx2]) ltaus.append(ltau) if len(ltaus) == 0: return False ltau = bestDiLepton(ltaus) electron = electrons[ltau.id1].p4() tau = taus[ltau.id2].p4() #print 'chosen tau1 (idx, pt) = ', ltau.id1, ltau.tau1_pt, 'check', electron.p4().Pt() #print 'chosen tau2 (idx, pt) = ', ltau.id2, ltau.tau2_pt, 'check', tau.p4().Pt() ##################################### self.out.cutflow.Fill(self.GoodDiLepton) ##################################### # VETOS self.out.extramuon_veto[0], self.out.extraelec_veto[ 0], self.out.dilepton_veto[0] = extraLeptonVetos( event, [-1], [ltau.id1], self.channel) self.out.lepton_vetos[0] = self.out.extramuon_veto[ 0] or self.out.extraelec_veto[0] or self.out.dilepton_veto[0] ###if self.doTight and (self.out.lepton_vetos[0] or event.Electron_pfRelIso03_all[ltau.id1]>0.10 or\ ### ord(event.Tau_idAntiMu[ltau.id2]<1 or ord(event.Tau_idAntiEle[ltau.id2]<8): ### return False # 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 electron.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.Electron_pfRelIso03_all[ltau.id1] < 0.50: self.btagTool.fillEfficiencies(event, jetIds) # 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 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 # ELECTRON self.out.pt_1[0] = event.Electron_pt[ltau.id1] self.out.eta_1[0] = event.Electron_eta[ltau.id1] self.out.phi_1[0] = event.Electron_phi[ltau.id1] self.out.m_1[0] = event.Electron_mass[ltau.id1] self.out.dxy_1[0] = event.Electron_dxy[ltau.id1] self.out.dz_1[0] = event.Electron_dz[ltau.id1] self.out.q_1[0] = event.Electron_charge[ltau.id1] self.out.pfRelIso03_all_1[0] = event.Electron_pfRelIso03_all[ltau.id1] self.out.cutBased_1[0] = event.Electron_cutBased[ltau.id1] self.out.mvaFall17Iso_1[0] = event.Electron_mvaFall17V2Iso[ltau.id1] self.out.mvaFall17Iso_WPL_1[0] = event.Electron_mvaFall17V2Iso_WPL[ ltau.id1] self.out.mvaFall17Iso_WP80_1[0] = event.Electron_mvaFall17V2Iso_WP80[ ltau.id1] self.out.mvaFall17Iso_WP90_1[0] = event.Electron_mvaFall17V2Iso_WP90[ 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.rawMVAnewDM2017v2_2[0] = event.Tau_rawMVAnewDM2017v2[ltau.id2] self.out.rawMVAoldDM2017v1_2[0] = event.Tau_rawMVAoldDM2017v1[ltau.id2] self.out.rawMVAoldDM2017v2_2[0] = event.Tau_rawMVAoldDM2017v2[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.Electron_genPartFlav[ltau.id1]) self.out.genPartFlav_2[0] = Tau_genmatch[ ltau.id2] # 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 # 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.CorrectPFMETByMeanResolution( 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.eleSFs.getTriggerSF( self.out.pt_1[0], self.out.eta_1[0]) self.out.idisoweight_1[0] = self.eleSFs.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.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] * self.out.met[0] * (1 - cos(deltaPhi(self.out.phi_1[0], self.out.metphi[0])))) self.out.pfmt_2[0] = sqrt( 2 * self.out.pt_2[0] * self.out.met[0] * (1 - cos(deltaPhi(self.out.phi_2[0], self.out.metphi[0])))) self.out.m_vis[0] = (electron + tau).M() self.out.pt_ll[0] = (electron + tau).Pt() self.out.dR_ll[0] = electron.DeltaR(tau) 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(electron.Px(), electron.Py(), 0.) leg2 = TVector3(tau.Px(), tau.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
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 TauTauProducer(Module): def __init__(self, name, dataType, **kwargs): self.name = name self.out = TreeProducerTauTau(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.jtf = kwargs.get('jtf', 1.0) 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 = 'tautau' year, channel = self.year, self.channel self.vlooseIso = getVLooseTauIso(year) if year == 2016: if self.isData: self.trigger = lambda e: e.HLT_DoubleMediumIsoPFTau35_Trk1_eta2p1_Reg \ if e.run<280919 else e.HLT_DoubleMediumCombinedIsoPFTau35_Trk1_eta2p1_Reg else: self.trigger = lambda e: e.HLT_DoubleMediumIsoPFTau35_Trk1_eta2p1_Reg or e.HLT_DoubleMediumCombinedIsoPFTau35_Trk1_eta2p1_Reg elif year == 2017: self.trigger = lambda e: e.HLT_DoubleTightChargedIsoPFTau35_Trk1_TightID_eta2p1_Reg or e.HLT_DoubleTightChargedIsoPFTau40_Trk1_eta2p1_Reg or e.HLT_DoubleMediumChargedIsoPFTau40_Trk1_TightID_eta2p1_Reg else: if self.isData: self.trigger = lambda e: e.HLT_DoubleTightChargedIsoPFTau35_Trk1_TightID_eta2p1_Reg or e.HLT_DoubleTightChargedIsoPFTau40_Trk1_eta2p1_Reg or e.HLT_DoubleMediumChargedIsoPFTau40_Trk1_TightID_eta2p1_Reg \ if e.run<317509 else e.HLT_DoubleMediumChargedIsoPFTauHPS35_Trk1_eta2p1_Reg else: self.trigger = lambda e: e.HLT_DoubleMediumChargedIsoPFTauHPS35_Trk1_eta2p1_Reg self.tauCutPt = 40 if not self.isData: self.tauSFs = TauTriggerSFs('tautau', 'tight', year=year) self.tauSFsVT = TauTriggerSFs('tautau', 'vtight', year=year) self.ltfSFs = LeptonTauFakeSFs('loose', 'vloose', 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.GoodTaus = 2 self.GoodDiTau = 3 self.Nocut_GT = 20 self.Trigger_GT = 21 self.GoodTaus_GT = 22 self.GoodDiTau_GT = 23 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.GoodTaus, "tau objects") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodDiTau, "ditau pair") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Nocut_GT, "no cut, GM") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Trigger_GT, "trigger, GM") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodTaus_GT, "tau objects, GM") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodDiTau_GT, "ditau pair, GM") 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() ##print '-'*80 ngentauhads = 0 ngentaus = 0 #if not self.isData: # for igp in range(event.nGenPart): # if abs(event.GenPart_pdgId[igp])==15 and event.GenPart_status[igp]==2: # genflag = event.GenPart_statusFlags[igp] # binary = format(genflag,'b').zfill(15) # # 0 : isPrompt # # 1 : isDecayedLeptonHadron # # 2 : isTauDecayProduct # # 3 : isPromptTauDecayProduct # # 4 : isDirectTauDecayProduct # # 5 : isDirectPromptTauDecayProduct # # 6 : isDirectHadronDecayProduct # # 7 : isHardProcess # # 8 : fromHardProcess # # 9 : isHardProcessTauDecayProduct # # 10 : isDirectHardProcessTauDecayProduct # # 11 : fromHardProcessBeforeFSR # # 12 : isFirstCopy # # 13 : isLastCopy # # 14 : isLastCopyBeforeFSR # # if int(binary[14])==0: continue # if int(binary[6])==0: continue # #print 'Tau found with status = 2 (pt, eta) = ', event.GenPart_pt[igp], event.GenPart_eta[igp], event.GenPart_statusFlags[igp] # # ngentaus += 1 # _pdg_ = -1 # _idx_ = event.GenPart_genPartIdxMother[igp] # #_status_ = -1 # flag_resonance = False # # while abs(_pdg_) not in [9000002, 9000006]: # if _idx_==-1: break # _pdg_ = event.GenPart_pdgId[_idx_] # # _status_ = event.GenPart_status[_idx_] # _idx_ = event.GenPart_genPartIdxMother[_idx_] # if abs(_pdg_) > 30 and abs(_pdg_) not in [9000002, 9000006]: # flag_resonance = True # #print '\t (pdg, mother id) = ', _pdg_, _status_, _idx_ # if flag_resonance: continue # _dr_ = 100. # for igvt in range(event.nGenVisTau): # dr = deltaR(event.GenPart_eta[igp], event.GenPart_phi[igp], event.GenVisTau_eta[igvt], event.GenVisTau_phi[igvt]) # #print dr, _dr_, event.GenPart_eta[igp], event.GenPart_phi[igp], event.GenVisTau_eta[igvt], event.GenVisTau_phi[igvt] # if _dr_ > dr: # _dr_ = dr # #print 'match !',_pdg_, event.nGenVisTau, _dr_ # if _dr_ < 0.1: # ngentauhads += 1 # # #for igvt in range(event.nGenVisTau): # # print 'status = ', event.GenVisTau_status[igvt], 'mother ID = ', event.GenVisTau_genPartIdxMother[igvt], 'pt = ', event.GenVisTau_pt[igvt], ', eta = ', event.GenVisTau_eta[igvt] # # ngentauhads += 1 # # if ngentaus != 2: # print 'WOW!!! ngentaus = %d != 2'%(ngentaus) ##################################### self.out.cutflow.Fill(self.Nocut) #if ngentauhads == 2: # self.out.cutflow.Fill(self.Nocut_GT) 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) #if ngentauhads == 2: # self.out.cutflow.Fill(self.Trigger_GT) ##################################### Tau_genmatch = {} # bug in Tau_genPartFlav idx_goodtaus = [] for itau in range(event.nTau): if abs(event.Tau_eta[itau]) > 2.1: 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 not self.vlooseIso(event, itau): continue if not self.isData: Tau_genmatch[itau] = genmatch(event, itau) #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 idx_goodtaus.append(itau) if len(idx_goodtaus) < 2: return False ##################################### self.out.cutflow.Fill(self.GoodTaus) #if ngentauhads == 2: # self.out.cutflow.Fill(self.GoodTaus_GT) ##################################### taus = Collection(event, 'Tau') ditaus = [] for idx1 in idx_goodtaus: for idx2 in idx_goodtaus: if idx1 >= idx2: continue dR = taus[idx1].p4().DeltaR(taus[idx2].p4()) if dR < 0.5: continue ditau = DiTauPair(idx1, event.Tau_pt[idx1], event.Tau_rawMVAoldDM[idx1], idx2, event.Tau_pt[idx2], event.Tau_rawMVAoldDM[idx2]) ditaus.append(ditau) if len(ditaus) == 0: return False ditau = bestDiLepton(ditaus) tau1 = taus[ditau.id1].p4() tau2 = taus[ditau.id2].p4() #print 'chosen tau1 (idx, pt) = ', ditau.id1, ditau.tau1_pt, 'check', tau1.p4().Pt() #print 'chosen tau2 (idx, pt) = ', ditau.id2, ditau.tau2_pt, 'check', tau2.p4().Pt() ##################################### self.out.cutflow.Fill(self.GoodDiTau) #if ngentauhads == 2: # self.out.cutflow.Fill(self.GoodDiTau_GT) ##################################### # VETOS self.out.extramuon_veto[0], self.out.extraelec_veto[ 0], self.out.dilepton_veto[0] = extraLeptonVetos( event, [-1], [-1], self.name) self.out.lepton_vetos[0] = self.out.extramuon_veto[ 0] or self.out.extraelec_veto[0] or self.out.dilepton_veto[0] jetIds = [] bjetIds = [] jets = Collection(event, 'Jet') #jets = filter(self.jetSel,jets): 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 tau1.DeltaR(jets[ijet].p4()) < 0.5: continue if tau2.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, ditau.id1) and self.vlooseIso(event, ditau.id2): self.btagTool.fillEfficiencies(event, jetIds) #eventSum = 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() # EVENT self.out.isData[0] = self.isData self.out.run[0] = event.run self.out.lumi[0] = event.luminosityBlock #print 'event =', event.event & 0xffffffffffffffff, 'original = ', event.event self.out.event[0] = event.event & 0xffffffffffffffff ###self.out.puppimetpt[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.ngentauhads[0] = ngentauhads self.out.ngentaus[0] = ngentaus 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 #print 'check (LO)', event.LHE_NpLO, type(event.LHE_NpLO) #print 'check (NLO)', event.LHE_NpNLO, type(event.LHE_NpNLO) #self.out.LHE_NpLO[0] = event.LHE_NpLO #self.out.LHE_NpNLO[0] = event.LHE_NpNLO #print self.out.LHE_Njets[0], event.LHE_Njets #print self.out.event[0], event.event, (event.event & 0xffffffffffffffff) #print self.out.LHE_Njets[0], event.LHE_Njets, int(event.LHE_Njets) #print event.LHE_NpNLO #print self.out.Pileup_nPU, event.Pileup_nPU # TAU 1 self.out.pt_1[0] = event.Tau_pt[ditau.id1] self.out.eta_1[0] = event.Tau_eta[ditau.id1] self.out.phi_1[0] = event.Tau_phi[ditau.id1] self.out.m_1[0] = event.Tau_mass[ditau.id1] self.out.dxy_1[0] = event.Tau_dxy[ditau.id1] self.out.dz_1[0] = event.Tau_dz[ditau.id1] self.out.leadTkPtOverTauPt_1[0] = event.Tau_leadTkPtOverTauPt[ ditau.id1] self.out.chargedIso_1[0] = event.Tau_chargedIso[ditau.id1] self.out.neutralIso_1[0] = event.Tau_neutralIso[ditau.id1] self.out.photonsOutsideSignalCone_1[ 0] = event.Tau_photonsOutsideSignalCone[ditau.id1] self.out.puCorr_1[0] = event.Tau_puCorr[ditau.id1] self.out.rawAntiEle_1[0] = event.Tau_rawAntiEle[ditau.id1] self.out.rawIso_1[0] = event.Tau_rawIso[ditau.id1] self.out.rawMVAnewDM2017v2_1[0] = event.Tau_rawMVAnewDM2017v2[ ditau.id1] self.out.rawMVAoldDM_1[0] = event.Tau_rawMVAoldDM[ditau.id1] self.out.rawMVAoldDM2017v1_1[0] = event.Tau_rawMVAoldDM2017v1[ ditau.id1] self.out.rawMVAoldDM2017v2_1[0] = event.Tau_rawMVAoldDM2017v2[ ditau.id1] self.out.q_1[0] = event.Tau_charge[ditau.id1] self.out.decayMode_1[0] = event.Tau_decayMode[ditau.id1] ###self.out.rawAntiEleCat_1[0] = event.Tau_rawAntiEleCat[ditau.id1] self.out.idAntiEle_1[0] = ord(event.Tau_idAntiEle[ditau.id1]) self.out.idAntiMu_1[0] = ord(event.Tau_idAntiMu[ditau.id1]) self.out.idDecayMode_1[0] = event.Tau_idDecayMode[ditau.id1] self.out.idDecayModeNewDMs_1[0] = event.Tau_idDecayModeNewDMs[ ditau.id1] self.out.idMVAnewDM2017v2_1[0] = ord( event.Tau_idMVAnewDM2017v2[ditau.id1]) self.out.idMVAoldDM_1[0] = ord(event.Tau_idMVAoldDM[ditau.id1]) self.out.idMVAoldDM2017v1_1[0] = ord( event.Tau_idMVAoldDM2017v1[ditau.id1]) self.out.idMVAoldDM2017v2_1[0] = ord( event.Tau_idMVAoldDM2017v2[ditau.id1]) # TAU 2 self.out.pt_2[0] = event.Tau_pt[ditau.id2] self.out.eta_2[0] = event.Tau_eta[ditau.id2] self.out.phi_2[0] = event.Tau_phi[ditau.id2] self.out.m_2[0] = event.Tau_mass[ditau.id2] self.out.dxy_2[0] = event.Tau_dxy[ditau.id2] self.out.dz_2[0] = event.Tau_dz[ditau.id2] self.out.leadTkPtOverTauPt_2[0] = event.Tau_leadTkPtOverTauPt[ ditau.id2] self.out.chargedIso_2[0] = event.Tau_chargedIso[ditau.id2] self.out.neutralIso_2[0] = event.Tau_neutralIso[ditau.id2] self.out.photonsOutsideSignalCone_2[ 0] = event.Tau_photonsOutsideSignalCone[ditau.id2] self.out.puCorr_2[0] = event.Tau_puCorr[ditau.id2] self.out.rawAntiEle_2[0] = event.Tau_rawAntiEle[ditau.id2] self.out.rawIso_2[0] = event.Tau_rawIso[ditau.id2] self.out.q_2[0] = event.Tau_charge[ditau.id2] self.out.decayMode_2[0] = event.Tau_decayMode[ditau.id2] ###self.out.rawAntiEleCat_2[0] = event.Tau_rawAntiEleCat[ditau.id2] self.out.idAntiEle_2[0] = ord(event.Tau_idAntiEle[ditau.id2]) self.out.idAntiMu_2[0] = ord(event.Tau_idAntiMu[ditau.id2]) self.out.idDecayMode_2[0] = event.Tau_idDecayMode[ditau.id2] self.out.idDecayModeNewDMs_2[0] = event.Tau_idDecayModeNewDMs[ ditau.id2] self.out.rawMVAoldDM_2[0] = event.Tau_rawMVAoldDM[ditau.id2] self.out.rawMVAoldDM2017v1_2[0] = event.Tau_rawMVAoldDM2017v1[ ditau.id2] self.out.rawMVAoldDM2017v2_2[0] = event.Tau_rawMVAoldDM2017v2[ ditau.id2] self.out.rawMVAnewDM2017v2_2[0] = event.Tau_rawMVAnewDM2017v2[ ditau.id2] self.out.idMVAoldDM_2[0] = ord(event.Tau_idMVAoldDM[ditau.id2]) self.out.idMVAoldDM2017v1_2[0] = ord( event.Tau_idMVAoldDM2017v1[ditau.id2]) self.out.idMVAoldDM2017v2_2[0] = ord( event.Tau_idMVAoldDM2017v2[ditau.id2]) self.out.idMVAnewDM2017v2_2[0] = ord( event.Tau_idMVAnewDM2017v2[ditau.id2]) # GENERATOR if not self.isData: self.out.genPartFlav_1[0] = Tau_genmatch[ditau.id1] self.out.genPartFlav_2[0] = Tau_genmatch[ditau.id2] genvistau = Collection(event, 'GenVisTau') dRmax1, dRmax2 = .5, .5 gendm1, gendm2 = -1, -1 genpt1, genpt2 = -1, -1 geneta1, geneta2 = -9, -9 genphi1, genphi2 = -9, -9 for igvt in range(event.nGenVisTau): dR = genvistau[igvt].p4().DeltaR(tau1) if dR < dRmax1: dRmax1 = dR gendm1 = event.GenVisTau_status[igvt] genpt1 = event.GenVisTau_pt[igvt] geneta1 = event.GenVisTau_eta[igvt] genphi1 = event.GenVisTau_phi[igvt] dR = genvistau[igvt].p4().DeltaR(tau2) if dR < dRmax2: dRmax2 = dR gendm2 = event.GenVisTau_status[igvt] genpt2 = event.GenVisTau_pt[igvt] geneta2 = event.GenVisTau_eta[igvt] genphi2 = event.GenVisTau_phi[igvt] self.out.gendecayMode_1[0] = gendm1 self.out.genvistaupt_1[0] = genpt1 self.out.genvistaueta_1[0] = geneta1 self.out.genvistauphi_1[0] = genphi1 self.out.gendecayMode_2[0] = gendm2 self.out.genvistaupt_2[0] = genpt2 self.out.genvistaueta_2[0] = geneta2 self.out.genvistauphi_2[0] = genphi2 # 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.CorrectPFMETByMeanResolution( 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) diTauLeg1SF = self.tauSFs.getTriggerSF(self.out.pt_1[0], self.out.eta_1[0], self.out.phi_1[0], self.out.decayMode_1[0], self.out.genPartFlav_1[0]) diTauLeg2SF = self.tauSFs.getTriggerSF(self.out.pt_2[0], self.out.eta_2[0], self.out.phi_2[0], self.out.decayMode_2[0], self.out.genPartFlav_2[0]) diTauLeg1SFVT = self.tauSFsVT.getTriggerSF( self.out.pt_1[0], self.out.eta_1[0], self.out.phi_1[0], self.out.decayMode_1[0], self.out.genPartFlav_1[0]) diTauLeg2SFVT = self.tauSFsVT.getTriggerSF( self.out.pt_2[0], self.out.eta_2[0], self.out.phi_2[0], self.out.decayMode_2[0], self.out.genPartFlav_2[0]) self.out.genweight[0] = event.genWeight self.out.trigweight[0] = diTauLeg1SF * diTauLeg2SF self.out.trigweightVT[0] = diTauLeg1SFVT * diTauLeg2SFVT self.out.puweight[0] = self.puTool.getWeight(event.Pileup_nTrueInt) self.out.idisoweight_1[0] = self.ltfSFs.getSF( self.out.genPartFlav_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.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] * self.out.met[0] * (1 - cos(deltaPhi(self.out.phi_1[0], self.out.metphi[0])))) self.out.pfmt_2[0] = sqrt( 2 * self.out.pt_2[0] * self.out.met[0] * (1 - cos(deltaPhi(self.out.phi_2[0], self.out.metphi[0])))) self.out.m_vis[0] = (tau1 + tau2).M() self.out.pt_ll[0] = (tau1 + tau2).Pt() self.out.dR_ll[0] = tau1.DeltaR(tau2) 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(tau1.Px(), tau1.Py(), 0.) leg2 = TVector3(tau2.Px(), tau2.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("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 Higgs(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["Nevents"] = ROOT.TH1F("Nevents", "Nevents", 1, 0, 1) self.hists["Acceptance"] = ROOT.TH1F("Acceptance", "Acceptance", 5, -0.5, 4.5) self.hists["genH_pt"] = ROOT.TH1F("genH_pt", ";generator H p_{T} (GeV)", 100, 0., 100.) self.hists["genH_eta"] = ROOT.TH1F("genH_eta", ";generator H #eta", 100, -5., 5.) self.hists["genH_phi"] = ROOT.TH1F("genH_phi", ";generator H #phi", 100, -3.15, 3.15) self.hists["genH_mass"] = ROOT.TH1F("genH_mass", ";generator H mass", 300, 0., 150.) self.hists["genJPsi_pt"] = ROOT.TH1F("genJPsi_pt", ";generator J/#Psi p_{T} (GeV)", 100, 0., 100.) self.hists["genJPsi_eta"] = ROOT.TH1F("genJPsi_eta", ";generator J/#Psi #eta", 100, -5., 5.) self.hists["genJPsi_phi"] = ROOT.TH1F("genJPsi_phi", ";generator J/#Psi #phi", 100, -3.15, 3.15) self.hists["genJPsi_mass"] = ROOT.TH1F("genJPsi_mass", ";generator J/#Psi mass", 200, 0., 4.) self.hists["genPhoton_pt"] = ROOT.TH1F("genPhoton_pt", ";generator #gamma p_{T} (GeV)", 100, 0., 100.) self.hists["genPhoton_eta"] = ROOT.TH1F("genPhoton_eta", ";generator #gamma #eta", 100, -5., 5.) self.hists["genMuon1_pt"] = ROOT.TH1F("genMuon1_pt", ";generator #mu^{-} p_{T} (GeV)", 100, 0., 100.) self.hists["genMuon1_eta"] = ROOT.TH1F("genMuon1_eta", ";generator #mu^{-} #eta", 100, -5., 5.) self.hists["genMuon2_pt"] = ROOT.TH1F("genMuon2_pt", ";generator #mu^{+} p_{T} (GeV)", 100, 0., 100.) self.hists["genMuon2_eta"] = ROOT.TH1F("genMuon2_eta", ";generator #mu^{+} #eta", 100, -5., 5.) self.hists["genCosThetaStar"] = ROOT.TH1F("genCosThetaStar", ";cos #theta^{*}", 100, -1., 1.) self.hists["genCosTheta1"] = ROOT.TH1F("genCosTheta1", ";cos #theta_{1}", 100, -1., 1.) self.hists["genPhi1"] = ROOT.TH1F("genPhi1", ";#Phi_{1}", 100, -3.1415, 3.1415) self.hists["genCosThetaStarZtoMM"] = ROOT.TH1F("genCosThetaStarZtoMM", ";cos #theta^{*}", 100, -1., 1.) self.hists["Cutflow"] = ROOT.TH1F("Cutflow", "Cutflow", 10, -0.5, 9.5) self.hists["Cutflow"].GetXaxis().SetBinLabel(1, "All events") self.hists["Cutflow"].GetXaxis().SetBinLabel(2, "Acceptance") self.hists["Cutflow"].GetXaxis().SetBinLabel(3, "2 reco muons") self.hists["Cutflow"].GetXaxis().SetBinLabel(4, "J/#Psi cand") self.hists["Cutflow"].GetXaxis().SetBinLabel(5, "reco #gamma") # self.addObject(self.h_events) # self.h_events.SetDirectory self.verbose = -1 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("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) def endFile(self, inputFile, outputFile, inputTree, wrappedOutputTree): outputFile.mkdir("Hists") outputFile.cd("Hists") for histname, hist in self.hists.iteritems(): hist.Write() outputFile.cd("..") if self.verbose >= 0: print "+ File closed successfully" pass def analyze(self, event): eventWeightLumi, lheWeight, stitchWeight, puWeight, qcdnloWeight, qcdnnloWeight, ewknloWeight, topWeight = 1., 1., 1., 1., 1., 1., 1., 1. triggerWeight, leptonWeight = 1., 1. isSingleMuonTrigger, isSingleMuonPhotonTrigger, isSingleMuonNoFiltersPhotonTrigger, isDoubleMuonTrigger, isDoubleMuonPhotonTrigger, isJPsiTrigger, isDisplacedTrigger = False, False, False, False, False, False, False nCleanElectron, nCleanMuon, nCleanTau, nCleanPhoton, nCleanJet, nCleanBTagJet, HT30 = 0, 0, 0, 0, 0, 0, 0 cosThetaStar, cosTheta1, phi1 = -2., -2., -4. genCosThetaStar, genCosTheta1, genPhi1 = -2., -2., -4. for t in self.SingleMuonTriggers: if hasattr(event, t) and getattr(event, t): isSingleMuonTrigger = True for t in self.SingleMuonPhotonTriggers: if hasattr(event, t) and getattr(event, t): isSingleMuonPhotonTrigger = True for t in self.SingleMuonNoFiltersPhotonTriggers: if hasattr(event, t) and getattr(event, t): isSingleMuonNoFiltersPhotonTrigger = True for t in self.DoubleMuonTriggers: if hasattr(event, t) and getattr(event, t): isDoubleMuonTrigger = True for t in self.DoubleMuonPhotonTriggers: if hasattr(event, t) and getattr(event, t): isDoubleMuonPhotonTrigger = True for t in self.JPsiTriggers: if hasattr(event, t) and getattr(event, t): isJPsiTrigger = True for t in self.DisplacedTriggers: if hasattr(event, t) and getattr(event, t): isDisplacedTrigger = True lheWeight = 1. if self.isMC: # Event weight if not self.isLO and hasattr(event, "LHEWeight_originalXWGTUP"): lheWeight = event.LHEWeight_originalXWGTUP # PU weight puWeight = self.puTool.getWeight(event.Pileup_nTrueInt) self.hists["Nevents"].Fill(0, lheWeight) self.hists["Acceptance"].Fill(0, lheWeight) self.hists["Cutflow"].Fill(0, lheWeight) # Gen studies if self.isMC and self.isSignal: genHIdx, genJPsiIdx, genMuon1Idx, genMuon2Idx, genPhotonIdx = -1, -1, -1, -1, -1 # print "-"*40 for i in range(event.nGenPart): # print i, "\t", event.GenPart_pdgId[i], "\t", event.GenPart_status[i], "\t", event.GenPart_statusFlags[i], "\t", event.GenPart_pt[i] if event.GenPart_pdgId[i] == 25 or event.GenPart_pdgId[i] == 23: genHIdx = i if event.GenPart_pdgId[i] == 443 and event.GenPart_genPartIdxMother[i] >= 0 and event.GenPart_pdgId[event.GenPart_genPartIdxMother[i]] == 25: genJPsiIdx = i if event.GenPart_pdgId[i] == 22 and event.GenPart_status[i] in [1, 23] and event.GenPart_genPartIdxMother[i] >= 0 and event.GenPart_pdgId[event.GenPart_genPartIdxMother[i]] == 25: genPhotonIdx = i #and (genPhotonIdx < 0 or event.GenPart_pt[i] > event.GenPart_pt[genPhotonIdx]) if event.GenPart_pdgId[i] == -13 and event.GenPart_status[i] == 1 and event.GenPart_genPartIdxMother[i] >= 0 and event.GenPart_pdgId[event.GenPart_genPartIdxMother[i]] != 22 and (genMuon1Idx < 0 or event.GenPart_pt[i] > event.GenPart_pt[genMuon1Idx]): genMuon1Idx = i if event.GenPart_pdgId[i] == +13 and event.GenPart_status[i] == 1 and event.GenPart_genPartIdxMother[i] >= 0 and event.GenPart_pdgId[event.GenPart_genPartIdxMother[i]] != 22 and (genMuon2Idx < 0 or event.GenPart_pt[i] > event.GenPart_pt[genMuon2Idx]): genMuon2Idx = i if genHIdx >= 0 and genJPsiIdx >= 0 and genPhotonIdx >= 0 and genMuon1Idx >= 0 and genMuon2Idx >= 0: genH, genJPsi, genMuon1, genMuon2, genPhoton = TLorentzVector(), TLorentzVector(), TLorentzVector(), TLorentzVector(), TLorentzVector() if genHIdx >= 0: genH.SetPtEtaPhiM(event.GenPart_pt[genHIdx], event.GenPart_eta[genHIdx], event.GenPart_phi[genHIdx], event.GenPart_mass[genHIdx]) if genJPsiIdx >= 0: genJPsi.SetPtEtaPhiM(event.GenPart_pt[genJPsiIdx], event.GenPart_eta[genJPsiIdx], event.GenPart_phi[genJPsiIdx], event.GenPart_mass[genJPsiIdx]) if genPhotonIdx >= 0: genPhoton.SetPtEtaPhiM(event.GenPart_pt[genPhotonIdx], event.GenPart_eta[genPhotonIdx], event.GenPart_phi[genPhotonIdx], event.GenPart_mass[genPhotonIdx]) if genMuon1Idx >= 0: genMuon1.SetPtEtaPhiM(event.GenPart_pt[genMuon1Idx], event.GenPart_eta[genMuon1Idx], event.GenPart_phi[genMuon1Idx], event.GenPart_mass[genMuon1Idx]) if genMuon2Idx >= 0: genMuon2.SetPtEtaPhiM(event.GenPart_pt[genMuon2Idx], event.GenPart_eta[genMuon2Idx], event.GenPart_phi[genMuon2Idx], event.GenPart_mass[genMuon2Idx]) # Recalculate candidate 4-vectors for consistent calculation of angular variables genJPsi = genMuon1 + genMuon2 genH = genJPsi + genPhoton genCosThetaStar, genCosTheta1, genPhi1 = self.returnCosThetaStar(genH, genJPsi), self.returnCosTheta1(genJPsi, genMuon1, genMuon2, genPhoton), self.returnPhi1(genH, genMuon1, genMuon2) self.hists["genH_pt"].Fill(genH.Pt(), lheWeight) self.hists["genH_eta"].Fill(genH.Eta(), lheWeight) self.hists["genH_phi"].Fill(genH.Phi(), lheWeight) self.hists["genH_mass"].Fill(genH.M(), lheWeight) self.hists["genJPsi_pt"].Fill(genJPsi.Pt(), lheWeight) self.hists["genJPsi_eta"].Fill(genJPsi.Eta(), lheWeight) self.hists["genJPsi_phi"].Fill(genJPsi.Phi(), lheWeight) self.hists["genJPsi_mass"].Fill(genJPsi.M(), lheWeight) self.hists["genPhoton_pt"].Fill(genPhoton.Pt(), lheWeight) self.hists["genPhoton_eta"].Fill(genPhoton.Eta(), lheWeight) self.hists["genMuon1_pt"].Fill(max(genMuon1.Pt(), genMuon2.Pt()), lheWeight) self.hists["genMuon1_eta"].Fill(genMuon1.Eta(), lheWeight) self.hists["genMuon2_pt"].Fill(min(genMuon1.Pt(), genMuon2.Pt()), lheWeight) self.hists["genMuon2_eta"].Fill(genMuon2.Eta(), lheWeight) self.hists["genCosThetaStar"].Fill(genCosThetaStar, lheWeight) self.hists["genCosTheta1"].Fill(genCosTheta1, lheWeight) self.hists["genPhi1"].Fill(genPhi1, lheWeight) self.hists["genCosThetaStarZtoMM"].Fill(self.returnCosThetaStar(genH, genMuon1), lheWeight) # Reweight topWeight = 3./4. * (1. + genCosTheta1**2) # Transverse polarization (H, Z) if 'ZToJPsiG' in self.sampleName: stitchWeight = 3./2. * (1. - genCosTheta1**2) # Longitudinal polarization (Z) # Acceptance if abs(genPhoton.Eta()) < 2.5: self.hists["Acceptance"].Fill(1, lheWeight) if abs(genMuon1.Eta()) < 2.4: self.hists["Acceptance"].Fill(2, lheWeight) if abs(genMuon2.Eta()) < 2.4: self.hists["Acceptance"].Fill(3, lheWeight) self.hists["Cutflow"].Fill(1, lheWeight) if genPhoton.Pt() > 15. and genMuon1.Pt() > 5. and genMuon2.Pt() > 5.: self.hists["Acceptance"].Fill(4, lheWeight) # Muons m1, m2 = -1, -1 for i in range(event.nMuon): if event.Muon_pt[i] > self.thMuons[0 if m1 < 0 else 1] and abs(event.Muon_eta[i]) < 2.4 and event.Muon_looseId[i]: if m1 < 0: m1 = i if m2 < 0 and m1 >= 0 and event.Muon_charge[m1] != event.Muon_charge[i]: m2 = i if m1 < 0 or m2 < 0: if self.verbose >= 2: print "- No OS loose muons in acceptance" return False self.hists["Cutflow"].Fill(2, lheWeight) muon1, muon2 = TLorentzVector(), TLorentzVector() muon1.SetPtEtaPhiM(event.Muon_pt[m1], event.Muon_eta[m1], event.Muon_phi[m1], event.Muon_mass[m1]) muon2.SetPtEtaPhiM(event.Muon_pt[m2], event.Muon_eta[m2], event.Muon_phi[m2], event.Muon_mass[m2]) muonP = muon1 if event.Muon_charge[m1] > event.Muon_charge[m2] else muon2 muonM = muon1 if event.Muon_charge[m1] < event.Muon_charge[m2] else muon2 muon1v2, muon2v2 = TVector2(muon1.Px(), muon1.Py()), TVector2(muon2.Px(), muon2.Py()) jpsi = muon1 + muon2 if jpsi.M() < 2. or jpsi.M() > 12.: if self.verbose >= 2: print "- Dimuon invariant mass < 2 or > 12 GeV" return False self.hists["Cutflow"].Fill(3, lheWeight) # Photons p0 = -1 for i in range(event.nPhoton): if event.Photon_pt[i] > self.thPhoton[0] and abs(event.Photon_eta[i]) < 2.5 and event.Photon_pfRelIso03_all[i] < 0.25: # and event.Photon_mvaID_WP80[i]: if p0 < 0: p0 = i if p0 < 0: if self.verbose >= 2: print "- No isolated photons in acceptance" return False self.hists["Cutflow"].Fill(4, lheWeight) photon = TLorentzVector() photon.SetPtEtaPhiM(event.Photon_pt[p0], event.Photon_eta[p0], event.Photon_phi[p0], event.Photon_mass[p0]) photonv2 = TVector2(photon.Px(), photon.Py()) met, metPlusPhoton = TVector2(), TVector2() met.SetMagPhi(event.MET_pt, event.MET_phi) metPlusPhoton.Set(met.Px() + photon.Px(), met.Py() + photon.Py()) h = jpsi + photon jpsi_pt = jpsi.Pt() jpsi_eta = jpsi.Eta() jpsi_phi = jpsi.Phi() jpsi_mass = jpsi.M() jpsi_dEta = abs(muon1.Eta() - muon2.Eta()) jpsi_dPhi = abs(muon1.DeltaPhi(muon2)) jpsi_dR = muon1.DeltaR(muon2) h_pt = h.Pt() h_eta = h.Eta() h_phi = h.Phi() h_mass = h.M() h_dEta = abs(jpsi.Eta() - photon.Eta()) h_dPhi = abs(jpsi.DeltaPhi(photon)) h_dR = jpsi.DeltaR(photon) Muon1TrkIso, Muon2TrkIso = event.Muon_tkRelIso[m1], event.Muon_tkRelIso[m2] if jpsi_dR < 0.3: Muon1TrkIso = max(0., (Muon1TrkIso * event.Muon_pt[m1] * event.Muon_tunepRelPt[m1] - event.Muon_pt[m2] * event.Muon_tunepRelPt[m2])) / (event.Muon_pt[m1] * event.Muon_tunepRelPt[m1]) Muon2TrkIso = max(0., (Muon2TrkIso * event.Muon_pt[m2] * event.Muon_tunepRelPt[m2] - event.Muon_pt[m1] * event.Muon_tunepRelPt[m1])) / (event.Muon_pt[m2] * event.Muon_tunepRelPt[m2]) minMuonTrkIso = min(Muon1TrkIso, Muon2TrkIso) maxMuonTrkIso = max(Muon1TrkIso, Muon2TrkIso) minMuonIso = min(event.Muon_pfRelIso03_all[m1], event.Muon_pfRelIso03_all[m2]) maxMuonIso = max(event.Muon_pfRelIso03_all[m1], event.Muon_pfRelIso03_all[m2]) minMuonMetDPhi = min(abs(muon1v2.DeltaPhi(met)), abs(muon2v2.DeltaPhi(met))) maxMuonMetDPhi = max(abs(muon1v2.DeltaPhi(met)), abs(muon2v2.DeltaPhi(met))) photonMetDPhi = abs(photonv2.DeltaPhi(met)) metPlusPhotonDPhi = abs(met.DeltaPhi(metPlusPhoton)) cosThetaStar = self.returnCosThetaStar(h, jpsi) cosTheta1 = self.returnCosTheta1(jpsi, muonP, muonM, photon) phi1 = self.returnPhi1(h, muonP, muonM) # Weights # if self.isMC: # triggerWeight = self.muSFs.getTriggerSF(event.Muon_pt[m1], event.Muon_eta[m1]) # 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 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 ### Event variables ### # Muons for i in range(event.nMuon): if i != m1 and i != m2 and event.Muon_pt[i] > 10. and abs(event.Muon_eta[i]) < 2.4 and event.Muon_looseId[i] and event.Muon_pfRelIso03_all[i] < 0.15: nCleanMuon += 1 # Electrons for i in range(event.nElectron): if event.Electron_pt[i] > 10. and abs(event.Electron_eta[i]) < 2.5 and event.Electron_cutBased[i] >= 2: nCleanElectron += 1 # Taus for i in range(event.nTau): if event.Tau_pt[i] > 20. and abs(event.Tau_eta[i]) < 2.5 and event.Tau_idDeepTau2017v2p1VSe[i] >= 16 and event.Tau_idDeepTau2017v2p1VSmu[i] >= 8 and event.Tau_idDeepTau2017v2p1VSjet[i] >= 16 and event.Tau_rawIsodR03[i] < 0.15: nCleanTau += 1 # Photons for i in range(event.nPhoton): if i != p0 and event.Photon_pt[i] > 15. and abs(event.Photon_eta[i]) < 2.5 and event.Photon_pfRelIso03_all[i] < 0.15 and event.Photon_mvaID_WP90[i]: nCleanPhoton += 1 # Jets and Event variables for i in range(event.nJet): if event.Jet_jetId[i] >= 6 and abs(event.Jet_eta[i]) < 2.5: HT30 += event.Jet_pt[i] nCleanJet += 1 if event.Jet_btagDeepB[i] >= self.btagMedium: nCleanBTagJet += 1 if self.isMC: eventWeightLumi = self.lumiWeight * lheWeight * puWeight * topWeight * qcdnloWeight * qcdnnloWeight * ewknloWeight * triggerWeight * leptonWeight self.out.fillBranch("isMC", self.isMC) self.out.fillBranch("is2016", (self.year == 2016)) self.out.fillBranch("is2017", (self.year == 2017)) self.out.fillBranch("is2018", (self.year == 2018)) self.out.fillBranch("isSingleMuonTrigger", isSingleMuonTrigger) self.out.fillBranch("isSingleMuonPhotonTrigger", isSingleMuonPhotonTrigger) self.out.fillBranch("isSingleMuonNoFiltersPhotonTrigger", isSingleMuonNoFiltersPhotonTrigger) self.out.fillBranch("isDoubleMuonTrigger", isDoubleMuonTrigger) self.out.fillBranch("isDoubleMuonPhotonTrigger", isDoubleMuonPhotonTrigger) self.out.fillBranch("isJPsiTrigger", isJPsiTrigger) self.out.fillBranch("passedMETFilters", passedMETFilters) self.out.fillBranch("nCleanElectron", nCleanElectron) self.out.fillBranch("nCleanMuon", nCleanMuon) self.out.fillBranch("nCleanTau", nCleanTau) self.out.fillBranch("nCleanPhoton", nCleanPhoton) self.out.fillBranch("nCleanJet", nCleanJet) self.out.fillBranch("nCleanBTagJet", nCleanBTagJet) self.out.fillBranch("HT30", HT30) self.out.fillBranch("iPhoton", p0) self.out.fillBranch("iMuon1", m1) self.out.fillBranch("iMuon2", m2) # self.out.fillBranch("Muon1_pt", event.Muon_pt[m1]) self.out.fillBranch("Muon1_eta", event.Muon_eta[m1]) self.out.fillBranch("Muon2_pt", event.Muon_pt[m2]) self.out.fillBranch("Muon2_eta", event.Muon_eta[m2]) self.out.fillBranch("Muon1_pfRelIso03_all", event.Muon_pfRelIso03_all[m1]) self.out.fillBranch("Muon2_pfRelIso03_all", event.Muon_pfRelIso03_all[m2]) self.out.fillBranch("Muon1_mediumId", event.Muon_mediumId[m1]) self.out.fillBranch("Muon2_mediumId", event.Muon_mediumId[m2]) self.out.fillBranch("Muon1_ip3d", event.Muon_ip3d[m1]) self.out.fillBranch("Muon2_ip3d", event.Muon_ip3d[m2]) self.out.fillBranch("minMuonIso", minMuonIso) self.out.fillBranch("maxMuonIso", maxMuonIso) self.out.fillBranch("minMuonTrkIso", minMuonTrkIso) self.out.fillBranch("maxMuonTrkIso", maxMuonTrkIso) self.out.fillBranch("Muon12_diffdxy", abs(event.Muon_dxy[m1]-event.Muon_dxy[m2])) self.out.fillBranch("Muon12_diffdz", abs(event.Muon_dz[m1]-event.Muon_dz[m2])) self.out.fillBranch("Muon12_signdxy", abs(event.Muon_dxy[m1]-event.Muon_dxy[m2]) / math.sqrt(event.Muon_dxyErr[m1]**2 + event.Muon_dxyErr[m2]**2)) self.out.fillBranch("Muon12_signdz", abs(event.Muon_dz[m1]-event.Muon_dz[m2]) / math.sqrt(event.Muon_dzErr[m1]**2 + event.Muon_dzErr[m2]**2)) self.out.fillBranch("Photon1_pt", event.Photon_pt[p0]) self.out.fillBranch("Photon1_eta", event.Photon_eta[p0]) self.out.fillBranch("Photon1_mvaID_WP80", event.Photon_mvaID_WP80[p0]) self.out.fillBranch("Photon1_pfRelIso03_all", event.Photon_pfRelIso03_all[p0]) # self.out.fillBranch("JPsi_pt", jpsi_pt) self.out.fillBranch("JPsi_eta", jpsi_eta) self.out.fillBranch("JPsi_phi", jpsi_phi) self.out.fillBranch("JPsi_mass", jpsi_mass) self.out.fillBranch("JPsi_dEta", jpsi_dEta) self.out.fillBranch("JPsi_dPhi", jpsi_dPhi) self.out.fillBranch("JPsi_dR", jpsi_dR) self.out.fillBranch("H_pt", h_pt) self.out.fillBranch("H_eta", h_eta) self.out.fillBranch("H_phi", h_phi) self.out.fillBranch("H_mass", h_mass) self.out.fillBranch("H_dEta", h_dEta) self.out.fillBranch("H_dPhi", h_dPhi) self.out.fillBranch("H_dR", h_dR) self.out.fillBranch("minMuonMetDPhi", minMuonMetDPhi) self.out.fillBranch("maxMuonMetDPhi", maxMuonMetDPhi) self.out.fillBranch("photonMetDPhi", photonMetDPhi) self.out.fillBranch("metPlusPhotonDPhi", metPlusPhotonDPhi) self.out.fillBranch("cosThetaStar", cosThetaStar) self.out.fillBranch("cosTheta1", cosTheta1) self.out.fillBranch("phi1", phi1) self.out.fillBranch("genCosThetaStar", genCosThetaStar) self.out.fillBranch("genCosTheta1", genCosTheta1) self.out.fillBranch("genPhi1", genPhi1) 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) if self.verbose >= 2: print "+ Tree filled" return True def returnCosThetaStar(self, theH, theJPsi): h, j = TLorentzVector(theH), TLorentzVector(theJPsi) # Boost the Z to the A rest frame j.Boost( -h.BoostVector() ) value = j.CosTheta() if value != value or math.isinf(value): return -2. return value def returnCosTheta1(self, theJPsi, theL1, theL2, thePhoton): j, l1, l2, g = TLorentzVector(theJPsi), TLorentzVector(theL1), TLorentzVector(theL2), TLorentzVector(thePhoton) # Boost objects to the JPsi rest frame l1.Boost( -j.BoostVector() ) l2.Boost( -j.BoostVector() ) g.Boost( -j.BoostVector() ) # cos theta = Gamma dot L1 / (|Gamma|*|L1|) value = g.Vect().Dot( l1.Vect() ) / ( (g.Vect().Mag())*(l1.Vect().Mag()) ) if g.Vect().Mag() > 0. and l1.Vect().Mag() > 0. else -2 if value != value or math.isinf(value): return -2. return value # TLorentzVector pA(theV); # TLorentzVector pL1(theL1); # TLorentzVector pL2(theL2); # TLorentzVector pB1(theB1); # TLorentzVector pB2(theB2); # // Boost objects to the A rest frame # pL1.Boost( -pA.BoostVector() ); # pL2.Boost( -pA.BoostVector() ); # pB1.Boost( -pA.BoostVector() ); # pB2.Boost( -pA.BoostVector() ); # // Reconstruct H in A rest frame # TLorentzVector pHr = pB1 + pB2; # // cos theta = H dot L1 / (|H|*|L1|) # float value=pHr.Vect().Dot( pL1.Vect() ) / ( pHr.Vect().Mag()*pL1.Vect().Mag() ); # if(value!=value || isinf(value)) return -2.; # return value; def returnPhi1(self, theH, theL1, theL2): h, l1, l2 = TLorentzVector(theH), TLorentzVector(theL1), TLorentzVector(theL2) beamAxis = TVector3(0., 0., 1.) # Boost objects to the A rest frame l1.Boost( -h.BoostVector() ) l2.Boost( -h.BoostVector() ) # Reconstruct JPsi in H rest frame j = l1 + l2 # Build unit vectors orthogonal to the decay planes Zplane = TVector3(l1.Vect().Cross( l2.Vect() )) # L1 x L2 Bplane = TVector3(beamAxis.Cross( j.Vect() )) # Beam x JPsi, beam/JPsi plane if Zplane.Mag() == 0. or Bplane.Mag() == 0.: return -4. Zplane.SetMag(1.) Bplane.SetMag(1.) # Sign of Phi1 sgn = j.Vect().Dot( Zplane.Cross(Bplane) ) sgn /= abs(sgn) if abs(Zplane.Dot(Bplane)) > 1.: return -5. value = sgn * math.acos( Zplane.Dot(Bplane) ) if value != value or math.isinf(value): return -5. return value
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 __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 __init__(self, name, dataType, **kwargs): self.name = name self.out = TreeProducerTauTau(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.jtf = kwargs.get('jtf', 1.0) 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 = 'tautau' year, channel = self.year, self.channel self.vlooseIso = getVLooseTauIso(year) if year == 2016: if self.isData: self.trigger = lambda e: e.HLT_DoubleMediumIsoPFTau35_Trk1_eta2p1_Reg \ if e.run<280919 else e.HLT_DoubleMediumCombinedIsoPFTau35_Trk1_eta2p1_Reg else: self.trigger = lambda e: e.HLT_DoubleMediumIsoPFTau35_Trk1_eta2p1_Reg or e.HLT_DoubleMediumCombinedIsoPFTau35_Trk1_eta2p1_Reg elif year == 2017: self.trigger = lambda e: e.HLT_DoubleTightChargedIsoPFTau35_Trk1_TightID_eta2p1_Reg or e.HLT_DoubleTightChargedIsoPFTau40_Trk1_eta2p1_Reg or e.HLT_DoubleMediumChargedIsoPFTau40_Trk1_TightID_eta2p1_Reg else: if self.isData: self.trigger = lambda e: e.HLT_DoubleTightChargedIsoPFTau35_Trk1_TightID_eta2p1_Reg or e.HLT_DoubleTightChargedIsoPFTau40_Trk1_eta2p1_Reg or e.HLT_DoubleMediumChargedIsoPFTau40_Trk1_TightID_eta2p1_Reg \ if e.run<317509 else e.HLT_DoubleMediumChargedIsoPFTauHPS35_Trk1_eta2p1_Reg else: self.trigger = lambda e: e.HLT_DoubleMediumChargedIsoPFTauHPS35_Trk1_eta2p1_Reg self.tauCutPt = 40 if not self.isData: self.tauSFs = TauTriggerSFs('tautau', 'tight', year=year) self.tauSFsVT = TauTriggerSFs('tautau', 'vtight', year=year) self.ltfSFs = LeptonTauFakeSFs('loose', 'vloose', 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.GoodTaus = 2 self.GoodDiTau = 3 self.Nocut_GT = 20 self.Trigger_GT = 21 self.GoodTaus_GT = 22 self.GoodDiTau_GT = 23 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.GoodTaus, "tau objects") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodDiTau, "ditau pair") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Nocut_GT, "no cut, GM") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Trigger_GT, "trigger, GM") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodTaus_GT, "tau objects, GM") self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodDiTau_GT, "ditau pair, GM") 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)