コード例 #1
0
    def __init__(self, cfg_ana, cfg_comp, looperName):
        super(VertexAnalyzer, self).__init__(cfg_ana, cfg_comp, looperName)

        self.doHists = True
        if (hasattr(self.cfg_ana,
                    'makeHists')) and (not self.cfg_ana.makeHists):
            self.doHists = False
        if self.doHists:
            self.pileup = VertexHistograms('/'.join(
                [self.dirName, 'pileup.root']))
コード例 #2
0
    def __init__(self, cfg_ana, cfg_comp, looperName):
        super(PileUpAnalyzer, self).__init__(cfg_ana, cfg_comp, looperName)

        self.doHists = True

        if (hasattr(self.cfg_ana,
                    'makeHists')) and (not self.cfg_ana.makeHists):
            self.doHists = False

        self.allVertices = self.cfg_ana.allVertices if (hasattr(
            self.cfg_ana, 'allVertices')) else "offlinePrimaryVertices"

        if self.cfg_comp.isMC and self.doHists:
            self.rawmcpileup = VertexHistograms('/'.join(
                [self.dirName, 'rawMCPU.root']))
        self.enable = True
        ## if component is embed return (has no trigger obj)
        if self.cfg_comp.isEmbed:
            self.cfg_comp.puFileMC = None
            self.cfg_comp.puFileData = None

        if self.cfg_comp.isMC or self.cfg_comp.isEmbed:
            if self.cfg_comp.puFileMC is None and self.cfg_comp.puFileData is None:
                self.enable = False
            else:
                assert (os.path.isfile(self.cfg_comp.puFileMC))
                assert (os.path.isfile(self.cfg_comp.puFileData))

                self.mcfile = TFile(self.cfg_comp.puFileMC)
                self.mchist = self.mcfile.Get('pileup')
                self.mchist.Scale(1 / self.mchist.Integral())

                self.datafile = TFile(self.cfg_comp.puFileData)
                self.datahist = self.datafile.Get('pileup')
                self.datahist.Scale(1 / self.datahist.Integral())
                # import pdb; pdb.set_trace()
                if self.mchist.GetNbinsX() != self.datahist.GetNbinsX():
                    raise ValueError(
                        'data and mc histograms must have the same number of bins'
                    )
                if self.mchist.GetXaxis().GetXmin() != self.datahist.GetXaxis(
                ).GetXmin():
                    raise ValueError(
                        'data and mc histograms must have the same xmin')
                if self.mchist.GetXaxis().GetXmax() != self.datahist.GetXaxis(
                ).GetXmax():
                    raise ValueError(
                        'data and mc histograms must have the same xmax')
コード例 #3
0
ファイル: PileUpAnalyzer.py プロジェクト: anantoni/CMG
    def __init__(self, cfg_ana, cfg_comp, looperName):
        super(PileUpAnalyzer, self).__init__(cfg_ana, cfg_comp, looperName)

        self.doHists=True

        if (hasattr(self.cfg_ana,'makeHists')) and (not self.cfg_ana.makeHists):
            self.doHists=False


        if self.cfg_comp.isMC and self.doHists:
            self.rawmcpileup = VertexHistograms('/'.join([self.dirName,
                                                          'rawMCPU.root']))
        self.enable = True
        if self.cfg_comp.isMC or self.cfg_comp.isEmbed:
            if self.cfg_comp.puFileMC is None and self.cfg_comp.puFileData is None:
                self.enable = False
            else:
                assert( os.path.isfile(self.cfg_comp.puFileMC) )
                assert( os.path.isfile(self.cfg_comp.puFileData) )

                self.mcfile = TFile( self.cfg_comp.puFileMC )
                self.mchist = self.mcfile.Get('pileup')
                self.mchist.Scale( 1 / self.mchist.Integral() )

                self.datafile = TFile( self.cfg_comp.puFileData )
                self.datahist = self.datafile.Get('pileup')
                self.datahist.Scale( 1 / self.datahist.Integral() )
                # import pdb; pdb.set_trace()
                if self.mchist.GetNbinsX() != self.datahist.GetNbinsX():
                    raise ValueError('data and mc histograms must have the same number of bins')
                if self.mchist.GetXaxis().GetXmin() != self.datahist.GetXaxis().GetXmin():
                    raise ValueError('data and mc histograms must have the same xmin')
                if self.mchist.GetXaxis().GetXmax() != self.datahist.GetXaxis().GetXmax():
                    raise ValueError('data and mc histograms must have the same xmax')
