def __init__(self, name, component, cfg): '''Build a loop object. listOfFiles can be "*.root". name will be used to make the output directory''' self.name = name self.cmp = component self.cfg = cfg self.events = Events(glob.glob(self.cmp.files)) self.triggerList = TriggerList(self.cmp.triggers) if self.cmp.isMC: self.trigEff = TriggerEfficiency() self.trigEff.tauEff = None self.trigEff.lepEff = None if self.cmp.tauEffWeight is not None: self.trigEff.tauEff = getattr(self.trigEff, self.cmp.tauEffWeight) if self.cmp.muEffWeight is not None: self.trigEff.lepEff = getattr(self.trigEff, self.cmp.muEffWeight) #self.cmp.turnOnCurve = None #if self.cmp.isMC: # if self.cmp.tauTriggerTOC is not None: # self.cmp.turnOnCurve = TurnOnCurve( self.cmp.tauTriggerTOC ) self._MakeOutputDir() self.counters = Counters() self.averages = {} # self.histograms = [] self.InitHandles()
def __init__(self, name, component, cfg): super( DiMuAnalyzer, self).__init__(component.fraction) self.name = name self.cmp = component self.cfg = cfg self.events = Events( glob.glob( self.cmp.files) ) self.triggerList = TriggerList( self.cmp.triggers ) ## if self.cmp.isMC or self.cmp.isEmbed: ## self.trigEff = TriggerEfficiency() ## self.trigEff.tauEff = None ## self.trigEff.lepEff = None ## if self.cmp.tauEffWeight is not None: ## self.trigEff.tauEff = getattr( self.trigEff, ## self.cmp.tauEffWeight ) ## if self.cmp.muEffWeight is not None: ## self.trigEff.lepEff = getattr( self.trigEff, ## self.cmp.muEffWeight ) # here create outputs ## self.regions = H2TauTauRegions( self.cfg.cuts ) ## self.output = Output( self.name, self.regions ) ## if self.cmp.name == 'DYJets': ## self.outputFakes = Output( self.name + '_Fakes', self.regions ) self.output = DiMuOutput( self.name ) self.counters = Counters() self.averages = {} self.InitHandles() self.InitCounters() self.logger = logging.getLogger(self.name) self.logger.addHandler(logging.FileHandler('/'.join([self.output.name, 'log.txt'])))
def InitOutput(self): '''Initialize histograms physics objects, counters.''' #COLIN do I really need to declare them? # declaring physics objects self.diTau = None self.triggerObject = None # declaring counters and averages self.counters = Counters() self.counters.addCounter('triggerPassed') self.counters.addCounter('exactlyOneDiTau') self.counters.addCounter('singleDiTau') self.counters.addCounter('VBF') # self.averages['triggerWeight']=Average('triggerWeight') self.averages['lepEffWeight'] = Average('lepEffWeight') self.averages['tauEffWeight'] = Average('tauEffWeight') self.averages['vertexWeight'] = Average('vertexWeight') self.averages['eventWeight'] = Average('eventWeight') self.regions = H2TauTauRegions(self.cfg.cuts) self.histoLists = {} inclusiveRegions = set() for regionName in self.regions.regionNames(): self.histoLists[regionName] = H2TauTauHistogramList('/'.join( [self.name, regionName])) incRegName = inclusiveRegionName(regionName) inclusiveRegions.add(incRegName) for regionName in inclusiveRegions: self.histoLists[regionName] = H2TauTauHistogramList('/'.join( [self.name, regionName]))
def __init__(self, name, component, cfg): '''Build a loop object. listOfFiles can be "*.root". name will be used to make the output directory''' self.name = name self.cmp = component self.cfg = cfg self.events = Events( glob.glob( self.cmp.files) ) self.triggerList = TriggerList( self.cmp.triggers ) if self.cmp.isMC: self.trigEff = TriggerEfficiency() self.trigEff.tauEff = None self.trigEff.lepEff = None if self.cmp.tauEffWeight is not None: self.trigEff.tauEff = getattr( self.trigEff, self.cmp.tauEffWeight ) if self.cmp.muEffWeight is not None: self.trigEff.lepEff = getattr( self.trigEff, self.cmp.muEffWeight ) #self.cmp.turnOnCurve = None #if self.cmp.isMC: # if self.cmp.tauTriggerTOC is not None: # self.cmp.turnOnCurve = TurnOnCurve( self.cmp.tauTriggerTOC ) self._MakeOutputDir() self.counters = Counters() self.averages = {} # self.histograms = [] self.InitHandles()
def InitOutput(self): '''Initialize histograms physics objects, counters.''' #COLIN do I really need to declare them? # declaring physics objects self.diTau = None self.triggerObject = None # declaring counters and averages self.counters = Counters() self.counters.addCounter('triggerPassed') self.counters.addCounter('exactlyOneDiTau') self.counters.addCounter('singleDiTau') self.counters.addCounter('VBF') # self.averages['triggerWeight']=Average('triggerWeight') self.averages['lepEffWeight']=Average('lepEffWeight') self.averages['tauEffWeight']=Average('tauEffWeight') self.averages['vertexWeight']=Average('vertexWeight') self.averages['eventWeight']=Average('eventWeight') self.regions = H2TauTauRegions( self.cfg.cuts ) self.histoLists = {} inclusiveRegions = set() for regionName in self.regions.regionNames(): self.histoLists[ regionName ] = H2TauTauHistogramList( '/'.join([self.name, regionName])) incRegName = inclusiveRegionName( regionName ) inclusiveRegions.add( incRegName ) for regionName in inclusiveRegions: self.histoLists[ regionName ] = H2TauTauHistogramList( '/'.join([self.name, regionName ]))
def InitCounters(self): '''Initialize histograms physics objects, counters.''' # declaring counters and averages self.counters = Counters() self.counters.addCounter('triggerPassed') self.counters.addCounter('exactlyOneDiMu') self.counters.addCounter('singleDiMu') self.counters.addCounter('VBF') # self.averages['triggerWeight']=Average('triggerWeight') ## self.averages['lepEffWeight']=Average('lepEffWeight') ## self.averages['tauEffWeight']=Average('tauEffWeight') self.averages['vertexWeight']=Average('vertexWeight') ## self.averages['generatorWeight']=Average('generatorWeight') self.averages['eventWeight']=Average('eventWeight')
def __init__(self, name, component, cfg): '''Build a loop object. listOfFiles can be "*.root". name will be used to make the output directory''' self.name = name self.cmp = component self.cfg = cfg self.events = Events(glob.glob(self.cmp.files)) self.triggerList = TriggerList(self.cmp.triggers) if self.cmp.isMC or self.cmp.isEmbed: self.trigEff = TriggerEfficiency() self.trigEff.tauEff = None self.trigEff.lepEff = None if self.cmp.tauEffWeight is not None: self.trigEff.tauEff = getattr(self.trigEff, self.cmp.tauEffWeight) if self.cmp.muEffWeight is not None: self.trigEff.lepEff = getattr(self.trigEff, self.cmp.muEffWeight) # here create outputs self.regions = H2TauTauRegions(self.cfg.cuts) self.output = Output(self.name, self.regions) if self.cmp.name == 'DYJets': self.outputFakes = Output(self.name + '_Fakes', self.regions) self.logger = logging.getLogger(self.name) self.logger.addHandler( logging.FileHandler('/'.join([self.name, 'log.txt']))) self.counters = Counters() self.averages = {} # self.histograms = [] self.InitHandles() self.InitCounters()
def __init__(self, name, component, cfg): '''Build a loop object. listOfFiles can be "*.root". name will be used to make the output directory''' self.name = name self.cmp = component self.cfg = cfg self.events = Events( glob.glob( self.cmp.files) ) self.triggerList = TriggerList( self.cmp.triggers ) if self.cmp.isMC or self.cmp.isEmbed: self.trigEff = TriggerEfficiency() self.trigEff.tauEff = None self.trigEff.lepEff = None if self.cmp.tauEffWeight is not None: self.trigEff.tauEff = getattr( self.trigEff, self.cmp.tauEffWeight ) if self.cmp.muEffWeight is not None: self.trigEff.lepEff = getattr( self.trigEff, self.cmp.muEffWeight ) # here create outputs self.regions = H2TauTauRegions( self.cfg.cuts ) self.output = Output( self.name, self.regions ) if self.cmp.name == 'DYJets': self.outputFakes = Output( self.name + '_Fakes', self.regions ) self.logger = logging.getLogger(self.name) self.logger.addHandler(logging.FileHandler('/'.join([self.name, 'log.txt']))) self.counters = Counters() self.averages = {} # self.histograms = [] self.InitHandles() self.InitCounters()
class Loop: '''Manages looping and navigation on a set of events.''' def __init__(self, name, component, cfg): '''Build a loop object. listOfFiles can be "*.root". name will be used to make the output directory''' self.name = name self.cmp = component self.cfg = cfg self.events = Events( glob.glob( self.cmp.files) ) self.triggerList = TriggerList( self.cmp.triggers ) if self.cmp.isMC: self.trigEff = TriggerEfficiency() self.trigEff.tauEff = None self.trigEff.lepEff = None if self.cmp.tauEffWeight is not None: self.trigEff.tauEff = getattr( self.trigEff, self.cmp.tauEffWeight ) if self.cmp.muEffWeight is not None: self.trigEff.lepEff = getattr( self.trigEff, self.cmp.muEffWeight ) #self.cmp.turnOnCurve = None #if self.cmp.isMC: # if self.cmp.tauTriggerTOC is not None: # self.cmp.turnOnCurve = TurnOnCurve( self.cmp.tauTriggerTOC ) self._MakeOutputDir() self.counters = Counters() self.averages = {} # self.histograms = [] self.InitHandles() def _MakeOutputDir(self): index = 0 name = self.name while True: try: # print 'mkdir', self.name os.mkdir( name ) break except OSError: index += 1 name = '%s_%d' % (self.name, index) self.logger = logging.getLogger(self.name) self.logger.addHandler(logging.FileHandler('/'.join([self.name, 'log.txt']))) def LoadCollections(self, event ): '''Load all collections''' for str,handle in self.handles.iteritems(): handle.Load( event ) # could do something clever to get the products... a setattr maybe? def InitHandles(self): '''Initialize all handles for the products we want to read''' self.handles = {} self.handles['cmgTauMuCorFullSelSVFit'] = AutoHandle( 'cmgTauMuCorSVFitFullSel', 'std::vector<cmg::DiObject<cmg::Tau,cmg::Muon>>') ## self.handles['cmgTauMu'] = AutoHandle( 'cmgTauMu', ## 'std::vector<cmg::DiObject<cmg::Tau,cmg::Muon>>') self.handles['cmgTriggerObjectSel'] = AutoHandle( 'cmgTriggerObjectSel', 'std::vector<cmg::TriggerObject>>') if self.cmp.isMC and self.cmp.vertexWeight is not None: self.handles['vertexWeight'] = AutoHandle( self.cmp.vertexWeight, 'double' ) self.handles['vertices'] = AutoHandle( 'offlinePrimaryVertices', 'std::vector<reco::Vertex>' ) self.handles['leptons'] = AutoHandle( 'cmgMuonSel', 'std::vector<cmg::Muon>' ) self.handles['jets'] = AutoHandle( 'cmgPFJetSel', 'std::vector<cmg::PFJet>' ) def InitOutput(self): '''Initialize histograms physics objects, counters.''' #COLIN do I really need to declare them? # declaring physics objects self.diTau = None self.triggerObject = None # declaring counters and averages self.counters = Counters() self.counters.addCounter('triggerPassed') self.counters.addCounter('exactlyOneDiTau') self.counters.addCounter('singleDiTau') self.counters.addCounter('VBF') # self.averages['triggerWeight']=Average('triggerWeight') self.averages['lepEffWeight']=Average('lepEffWeight') self.averages['tauEffWeight']=Average('tauEffWeight') self.averages['vertexWeight']=Average('vertexWeight') self.averages['eventWeight']=Average('eventWeight') self.regions = H2TauTauRegions( self.cfg.cuts ) self.histoLists = {} inclusiveRegions = set() for regionName in self.regions.regionNames(): self.histoLists[ regionName ] = H2TauTauHistogramList( '/'.join([self.name, regionName])) incRegName = inclusiveRegionName( regionName ) inclusiveRegions.add( incRegName ) for regionName in inclusiveRegions: self.histoLists[ regionName ] = H2TauTauHistogramList( '/'.join([self.name, regionName ])) def ToEvent( self, iEv ): '''Navigate to a given event and process it.''' # output event structure self.event = Event() # navigating to the correct FWLite event self.iEvent = iEv self.events.to(iEv) self.LoadCollections(self.events) # reading CMG objects from the handle #COLIN this kind of stuff could be automatized cmgDiTaus = self.handles['cmgTauMuCorFullSelSVFit'].product() cmgLeptons = self.handles['leptons'].product() self.event.triggerObject = self.handles['cmgTriggerObjectSel'].product()[0] self.event.vertices = self.handles['vertices'].product() cmgJets = self.handles['jets'].product() # converting them into my own python objects self.event.diTaus = [ DiTau(diTau) for diTau in cmgDiTaus ] self.event.leptons = [ Lepton(lepton) for lepton in cmgLeptons ] self.event.jets = [ Jet(jet) for jet in cmgJets if testJet(jet, self.cfg.cuts) ] self.event.jets = [] for cmgJet in cmgJets: if not testJet( jet, self.cfg.cuts): continue jet = Jet( cmgJet ) # print jet.energy() jet.scaleEnergy( 1 ) # print jet.energy() self.event.jets.append(jet) self.counters.counter('triggerPassed').inc('a: All events') if not self.triggerList.triggerPassed(self.event.triggerObject): return False self.counters.counter('triggerPassed').inc('b: Trig OK ') self.counters.counter('exactlyOneDiTau').inc('a: any # of di-taus ') if len(self.event.diTaus)==0: print 'Event %d : No tau mu.' % i return False if len(self.event.diTaus)>1: # print 'Event %d : Too many tau-mus: n = %d' % (iEv, len(self.event.diTaus)) #COLIN could be nice to have a counter class # which knows why events are rejected. make histograms with that. self.logger.warning('Ev %d: more than 1 di-tau : n = %d' % (iEv, len(self.event.diTaus))) self.counters.counter('exactlyOneDiTau').inc('b: at least 1 di-tau ') if not leptonAccept(self.event.leptons): return False self.counters.counter('exactlyOneDiTau').inc('c: exactly one lepton ') self.event.diTau = self.event.diTaus[0] if len(self.event.diTaus)>1: self.event.diTau = bestDiTau( self.event.diTaus ) elif len(self.event.diTaus)==1: self.counters.counter('exactlyOneDiTau').inc('d: exactly 1 di-tau ') else: raise ValueError('should not happen!') cuts = self.cfg.cuts self.counters.counter('singleDiTau').inc('a: best di-tau') self.event.tau = Tau( self.event.diTau.leg1() ) if self.event.tau.calcEOverP() > 0.2: self.counters.counter('singleDiTau').inc('b: E/p > 0.2 ') else: return False if self.event.tau.pt()>cuts.tauPt: self.counters.counter('singleDiTau').inc('c: tau pt > {ptCut:3.1f}'.format(ptCut = cuts.tauPt)) else: return False self.event.lepton = Lepton( self.event.diTau.leg2() ) if self.event.lepton.pt()>cuts.lepPt: self.counters.counter('singleDiTau').inc('d: lep pt > {ptCut:3.1f}'.format(ptCut = cuts.lepPt)) else: return False if abs( self.event.lepton.eta() ) < cuts.lepEta: self.counters.counter('singleDiTau').inc('e: lep |eta| <{etaCut:3.1f}'.format(etaCut = cuts.lepEta)) else: return False self.counters.counter('VBF').inc('a: all events ') if len(self.event.jets)>1: self.counters.counter('VBF').inc('b: at least 2 jets ') self.event.vbf = VBF( self.event.jets ) if self.event.vbf.mjj > cuts.VBF_Mjj: self.counters.counter('VBF').inc('c: Mjj > {mjj:3.1f}'.format(mjj = cuts.VBF_Mjj)) if abs(self.event.vbf.deta) > cuts.VBF_Deta: self.counters.counter('VBF').inc('d: deta > {deta:3.1f}'.format(deta = cuts.VBF_Deta)) if len(self.event.vbf.centralJets)==0: self.counters.counter('VBF').inc('e: no central jet ') # print self.event.vbf self.event.eventWeight = 1 # self.event.triggerWeight = 1 self.event.vertexWeight = 1 self.event.tauEffWeight = 1 self.event.lepEffWeight = 1 if self.cmp.isMC: self.event.vertexWeight = self.handles['vertexWeight'].product()[0] self.event.eventWeight *= self.event.vertexWeight if self.trigEff.tauEff is not None: self.event.tauEffWeight = self.trigEff.tauEff(self.event.tau.pt()) if self.trigEff.lepEff is not None: self.event.lepEffWeight = self.trigEff.lepEff( self.event.lepton.pt(), self.event.lepton.eta() ) self.event.eventWeight = self.event.vertexWeight * \ self.event.tauEffWeight * \ self.event.lepEffWeight # if self.cmp.turnOnCurve is not None: # self.event.triggerWeight = self.cmp.turnOnCurve.weight( # self.event.tau.pt() ) # self.event.eventWeight *= self.event.triggerWeight # self.averages['triggerWeight'].add( self.event.triggerWeight ) self.averages['tauEffWeight'].add( self.event.tauEffWeight ) self.averages['lepEffWeight'].add( self.event.lepEffWeight ) self.averages['vertexWeight'].add( self.event.vertexWeight ) self.averages['eventWeight'].add( self.event.eventWeight ) # exclusive analysis regionName = self.regions.test( self.event ) histoList = self.histoLists[regionName] histoList.Fill( self.event, self.event.eventWeight ) # inclusive analysis incRegionName = inclusiveRegionName( regionName ) histoList = self.histoLists[incRegionName] histoList.Fill( self.event, self.event.eventWeight ) return True def Loop(self, nEvents=-1 ): '''Loop on a given number of events, and call ToEvent for each event.''' print 'starting loop' self.InitOutput() nEvents = int(nEvents) for iEv in range(0, self.events.size() ): if iEv == nEvents: break if iEv%1000 ==0: print 'event', iEv try: self.ToEvent( iEv ) except ValueError: #COLIN should not be a value error break self.logger.warning( str(self) ) def Write(self): '''Write all histograms to their root files''' # for hist in self.histograms: # hist.Write() for histoList in self.histoLists.values(): histoList.Write() def __str__(self): name = 'Loop %s' % self.name component = str(self.cmp) counters = map(str, self.counters.counters) strave = map(str, self.averages.values()) # triggers = ': '.join( ['triggers', str(self.triggers)] ) # trigs = str( self.triggerList ) # vertexWeight = ': '.join( ['vertex weight', str(self.cmp.vertexWeight) ]) return '\n'.join([name, component] + counters + strave )
class DiMuAnalyzer( Looper ): def __init__(self, name, component, cfg): super( DiMuAnalyzer, self).__init__(component.fraction) self.name = name self.cmp = component self.cfg = cfg self.events = Events( glob.glob( self.cmp.files) ) self.triggerList = TriggerList( self.cmp.triggers ) ## if self.cmp.isMC or self.cmp.isEmbed: ## self.trigEff = TriggerEfficiency() ## self.trigEff.tauEff = None ## self.trigEff.lepEff = None ## if self.cmp.tauEffWeight is not None: ## self.trigEff.tauEff = getattr( self.trigEff, ## self.cmp.tauEffWeight ) ## if self.cmp.muEffWeight is not None: ## self.trigEff.lepEff = getattr( self.trigEff, ## self.cmp.muEffWeight ) # here create outputs ## self.regions = H2TauTauRegions( self.cfg.cuts ) ## self.output = Output( self.name, self.regions ) ## if self.cmp.name == 'DYJets': ## self.outputFakes = Output( self.name + '_Fakes', self.regions ) self.output = DiMuOutput( self.name ) self.counters = Counters() self.averages = {} self.InitHandles() self.InitCounters() self.logger = logging.getLogger(self.name) self.logger.addHandler(logging.FileHandler('/'.join([self.output.name, 'log.txt']))) def LoadCollections(self, event ): '''Load all collections''' for str,handle in self.handles.iteritems(): handle.Load( event ) # could do something clever to get the products... a setattr maybe? if self.cmp.isMC: for str,handle in self.mchandles.iteritems(): handle.Load( event ) if self.cmp.isEmbed: for str,handle in self.embhandles.iteritems(): handle.Load( event ) def InitHandles(self): '''Initialize all handles for the products we want to read''' self.handles = {} self.mchandles = {} self.embhandles = {} self.handles['cmgTriggerObjectSel'] = AutoHandle( 'cmgTriggerObjectSel', 'std::vector<cmg::TriggerObject>>') if self.cmp.isMC and self.cmp.vertexWeight is not None: self.handles['vertexWeight'] = AutoHandle( self.cmp.vertexWeight, 'double' ) self.handles['vertices'] = AutoHandle( 'offlinePrimaryVertices', 'std::vector<reco::Vertex>' ) self.handles['jets'] = AutoHandle( 'cmgPFJetSel', 'std::vector<cmg::PFJet>' ) self.mchandles['genParticles'] = AutoHandle( 'genParticlesStatus3', 'std::vector<reco::GenParticle>' ) self.embhandles['generatorWeight'] = AutoHandle( ('generator', 'weight'), 'double') self.handles['diMu'] = AutoHandle( 'cmgDiMuonSel', 'std::vector<cmg::DiObject<cmg::Muon,cmg::Muon>>') def InitCounters(self): '''Initialize histograms physics objects, counters.''' # declaring counters and averages self.counters = Counters() self.counters.addCounter('triggerPassed') self.counters.addCounter('exactlyOneDiMu') self.counters.addCounter('singleDiMu') self.counters.addCounter('VBF') # self.averages['triggerWeight']=Average('triggerWeight') ## self.averages['lepEffWeight']=Average('lepEffWeight') ## self.averages['tauEffWeight']=Average('tauEffWeight') self.averages['vertexWeight']=Average('vertexWeight') ## self.averages['generatorWeight']=Average('generatorWeight') self.averages['eventWeight']=Average('eventWeight') def process( self, iEv ): '''Navigate to a given event and process it.''' cuts = self.cfg.cuts # output event structure self.event = Event() # navigating to the correct FWLite event self.iEvent = iEv self.events.to(iEv) self.LoadCollections(self.events) # reading CMG objects from the handle #COLIN this kind of stuff could be automatized cmgDiMus = self.handles['diMu'].product() ## cmgLeptons = self.handles['leptons'].product() self.event.triggerObject = self.handles['cmgTriggerObjectSel'].product()[0] self.event.vertices = self.handles['vertices'].product() cmgJets = self.handles['jets'].product() if self.cmp.isMC: genParticles = self.mchandles['genParticles'].product() self.event.genParticles = map( GenParticle, genParticles) # converting them into my own python objects def testMuon(muon): if muon.pt() > cuts.muPt: return True else: return False def testDiMuon(diMuon): return testMuon( diMuon.leg1() ) and testMuon( diMuon.leg2() ) self.event.diMus = [ DiLepton(diMu) for diMu in cmgDiMus if testDiMuon(diMu) ] # self.event.leptons = [ Lepton(lepton) for lepton in cmgLeptons ] self.event.dirtyJets = [] for cmgJet in cmgJets: jet = Jet( cmgJet ) if self.cmp.isMC: scale = random.gauss( self.cmp.jetScale, self.cmp.jetSmear) jet.scaleEnergy( scale ) if not testJet( cmgJet, cuts): continue self.event.dirtyJets.append(jet) self.counters.counter('triggerPassed').inc('a: All events') if not self.triggerList.triggerPassed(self.event.triggerObject): return False self.counters.counter('triggerPassed').inc('b: Trig OK ') self.counters.counter('exactlyOneDiMu').inc('a: any # of di-mus ') if len(self.event.diMus)==0: # print 'Event %d : No di-mu.' % iEv return False if len(self.event.diMus)>1: # print 'Event %d : Too many tau-mus: n = %d' % (iEv, len(self.event.diMus)) #COLIN could be nice to have a counter class # which knows why events are rejected. make histograms with that. self.logger.warning('Ev %d: more than 1 di-mu : n = %d' % (iEv, len(self.event.diMus))) self.counters.counter('exactlyOneDiMu').inc('b: at least 1 di-mu ') #MUONS #if not self.leptonAccept(self.event.leptons): # return False # self.counters.counter('exactlyOneDiMu').inc('c: exactly one lepton ') self.event.diMu = self.event.diMus[0] if len(self.event.diMus)>1: self.event.diMu = bestDiMu( self.event.diMus ) elif len(self.event.diMus)==1: self.counters.counter('exactlyOneDiMu').inc('d: exactly 1 di-mu ') else: raise ValueError('should not happen!') ################## Starting from here, we have the di-mu ############### self.event.diTau = self.event.diMu diMu = self.event.diMu self.counters.counter('singleDiMu').inc('a: best di-mu') if diMu.leg1().pt() > cuts.muPt and \ diMu.leg2().pt() > cuts.muPt : self.counters.counter('singleDiMu').inc( 'b: pt1,2 > {pt:3.1f}'.format( pt = cuts.muPt) ) else: return False if abs(diMu.leg1().eta()) < cuts.muEta and \ abs(diMu.leg2().eta()) < cuts.muEta : self.counters.counter('singleDiMu').inc( 'c: |eta1,2| < {eta:3.1f}'.format( eta = cuts.muEta) ) else: return False if cuts.minMass < diMu.mass() and diMu.mass() < cuts.maxMass: self.counters.counter('singleDiMu').inc( 'd: {min:3.1f} < m < {max:3.1f}'.format(min = cuts.minMass, max = cuts.maxMass) ) else: return False if diMu.leg1().relIso( 0.5 ) < cuts.muIso and \ diMu.leg2().relIso( 0.5 ) < cuts.muIso: self.counters.counter('singleDiMu').inc( 'e: iso1,2 < {iso:3.1f}'.format(iso=cuts.muIso) ) else: return False #SELECT BARREL MUONS # clean up jet collection self.event.jets = cleanObjectCollection( self.event.dirtyJets, masks = [self.event.diMu.leg1(), self.event.diMu.leg2() ], deltaRMin = 0.5 ) # print '-----------' # if len(self.event.dirtyJets)>0: # print 'Dirty:' # print '\n\t'.join( map(str, self.event.dirtyJets) ) # print self.event.diMu # print 'Clean:' # print '\n\t'.join( map(str, self.event.jets) ) self.counters.counter('VBF').inc('a: all events ') if len(self.event.jets)>1: self.counters.counter('VBF').inc('b: at least 2 jets ') self.event.vbf = VBF( self.event.jets ) if self.event.vbf.mjj > cuts.VBF_Mjj: self.counters.counter('VBF').inc('c: Mjj > {mjj:3.1f}'.format(mjj = cuts.VBF_Mjj)) if abs(self.event.vbf.deta) > cuts.VBF_Deta: self.counters.counter('VBF').inc('d: deta > {deta:3.1f}'.format(deta = cuts.VBF_Deta)) if len(self.event.vbf.centralJets)==0: self.counters.counter('VBF').inc('e: no central jet ') self.event.eventWeight = 1 # self.event.triggerWeight = 1 self.event.vertexWeight = 1 if self.cmp.isMC: self.event.vertexWeight = self.handles['vertexWeight'].product()[0] self.event.eventWeight = self.event.vertexWeight self.output.Fill( self.event ) self.averages['vertexWeight'].add( self.event.vertexWeight ) self.averages['eventWeight'].add( self.event.eventWeight ) return True def Write(self): '''Write all histograms to their root files''' self.output.Write() def __str__(self): name = 'Loop %s' % self.name component = str(self.cmp) counters = map(str, self.counters.counters) strave = map(str, self.averages.values()) return '\n'.join([name, component] + counters + strave )
class Loop: '''Manages looping and navigation on a set of events.''' def __init__(self, name, component, cfg): '''Build a loop object. listOfFiles can be "*.root". name will be used to make the output directory''' self.name = name self.cmp = component self.cfg = cfg self.events = Events(glob.glob(self.cmp.files)) self.triggerList = TriggerList(self.cmp.triggers) if self.cmp.isMC: self.trigEff = TriggerEfficiency() self.trigEff.tauEff = None self.trigEff.lepEff = None if self.cmp.tauEffWeight is not None: self.trigEff.tauEff = getattr(self.trigEff, self.cmp.tauEffWeight) if self.cmp.muEffWeight is not None: self.trigEff.lepEff = getattr(self.trigEff, self.cmp.muEffWeight) #self.cmp.turnOnCurve = None #if self.cmp.isMC: # if self.cmp.tauTriggerTOC is not None: # self.cmp.turnOnCurve = TurnOnCurve( self.cmp.tauTriggerTOC ) self._MakeOutputDir() self.counters = Counters() self.averages = {} # self.histograms = [] self.InitHandles() def _MakeOutputDir(self): index = 0 name = self.name while True: try: # print 'mkdir', self.name os.mkdir(name) break except OSError: index += 1 name = '%s_%d' % (self.name, index) self.logger = logging.getLogger(self.name) self.logger.addHandler( logging.FileHandler('/'.join([self.name, 'log.txt']))) def LoadCollections(self, event): '''Load all collections''' for str, handle in self.handles.iteritems(): handle.Load(event) # could do something clever to get the products... a setattr maybe? def InitHandles(self): '''Initialize all handles for the products we want to read''' self.handles = {} self.handles['cmgTauMuCorFullSelSVFit'] = AutoHandle( 'cmgTauMuCorSVFitFullSel', 'std::vector<cmg::DiObject<cmg::Tau,cmg::Muon>>') ## self.handles['cmgTauMu'] = AutoHandle( 'cmgTauMu', ## 'std::vector<cmg::DiObject<cmg::Tau,cmg::Muon>>') self.handles['cmgTriggerObjectSel'] = AutoHandle( 'cmgTriggerObjectSel', 'std::vector<cmg::TriggerObject>>') if self.cmp.isMC and self.cmp.vertexWeight is not None: self.handles['vertexWeight'] = AutoHandle(self.cmp.vertexWeight, 'double') self.handles['vertices'] = AutoHandle('offlinePrimaryVertices', 'std::vector<reco::Vertex>') self.handles['leptons'] = AutoHandle('cmgMuonSel', 'std::vector<cmg::Muon>') self.handles['jets'] = AutoHandle('cmgPFJetSel', 'std::vector<cmg::PFJet>') def InitOutput(self): '''Initialize histograms physics objects, counters.''' #COLIN do I really need to declare them? # declaring physics objects self.diTau = None self.triggerObject = None # declaring counters and averages self.counters = Counters() self.counters.addCounter('triggerPassed') self.counters.addCounter('exactlyOneDiTau') self.counters.addCounter('singleDiTau') self.counters.addCounter('VBF') # self.averages['triggerWeight']=Average('triggerWeight') self.averages['lepEffWeight'] = Average('lepEffWeight') self.averages['tauEffWeight'] = Average('tauEffWeight') self.averages['vertexWeight'] = Average('vertexWeight') self.averages['eventWeight'] = Average('eventWeight') self.regions = H2TauTauRegions(self.cfg.cuts) self.histoLists = {} inclusiveRegions = set() for regionName in self.regions.regionNames(): self.histoLists[regionName] = H2TauTauHistogramList('/'.join( [self.name, regionName])) incRegName = inclusiveRegionName(regionName) inclusiveRegions.add(incRegName) for regionName in inclusiveRegions: self.histoLists[regionName] = H2TauTauHistogramList('/'.join( [self.name, regionName])) def ToEvent(self, iEv): '''Navigate to a given event and process it.''' # output event structure self.event = Event() # navigating to the correct FWLite event self.iEvent = iEv self.events.to(iEv) self.LoadCollections(self.events) # reading CMG objects from the handle #COLIN this kind of stuff could be automatized cmgDiTaus = self.handles['cmgTauMuCorFullSelSVFit'].product() cmgLeptons = self.handles['leptons'].product() self.event.triggerObject = self.handles['cmgTriggerObjectSel'].product( )[0] self.event.vertices = self.handles['vertices'].product() cmgJets = self.handles['jets'].product() # converting them into my own python objects self.event.diTaus = [DiTau(diTau) for diTau in cmgDiTaus] self.event.leptons = [Lepton(lepton) for lepton in cmgLeptons] self.event.jets = [ Jet(jet) for jet in cmgJets if testJet(jet, self.cfg.cuts) ] self.event.jets = [] for cmgJet in cmgJets: if not testJet(jet, self.cfg.cuts): continue jet = Jet(cmgJet) # print jet.energy() jet.scaleEnergy(1) # print jet.energy() self.event.jets.append(jet) self.counters.counter('triggerPassed').inc('a: All events') if not self.triggerList.triggerPassed(self.event.triggerObject): return False self.counters.counter('triggerPassed').inc('b: Trig OK ') self.counters.counter('exactlyOneDiTau').inc('a: any # of di-taus ') if len(self.event.diTaus) == 0: print 'Event %d : No tau mu.' % i return False if len(self.event.diTaus) > 1: # print 'Event %d : Too many tau-mus: n = %d' % (iEv, len(self.event.diTaus)) #COLIN could be nice to have a counter class # which knows why events are rejected. make histograms with that. self.logger.warning('Ev %d: more than 1 di-tau : n = %d' % (iEv, len(self.event.diTaus))) self.counters.counter('exactlyOneDiTau').inc('b: at least 1 di-tau ') if not leptonAccept(self.event.leptons): return False self.counters.counter('exactlyOneDiTau').inc('c: exactly one lepton ') self.event.diTau = self.event.diTaus[0] if len(self.event.diTaus) > 1: self.event.diTau = bestDiTau(self.event.diTaus) elif len(self.event.diTaus) == 1: self.counters.counter('exactlyOneDiTau').inc( 'd: exactly 1 di-tau ') else: raise ValueError('should not happen!') cuts = self.cfg.cuts self.counters.counter('singleDiTau').inc('a: best di-tau') self.event.tau = Tau(self.event.diTau.leg1()) if self.event.tau.calcEOverP() > 0.2: self.counters.counter('singleDiTau').inc('b: E/p > 0.2 ') else: return False if self.event.tau.pt() > cuts.tauPt: self.counters.counter('singleDiTau').inc( 'c: tau pt > {ptCut:3.1f}'.format(ptCut=cuts.tauPt)) else: return False self.event.lepton = Lepton(self.event.diTau.leg2()) if self.event.lepton.pt() > cuts.lepPt: self.counters.counter('singleDiTau').inc( 'd: lep pt > {ptCut:3.1f}'.format(ptCut=cuts.lepPt)) else: return False if abs(self.event.lepton.eta()) < cuts.lepEta: self.counters.counter('singleDiTau').inc( 'e: lep |eta| <{etaCut:3.1f}'.format(etaCut=cuts.lepEta)) else: return False self.counters.counter('VBF').inc('a: all events ') if len(self.event.jets) > 1: self.counters.counter('VBF').inc('b: at least 2 jets ') self.event.vbf = VBF(self.event.jets) if self.event.vbf.mjj > cuts.VBF_Mjj: self.counters.counter('VBF').inc( 'c: Mjj > {mjj:3.1f}'.format(mjj=cuts.VBF_Mjj)) if abs(self.event.vbf.deta) > cuts.VBF_Deta: self.counters.counter('VBF').inc( 'd: deta > {deta:3.1f}'.format(deta=cuts.VBF_Deta)) if len(self.event.vbf.centralJets) == 0: self.counters.counter('VBF').inc('e: no central jet ') # print self.event.vbf self.event.eventWeight = 1 # self.event.triggerWeight = 1 self.event.vertexWeight = 1 self.event.tauEffWeight = 1 self.event.lepEffWeight = 1 if self.cmp.isMC: self.event.vertexWeight = self.handles['vertexWeight'].product()[0] self.event.eventWeight *= self.event.vertexWeight if self.trigEff.tauEff is not None: self.event.tauEffWeight = self.trigEff.tauEff( self.event.tau.pt()) if self.trigEff.lepEff is not None: self.event.lepEffWeight = self.trigEff.lepEff( self.event.lepton.pt(), self.event.lepton.eta()) self.event.eventWeight = self.event.vertexWeight * \ self.event.tauEffWeight * \ self.event.lepEffWeight # if self.cmp.turnOnCurve is not None: # self.event.triggerWeight = self.cmp.turnOnCurve.weight( # self.event.tau.pt() ) # self.event.eventWeight *= self.event.triggerWeight # self.averages['triggerWeight'].add( self.event.triggerWeight ) self.averages['tauEffWeight'].add(self.event.tauEffWeight) self.averages['lepEffWeight'].add(self.event.lepEffWeight) self.averages['vertexWeight'].add(self.event.vertexWeight) self.averages['eventWeight'].add(self.event.eventWeight) # exclusive analysis regionName = self.regions.test(self.event) histoList = self.histoLists[regionName] histoList.Fill(self.event, self.event.eventWeight) # inclusive analysis incRegionName = inclusiveRegionName(regionName) histoList = self.histoLists[incRegionName] histoList.Fill(self.event, self.event.eventWeight) return True def Loop(self, nEvents=-1): '''Loop on a given number of events, and call ToEvent for each event.''' print 'starting loop' self.InitOutput() nEvents = int(nEvents) for iEv in range(0, self.events.size()): if iEv == nEvents: break if iEv % 1000 == 0: print 'event', iEv try: self.ToEvent(iEv) except ValueError: #COLIN should not be a value error break self.logger.warning(str(self)) def Write(self): '''Write all histograms to their root files''' # for hist in self.histograms: # hist.Write() for histoList in self.histoLists.values(): histoList.Write() def __str__(self): name = 'Loop %s' % self.name component = str(self.cmp) counters = map(str, self.counters.counters) strave = map(str, self.averages.values()) # triggers = ': '.join( ['triggers', str(self.triggers)] ) # trigs = str( self.triggerList ) # vertexWeight = ': '.join( ['vertex weight', str(self.cmp.vertexWeight) ]) return '\n'.join([name, component] + counters + strave)
class H2TauTauAnalyzer( Looper ): def __init__(self, name, component, cfg): self.name = name self.cmp = component self.cfg = cfg self.events = Events( glob.glob( self.cmp.files) ) self.triggerList = TriggerList( self.cmp.triggers ) #SPEC? if self.cmp.isMC or self.cmp.isEmbed: self.trigEff = TriggerEfficiency() self.trigEff.tauEff = None self.trigEff.lepEff = None if self.cmp.tauEffWeight is not None: self.trigEff.tauEff = getattr( self.trigEff, self.cmp.tauEffWeight ) if self.cmp.muEffWeight is not None: self.trigEff.lepEff = getattr( self.trigEff, self.cmp.muEffWeight ) # here create outputs self.regions = H2TauTauRegions( self.cfg.cuts ) self.output = H2TauTauOutput( self.name, self.regions ) if self.cmp.name == 'DYJets': self.outputFakes = H2TauTauOutput( self.name + '_Fakes', self.regions ) self.logger = logging.getLogger(self.name) self.logger.addHandler(logging.FileHandler('/'.join([self.output.name, 'log.txt']))) self.counters = Counters() self.averages = {} self.InitHandles() self.InitCounters() def LoadCollections(self, event ): '''Load all collections''' for str,handle in self.handles.iteritems(): handle.Load( event ) # could do something clever to get the products... a setattr maybe? if self.cmp.isMC: for str,handle in self.mchandles.iteritems(): handle.Load( event ) if self.cmp.isEmbed: for str,handle in self.embhandles.iteritems(): handle.Load( event ) def InitHandles(self): '''Initialize all handles for the products we want to read''' self.handles = {} self.mchandles = {} self.embhandles = {} self.handles['cmgTriggerObjectSel'] = AutoHandle( 'cmgTriggerObjectSel', 'std::vector<cmg::TriggerObject>>') if self.cmp.isMC and self.cmp.vertexWeight is not None: self.handles['vertexWeight'] = AutoHandle( self.cmp.vertexWeight, 'double' ) self.handles['vertices'] = AutoHandle( 'offlinePrimaryVertices', 'std::vector<reco::Vertex>' ) self.handles['jets'] = AutoHandle( 'cmgPFJetSel', 'std::vector<cmg::PFJet>' ) self.mchandles['genParticles'] = AutoHandle( 'genParticlesStatus3', 'std::vector<reco::GenParticle>' ) self.embhandles['generatorWeight'] = AutoHandle( ('generator', 'weight'), 'double') self.InitSpecificHandles() def InitCounters(self): '''Initialize histograms physics objects, counters.''' # declaring counters and averages self.counters = Counters() self.counters.addCounter('triggerPassed') self.counters.addCounter('exactlyOneDiTau') self.counters.addCounter('singleDiTau') self.counters.addCounter('VBF') # self.averages['triggerWeight']=Average('triggerWeight') self.averages['lepEffWeight']=Average('lepEffWeight') self.averages['tauEffWeight']=Average('tauEffWeight') self.averages['vertexWeight']=Average('vertexWeight') self.averages['generatorWeight']=Average('generatorWeight') self.averages['eventWeight']=Average('eventWeight') def process( self, iEv ): '''Navigate to a given event and process it.''' # output event structure self.event = Event() # navigating to the correct FWLite event self.iEvent = iEv self.events.to(iEv) self.LoadCollections(self.events) # reading CMG objects from the handle #COLIN this kind of stuff could be automatized cmgDiTaus = self.handles['diTau'].product() cmgLeptons = self.handles['leptons'].product() self.event.triggerObject = self.handles['cmgTriggerObjectSel'].product()[0] self.event.vertices = self.handles['vertices'].product() cmgJets = self.handles['jets'].product() if self.cmp.isMC: genParticles = self.mchandles['genParticles'].product() self.event.genParticles = map( GenParticle, genParticles) # converting them into my own python objects self.event.diTaus = [ DiTau(diTau) for diTau in cmgDiTaus ] self.event.leptons = [ Lepton(lepton) for lepton in cmgLeptons ] # self.event.dirtyJets = [ Jet(jet) for jet in cmgJets if testJet(jet, self.cfg.cuts) ] self.event.dirtyJets = [] for cmgJet in cmgJets: jet = Jet( cmgJet ) if self.cmp.isMC: scale = random.gauss( self.cmp.jetScale, self.cmp.jetSmear) jet.scaleEnergy( scale ) if not testJet( cmgJet, self.cfg.cuts): continue self.event.dirtyJets.append(jet) self.counters.counter('triggerPassed').inc('a: All events') if not self.triggerList.triggerPassed(self.event.triggerObject): return False self.counters.counter('triggerPassed').inc('b: Trig OK ') self.counters.counter('exactlyOneDiTau').inc('a: any # of di-taus ') if len(self.event.diTaus)==0: print 'Event %d : No di-tau.' % i return False if len(self.event.diTaus)>1: # print 'Event %d : Too many tau-mus: n = %d' % (iEv, len(self.event.diTaus)) #COLIN could be nice to have a counter class # which knows why events are rejected. make histograms with that. self.logger.warning('Ev %d: more than 1 di-tau : n = %d' % (iEv, len(self.event.diTaus))) self.counters.counter('exactlyOneDiTau').inc('b: at least 1 di-tau ') #MUONS if not self.leptonAccept(self.event.leptons): return False self.counters.counter('exactlyOneDiTau').inc('c: exactly one lepton ') self.event.diTau = self.event.diTaus[0] if len(self.event.diTaus)>1: self.event.diTau = bestDiTau( self.event.diTaus ) elif len(self.event.diTaus)==1: self.counters.counter('exactlyOneDiTau').inc('d: exactly 1 di-tau ') else: raise ValueError('should not happen!') cuts = self.cfg.cuts self.counters.counter('singleDiTau').inc('a: best di-tau') self.event.tau = Tau( self.event.diTau.leg1() ) if self.event.tau.decayMode() == 0 and \ self.event.tau.calcEOverP() < 0.2: #MUONS return False else: self.counters.counter('singleDiTau').inc('b: E/p > 0.2 ') if self.event.tau.pt()>cuts.tauPt: self.counters.counter('singleDiTau').inc('c: tau pt > {ptCut:3.1f}'.format(ptCut = cuts.tauPt)) else: return False self.event.lepton = Lepton( self.event.diTau.leg2() ) if self.event.lepton.pt()>cuts.lepPt: self.counters.counter('singleDiTau').inc('d: lep pt > {ptCut:3.1f}'.format(ptCut = cuts.lepPt)) else: return False if abs( self.event.lepton.eta() ) < cuts.lepEta: self.counters.counter('singleDiTau').inc('e: lep |eta| <{etaCut:3.1f}'.format(etaCut = cuts.lepEta)) else: return False ################## Starting from here, we have the di-tau ############### # clean up jet collection self.event.jets = cleanObjectCollection( self.event.dirtyJets, masks = [self.event.diTau.leg1(), self.event.diTau.leg2() ], deltaRMin = 0.5 ) # print '-----------' # if len(self.event.dirtyJets)>0: # print 'Dirty:' # print '\n\t'.join( map(str, self.event.dirtyJets) ) # print self.event.diTau # print 'Clean:' # print '\n\t'.join( map(str, self.event.jets) ) self.counters.counter('VBF').inc('a: all events ') if len(self.event.jets)>1: self.counters.counter('VBF').inc('b: at least 2 jets ') self.event.vbf = VBF( self.event.jets ) if self.event.vbf.mjj > cuts.VBF_Mjj: self.counters.counter('VBF').inc('c: Mjj > {mjj:3.1f}'.format(mjj = cuts.VBF_Mjj)) if abs(self.event.vbf.deta) > cuts.VBF_Deta: self.counters.counter('VBF').inc('d: deta > {deta:3.1f}'.format(deta = cuts.VBF_Deta)) if len(self.event.vbf.centralJets)==0: self.counters.counter('VBF').inc('e: no central jet ') matched = None if self.cmp.name == 'DYJets': leg1DeltaR, leg2DeltaR = self.event.diTau.match( self.event.genParticles ) if leg1DeltaR>-1 and leg1DeltaR < 0.1 and \ leg2DeltaR>-1 and leg2DeltaR < 0.1: matched = True else: matched = False self.event.eventWeight = 1 # self.event.triggerWeight = 1 self.event.vertexWeight = 1 self.event.tauEffWeight = 1 self.event.lepEffWeight = 1 self.event.generatorWeight = 1 if self.cmp.isMC: self.event.vertexWeight = self.handles['vertexWeight'].product()[0] if self.cmp.isEmbed: self.event.generatorWeight = self.embhandles['generatorWeight'].product()[0] if self.cmp.isMC or self.cmp.isEmbed: if self.trigEff.tauEff is not None: self.event.tauEffWeight = self.trigEff.tauEff(self.event.tau.pt()) #MUONS if self.trigEff.lepEff is not None: self.event.lepEffWeight = self.trigEff.lepEff( self.event.lepton.pt(), self.event.lepton.eta() ) self.event.eventWeight = self.event.vertexWeight * \ self.event.tauEffWeight * \ self.event.lepEffWeight * \ self.event.generatorWeight # self.averages['triggerWeight'].add( self.event.triggerWeight ) self.averages['tauEffWeight'].add( self.event.tauEffWeight ) self.averages['lepEffWeight'].add( self.event.lepEffWeight ) self.averages['vertexWeight'].add( self.event.vertexWeight ) self.averages['generatorWeight'].add( self.event.generatorWeight ) self.averages['eventWeight'].add( self.event.eventWeight ) regionName = self.regions.test( self.event ) if matched is None or matched is True: self.output.Fill( self.event, regionName ) elif matched is False: self.outputFakes.Fill( self.event, regionName ) else: raise ValueError('should not happen!') return True def Write(self): '''Write all histograms to their root files''' # for hist in self.histograms: # hist.Write() self.output.Write() if self.cmp.name == 'DYJets': self.outputFakes.Write() def __str__(self): name = 'Loop %s' % self.name component = str(self.cmp) counters = map(str, self.counters.counters) strave = map(str, self.averages.values()) return '\n'.join([name, component] + counters + strave )