CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
List of all members | Public Member Functions | Public Attributes
gen.GeneratorAnalyzer.GeneratorAnalyzer Class Reference
Inheritance diagram for gen.GeneratorAnalyzer.GeneratorAnalyzer:

Public Member Functions

def __init__
 
def beginLoop
 
def declareHandles
 
def makeMCInfo
 
def process
 

Public Attributes

 allGenTaus
 
 makeAllGenParticles
 
 makeSplittedGenLists
 
 savePreFSRParticleIds
 
 stableBSMParticleIds
 

Detailed Description

Save the hard-scattering final state of the event: top quarks, gauge & higgs bosons and BSM
   particles, plus their immediate decay products, and their siblings (in order to get the jets
   from matched X+jets generation.
   Incoming partons are not included, by design.

   In the default configuration, leptons, light quarks and gluons are saved before FSR (a la status 3).
   Everything else is saved after any radiation, i.e. immediately before the decay.

   Particles are saved in a list event.generatorSummary, with the index of their mothers ('motherIndex') 
   if the mother is also in the list, and with the pdgId of the mother ('motherId') and grand-mother
   ('grandmotherId'). Particles also carry their index in the miniAOD genparticles collection ('rawIndex')
   In addition, a 'sourceId' is set to the pdgId of the heaviest ancestor (or of the particle itself)
   i.e.  in  top -> W -> lepton: the lepton sourceId will be 6
         in  tt+W with W -> lepton, the sourceId of the lepton will be 24.
   sourceId will be 99 for paricles from hard scattering whose mother is light 

   If requested, the full list of genParticles is also produced in event.genParticles (with indices
   aligned to the miniAOD one). For particles that are in the generatorSummary, the same object is used.
   An extra index 'genSummaryIndex' will be added to all particles, with the index in the generatorSummary
   or -1 if the particle is not in the generatorSummary.

   Also, if requested it creates the splitted collections:
        event.genHiggsBosons = []
        event.genVBosons = []
        event.gennus     = []  # prompt neutrinos
        event.gennusFromTop = []  # Neutrinos from t->W decay
        event.genleps    = []  # leptons from direct decays
        event.gentauleps = []  # leptons from prompt taus
        event.gentaus    = []  # hadronically-decaying taus (if allGenTaus is False) or all taus (if allGenTaus is True)
        event.gentopquarks  = [] 
        event.genbquarks    = [] # b quarks from hard event (e.g. from top decays)
        event.genwzquarks   = [] # quarks from W,Z decays
        event.genbquarksFromTop = []
        event.genbquarksFromH   = []
        event.genlepsFromTop = [] #mu/ele that have a t->W chain as ancestor, also contained in event.genleps
   event.genwzquarks and event.genbquarks, might have overlaps 
   event.genbquarksFromTop and event.genbquarksFromH are all contained in event.genbquarks

Definition at line 9 of file GeneratorAnalyzer.py.

Constructor & Destructor Documentation

def gen.GeneratorAnalyzer.GeneratorAnalyzer.__init__ (   self,
  cfg_ana,
  cfg_comp,
  looperName 
)

Definition at line 50 of file GeneratorAnalyzer.py.

50 
51  def __init__(self, cfg_ana, cfg_comp, looperName ):
52  super(GeneratorAnalyzer,self).__init__(cfg_ana,cfg_comp,looperName)
53  self.stableBSMParticleIds = set(cfg_ana.stableBSMParticleIds) # neutralinos and such
54  self.savePreFSRParticleIds = set(cfg_ana.savePreFSRParticleIds)
55  self.makeAllGenParticles = cfg_ana.makeAllGenParticles
56  self.makeSplittedGenLists = cfg_ana.makeSplittedGenLists
57  self.allGenTaus = cfg_ana.allGenTaus if self.makeSplittedGenLists else False

Member Function Documentation

def gen.GeneratorAnalyzer.GeneratorAnalyzer.beginLoop (   self,
  setup 
)

Definition at line 62 of file GeneratorAnalyzer.py.

62 
63  def beginLoop(self,setup):
64  super(GeneratorAnalyzer,self).beginLoop(setup)
def gen.GeneratorAnalyzer.GeneratorAnalyzer.declareHandles (   self)

Definition at line 58 of file GeneratorAnalyzer.py.

References core.Analyzer.Analyzer.mchandles.

58 
59  def declareHandles(self):
60  super(GeneratorAnalyzer, self).declareHandles()
61  self.mchandles['genParticles'] = AutoHandle( 'prunedGenParticles', 'std::vector<reco::GenParticle>' )
def gen.GeneratorAnalyzer.GeneratorAnalyzer.makeMCInfo (   self,
  event 
)

Definition at line 65 of file GeneratorAnalyzer.py.

References funct.abs(), gen.GeneratorAnalyzer.GeneratorAnalyzer.allGenTaus, any(), analyzer.Analyzer.cfg_ana, gen.GeneratorAnalyzer.interestingPdgId(), genutils.isNotFromHadronicShower(), join(), gen.GeneratorAnalyzer.GeneratorAnalyzer.makeAllGenParticles, gen.GeneratorAnalyzer.GeneratorAnalyzer.makeSplittedGenLists, core.Analyzer.Analyzer.mchandles, benchmark_cfg.pdgId, genutils.realGenDaughters(), genutils.realGenMothers(), gen.GeneratorAnalyzer.GeneratorAnalyzer.savePreFSRParticleIds, gen.GeneratorAnalyzer.GeneratorAnalyzer.stableBSMParticleIds, and ntuplemaker.status.

Referenced by gen.GeneratorAnalyzer.GeneratorAnalyzer.process().

65 
66  def makeMCInfo(self, event):
67  verbose = getattr(self.cfg_ana, 'verbose', False)
68  rawGenParticles = self.mchandles['genParticles'].product()
69  good = []; keymap = {};
70  allGenParticles = []
71  for rawIndex,p in enumerate(rawGenParticles):
72  if self.makeAllGenParticles: allGenParticles.append(p)
73  id = abs(p.pdgId())
74  status = p.status()
75  # particles must be status > 2, except for prompt leptons, photons, neutralinos
76  if status <= 2:
77  if ((id not in self.stableBSMParticleIds) and
78  (id not in [11,12,13,14,15,16,22] or not isNotFromHadronicShower(p))):
79  continue
80  # a particle must not be decaying into itself
81  #print " test %6d : %+8d %3d : %8.2f %+5.2f %+5.2f : %d %d : %+8d {%6d}: %s" % ( rawIndex,
82  # p.pdgId(), p.status(), p.pt(), p.eta(), p.phi(), p.numberOfMothers(), p.numberOfDaughters(),
83  # p.motherRef(0).pdgId() if p.numberOfMothers() > 0 else -999, p.motherRef(0).key() if p.numberOfMothers() > 0 else -999,
84  # " ".join("%d[%d]" % (p.daughter(i).pdgId(), p.daughter(i).status()) for i in xrange(p.numberOfDaughters())))
85  if id in self.savePreFSRParticleIds:
86  # for light objects, we want them pre-radiation
87  if any((p.mother(j).pdgId() == p.pdgId()) for j in xrange(p.numberOfMothers())):
88  #print " fail auto-decay"
89  continue
90  else:
91  # everything else, we want it after radiation, i.e. just before decay
92  if any((p.daughter(j).pdgId() == p.pdgId() and p.daughter(j).status() > 2) for j in xrange(p.numberOfDaughters())):
93  #print " fail auto-decay"
94  continue
95  # FIXME find a better criterion to discard there
96  if status == 71:
97  #drop QCD radiation with unclear parentage
98  continue
99  # is it an interesting particle?
100  ok = False
101  if interestingPdgId(id):
102  #print " pass pdgId"
103  ok = True
104  ### no: we don't select by decay, so that we keep the particle summary free of incoming partons and such
105  # if not ok and any(interestingPdgId(d.pdgId()) for d in realGenDaughters(p)):
106  # #print " pass dau"
107  # ok = True
108  if not ok:
109  for mom in realGenMothers(p):
110  if interestingPdgId(mom.pdgId()) or (getattr(mom,'rawIndex',-1) in keymap):
111  #print " interesting mom"
112  # exclude extra x from p -> p + x
113  if not any(mom.daughter(j2).pdgId() == mom.pdgId() for j2 in xrange(mom.numberOfDaughters())):
114  #print " pass no-self-decay"
115  ok = True
116  # Account for generator feature with Higgs decaying to itself with same four-vector but no daughters
117  elif mom.pdgId() == 25 and any(mom.daughter(j2).pdgId() == 25 and mom.daughter(j2).numberOfDaughters()==0 for j2 in range(mom.numberOfDaughters())):
118  ok = True
119  if abs(mom.pdgId()) == 15:
120  # if we're a tau daughter we're status 2
121  # if we passed all the previous steps, then we're a prompt lepton
122  # so we'd like to be included
123  ok = True
124  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)):
125  # interesting for being a parton brother of an interesting particle (to get the extra jets in ME+PS)
126  ok = True
127  if ok:
128  gp = p
129  gp.rawIndex = rawIndex # remember its index, so that we can set the mother index later
130  keymap[rawIndex] = len(good)
131  good.append(gp)
132  # connect mother links
133  for igp,gp in enumerate(good):
134  gp.motherIndex = -1
135  gp.sourceId = 99
136  gp.genSummaryIndex = igp
137  ancestor = None if gp.numberOfMothers() == 0 else gp.motherRef(0)
138  while ancestor != None and ancestor.isNonnull():
139  if ancestor.key() in keymap:
140  gp.motherIndex = keymap[ancestor.key()]
141  if ancestor.pdgId() != good[gp.motherIndex].pdgId():
142  print "Error keying %d: motherIndex %d, ancestor.pdgId %d, good[gp.motherIndex].pdgId() %d " % (igp, gp.motherIndex, ancestor.pdgId(), good[gp.motherIndex].pdgId())
143  break
144  ancestor = None if ancestor.numberOfMothers() == 0 else ancestor.motherRef(0)
145  if abs(gp.pdgId()) not in [1,2,3,4,5,11,12,13,14,15,16,21]:
146  gp.sourceId = gp.pdgId()
147  if gp.motherIndex != -1:
148  ancestor = good[gp.motherIndex]
149  if ancestor.sourceId != 99 and (ancestor.mass() > gp.mass() or gp.sourceId == 99):
150  gp.sourceId = ancestor.sourceId
151  event.generatorSummary = good
152  # add the ID of the mother to be able to recreate last decay chains
153  for ip,p in enumerate(good):
154  moms = realGenMothers(p)
155  if len(moms)==0:
156  p.motherId = 0
157  p.grandmotherId = 0
158  elif len(moms)==1:
159  p.motherId = moms[0].pdgId()
160  gmoms = realGenMothers(moms[0])
161  p.grandmotherId = (gmoms[0].pdgId() if len(gmoms)==1 else (0 if len(gmoms)==0 else -9999))
162  else:
163  #print " unclear what mothers to give to this particle, among "," ".join("%d[%d]" % (m.pdgId(),m.status()) for m in moms)
164  p.motherId = -9999
165  p.grandmotherId = -9999
166  if verbose:
167  print "%3d {%6d}: %+8d %3d : %8.2f %+5.2f %+5.2f : %d %2d : %+8d {%3d}: %s" % ( ip,p.rawIndex,
168  p.pdgId(), p.status(), p.pt(), p.eta(), p.phi(), len(moms), p.numberOfDaughters(),
169  p.motherId, p.motherIndex,
170  " ".join("%d[%d]" % (p.daughter(i).pdgId(), p.daughter(i).status()) for i in xrange(p.numberOfDaughters())))
171  if verbose:
172  print "\n\n"
173 
174  if self.makeAllGenParticles:
175  event.genParticles = allGenParticles
176 
177  if self.makeSplittedGenLists:
178  event.genHiggsBosons = []
179  event.genVBosons = []
180  event.gennus = []
181  event.gennusFromTop = []
182  event.genleps = []
183  event.gentauleps = []
184  event.gentaus = []
185  event.gentopquarks = []
186  event.genbquarks = []
187  event.genwzquarks = []
188  event.genbquarksFromTop = []
189  event.genbquarksFromH = []
190  event.genlepsFromTop = []
191  for p in event.generatorSummary:
192  id = abs(p.pdgId())
193  if id == 25:
194  event.genHiggsBosons.append(p)
195  elif id in {23,24}:
196  event.genVBosons.append(p)
197  elif id in {12,14,16}:
198  event.gennus.append(p)
199 
200  momids = [(m, abs(m.pdgId())) for m in realGenMothers(p)]
201 
202  #have a look at the lepton mothers
203  for mom, momid in momids:
204  #lepton from W
205  if momid == 24:
206  wmomids = [abs(m.pdgId()) for m in realGenMothers(mom)]
207  #W from t
208  if 6 in wmomids:
209  #save mu,e from t->W->mu/e
210  event.gennusFromTop.append(p)
211 
212  elif id in {11,13}:
213  #taus to separate vector
214  if abs(p.motherId) == 15:
215  event.gentauleps.append(p)
216  #all muons and electrons
217  else:
218  event.genleps.append(p)
219  momids = [(m, abs(m.pdgId())) for m in realGenMothers(p)]
220 
221  #have a look at the lepton mothers
222  for mom, momid in momids:
223  #lepton from W
224  if momid == 24:
225  wmomids = [abs(m.pdgId()) for m in realGenMothers(mom)]
226  #W from t
227  if 6 in wmomids:
228  #save mu,e from t->W->mu/e
229  event.genlepsFromTop.append(p)
230  elif id == 15:
231  if self.allGenTaus or not any([abs(d.pdgId()) in {11,13} for d in realGenDaughters(p)]):
232  event.gentaus.append(p)
233  elif id == 6:
234  event.gentopquarks.append(p)
235  elif id == 5:
236  event.genbquarks.append(p)
237  momids = [abs(m.pdgId()) for m in realGenMothers(p)]
238  if 6 in momids: event.genbquarksFromTop.append(p)
239  if 25 in momids: event.genbquarksFromH.append(p)
240  if id <= 5 and any([abs(m.pdgId()) in {23,24} for m in realGenMothers(p)]):
241  event.genwzquarks.append(p)
def realGenMothers
Definition: genutils.py:96
def isNotFromHadronicShower
Definition: genutils.py:65
bool any(const std::vector< T > &v, const T &what)
Definition: ECalSD.cc:34
def realGenDaughters
Definition: genutils.py:77
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
tuple status
Definition: ntuplemaker.py:245
def gen.GeneratorAnalyzer.GeneratorAnalyzer.process (   self,
  event 
)

