def makeMCInfo(self, event): verbose = getattr(self.cfg_ana, 'verbose', False) rawGenParticles = self.mchandles['genParticles'].product() good = [] keymap = {} allGenParticles = [] for rawIndex, p in enumerate(rawGenParticles): if self.makeAllGenParticles: allGenParticles.append(p) id = abs(p.pdgId()) status = p.status() # particles must be status > 2, except for prompt leptons, photons, neutralinos if status <= 2: if ((id not in self.stableBSMParticleIds) and (id not in [11, 12, 13, 14, 15, 16, 22] or not isNotFromHadronicShower(p))): continue # a particle must not be decaying into itself #print " test %6d : %+8d %3d : %8.2f %+5.2f %+5.2f : %d %d : %+8d {%6d}: %s" % ( rawIndex, # p.pdgId(), p.status(), p.pt(), p.eta(), p.phi(), p.numberOfMothers(), p.numberOfDaughters(), # p.motherRef(0).pdgId() if p.numberOfMothers() > 0 else -999, p.motherRef(0).key() if p.numberOfMothers() > 0 else -999, # " ".join("%d[%d]" % (p.daughter(i).pdgId(), p.daughter(i).status()) for i in xrange(p.numberOfDaughters()))) if id in self.savePreFSRParticleIds: # for light objects, we want them pre-radiation if any((p.mother(j).pdgId() == p.pdgId()) for j in xrange(p.numberOfMothers())): #print " fail auto-decay" continue else: # everything else, we want it after radiation, i.e. just before decay if any((p.daughter(j).pdgId() == p.pdgId() and p.daughter(j).status() > 2) for j in xrange(p.numberOfDaughters())): #print " fail auto-decay" continue # FIXME find a better criterion to discard there if status == 71: #drop QCD radiation with unclear parentage continue # is it an interesting particle? ok = False if interestingPdgId(id): #print " pass pdgId" ok = True ### no: we don't select by decay, so that we keep the particle summary free of incoming partons and such # if not ok and any(interestingPdgId(d.pdgId()) for d in realGenDaughters(p)): # #print " pass dau" # ok = True if not ok: for mom in realGenMothers(p): if interestingPdgId(mom.pdgId()) or (getattr( mom, 'rawIndex', -1) in keymap): #print " interesting mom" # exclude extra x from p -> p + x if not any( mom.daughter(j2).pdgId() == mom.pdgId() for j2 in xrange(mom.numberOfDaughters())): #print " pass no-self-decay" ok = True # Account for generator feature with Higgs decaying to itself with same four-vector but no daughters elif mom.pdgId() == 25 and any( mom.daughter(j2).pdgId() == 25 and mom.daughter(j2).numberOfDaughters() == 0 for j2 in range(mom.numberOfDaughters())): ok = True if abs(mom.pdgId()) == 15: # if we're a tau daughter we're status 2 # if we passed all the previous steps, then we're a prompt lepton # so we'd like to be included ok = True if not ok and p.pt() > 10 and id in [ 1, 2, 3, 4, 5, 21, 22 ] and any( interestingPdgId(d.pdgId()) for d in realGenDaughters(mom)): # interesting for being a parton brother of an interesting particle (to get the extra jets in ME+PS) ok = True if ok: gp = p gp.rawIndex = rawIndex # remember its index, so that we can set the mother index later keymap[rawIndex] = len(good) good.append(gp) # connect mother links for igp, gp in enumerate(good): gp.motherIndex = -1 gp.sourceId = 99 gp.genSummaryIndex = igp ancestor = None if gp.numberOfMothers() == 0 else gp.motherRef(0) while ancestor != None and ancestor.isNonnull(): if ancestor.key() in keymap: gp.motherIndex = keymap[ancestor.key()] if ancestor.pdgId() != good[gp.motherIndex].pdgId(): print "Error keying %d: motherIndex %d, ancestor.pdgId %d, good[gp.motherIndex].pdgId() %d " % ( igp, gp.motherIndex, ancestor.pdgId(), good[gp.motherIndex].pdgId()) break ancestor = None if ancestor.numberOfMothers( ) == 0 else ancestor.motherRef(0) if abs(gp.pdgId()) not in [ 1, 2, 3, 4, 5, 11, 12, 13, 14, 15, 16, 21 ]: gp.sourceId = gp.pdgId() if gp.motherIndex != -1: ancestor = good[gp.motherIndex] if ancestor.sourceId != 99 and (ancestor.mass() > gp.mass() or gp.sourceId == 99): gp.sourceId = ancestor.sourceId event.generatorSummary = good # add the ID of the mother to be able to recreate last decay chains for ip, p in enumerate(good): moms = realGenMothers(p) if len(moms) == 0: p.motherId = 0 p.grandmotherId = 0 elif len(moms) == 1: p.motherId = moms[0].pdgId() gmoms = realGenMothers(moms[0]) p.grandmotherId = (gmoms[0].pdgId() if len(gmoms) == 1 else (0 if len(gmoms) == 0 else -9999)) else: #print " unclear what mothers to give to this particle, among "," ".join("%d[%d]" % (m.pdgId(),m.status()) for m in moms) p.motherId = -9999 p.grandmotherId = -9999 if verbose: print "%3d {%6d}: %+8d %3d : %8.2f %+5.2f %+5.2f : %d %2d : %+8d {%3d}: %s" % ( ip, p.rawIndex, p.pdgId(), p.status(), p.pt(), p.eta(), p.phi(), len(moms), p.numberOfDaughters(), p.motherId, p.motherIndex, " ".join( "%d[%d]" % (p.daughter(i).pdgId(), p.daughter(i).status()) for i in xrange(p.numberOfDaughters()))) if verbose: print "\n\n" if self.makeAllGenParticles: event.genParticles = allGenParticles if self.makeSplittedGenLists: event.genHiggsBosons = [] event.genVBosons = [] event.gennus = [] event.gennusFromTop = [] event.genleps = [] event.gentauleps = [] event.gentaus = [] event.gentopquarks = [] event.genbquarks = [] event.genwzquarks = [] event.genbquarksFromTop = [] event.genbquarksFromH = [] event.genlepsFromTop = [] event.genvertex = 0 if len(event.generatorSummary) > 2: event.genvertex = event.generatorSummary[2].vertex().z() for p in event.generatorSummary: id = abs(p.pdgId()) if id == 25: event.genHiggsBosons.append(p) elif id in {23, 24}: event.genVBosons.append(p) elif id in {12, 14, 16}: event.gennus.append(p) momids = [(m, abs(m.pdgId())) for m in realGenMothers(p)] #have a look at the lepton mothers for mom, momid in momids: #lepton from W if momid == 24: wmomids = [ abs(m.pdgId()) for m in realGenMothers(mom) ] #W from t if 6 in wmomids: #save mu,e from t->W->mu/e event.gennusFromTop.append(p) elif id in {11, 13}: #taus to separate vector if abs(p.motherId) == 15: event.gentauleps.append(p) #all muons and electrons else: event.genleps.append(p) momids = [(m, abs(m.pdgId())) for m in realGenMothers(p)] #have a look at the lepton mothers for mom, momid in momids: #lepton from W if momid == 24: wmomids = [ abs(m.pdgId()) for m in realGenMothers(mom) ] #W from t if 6 in wmomids: #save mu,e from t->W->mu/e event.genlepsFromTop.append(p) elif id == 15: if self.allGenTaus or not any([ abs(d.pdgId()) in {11, 13} for d in realGenDaughters(p) ]): event.gentaus.append(p) elif id == 6: event.gentopquarks.append(p) elif id == 5: event.genbquarks.append(p) momids = [abs(m.pdgId()) for m in realGenMothers(p)] if 6 in momids: event.genbquarksFromTop.append(p) if 25 in momids: event.genbquarksFromH.append(p) if id <= 5 and any( [abs(m.pdgId()) in {23, 24} for m in realGenMothers(p)]): event.genwzquarks.append(p)
def makeMCInfo(self, event): verbose = getattr(self.cfg_ana, 'verbose', False) rawGenParticles = self.mchandles['genParticles'].product() good = []; keymap = {}; allGenParticles = [] for rawIndex,p in enumerate(rawGenParticles): if self.makeAllGenParticles: allGenParticles.append(p) id = abs(p.pdgId()) status = p.status() # particles must be status > 2, except for prompt leptons, photons, neutralinos if status <= 2: if ((id not in self.stableBSMParticleIds) and (id not in [11,12,13,14,15,16,22] or not isNotFromHadronicShower(p))): continue # a particle must not be decaying into itself #print " test %6d : %+8d %3d : %8.2f %+5.2f %+5.2f : %d %d : %+8d {%6d}: %s" % ( rawIndex, # p.pdgId(), p.status(), p.pt(), p.eta(), p.phi(), p.numberOfMothers(), p.numberOfDaughters(), # p.motherRef(0).pdgId() if p.numberOfMothers() > 0 else -999, p.motherRef(0).key() if p.numberOfMothers() > 0 else -999, # " ".join("%d[%d]" % (p.daughter(i).pdgId(), p.daughter(i).status()) for i in xrange(p.numberOfDaughters()))) if id in self.savePreFSRParticleIds: # for light objects, we want them pre-radiation if any((p.mother(j).pdgId() == p.pdgId()) for j in xrange(p.numberOfMothers())): #print " fail auto-decay" continue else: # everything else, we want it after radiation, i.e. just before decay if any((p.daughter(j).pdgId() == p.pdgId() and p.daughter(j).status() > 2) for j in xrange(p.numberOfDaughters())): #print " fail auto-decay" continue # FIXME find a better criterion to discard there if status == 71: #drop QCD radiation with unclear parentage continue # is it an interesting particle? ok = False if interestingPdgId(id): #print " pass pdgId" ok = True ### no: we don't select by decay, so that we keep the particle summary free of incoming partons and such # if not ok and any(interestingPdgId(d.pdgId()) for d in realGenDaughters(p)): # #print " pass dau" # ok = True if not ok: for mom in realGenMothers(p): if interestingPdgId(mom.pdgId()) or (getattr(mom,'rawIndex',-1) in keymap): #print " interesting mom" # exclude extra x from p -> p + x if not any(mom.daughter(j2).pdgId() == mom.pdgId() for j2 in xrange(mom.numberOfDaughters())): #print " pass no-self-decay" ok = True # Account for generator feature with Higgs decaying to itself with same four-vector but no daughters elif mom.pdgId() == 25 and any(mom.daughter(j2).pdgId() == 25 and mom.daughter(j2).numberOfDaughters()==0 for j2 in range(mom.numberOfDaughters())): ok = True if abs(mom.pdgId()) == 15: # if we're a tau daughter we're status 2 # if we passed all the previous steps, then we're a prompt lepton # so we'd like to be included ok = True if not ok and p.pt() > 10 and id in [1,2,3,4,5,21,22] and any(interestingPdgId(d.pdgId()) for d in realGenDaughters(mom)): # interesting for being a parton brother of an interesting particle (to get the extra jets in ME+PS) ok = True if not ok and id in [11, 13, 15] and abs(mom.pdgId()) in [1,2,3,4,5,21]: # Lepton e.g. in off-shell DY with the mother being one of the incoming partons ok = True if ok: gp = p gp.rawIndex = rawIndex # remember its index, so that we can set the mother index later keymap[rawIndex] = len(good) good.append(gp) # connect mother links for igp,gp in enumerate(good): gp.motherIndex = -1 gp.sourceId = 99 gp.genSummaryIndex = igp ancestor = None if gp.numberOfMothers() == 0 else gp.motherRef(0) while ancestor != None and ancestor.isNonnull(): if ancestor.key() in keymap: gp.motherIndex = keymap[ancestor.key()] if ancestor.pdgId() != good[gp.motherIndex].pdgId(): print "Error keying %d: motherIndex %d, ancestor.pdgId %d, good[gp.motherIndex].pdgId() %d " % (igp, gp.motherIndex, ancestor.pdgId(), good[gp.motherIndex].pdgId()) break ancestor = None if ancestor.numberOfMothers() == 0 else ancestor.motherRef(0) if abs(gp.pdgId()) not in [1,2,3,4,5,11,12,13,14,15,16,21]: gp.sourceId = gp.pdgId() if gp.motherIndex != -1: ancestor = good[gp.motherIndex] if ancestor.sourceId != 99 and (ancestor.mass() > gp.mass() or gp.sourceId == 99): gp.sourceId = ancestor.sourceId event.generatorSummary = good # add the ID of the mother to be able to recreate last decay chains for ip,p in enumerate(good): moms = realGenMothers(p) if len(moms)==0: p.motherId = 0 p.grandmotherId = 0 elif len(moms)==1: p.motherId = moms[0].pdgId() gmoms = realGenMothers(moms[0]) p.grandmotherId = (gmoms[0].pdgId() if len(gmoms)==1 else (0 if len(gmoms)==0 else -9999)) else: #print " unclear what mothers to give to this particle, among "," ".join("%d[%d]" % (m.pdgId(),m.status()) for m in moms) p.motherId = -9999 p.grandmotherId = -9999 if verbose: print "%3d {%6d}: %+8d %3d : %8.2f %+5.2f %+5.2f : %d %2d : %+8d {%3d}: %s" % ( ip,p.rawIndex, p.pdgId(), p.status(), p.pt(), p.eta(), p.phi(), len(moms), p.numberOfDaughters(), p.motherId, p.motherIndex, " ".join("%d[%d]" % (p.daughter(i).pdgId(), p.daughter(i).status()) for i in xrange(p.numberOfDaughters()))) if verbose: print "\n\n" if self.makeAllGenParticles: event.genParticles = allGenParticles if self.makeSplittedGenLists: event.genHiggsBosons = [] event.genVBosons = [] event.gennus = [] event.gennusFromTop = [] event.genleps = [] event.gentauleps = [] event.gentaus = [] event.gentopquarks = [] event.genbquarks = [] event.genwzquarks = [] event.genbquarksFromTop = [] event.genbquarksFromH = [] event.genlepsFromTop = [] for p in event.generatorSummary: id = abs(p.pdgId()) if id == 25: event.genHiggsBosons.append(p) elif id in {23,24}: event.genVBosons.append(p) elif id in {12,14,16}: event.gennus.append(p) momids = [(m, abs(m.pdgId())) for m in realGenMothers(p)] #have a look at the lepton mothers for mom, momid in momids: #lepton from W if momid == 24: wmomids = [abs(m.pdgId()) for m in realGenMothers(mom)] #W from t if 6 in wmomids: #save mu,e from t->W->mu/e event.gennusFromTop.append(p) elif id in {11,13}: #taus to separate vector if abs(p.motherId) == 15: event.gentauleps.append(p) #all muons and electrons else: event.genleps.append(p) momids = [(m, abs(m.pdgId())) for m in realGenMothers(p)] #have a look at the lepton mothers for mom, momid in momids: #lepton from W if momid == 24: wmomids = [abs(m.pdgId()) for m in realGenMothers(mom)] #W from t if 6 in wmomids: #save mu,e from t->W->mu/e event.genlepsFromTop.append(p) elif id == 15: if self.allGenTaus or not any([abs(d.pdgId()) in {11,13} for d in realGenDaughters(p)]): event.gentaus.append(p) elif id == 6: event.gentopquarks.append(p) elif id == 5: event.genbquarks.append(p) momids = [abs(m.pdgId()) for m in realGenMothers(p)] if 6 in momids: event.genbquarksFromTop.append(p) if 25 in momids: event.genbquarksFromH.append(p) if id <= 5 and any([abs(m.pdgId()) in {23,24} for m in realGenMothers(p)]): event.genwzquarks.append(p)
def process(self, event): event.genV = ROOT.reco.GenParticle() event.gennu = ROOT.reco.GenParticle() event.genlep = ROOT.reco.GenParticle() event.genmet = ROOT.reco.Particle.LorentzVector() event.genChi = [] event.genLeptFromW = [] event.genTauHadFromW = [] event.genTauLepFromW = [] event.genWtauHad = 0 event.genWtauLep = 0 event.weight = 1. event.FacScaleUp = 1. event.FacScaleDown = 1. event.RenScaleUp = 1. event.RenScaleDown = 1. event.FacRenScaleUp = 1. event.FacRenScaleDown = 1. event.PDFweight = 1. if not hasattr(event, "gentopquarks"): event.gentopquarks = [] # LHE weights if hasattr(event, "LHE_originalWeight"): event.weight = abs(event.LHE_originalWeight)/event.LHE_originalWeight if hasattr(event, "LHE_weights"): if len(event.LHE_weights) > 6: event.FacScaleUp = abs(event.LHE_weights[1].wgt/event.LHE_originalWeight) event.FacScaleDown = abs(event.LHE_weights[2].wgt/event.LHE_originalWeight) event.RenScaleUp = abs(event.LHE_weights[3].wgt/event.LHE_originalWeight) event.RenScaleDown = abs(event.LHE_weights[6].wgt/event.LHE_originalWeight) event.FacRenScaleUp = abs(event.LHE_weights[4].wgt/event.LHE_originalWeight) event.FacRenScaleDown = abs(event.LHE_weights[8].wgt/event.LHE_originalWeight) PDFw = [] if len(event.LHE_weights) > 8: for i in range(9,min(109, len(event.LHE_weights))): PDFw.append(abs(event.LHE_weights[i].wgt/event.LHE_originalWeight)) event.PDFweight = math.sqrt(sum(n*n for n in PDFw)/len(PDFw)) pass pass pass if not hasattr(event, "genParticles"): return True if hasattr(event, "genVBosons") and len(event.genVBosons) > 0: event.genV = event.genVBosons[0] # check for gen neutrino from W-> l nu if abs(event.genV.pdgId()) == 24: for d in realGenDaughters(event.genVBosons[0]): if abs(d.pdgId()) in [12, 14, 16]: event.gennu = d else: leptons = [x for x in event.genParticles if abs(x.pdgId())>10 and abs(x.pdgId())<17 and x.status()==23] if len(leptons) >=2: event.genV = ROOT.reco.GenParticle(0, leptons[0].p4()+leptons[1].p4(), leptons[0].vertex(), 23, 1, 0) if hasattr(event, "gennus"): for i in range(len(event.gennus)): event.genmet += event.gennus[i].p4() for g in event.genParticles: if g.pdgId() in self.cfg_ana.phi: event.genPhi = g if g.pdgId() in self.cfg_ana.chi: event.genChi.append(g) if hasattr(event, "genPhi"): self.Hist["GenPhi1mass"].Fill(event.genPhi.mass(), event.weight) self.Hist["GenPhi1pt"].Fill(event.genPhi.pt(), event.weight) self.Hist["GenPhi1eta"].Fill(event.genPhi.eta(), event.weight) self.Hist["GenPhi1y"].Fill(event.genPhi.rapidity(), event.weight) if len(event.genChi) >= 2: i1, i2 = [0, 1] if event.genChi[0].pt() > event.genChi[1].pt() else [1, 0] self.Hist["GenChi1mass"].Fill(event.genChi[i1].mass(), event.weight) self.Hist["GenChi1pt"].Fill(event.genChi[i1].pt(), event.weight) self.Hist["GenChi1eta"].Fill(event.genChi[i1].eta(), event.weight) self.Hist["GenChi2mass"].Fill(event.genChi[i1].mass(), event.weight) self.Hist["GenChi2pt"].Fill(event.genChi[i1].pt(), event.weight) self.Hist["GenChi2eta"].Fill(event.genChi[i1].eta(), event.weight) self.Hist["GenChi12dR"].Fill(deltaR(event.genChi[0].eta(), event.genChi[0].phi(), event.genChi[1].eta(), event.genChi[1].phi()), event.weight) # Z/W if hasattr(event, "genVBosons"): if len(event.genVBosons) > 0: if event.genVBosons[0].pdgId() == 23: self.Hist["GenZmass"].Fill(event.genVBosons[0].mass(), event.weight) self.Hist["GenZpt"].Fill(event.genVBosons[0].pt(), event.weight) self.Hist["GenZeta"].Fill(event.genVBosons[0].eta(), event.weight) self.Hist["GenZy"].Fill(event.genVBosons[0].rapidity(), event.weight) elif event.genVBosons[0].pdgId() == 24: self.Hist["GenWmass"].Fill(event.genVBosons[0].mass(), event.weight) self.Hist["GenWpt"].Fill(event.genVBosons[0].pt(), event.weight) self.Hist["GenWeta"].Fill(event.genVBosons[0].eta(), event.weight) self.Hist["GenWy"].Fill(event.genVBosons[0].rapidity(), event.weight) # check the W->lv decay for d in realGenDaughters(event.genVBosons[0]): # save only if is leptonic if abs(d.pdgId()) == 11 or abs(d.pdgId()) == 13 or abs(d.pdgId()) == 15: event.genLeptFromW.append(d) # if tau split hadronic and leptonic contributions if abs(d.pdgId()) == 15: taulep = [i for i in realGenDaughters(d) if (abs(i.pdgId()) == 11 or abs(i.pdgId()) == 13) ] if len(taulep) > 0: event.genTauLepFromW.append(d) event.genWtauLep = 1 else: event.genTauHadFromW.append(d) event.genWtauHad = 1 # Higgs if hasattr(event, "genHiggsBosons"): if len(event.genHiggsBosons) > 0: self.Hist["GenHmass"].Fill(event.genHiggsBosons[0].mass(), event.weight) self.Hist["GenHpt"].Fill(event.genHiggsBosons[0].pt(), event.weight) self.Hist["GenHeta"].Fill(event.genHiggsBosons[0].eta(), event.weight) self.Hist["GenHy"].Fill(event.genHiggsBosons[0].rapidity(), event.weight) # Leptons from Z if hasattr(event, "genleps"): if len(event.genleps) >= 1: event.genlep = event.genleps[0].p4() if len(event.genleps) >= 2: self.Hist["GenZdecay"].Fill(abs(event.genleps[0].pdgId()), event.weight) self.Hist["GenZdR"].Fill(deltaR(event.genleps[0].eta(), event.genleps[0].phi(), event.genleps[1].eta(), event.genleps[1].phi()), event.weight) i1, i2 = [0, 1] if event.genleps[0].pt() > event.genleps[1].pt() else [1, 0] self.Hist["GenLepton1pt"].Fill(event.genleps[i1].pt(), event.weight) self.Hist["GenLepton1eta"].Fill(event.genleps[i1].eta(), event.weight) self.Hist["GenLepton2pt"].Fill(event.genleps[i2].pt(), event.weight) self.Hist["GenLepton2eta"].Fill(event.genleps[i2].eta(), event.weight) # b-quarks from Higgs if hasattr(event, "genbquarks"): if len(event.genbquarks) == 1: self.Hist["GenBquark1pt"].Fill(event.genbquarks[0].pt(), event.weight) self.Hist["GenBquark1eta"].Fill(event.genbquarks[0].eta(), event.weight) elif len(event.genbquarks) >= 2: self.Hist["GenHdecay"].Fill(abs(event.genbquarks[0].pdgId()), event.weight) self.Hist["GenHdR"].Fill(deltaR(event.genbquarks[0].eta(), event.genbquarks[0].phi(), event.genbquarks[1].eta(), event.genbquarks[1].phi()), event.weight) self.Hist["GenHdPhi"].Fill(deltaPhi(event.genbquarks[0].phi(), event.genbquarks[1].phi()), event.weight) i1, i2 = [0, 1] if event.genbquarks[0].pt() > event.genbquarks[1].pt() else [1, 0] self.Hist["GenBquark1pt"].Fill(event.genbquarks[i1].pt(), event.weight) self.Hist["GenBquark1eta"].Fill(event.genbquarks[i1].eta(), event.weight) self.Hist["GenBquark2pt"].Fill(event.genbquarks[i2].pt(), event.weight) self.Hist["GenBquark2eta"].Fill(event.genbquarks[i2].eta(), event.weight) ### LHE event ### if not hasattr(event, "lheV_pt"): return True self.Hist["LheVpt"].Fill(event.lheV_pt, event.weight) self.Hist["LheHT"].Fill(event.lheHT, event.weight) self.Hist["LheNj"].Fill(event.lheNj, event.weight) self.Hist["LheNb"].Fill(event.lheNb, event.weight) self.Hist["LheNc"].Fill(event.lheNc, event.weight) self.Hist["LheNl"].Fill(event.lheNl, event.weight) self.Hist["LheNg"].Fill(event.lheNg, event.weight) return True