コード例 #4
0
    def __init__(self, cfg_ana, cfg_comp, looperName):
        super(VertexAnalyzer, self).__init__(cfg_ana, cfg_comp, looperName)

        self.doHists = True
        if (hasattr(self.cfg_ana, "makeHists")) and (not self.cfg_ana.makeHists):
            self.doHists = False
        if self.doHists:
            self.pileup = VertexHistograms("/".join([self.dirName, "pileup.root"]))
コード例 #5
0
    def __init__(self, cfg_ana, cfg_comp, looperName):
        super(VertexAnalyzer, self).__init__(cfg_ana, cfg_comp, looperName)

        self.doHists=True
        if (hasattr(self.cfg_ana,'makeHists')) and (not self.cfg_ana.makeHists):
            self.doHists=False
        if self.doHists:
            self.pileup = VertexHistograms('/'.join([self.dirName,
                                                     'pileup.root']))

        self.allVertices = self.cfg_ana.allVertices if (hasattr(self.cfg_ana,'allVertices')) else "offlinePrimaryVertices"
コード例 #6
0
class PileUpAnalyzer(Analyzer):
    '''Computes pile-up weights for MC from the pile up histograms for MC and data.
    These histograms should be set on the components as
    puFileData, puFileMC attributes, as is done here:
    
    http://cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/UserCode/CMG/CMGTools/H2TauTau/Colin/test_tauMu_2012_cfg.py?view=markup

    THESE HISTOGRAMS MUST BE CONSISTENT, SEE
    https://twiki.cern.ch/twiki/bin/view/CMS/CMGToolsPileUpReweighting#Generating_pile_up_distributions

    If the component is not MC, or if the puFileData and puFileMC are not
    set for the component, the reweighting is not done. 
    
    The analyzer sets event.vertexWeight.
    This weight is multiplied to the global event weight, event.eventWeight.
    When using this analyzer, make sure that the VertexAnalyzer is disabled,
    as you would be reweighting the MC PU distribution twice!
    
    Additionally, this analyzer writes in the output an histogram containing the unweighting MC
    pile-up distribution, to be used in input of the weighting for a later pass. 
    
    Example of use: 
    
    puAna = cfg.Analyzer(
      "PileUpAnalyzer",
      # build unweighted pu distribution using number of pile up interactions if False
      # otherwise, use fill the distribution using number of true interactions
      true = True
      )
    '''
    def __init__(self, cfg_ana, cfg_comp, looperName):
        super(PileUpAnalyzer, self).__init__(cfg_ana, cfg_comp, looperName)

        self.doHists = True

        if (hasattr(self.cfg_ana,
                    'makeHists')) and (not self.cfg_ana.makeHists):
            self.doHists = False

        self.allVertices = self.cfg_ana.allVertices if (hasattr(
            self.cfg_ana, 'allVertices')) else "offlinePrimaryVertices"

        if self.cfg_comp.isMC and self.doHists:
            self.rawmcpileup = VertexHistograms('/'.join(
                [self.dirName, 'rawMCPU.root']))
        self.enable = True
        ## if component is embed return (has no trigger obj)
        if self.cfg_comp.isEmbed:
            self.cfg_comp.puFileMC = None
            self.cfg_comp.puFileData = None

        if self.cfg_comp.isMC or self.cfg_comp.isEmbed:
            if self.cfg_comp.puFileMC is None and self.cfg_comp.puFileData is None:
                self.enable = False
            else:
                assert (os.path.isfile(self.cfg_comp.puFileMC))
                assert (os.path.isfile(self.cfg_comp.puFileData))

                self.mcfile = TFile(self.cfg_comp.puFileMC)
                self.mchist = self.mcfile.Get('pileup')
                self.mchist.Scale(1 / self.mchist.Integral())

                self.datafile = TFile(self.cfg_comp.puFileData)
                self.datahist = self.datafile.Get('pileup')
                self.datahist.Scale(1 / self.datahist.Integral())
                # import pdb; pdb.set_trace()
                if self.mchist.GetNbinsX() != self.datahist.GetNbinsX():
                    raise ValueError(
                        'data and mc histograms must have the same number of bins'
                    )
                if self.mchist.GetXaxis().GetXmin() != self.datahist.GetXaxis(
                ).GetXmin():
                    raise ValueError(
                        'data and mc histograms must have the same xmin')
                if self.mchist.GetXaxis().GetXmax() != self.datahist.GetXaxis(
                ).GetXmax():
                    raise ValueError(
                        'data and mc histograms must have the same xmax')

    def declareHandles(self):
        super(PileUpAnalyzer, self).declareHandles()
        self.mchandles['pusi'] = AutoHandle('addPileupInfo',
                                            'std::vector<PileupSummaryInfo>')
        self.handles['vertices'] = AutoHandle(self.allVertices,
                                              'std::vector<reco::Vertex>')

    def beginLoop(self):
        super(PileUpAnalyzer, self).beginLoop()
        self.averages.add('vertexWeight', Average('vertexWeight'))

    def process(self, iEvent, event):
        self.readCollections(iEvent)
        ## if component is embed return (has no trigger obj)
        if self.cfg_comp.isEmbed:
            return True

        event.vertexWeight = 1
        nPU = None
        if self.cfg_comp.isMC:
            event.pileUpInfo = map(PileUpSummaryInfo,
                                   self.mchandles['pusi'].product())
            for puInfo in event.pileUpInfo:
                if puInfo.getBunchCrossing() == 0:
                    # import pdb; pdb.set_trace()
                    if self.cfg_ana.true is False:
                        nPU = puInfo.nPU()
                    else:
                        nPU = puInfo.nTrueInteractions()

                    if self.doHists:
                        self.rawmcpileup.hist.Fill(nPU)

            if nPU is None:
                raise ValueError(
                    'nPU cannot be None! means that no pu info has been found for bunch crossing 0.'
                )
        elif self.cfg_comp.isEmbed:
            vertices = self.handles['vertices'].product()
            nPU = len(vertices)
        else:
            return True

        if self.enable:
            bin = self.datahist.FindBin(nPU)
            if bin < 1 or bin > self.datahist.GetNbinsX():
                event.vertexWeight = 0
            else:
                data = self.datahist.GetBinContent(bin)
                mc = self.mchist.GetBinContent(bin)
                #Protect 0 division!!!!
                if mc != 0.0:
                    event.vertexWeight = data / mc
                else:
                    event.vertexWeight = 1

        event.eventWeight *= event.vertexWeight
        self.averages['vertexWeight'].add(event.vertexWeight)
        return True

    def write(self):
        super(PileUpAnalyzer, self).write()
        if self.cfg_comp.isMC and self.doHists:
            self.rawmcpileup.write()