Definition at line 242 of file GeneratorAnalyzer.py.

References gen.GeneratorAnalyzer.GeneratorAnalyzer.makeMCInfo(), and core.Analyzer.Analyzer.readCollections().

Referenced by ConfigBuilder.ConfigBuilder.addExtraStream(), ConfigBuilder.ConfigBuilder.completeInputCommand(), ConfigBuilder.ConfigBuilder.doNotInlineEventContent(), ConfigBuilder.ConfigBuilder.PrintAllModules.leave(), ConfigBuilder.ConfigBuilder.prepare_HLT(), ConfigBuilder.ConfigBuilder.prepare_LHE(), ConfigBuilder.ConfigBuilder.prepare_PATFILTER(), ConfigBuilder.ConfigBuilder.prepare_VALIDATION(), ConfigBuilder.ConfigBuilder.renameHLTprocessInSequence(), ConfigBuilder.ConfigBuilder.renameInputTagsInSequence(), and ConfigBuilder.ConfigBuilder.scheduleSequence().

243  def process(self, event):
244  self.readCollections( event.input )
245 
246  # if not MC, nothing to do
247  if not self.cfg_comp.isMC:
248  return True
249  # do MC level analysis
250  self.makeMCInfo(event)
251  return True

Member Data Documentation

gen.GeneratorAnalyzer.GeneratorAnalyzer.allGenTaus

Definition at line 56 of file GeneratorAnalyzer.py.

Referenced by gen.GeneratorAnalyzer.GeneratorAnalyzer.makeMCInfo().

gen.GeneratorAnalyzer.GeneratorAnalyzer.makeAllGenParticles

Definition at line 54 of file GeneratorAnalyzer.py.

Referenced by gen.GeneratorAnalyzer.GeneratorAnalyzer.makeMCInfo().

gen.GeneratorAnalyzer.GeneratorAnalyzer.makeSplittedGenLists

Definition at line 55 of file GeneratorAnalyzer.py.

Referenced by gen.GeneratorAnalyzer.GeneratorAnalyzer.makeMCInfo().

gen.GeneratorAnalyzer.GeneratorAnalyzer.savePreFSRParticleIds

Definition at line 53 of file GeneratorAnalyzer.py.

Referenced by gen.GeneratorAnalyzer.GeneratorAnalyzer.makeMCInfo().

gen.GeneratorAnalyzer.GeneratorAnalyzer.stableBSMParticleIds

Definition at line 52 of file GeneratorAnalyzer.py.

Referenced by gen.GeneratorAnalyzer.GeneratorAnalyzer.makeMCInfo().