1 from PhysicsTools.Heppy.analyzers.core.Analyzer
import Analyzer
2 from PhysicsTools.Heppy.analyzers.core.AutoHandle
import AutoHandle
7 return id
in [6,7,8,17,18]
or (includeLeptons
and 11 <= id
and id < 16)
or (22 <= id
and id < 40)
or id > 1000000
10 """Save the hard-scattering final state of the event: top quarks, gauge & higgs bosons and BSM
11 particles, plus their immediate decay products, and their siblings (in order to get the jets
12 from matched X+jets generation.
13 Incoming partons are not included, by design.
15 In the default configuration, leptons, light quarks and gluons are saved before FSR (a la status 3).
16 Everything else is saved after any radiation, i.e. immediately before the decay.
18 Particles are saved in a list event.generatorSummary, with the index of their mothers ('motherIndex')
19 if the mother is also in the list, and with the pdgId of the mother ('motherId') and grand-mother
20 ('grandmotherId'). Particles also carry their index in the miniAOD genparticles collection ('rawIndex')
21 In addition, a 'sourceId' is set to the pdgId of the heaviest ancestor (or of the particle itself)
22 i.e. in top -> W -> lepton: the lepton sourceId will be 6
23 in tt+W with W -> lepton, the sourceId of the lepton will be 24.
24 sourceId will be 99 for paricles from hard scattering whose mother is light
26 If requested, the full list of genParticles is also produced in event.genParticles (with indices
27 aligned to the miniAOD one). For particles that are in the generatorSummary, the same object is used.
28 An extra index 'genSummaryIndex' will be added to all particles, with the index in the generatorSummary
29 or -1 if the particle is not in the generatorSummary.
31 Also, if requested it creates the splitted collections:
32 event.genHiggsBosons = []
34 event.gennus = [] # prompt neutrinos
35 event.gennusFromTop = [] # Neutrinos from t->W decay
36 event.genleps = [] # leptons from direct decays
37 event.gentauleps = [] # leptons from prompt taus
38 event.gentaus = [] # hadronically-decaying taus (if allGenTaus is False) or all taus (if allGenTaus is True)
39 event.gentopquarks = []
40 event.genbquarks = [] # b quarks from hard event (e.g. from top decays)
41 event.genwzquarks = [] # quarks from W,Z decays
42 event.genbquarksFromTop = []
43 event.genbquarksFromH = []
44 event.genlepsFromTop = [] #mu/ele that have a t->W chain as ancestor, also contained in event.genleps
45 event.genwzquarks and event.genbquarks, might have overlaps
46 event.genbquarksFromTop and event.genbquarksFromH are all contained in event.genbquarks
50 def __init__(self, cfg_ana, cfg_comp, looperName ):
51 super(GeneratorAnalyzer,self).
__init__(cfg_ana,cfg_comp,looperName)
60 self.mchandles[
'genParticles'] = AutoHandle(
'prunedGenParticles',
'std::vector<reco::GenParticle>' )
63 super(GeneratorAnalyzer,self).
beginLoop(setup)
66 verbose = getattr(self.cfg_ana,
'verbose',
False)
67 rawGenParticles = self.mchandles[
'genParticles'].product()
68 good = []; keymap = {};
70 for rawIndex,p
in enumerate(rawGenParticles):
86 if any((p.mother(j).
pdgId() == p.pdgId())
for j
in xrange(p.numberOfMothers())):
91 if any((p.daughter(j).
pdgId() == p.pdgId()
and p.daughter(j).
status() > 2)
for j
in xrange(p.numberOfDaughters())):
112 if not any(mom.daughter(j2).
pdgId() == mom.pdgId()
for j2
in xrange(mom.numberOfDaughters())):
116 elif mom.pdgId() == 25
and any(mom.daughter(j2).
pdgId() == 25
and mom.daughter(j2).numberOfDaughters()==0
for j2
in range(mom.numberOfDaughters())):
118 if abs(mom.pdgId()) == 15:
126 if not ok
and id
in [11, 13, 15]
and abs(mom.pdgId())
in [1,2,3,4,5,21]:
131 gp.rawIndex = rawIndex
132 keymap[rawIndex] = len(good)
135 for igp,gp
in enumerate(good):
138 gp.genSummaryIndex = igp
139 ancestor =
None if gp.numberOfMothers() == 0
else gp.motherRef(0)
140 while ancestor !=
None and ancestor.isNonnull():
141 if ancestor.key()
in keymap:
142 gp.motherIndex = keymap[ancestor.key()]
143 if ancestor.pdgId() != good[gp.motherIndex].
pdgId():
144 print "Error keying %d: motherIndex %d, ancestor.pdgId %d, good[gp.motherIndex].pdgId() %d " % (igp, gp.motherIndex, ancestor.pdgId(), good[gp.motherIndex].
pdgId())
146 ancestor =
None if ancestor.numberOfMothers() == 0
else ancestor.motherRef(0)
147 if abs(gp.pdgId())
not in [1,2,3,4,5,11,12,13,14,15,16,21]:
148 gp.sourceId = gp.pdgId()
149 if gp.motherIndex != -1:
150 ancestor = good[gp.motherIndex]
151 if ancestor.sourceId != 99
and (ancestor.mass() > gp.mass()
or gp.sourceId == 99):
152 gp.sourceId = ancestor.sourceId
153 event.generatorSummary = good
155 for ip,p
in enumerate(good):
161 p.motherId = moms[0].
pdgId()
163 p.grandmotherId = (gmoms[0].
pdgId()
if len(gmoms)==1
else (0
if len(gmoms)==0
else -9999))
167 p.grandmotherId = -9999
169 print "%3d {%6d}: %+8d %3d : %8.2f %+5.2f %+5.2f : %d %2d : %+8d {%3d}: %s" % ( ip,p.rawIndex,
170 p.pdgId(), p.status(), p.pt(), p.eta(), p.phi(), len(moms), p.numberOfDaughters(),
171 p.motherId, p.motherIndex,
172 " ".
join(
"%d[%d]" % (p.daughter(i).
pdgId(), p.daughter(i).
status())
for i
in xrange(p.numberOfDaughters())))
177 event.genParticles = allGenParticles
180 event.genHiggsBosons = []
181 event.genVBosons = []
183 event.gennusFromTop = []
185 event.gentauleps = []
187 event.gentopquarks = []
188 event.genbquarks = []
189 event.genwzquarks = []
190 event.genbquarksFromTop = []
191 event.genbquarksFromH = []
192 event.genlepsFromTop = []
193 for p
in event.generatorSummary:
196 event.genHiggsBosons.append(p)
198 event.genVBosons.append(p)
199 elif id
in {12,14,16}:
200 event.gennus.append(p)
205 for mom, momid
in momids:
212 event.gennusFromTop.append(p)
216 if abs(p.motherId) == 15:
217 event.gentauleps.append(p)
220 event.genleps.append(p)
224 for mom, momid
in momids:
231 event.genlepsFromTop.append(p)
234 event.gentaus.append(p)
236 event.gentopquarks.append(p)
238 event.genbquarks.append(p)
240 if 6
in momids: event.genbquarksFromTop.append(p)
241 if 25
in momids: event.genbquarksFromH.append(p)
243 event.genwzquarks.append(p)
246 self.readCollections( event.input )
249 if not self.cfg_comp.isMC:
255 import PhysicsTools.HeppyCore.framework.config
as cfg
256 setattr(GeneratorAnalyzer,
"defaultConfig",
257 cfg.Analyzer(GeneratorAnalyzer,
259 stableBSMParticleIds = [ 1000022 ],
263 savePreFSRParticleIds = [ 1,2,3,4,5, 11,12,13,14,15,16, 21 ],
265 makeAllGenParticles =
True,
267 makeSplittedGenLists =
True,
def isNotFromHadronicShower
bool any(const std::vector< T > &v, const T &what)
Abs< T >::type abs(const T &t)
static std::string join(char **cmd)