コード例 #7
0
class VertexAnalyzer( Analyzer ):
    """selects a list of good primary vertices,
    and optionally add a pile-up weight to MC events.

    The list of good primary vertices is put in event.goodVertices.
    if no good vertex is found, the process function returns False.

    The weight is put in event.vertexWeight, and is multiplied to
    the global event weight, event.eventWeight.

    Example:

    vertexAna = cfg.Analyzer(
      'VertexAnalyzer',
      goodVertices = 'goodPVFilter',
      vertexWeight = 'vertexWeightFall112011AB',
      # uncomment the following line if you want a vertex weight = 1 (no weighting)
      # fixedWeight = 1,
      verbose = False
      )

    If fixedWeight is set to None, the vertex weight is read from the EDM collection with module name
    'vertexWeightFall112011AB'.
    Otherwise, the weight is set to fixedWeight.

    The vertex weight collection was at some point produced in the PAT+CMG step,
    and could directly be accessed from the PAT or CMG tuple.
    In the most recent versions of the PAT+CMG tuple, this collection is not present anymore,
    and an additional full framework process must be ran to produce this collection,
    so that this analyzer can read it. An example cfg to do that can be found here:
    http://cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/UserCode/CMG/CMGTools/H2TauTau/prod/vertexWeight2011_cfg.py?view=markup


    """

    def __init__(self, cfg_ana, cfg_comp, looperName):
        super(VertexAnalyzer, self).__init__(cfg_ana, cfg_comp, looperName)

        self.doHists=True
        if (hasattr(self.cfg_ana,'makeHists')) and (not self.cfg_ana.makeHists):
            self.doHists=False
        if self.doHists:
            self.pileup = VertexHistograms('/'.join([self.dirName,
                                                     'pileup.root']))

        self.allVertices = self.cfg_ana.allVertices if (hasattr(self.cfg_ana,'allVertices')) else "offlinePrimaryVertices"

    def declareHandles(self):
        super(VertexAnalyzer, self).declareHandles()
