CMS 3D CMS Logo

VertexAnalyzer.py
Go to the documentation of this file.
1 from __future__ import print_function
2 import itertools
3 
4 from PhysicsTools.Heppy.analyzers.core.VertexHistograms import VertexHistograms
5 from PhysicsTools.Heppy.analyzers.core.Analyzer import Analyzer
6 from PhysicsTools.Heppy.analyzers.core.AutoHandle import AutoHandle
7 from PhysicsTools.HeppyCore.statistics.average import Average
8 from PhysicsTools.Heppy.physicsutils.PileUpSummaryInfo import PileUpSummaryInfo
9 import PhysicsTools.HeppyCore.framework.config as cfg
10 
11 class VertexAnalyzer( Analyzer ):
12  """selects a list of good primary vertices,
13  and optionally add a pile-up weight to MC events.
14 
15  The list of good primary vertices is put in event.goodVertices.
16  if no good vertex is found, the process function returns False.
17 
18  The weight is put in event.vertexWeight, and is multiplied to
19  the global event weight, event.eventWeight.
20 
21  Example:
22 
23  vertexAna = cfg.Analyzer(
24  'VertexAnalyzer',
25  goodVertices = 'goodPVFilter',
26  vertexWeight = 'vertexWeightFall112011AB',
27  # uncomment the following line if you want a vertex weight = 1 (no weighting)
28  # fixedWeight = 1,
29  verbose = False
30  )
31 
32  If fixedWeight is set to None, the vertex weight is read from the EDM collection with module name
33  'vertexWeightFall112011AB'.
34  Otherwise, the weight is set to fixedWeight.
35 
36  The vertex weight collection was at some point produced in the PAT+CMG step,
37  and could directly be accessed from the PAT or CMG tuple.
38  In the most recent versions of the PAT+CMG tuple, this collection is not present anymore,
39  and an additional full framework process must be ran to produce this collection,
40  so that this analyzer can read it. An example cfg to do that can be found here:
41  http://cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/UserCode/CMG/CMGTools/H2TauTau/prod/vertexWeight2011_cfg.py?view=markup
42 
43 
44  """
45 
46  def __init__(self, cfg_ana, cfg_comp, looperName):
47  super(VertexAnalyzer, self).__init__(cfg_ana, cfg_comp, looperName)
48 
49  self.doHists=True
50  if (hasattr(self.cfg_ana,'makeHists')) and (not self.cfg_ana.makeHists):
51  self.doHists=False
52  if self.doHists:
53  self.pileup = VertexHistograms('/'.join([self.dirName,
54  'pileup.root']))
55 
56  self.allVertices = self.cfg_ana.allVertices if (hasattr(self.cfg_ana,'allVertices')) else "_AUTO_"
57 
58  def declareHandles(self):
59  super(VertexAnalyzer, self).declareHandles()
60  if self.allVertices == '_AUTO_':
61  self.handles['vertices'] = AutoHandle( "offlineSlimmedPrimaryVertices", 'std::vector<reco::Vertex>', fallbackLabel="offlinePrimaryVertices" )
62  else:
63  self.handles['vertices'] = AutoHandle( self.allVertices, 'std::vector<reco::Vertex>' )
64  self.fixedWeight = None
65  if self.cfg_comp.isMC:
66  if hasattr( self.cfg_ana, 'fixedWeight'):
67  self.fixedWeight = self.cfg_ana.fixedWeight
68  else:
69  self.mchandles['vertexWeight'] = AutoHandle( self.cfg_ana.vertexWeight,
70  'double' )
71 
72  self.mchandles['pusi'] = AutoHandle(
73  'slimmedAddPileupInfo',
74  'std::vector<PileupSummaryInfo>',
75  fallbackLabel='addPileupInfo',
76  )
77 
78  self.handles['rho'] = AutoHandle(
79  ('fixedGridRhoFastjetAll',''),
80  'double'
81  )
82  self.handles['rhoCN'] = AutoHandle(
83  ('fixedGridRhoFastjetCentralNeutral',''),
84  'double'
85  )
86  self.handles['sigma'] = AutoHandle(
87  ('fixedGridSigmaFastjetAll',''),
88  'double',
89  mayFail=True
90  )
91 
92  def beginLoop(self, setup):
93  super(VertexAnalyzer,self).beginLoop(setup)
94  self.averages.add('vertexWeight', Average('vertexWeight') )
95  self.counters.addCounter('GoodVertex')
96  self.count = self.counters.counter('GoodVertex')
97  self.count.register('All Events')
98  self.count.register('Events With Good Vertex')
99 
100 
101  def process(self, event):
102  self.readCollections(event.input )
103  event.rho = self.handles['rho'].product()[0]
104  event.rhoCN = self.handles['rhoCN'].product()[0]
105  event.sigma = self.handles['sigma'].product()[0] if self.handles['sigma'].isValid() else -999
106  event.vertices = self.handles['vertices'].product()
107  event.goodVertices = list(filter(self.testGoodVertex,event.vertices))
108 
109 
110  self.count.inc('All Events')
111 
112 
113  event.vertexWeight = 1
114  if self.cfg_comp.isMC:
115  event.pileUpInfo = map( PileUpSummaryInfo,
116  self.mchandles['pusi'].product() )
117  if self.fixedWeight is None:
118  event.vertexWeight = self.mchandles['vertexWeight'].product()[0]
119  else:
120  event.vertexWeight = self.fixedWeight
121  event.eventWeight *= event.vertexWeight
122 
123  self.averages['vertexWeight'].add( event.vertexWeight )
124  if self.verbose:
125  print('VertexAnalyzer: #vert = ', len(event.vertices), \
126  ', weight = ', event.vertexWeight)
127 
128  # Check if events needs to be skipped if no good vertex is found (useful for generator level studies)
129  keepFailingEvents = False
130  if hasattr( self.cfg_ana, 'keepFailingEvents'):
131  keepFailingEvents = self.cfg_ana.keepFailingEvents
132  if len(event.goodVertices)==0:
133  event.passedVertexAnalyzer=False
134  if not keepFailingEvents:
135  return False
136  else:
137  event.passedVertexAnalyzer=True
138 
139  if self.doHists:
140  self.pileup.hist.Fill( len(event.goodVertices) )
141 #A.R. mindist is one of the slowest functions, default commented
142 # self.pileup.mindist.Fill( self.mindist(event.goodVertices) )
143 
144  self.count.inc('Events With Good Vertex')
145  return True
146 
147 
148  def testGoodVertex(self,vertex):
149  if vertex.isFake():
150  return False
151  if vertex.ndof()<=4:
152  return False
153  if abs(vertex.z())>24:
154  return False
155  if vertex.position().Rho()>2:
156  return False
157 
158  return True
159 
160  def mindist(self, vertices):
161  mindist = 999999
162  for comb in itertools.combinations(vertices, 2):
163  dist = abs(comb[0].z() - comb[1].z())
164  if dist<mindist:
165  mindist = dist
166  return mindist
167 
168  def write(self, setup):
169  super(VertexAnalyzer, self).write(setup)
170  if self.doHists:
171  self.pileup.write()
172 
173 setattr(VertexAnalyzer,"defaultConfig",cfg.Analyzer(
174  class_object=VertexAnalyzer,
175  vertexWeight = None,
176  fixedWeight = 1,
177  verbose = False
178  )
179 )
S & print(S &os, JobReport::InputFile const &f)
Definition: JobReport.cc:66
def __init__(self, cfg_ana, cfg_comp, looperName)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void add(std::map< std::string, TH1 * > &h, TH1 *hist)
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger list("!*","!HLTx*"if it matches 2 triggers or more) will accept the event if all the matching triggers are FAIL.It will reject the event if any of the triggers are PASS or EXCEPTION(this matches the behavior of"!*"before the partial wildcard feature was incorporated).Triggers which are in the READY state are completely ignored.(READY should never be returned since the trigger paths have been run