def arbitrate(self): pi1 = ROOT.Math.LorentzVector('<ROOT::Math::PxPyPzM4D<double> >')( self.tk1_.px(), self.tk1_.py(), self.tk1_.pz(), m_pi_ch) pi2 = ROOT.Math.LorentzVector('<ROOT::Math::PxPyPzM4D<double> >')( self.tk2_.px(), self.tk2_.py(), self.tk2_.pz(), m_pi_ch) k1 = ROOT.Math.LorentzVector('<ROOT::Math::PxPyPzM4D<double> >')( self.tk1_.px(), self.tk1_.py(), self.tk1_.pz(), m_k_ch) k2 = ROOT.Math.LorentzVector('<ROOT::Math::PxPyPzM4D<double> >')( self.tk2_.px(), self.tk2_.py(), self.tk2_.pz(), m_k_ch) # assign the mass hypotheses if abs((pi1 + k2).mass() - m_k_st_zero) < abs((pi2 + k1).mass() - m_k_st_zero): self.pi_ = PhysicsObject( ROOT.pat.PackedCandidate(self.tk1_.physObj)) self.k_ = PhysicsObject(ROOT.pat.PackedCandidate( self.tk2_.physObj)) else: self.pi_ = PhysicsObject( ROOT.pat.PackedCandidate(self.tk2_.physObj)) self.k_ = PhysicsObject(ROOT.pat.PackedCandidate( self.tk1_.physObj)) self.pi_.setMass(m_pi_ch) self.k_.setMass(m_k_ch) self.pi_.setPdgId(self.pi_.charge() * 211) self.k_.setPdgId(self.k_.charge() * 321)
def __init__(self, leg1, leg2, pdgid, status=3, sort_by_pt=False, mass1=-1, mass2=-1): ''' Parameters (stored as attributes): leg1,2 : first and second leg. pdgid : pdg code of the resonance status : status code of the resonance ''' if isinstance(leg1.physObj, ROOT.pat.PackedCandidate): leg1 = PhysicsObject(ROOT.pat.PackedCandidate(leg1.physObj)) if isinstance(leg2.physObj, ROOT.pat.PackedCandidate): leg2 = PhysicsObject(ROOT.pat.PackedCandidate(leg2.physObj)) if sort_by_pt: self.leg1 = leg1 if leg1.pt() >= leg2.pt() else leg2 self.leg2 = leg2 if leg1.pt() >= leg2.pt() else leg1 else: self.leg1 = leg1 self.leg2 = leg2 if mass1>0: self.leg1.setMass(mass1) if mass2>0: self.leg2.setMass(mass2) self._p4 = leg1.p4() + leg2.p4() self._charge = leg1.charge() + leg2.charge() self._pdgid = pdgid self._status = status
def process(self, event): run = event.input.eventAuxiliary().id().run() lumi = event.input.eventAuxiliary().id().luminosityBlock() eventId = event.input.eventAuxiliary().id().event() self.readCollections( event.input ) # Will need who for jet calibration later rho = self.handles["rho"].product()[0] ######## # AK8 Jets from MiniAOD + Subjet btags ######## setattr(event, "ak08", map(PhysicsObject, self.handles["ak08"].product())) setattr(event, "ak0softdropsubjets", map(PhysicsObject, self.handles["ak08softdropsubjets"].product())) # bb-tag Output newtags = self.handles['ak08bbtag'].product() # Loop over jets for ij, jet in enumerate(getattr(event, "ak08")): # Fill bb-tag for i in xrange(len(newtags)) : if jet.physObj == newtags.key(i).get(): jet.bbtag = newtags.value(i) # bb-tag Inputs muonTagInfos = self.handles['ak08muonTagInfos'].product()[ij] elecTagInfos = self.handles['ak08elecTagInfos'].product()[ij] ipTagInfo = self.handles['ak08ipTagInfos'].product()[ij] svTagInfo = self.handles['ak08svTagInfos'].product()[ij] calcBBTagVariables(jet, muonTagInfos, elecTagInfos, ipTagInfo, svTagInfo, njettiness_08, maxSVDeltaRToJet = 0.7,) # end of loop over jets ######## # Ungroomed Fatjets + NSubjettiness + Hbb Tagging ######## for prefix in ["ca15"]: if self.skip_ca15 and ("ca15" in prefix): continue # N-Subjettiness tau1 = self.handles[prefix+'tau1'].product() tau2 = self.handles[prefix+'tau2'].product() tau3 = self.handles[prefix+'tau3'].product() # bb-tag Output newtags = self.handles[prefix+'bbtag'].product() # Four Vector setattr(event, prefix+"ungroomed", map(PhysicsObject, self.handles[prefix+'ungroomed'].product())) # Loop over jets for ij, jet in enumerate(getattr(event, prefix+"ungroomed")): # Fill N-Subjettiness jet.tau1 = tau1.get(ij) jet.tau2 = tau2.get(ij) jet.tau3 = tau3.get(ij) # Fill bb-tag for i in xrange(len(newtags)) : if jet.physObj == newtags.key(i).get(): jet.bbtag = newtags.value(i) # bb-tag Inputs muonTagInfos = self.handles['ca15muonTagInfos'].product()[ij] elecTagInfos = self.handles['ca15elecTagInfos'].product()[ij] ipTagInfo = self.handles['ca15ipTagInfos'].product()[ij] svTagInfo = self.handles['ca15svTagInfos'].product()[ij] calcBBTagVariables(jet, muonTagInfos, elecTagInfos, ipTagInfo, svTagInfo, njettiness_15, maxSVDeltaRToJet = 1.3) # end of loop over jets ######## # Softdrop Fatjets + NSubjettiness ######## for fj_name in ["ca15softdropz2b1"]: if self.skip_ca15 and ("ca15" in fj_name): continue # Set the four-vector setattr(event, fj_name, map(PhysicsObject, self.handles[fj_name].product())) # N-Subjettiness tau1 = self.handles[fj_name+'tau1'].product() tau2 = self.handles[fj_name+'tau2'].product() tau3 = self.handles[fj_name+'tau3'].product() # Loop over jets for ij, jet in enumerate(getattr(event, fj_name)): # Fill N-Subjettiness jet.tau1 = tau1.get(ij) jet.tau2 = tau2.get(ij) jet.tau3 = tau3.get(ij) # end of loop over jets ######## # Groomed Uncalibrated Fatjets ######## for fj_name in ['ak08pruned', 'ca15trimmed', 'ca15softdrop', 'ca15pruned']: if self.skip_ca15 and ("ca15" in fj_name): continue setattr(event, fj_name, map(PhysicsObject, self.handles[fj_name].product())) ######## # Groomed Fatjets to calibrate ######## pruned_cal_jets = [] for groomed_fj in self.handles['ak08pruned'].product(): # We need the closest ungroomed fatjet to get the JEC: # - Make a list of pairs: deltaR(ungroomed fj, groomed fj) for all ungroomed fatjets # - Sort by deltaR # - And take the minimum if len(getattr(event, "ak08")): closest_ung_fj_and_dr = sorted( [(ung_fj, deltaR2(ung_fj, groomed_fj)) for ung_fj in getattr(event, "ak08")], key=lambda x:x[1])[0] else: print "WARNING: No ungroomed fatjets found in event with groomed fatjet. Skipping" continue # Use the jet cone size for matching minimal_dr_groomed_ungroomed = 0.8 if closest_ung_fj_and_dr[1] > minimal_dr_groomed_ungroomed: print "WARNING: No ungroomed fatjet found close to groomed fatjet. Skipping" continue ungroomed_jet = Jet(closest_ung_fj_and_dr[0]) c = self.jetReCalibrator.getCorrection(ungroomed_jet, rho) # Need to do a deep-copy. Otherwise the original jet will be modified cal_groomed_fj = PhysicsObject(groomed_fj).__copy__() cal_groomed_fj.scaleEnergy(c) pruned_cal_jets.append(cal_groomed_fj) setattr(event, 'ak08prunedcal', pruned_cal_jets) ######## # AK08 Regression ####### self.regressionsAK08[0].evaluateRegressionAK08(event) ######## # Subjets ######## for fj_name in ['ak08pruned','ca15pruned']: if self.skip_ca15 and ("ca15" in fj_name): continue setattr(event, fj_name + "subjets", map(PhysicsObject, self.handles[fj_name+"subjets"].product())) newtags = self.handles[fj_name+'subjetbtag'].product() for i in xrange(0,len(newtags)) : for j in getattr(event, fj_name+"subjets"): if j.physObj == newtags.key(i).get(): j.btag = newtags.value(i) ######## # HEPTopTagger ######## if not self.skip_ca15: candJets = self.handles['httCandJets'].product() candInfos = self.handles['httCandInfos'].product() event.httCandidates = map(PhysicsObject, candJets) sjbtags = self.handles['httSubjetBtags'].product() for i in xrange(0, len(candJets)): event.httCandidates[i].fRec = candInfos[i].properties().fRec event.httCandidates[i].Ropt = candInfos[i].properties().Ropt event.httCandidates[i].RoptCalc = candInfos[i].properties().RoptCalc event.httCandidates[i].ptForRoptCalc = candInfos[i].properties().ptForRoptCalc # HTT return the subjet-pair closest to the W-mass as W-subjets # Could be improved by b-tagging if we run into a problem [sj_w1, sj_w2, sj_nonw] = [con.__deref__() for con in candJets[i].getJetConstituents() if not con.isNull()] event.httCandidates[i].sjW1pt = sj_w1.pt() event.httCandidates[i].sjW1eta = sj_w1.eta() event.httCandidates[i].sjW1phi = sj_w1.phi() event.httCandidates[i].sjW1mass = sj_w1.mass() # Get the correct b-tag for ib in xrange(0, len(sjbtags)) : if sj_w1 == sjbtags.key(ib).get(): event.httCandidates[i].sjW1btag = sjbtags.value(ib) event.httCandidates[i].sjW2pt = sj_w2.pt() event.httCandidates[i].sjW2eta = sj_w2.eta() event.httCandidates[i].sjW2phi = sj_w2.phi() event.httCandidates[i].sjW2mass = sj_w2.mass() # Get the correct b-tag for ib in xrange(0, len(sjbtags)) : if sj_w2 == sjbtags.key(ib).get(): event.httCandidates[i].sjW2btag = sjbtags.value(ib) event.httCandidates[i].sjNonWpt = sj_nonw.pt() event.httCandidates[i].sjNonWeta = sj_nonw.eta() event.httCandidates[i].sjNonWphi = sj_nonw.phi() event.httCandidates[i].sjNonWmass = sj_nonw.mass() # Get the correct b-tag for ib in xrange(0, len(sjbtags)) : if sj_nonw == sjbtags.key(ib).get(): event.httCandidates[i].sjNonWbtag = sjbtags.value(ib) return True
def genMatch(event, leg, ptSelGentauleps, ptSelGenleps, ptSelGenSummary, dR=0.2, matchAll=True): dR2 = dR * dR leg.isTauHad = False leg.isTauLep = False leg.isPromptLep = False leg.genp = None best_dr2 = dR2 # if hasattr(leg, 'genJet') and leg.genJet(): # if leg.genJet().pt() > 15.: # dr2 = deltaR2(leg.eta(), leg.phi(), leg.genJet().eta(), leg.genJet().phi()) # if dr2 < best_dr2: # best_dr2 = dr2 # leg.genp = leg.genJet() # leg.genp.setPdgId(-15 * leg.genp.charge()) # leg.isTauHad = True l1match, dR2best = bestMatch(leg, event.genTauJets) if dR2best < best_dr2: best_dr2 = dR2best leg.genp = GenParticle(l1match) leg.genp.setPdgId(-15 * leg.genp.charge()) leg.isTauHad = True # to generated leptons from taus l1match, dR2best = bestMatch(leg, ptSelGentauleps) if dR2best < best_dr2: best_dr2 = dR2best leg.genp = l1match leg.isTauLep = True leg.isTauHad = False # to generated prompt leptons l1match, dR2best = bestMatch(leg, ptSelGenleps) if dR2best < best_dr2: best_dr2 = dR2best leg.genp = l1match leg.isPromptLep = True leg.isTauLep = False leg.isTauHad = False if best_dr2 < dR2: return # match with any other relevant gen particle if matchAll: l1match, dR2best = bestMatch(leg, ptSelGenSummary) if dR2best < best_dr2: leg.genp = l1match return # Ok do one more Pythia 8 trick... # This is to overcome that the GenAnalyzer doesn't like particles # that have daughters with same pdgId and status 71 if not hasattr(event, 'pythiaQuarksGluons'): event.pythiaQuarksGluons = [] for gen in event.genParticles: pdg = abs(gen.pdgId()) status = gen.status() if pdg in [1, 2, 3, 4, 5, 21] and status > 3: if gen.isMostlyLikePythia6Status3(): event.pythiaQuarksGluons.append(gen) l1match, dR2best = bestMatch(leg, event.pythiaQuarksGluons) if dR2best < best_dr2: leg.genp = l1match return # Now this may be a pileup lepton, or one whose ancestor doesn't # appear in the gen summary because it's an unclear case in Pythia 8 # To check the latter, match against jets as well... l1match, dR2best = bestMatch(leg, event.genJets) # Check if there's a gen jet with pT > 10 GeV (otherwise it's PU) if dR2best < dR2 and l1match.pt() > 10.: leg.genp = PhysicsObject(l1match) jet, dR2best = bestMatch(l1match, event.jets) if dR2best < dR2: leg.genp.detFlavour = jet.partonFlavour() else: print 'no match found', leg.pt(), leg.eta()
def genMatch(event, leg, ptSelGentauleps, ptSelGenleps, ptSelGenSummary, dR=0.2, matchAll=True): dR2 = dR * dR leg.isTauHad = False leg.isTauLep = False leg.isPromptLep = False leg.genp = None best_dr2 = dR2 # The following would work for pat::Taus, but we also want to flag a # muon/electron as coming from a hadronic tau with the usual definition # if this happens # if hasattr(leg, 'genJet') and leg.genJet(): # if leg.genJet().pt() > 15.: # dr2 = deltaR2(leg.eta(), leg.phi(), leg.genJet().eta(), leg.genJet().phi()) # if dr2 < best_dr2: # best_dr2 = dr2 # leg.genp = leg.genJet() # leg.genp.setPdgId(-15 * leg.genp.charge()) # leg.isTauHad = True # RM: needed to append genTauJets to the events, # when genMatch is used as a static method if not hasattr(event, 'genTauJets'): HTTGenAnalyzer.getGenTauJets(event) l1match, dR2best = bestMatch(leg, event.genTauJets) if dR2best < best_dr2: best_dr2 = dR2best # leg.genp = GenParticle(l1match) leg.genp = l1match leg.genp.setPdgId(-15 * leg.genp.charge()) leg.isTauHad = True # if not leg.genJet(): # print 'Warning, tau does not have matched gen tau' # elif leg.genJet().pt() < 15.: # print 'Warning, tau has matched gen jet but with pt =', leg.genJet().pt() # to generated leptons from taus l1match, dR2best = bestMatch(leg, ptSelGentauleps) if dR2best < best_dr2: best_dr2 = dR2best leg.genp = l1match leg.isTauLep = True leg.isTauHad = False # to generated prompt leptons l1match, dR2best = bestMatch(leg, ptSelGenleps) if dR2best < best_dr2: best_dr2 = dR2best leg.genp = l1match leg.isPromptLep = True leg.isTauLep = False leg.isTauHad = False if best_dr2 < dR2: return # match with any other relevant gen particle if matchAll: l1match, dR2best = bestMatch(leg, ptSelGenSummary) if dR2best < best_dr2: leg.genp = l1match return # Ok do one more Pythia 8 trick... # This is to overcome that the GenAnalyzer doesn't like particles # that have daughters with same pdgId and status 71 if not hasattr(event, 'pythiaQuarksGluons'): event.pythiaQuarksGluons = [] for gen in event.genParticles: pdg = abs(gen.pdgId()) status = gen.status() if pdg in [1, 2, 3, 4, 5, 21] and status > 3: if gen.isMostlyLikePythia6Status3(): event.pythiaQuarksGluons.append(gen) l1match, dR2best = bestMatch(leg, event.pythiaQuarksGluons) if dR2best < best_dr2: leg.genp = l1match return # Now this may be a pileup lepton, or one whose ancestor doesn't # appear in the gen summary because it's an unclear case in Pythia 8 # To check the latter, match against jets as well... l1match, dR2best = bestMatch(leg, getattr(event, 'genJets', [])) # Check if there's a gen jet with pT > 10 GeV (otherwise it's PU) if dR2best < dR2 and l1match.pt() > 10.: leg.genp = PhysicsObject(l1match) jet, dR2best = bestMatch(l1match, event.jets) if dR2best < dR2: leg.genp.detFlavour = jet.partonFlavour() else: print 'no match found', leg.pt(), leg.eta()
def evaluateRegressionAK08(self, event): #self.readCollections( event.input ) reg_fj = [] for ung_fj in getattr(event, "ak08"): # We need the closest ungroomed fatjet to get the JEC: # - Make a list of pairs: deltaR(ungroomed fj, groomed fj) for all ungroomed fatjets # - Sort by deltaR # - And take the minimum if len(getattr(event, "ak08pruned")): closest_pr_fj_and_dr = sorted( [(pr_fj, deltaR2(ung_fj, pr_fj)) for pr_fj in getattr(event, "ak08pruned")], key=lambda x: x[1])[0] else: print "WARNING: No pruned fatjets found in event with ungroomed fatjet. Skipping" continue # Use the jet cone size for matching minimal_dr_groomed_ungroomed = 0.8 if closest_pr_fj_and_dr[1] > minimal_dr_groomed_ungroomed: print "WARNING: No pruned fatjet found close to ungroomed fatjet. Skipping" continue pr_jet = Jet(closest_pr_fj_and_dr[0]) if len(getattr(event, "ak08prunedcal")): closest_cal_fj_and_dr = sorted( [(cal_fj, deltaR2(ung_fj, cal_fj)) for cal_fj in getattr(event, "ak08prunedcal")], key=lambda x: x[1])[0] else: print "WARNING: No calib groomed fatjets found in event with ungroomed fatjet. Skipping" continue if closest_cal_fj_and_dr[1] > minimal_dr_groomed_ungroomed: print "WARNING: No calib fatjet found close to ungroomed fatjet. Skipping" continue cal_jet = Jet(closest_cal_fj_and_dr[0]) # now check the AK08 jet is not a lepton # if len(getattr(event, "selectedLeptons")): # closest_pr_lep_and_dr = sorted( [(lep, deltaR2(cal_jet,lep)) for lep in getattr(event, "vLeptons")], key=lambda x:x[1])[0] # if closest_pr_lep_and_dr[1] < (0.4 * 0.4): # print "WARNING: No groomed fatjet is overlapping with a vLepton. Skipping" # continue # Need to do a deep-copy. Otherwise the original jet will be modified reg_groomed_fj = PhysicsObject(closest_cal_fj_and_dr[0]).__copy__() # for j in event.FatjetAK08pruned: self.FatjetAK08ungroomed_pt[0] = ung_fj.pt() # print 'ung_fj.pt() ', ung_fj.pt() self.FatjetAK08pruned_pt[0] = pr_jet.pt() # print 'pr_jet.pt() ', pr_jet.pt() self.FatjetAK08prunedCal_pt[0] = cal_jet.pt() # print 'cal_jet.pt() ', cal_jet.pt() self.FatjetAK08prunedCal_eta[0] = cal_jet.eta() self.FatjetAK08ungroomed_vertexNTracks[0] = ung_fj.vertexNTracks self.FatjetAK08ungroomed_SV_mass_0[0] = ung_fj.SV_mass_0 self.FatjetAK08ungroomed_SV_EnergyRatio_0[ 0] = ung_fj.SV_EnergyRatio_0 self.FatjetAK08ungroomed_SV_EnergyRatio_1[ 0] = ung_fj.SV_EnergyRatio_1 self.FatjetAK08ungroomed_PFLepton_ptrel[0] = ung_fj.PFLepton_ptrel self.FatjetAK08ungroomed_nSL[0] = ung_fj.nSL # print 'ung_fj.nSL ', ung_fj.nSL reg_groomed_fj.scaleEnergy( self.reader.EvaluateRegression(self.name)[0]) reg_fj.append(reg_groomed_fj) # print 'reg_groomed_fj.pt() ', reg_groomed_fj.pt() setattr(event, 'ak08prunedreg', reg_fj)