#         self.handles['vertices'] =  AutoHandle(
#             self.allVertices,
#             'std::vector<reco::Vertex>'
#             )
        self.handles['vertices'] =  AutoHandle(
            'slimmedPrimaryVertices', ## for >= 5_18_0
            'std::vector<reco::Vertex>'
            )
        self.fixedWeight = None
        if self.cfg_comp.isMC:
            if hasattr( self.cfg_ana, 'fixedWeight'):
                self.fixedWeight = self.cfg_ana.fixedWeight
            else:
                self.mchandles['vertexWeight'] = AutoHandle( self.cfg_ana.vertexWeight,
                                                             'double' )

        self.mchandles['pusi'] =  AutoHandle(
            'addPileupInfo',
            'std::vector<PileupSummaryInfo>'
            )

        self.handles['rho'] =  AutoHandle(
            ('kt6PFJets','rho'),
            'double'
            )

    def beginLoop(self):
        super(VertexAnalyzer,self).beginLoop()
        self.averages.add('vertexWeight', Average('vertexWeight') )
        self.counters.addCounter('GoodVertex')
        self.count = self.counters.counter('GoodVertex')
        self.count.register('All Events')
        self.count.register('Events With Good Vertex')


    def process(self, iEvent, event):
        self.readCollections( iEvent )
        event.rho = self.handles['rho'].product()[0]
        event.vertices = self.handles['vertices'].product()
        event.goodVertices = filter(self.testGoodVertex,event.vertices)


        self.count.inc('All Events')


        event.vertexWeight = 1
        if self.cfg_comp.isMC:
            event.pileUpInfo = map( PileUpSummaryInfo,
                                    self.mchandles['pusi'].product() )
            if self.fixedWeight is None:
                event.vertexWeight = self.mchandles['vertexWeight'].product()[0]
            else:
                event.vertexWeight = self.fixedWeight
        event.eventWeight *= event.vertexWeight

        self.averages['vertexWeight'].add( event.vertexWeight )
        if self.verbose:
            print 'VertexAnalyzer: #vert = ', len(event.vertices), \
                  ', weight = ', event.vertexWeight

        # Check if events needs to be skipped if no good vertex is found (useful for generator level studies)
        keepFailingEvents = False
        if hasattr( self.cfg_ana, 'keepFailingEvents'):
            keepFailingEvents = self.cfg_ana.keepFailingEvents
        if len(event.goodVertices)==0:
            event.passedVertexAnalyzer=False
            if not keepFailingEvents:
                return False
        else:
            event.passedVertexAnalyzer=True

        if self.doHists:
            self.pileup.hist.Fill( len(event.goodVertices) )
            self.pileup.mindist.Fill( self.mindist(event.goodVertices) )

        self.count.inc('Events With Good Vertex')
        return True


    def testGoodVertex(self,vertex):
        if vertex.isFake():
            return False
        if vertex.ndof()<=4:
            return False
        if abs(vertex.z())>24:
            return False
        if vertex.position().Rho()>2:
            return False

        return True

    def mindist(self, vertices):
        mindist = 999999
        for comb in itertools.combinations(vertices, 2):
            dist = abs(comb[0].z() - comb[1].z())
            if dist<mindist:
                mindist = dist
        return mindist

    def write(self):
        super(VertexAnalyzer, self).write()
        if self.doHists:
            self.pileup.write()
