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']))
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 __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 __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"]))
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"
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()
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()
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()
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()