コード例 #8
0
ファイル: PileUpAnalyzer.py プロジェクト: anantoni/CMG
class PileUpAnalyzer( Analyzer ):
    '''Computes pile-up weights for MC from the pile up histograms for MC and data.
    These histograms should be set on the components as
    puFileData, puFileMC attributes, as is done here:
    
    http://cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/UserCode/CMG/CMGTools/H2TauTau/Colin/test_tauMu_2012_cfg.py?view=markup

    THESE HISTOGRAMS MUST BE CONSISTENT, SEE
    https://twiki.cern.ch/twiki/bin/view/CMS/CMGToolsPileUpReweighting#Generating_pile_up_distributions

    If the component is not MC, or if the puFileData and puFileMC are not
    set for the component, the reweighting is not done. 
    
    The analyzer sets event.vertexWeight.
    This weight is multiplied to the global event weight, event.eventWeight.
    When using this analyzer, make sure that the VertexAnalyzer is disabled,
    as you would be reweighting the MC PU distribution twice!
    
    Additionally, this analyzer writes in the output an histogram containing the unweighting MC
    pile-up distribution, to be used in input of the weighting for a later pass. 
    
    Example of use: 
    
    puAna = cfg.Analyzer(
      "PileUpAnalyzer",
      # build unweighted pu distribution using number of pile up interactions if False
      # otherwise, use fill the distribution using number of true interactions
      true = True
      )
    '''

    def __init__(self, cfg_ana, cfg_comp, looperName):
        super(PileUpAnalyzer, self).__init__(cfg_ana, cfg_comp, looperName)

        self.doHists=True

        if (hasattr(self.cfg_ana,'makeHists')) and (not self.cfg_ana.makeHists):
            self.doHists=False


        if self.cfg_comp.isMC and self.doHists:
            self.rawmcpileup = VertexHistograms('/'.join([self.dirName,
                                                          'rawMCPU.root']))
        self.enable = True
        if self.cfg_comp.isMC or self.cfg_comp.isEmbed:
            if self.cfg_comp.puFileMC is None and self.cfg_comp.puFileData is None:
                self.enable = False
            else:
                assert( os.path.isfile(self.cfg_comp.puFileMC) )
                assert( os.path.isfile(self.cfg_comp.puFileData) )

                self.mcfile = TFile( self.cfg_comp.puFileMC )
                self.mchist = self.mcfile.Get('pileup')
                self.mchist.Scale( 1 / self.mchist.Integral() )

                self.datafile = TFile( self.cfg_comp.puFileData )
                self.datahist = self.datafile.Get('pileup')
                self.datahist.Scale( 1 / self.datahist.Integral() )
                # import pdb; pdb.set_trace()
                if self.mchist.GetNbinsX() != self.datahist.GetNbinsX():
                    raise ValueError('data and mc histograms must have the same number of bins')
                if self.mchist.GetXaxis().GetXmin() != self.datahist.GetXaxis().GetXmin():
                    raise ValueError('data and mc histograms must have the same xmin')
                if self.mchist.GetXaxis().GetXmax() != self.datahist.GetXaxis().GetXmax():
                    raise ValueError('data and mc histograms must have the same xmax')

    def declareHandles(self):
        super(PileUpAnalyzer, self).declareHandles()
        self.mchandles['pusi'] =  AutoHandle(
            'addPileupInfo',
            'std::vector<PileupSummaryInfo>' 
            ) 
        self.handles['vertices'] =  AutoHandle(
            'offlinePrimaryVertices',
            'std::vector<reco::Vertex>' 
            ) 

    def beginLoop(self):
        super(PileUpAnalyzer,self).beginLoop()
        self.averages.add('vertexWeight', Average('vertexWeight') )


    def process(self, iEvent, event):
        self.readCollections( iEvent )

        event.vertexWeight = 1
        nPU = None
        if self.cfg_comp.isMC:
            event.pileUpInfo = map( PileUpSummaryInfo,
                                    self.mchandles['pusi'].product() )
            for puInfo in event.pileUpInfo:
                if puInfo.getBunchCrossing()==0:
                    # import pdb; pdb.set_trace()
                    if self.cfg_ana.true is False:
                        nPU = puInfo.nPU()
                    else:
                        nPU = puInfo.nTrueInteractions()

                    if self.doHists:
                        self.rawmcpileup.hist.Fill( nPU )

            if nPU is None:
                raise ValueError('nPU cannot be None! means that no pu info has been found for bunch crossing 0.')
        elif self.cfg_comp.isEmbed:
            vertices = self.handles['vertices'].product()
            nPU = len(vertices)
        else:
            return True

        if self.enable:
            bin = self.datahist.FindBin(nPU)
            if bin<1 or bin>self.datahist.GetNbinsX():
                event.vertexWeight = 0
            else:
                data = self.datahist.GetBinContent(bin)
                mc = self.mchist.GetBinContent(bin)
                #Protect 0 division!!!!
                if mc !=0.0:
                    event.vertexWeight = data/mc
                else:
                    event.vertexWeight = 1
                
        event.eventWeight *= event.vertexWeight
        self.averages['vertexWeight'].add( event.vertexWeight )
        return True
        
    def write(self):
        super(PileUpAnalyzer, self).write()
        if self.cfg_comp.isMC and self.doHists:
            self.rawmcpileup.write()
コード例 #9
0
class VertexAnalyzer( Analyzer ):
    """selects a list of good primary vertices,
    and optionally add a pile-up weight to MC events.

    The list of good primary vertices is put in event.goodVertices.
    if no good vertex is found, the process function returns False.

    The weight is put in event.vertexWeight, and is multiplied to
    the global event weight, event.eventWeight. 

    Example:
    
    vertexAna = cfg.Analyzer(
      'VertexAnalyzer',
      goodVertices = 'goodPVFilter',
      vertexWeight = 'vertexWeightFall112011AB',
      # uncomment the following line if you want a vertex weight = 1 (no weighting)
      # fixedWeight = 1, 
      verbose = False
      )

    If fixedWeight is set to None, the vertex weight is read from the EDM collection with module name
    'vertexWeightFall112011AB'.
    Otherwise, the weight is set to fixedWeight.

    The vertex weight collection was at some point produced in the PAT+CMG step,
    and could directly be accessed from the PAT or CMG tuple. 
    In the most recent versions of the PAT+CMG tuple, this collection is not present anymore,
    and an additional full framework process must be ran to produce this collection,
    so that this analyzer can read it. An example cfg to do that can be found here:
    http://cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/UserCode/CMG/CMGTools/H2TauTau/prod/vertexWeight2011_cfg.py?view=markup

    
    """

    def __init__(self, cfg_ana, cfg_comp, looperName):
        super(VertexAnalyzer, self).__init__(cfg_ana, cfg_comp, looperName)

        self.doHists=True
        if (hasattr(self.cfg_ana,'makeHists')) and (not self.cfg_ana.makeHists):
            self.doHists=False
        if self.doHists:    
            self.pileup = VertexHistograms('/'.join([self.dirName,
                                                     'pileup.root']))
        
        self.allVertices = self.cfg_ana.allVertices if (hasattr(self.cfg_ana,'allVertices')) else "_AUTO_"

    def declareHandles(self):
        super(VertexAnalyzer, self).declareHandles()
        if self.allVertices == '_AUTO_':
          self.handles['vertices'] =  AutoHandle( "offlineSlimmedPrimaryVertices", 'std::vector<reco::Vertex>', fallbackLabel="offlinePrimaryVertices" )
        else:
          self.handles['vertices'] =  AutoHandle( self.allVertices, 'std::vector<reco::Vertex>' )
        self.fixedWeight = None
        if self.cfg_comp.isMC:
            if hasattr( self.cfg_ana, 'fixedWeight'):
                self.fixedWeight = self.cfg_ana.fixedWeight
            else:
                self.mchandles['vertexWeight'] = AutoHandle( self.cfg_ana.vertexWeight,
                                                             'double' )

        self.mchandles['pusi'] =  AutoHandle(
            'addPileupInfo',
            'std::vector<PileupSummaryInfo>' 
            )        

        self.handles['rho'] =  AutoHandle(
            ('fixedGridRhoFastjetAll', ''),
            'double' 
            )        

    def beginLoop(self):
        super(VertexAnalyzer,self).beginLoop()
        self.averages.add('vertexWeight', Average('vertexWeight') )
        self.counters.addCounter('GoodVertex')
        self.count = self.counters.counter('GoodVertex')
        self.count.register('All Events')
        self.count.register('Events With Good Vertex')

        
    def process(self, iEvent, event):
        self.readCollections( iEvent )
        event.rho = self.handles['rho'].product()[0]
        event.vertices = self.handles['vertices'].product()
        event.goodVertices = filter(self.testGoodVertex,event.vertices)


        self.count.inc('All Events')

        
        event.vertexWeight = 1
        if self.cfg_comp.isMC:
            event.pileUpInfo = map( PileUpSummaryInfo,
                                    self.mchandles['pusi'].product() )
            if self.fixedWeight is None:
                event.vertexWeight = self.mchandles['vertexWeight'].product()[0]
            else:
                event.vertexWeight = self.fixedWeight
        event.eventWeight *= event.vertexWeight
            
        self.averages['vertexWeight'].add( event.vertexWeight )
        if self.verbose:
            print 'VertexAnalyzer: #vert = ', len(event.vertices), \
                  ', weight = ', event.vertexWeight

        # Check if events needs to be skipped if no good vertex is found (useful for generator level studies)
        keepFailingEvents = False
        if hasattr( self.cfg_ana, 'keepFailingEvents'):
            keepFailingEvents = self.cfg_ana.keepFailingEvents
        if len(event.goodVertices)==0:
            event.passedVertexAnalyzer=False
            if not keepFailingEvents:
                return False
        else:
            event.passedVertexAnalyzer=True

        if self.doHists:
            self.pileup.hist.Fill( len(event.goodVertices) )
            self.pileup.mindist.Fill( self.mindist(event.goodVertices) )

        self.count.inc('Events With Good Vertex')
        return True


    def testGoodVertex(self,vertex):
        if vertex.isFake():
            return False
        if vertex.ndof()<=4:
            return False
        if abs(vertex.z())>24:
            return False
        if vertex.position().Rho()>2:
            return False
     
        return True

    def mindist(self, vertices):
        mindist = 999999
        for comb in itertools.combinations(vertices, 2):
            dist = abs(comb[0].z() - comb[1].z())
            if dist<mindist:
                mindist = dist
        return mindist
                                                                 
    def write(self):
        super(VertexAnalyzer, self).write()
        if self.doHists:
            self.pileup.write()