def __init__(self, cfg_ana, cfg_comp, looperName): super(ttHLepAnalyzerBase, self).__init__(cfg_ana, cfg_comp, looperName) if self.cfg_ana.doElectronScaleCorrections: tag = "Summer12_DR53X_HCP2012" if cfg_comp.isMC else "Moriond2013" self.electronEnergyCalibrator = ElectronEnergyCalibrator( tag, ## dataset True, # isAOD cfg_comp.isMC, # isMC True, # updateEnergyError, 999, # applyCorrections (999 = correct and/or smear for SC-based energy estimation) 0.607, # smearing ratio False, False, #verbose, sync TRandom3(0), ) # random number generator if hasattr(cfg_comp, 'efficiency'): self.efficiency = EfficiencyCorrector(cfg_comp.efficiency) self.relaxId = cfg_ana.relaxId if hasattr(cfg_ana, 'relaxId') else False
def __init__(self,isMC,reReco=False,correctionType=1,combinationType=1,verbose=0): self.correctionType = correctionType self.combinationType = combinationType tag = "Summer12_DR53X_HCP2012" if isMC else "Moriond2013"; base = "%s/src/" % os.environ['CMSSW_BASE']; pathData = base+"EgammaAnalysis/ElectronTools/data/scalesMoriond.csv" pathLin = base+"EgammaAnalysis/ElectronTools/data/linearityNewReg-May2013.csv" self.electronEnergyCalibrator = ElectronEnergyCalibrator( pathData, pathLin, tag, ## dataset correctionType, False, # apply linearity 0.607, # smearing ratio 1 if isMC else 0, # isMC True, # updateEnergyError, verbose, False, #verbose, sync TRandom3(0)) # random number generator self.myCombinator = ElectronEPcombinator() self.isMC = isMC
def __init__(self, cfg_ana, cfg_comp, looperName ): super(ttHLepAnalyzerBase,self).__init__(cfg_ana,cfg_comp,looperName) if self.cfg_ana.doElectronScaleCorrections: tag = "Summer12_DR53X_HCP2012" if cfg_comp.isMC else "Moriond2013"; self.electronEnergyCalibrator = ElectronEnergyCalibrator( tag, ## dataset True, # isAOD cfg_comp.isMC, # isMC True, # updateEnergyError, 999, # applyCorrections (999 = correct and/or smear for SC-based energy estimation) 0.607, # smearing ratio False, False, #verbose, sync TRandom3(0),) # random number generator if hasattr(cfg_comp,'efficiency'): self.efficiency= EfficiencyCorrector(cfg_comp.efficiency) self.relaxId = cfg_ana.relaxId if hasattr(cfg_ana,'relaxId') else False
class ttHLepAnalyzerBase( Analyzer ): def __init__(self, cfg_ana, cfg_comp, looperName ): super(ttHLepAnalyzerBase,self).__init__(cfg_ana,cfg_comp,looperName) if self.cfg_ana.doElectronScaleCorrections: tag = "Summer12_DR53X_HCP2012" if cfg_comp.isMC else "Moriond2013"; self.electronEnergyCalibrator = ElectronEnergyCalibrator( tag, ## dataset True, # isAOD cfg_comp.isMC, # isMC True, # updateEnergyError, 999, # applyCorrections (999 = correct and/or smear for SC-based energy estimation) 0.607, # smearing ratio False, False, #verbose, sync TRandom3(0),) # random number generator if hasattr(cfg_comp,'efficiency'): self.efficiency= EfficiencyCorrector(cfg_comp.efficiency) self.relaxId = cfg_ana.relaxId if hasattr(cfg_ana,'relaxId') else False #---------------------------------------- # DECLARATION OF HANDLES OF LEPTONS STUFF #---------------------------------------- def declareHandles(self): super(ttHLepAnalyzerBase, self).declareHandles() #leptons self.handles['muons'] = AutoHandle(self.cfg_ana.muons,"std::vector<cmg::Muon>") self.handles['electrons'] = AutoHandle(self.cfg_ana.electrons,"std::vector<cmg::Electron>") #rho for muons self.handles['rhoMu'] = AutoHandle( (self.cfg_ana.rhoMuon, 'rho'), 'double') #rho for electrons self.handles['rhoEle'] = AutoHandle( (self.cfg_ana.rhoElectron, 'rho'), 'double') #photons (a la hzz4l definition) self.handles['photons'] = AutoHandle( ('cmgPhotonSel',''),'std::vector<cmg::Photon>') def beginLoop(self): super(ttHLepAnalyzerBase,self).beginLoop() #------------------ # MAKE LEPTON LISTS #------------------ # the muons are already corrected with Rochester corrections, are already cleaned with the ghost cleaning # the electrons have already the electron energy regression and calibration applied # the V5_10_0 cmgTuple, have been corrected with Mike's patch for the SIP computation -> cmgMuons have been remade -> # (cvs up -r michalis_sipPatchBranch CMGTools/Common/src/MuonFactory.cc) # nb: the event vertex needs to be defined first -> using the vertex analyzer # nb: in the following dxy and dz are computed with respect to the PV good vertex, sip with respect to the PV def makeLeptons(self, event): event.looseLeptons = [] event.selectedLeptons = [] #muons allmuons = map( Muon, self.handles['muons'].product() ) if self.cfg_ana.doRecomputeSIP3D: for mu in allmuons: if mu.sourcePtr().innerTrack().isNonnull(): ## compute the variable and set it mu._sip3d = abs(signedSip3D(mu, event.goodVertices[0])) ## attach it to the object redefining the sip3D() method mu.sip3D = types.MethodType(lambda self : self._sip3d, mu, mu.__class__) if self.cfg_ana.doRochesterCorrections: for mu in allmuons: corp4 = rochcor.corrected_p4(mu, event.run) mu.setP4( corp4 ) if self.cfg_ana.doSegmentBasedMuonCleaning: isgood = cmgMuonCleanerBySegments.clean( self.handles['muons'].product() ) newmu = [] for i,mu in enumerate(allmuons): if isgood[i]: newmu.append(mu) allmuons = newmu for mu in allmuons: mu.associatedVertex = event.goodVertices[0] if (mu.isGlobal() or mu.isTracker() and mu.numberOfMatches()>0) and mu.pt()>5 and abs(mu.eta())<2.4 and abs(mu.dxy())<0.5 and abs(mu.dz())<1.: if mu.sourcePtr().userFloat("isPFMuon")>0.5 and (self.relaxId or mu.sip3D()<10) and mu.relIso(dBetaFactor=0.5)<self.cfg_ana.isolationCut: event.selectedLeptons.append(mu) else: event.looseLeptons.append(mu) #electrons allelectrons = map( Electron, self.handles['electrons'].product() ) if self.cfg_ana.doRecomputeSIP3D: for ele in allelectrons: if ele.sourcePtr().gsfTrack().isNonnull(): ## compute the variable and set it ele._sip3d = abs(signedSip3D(ele, event.goodVertices[0])) ## attach it to the object redefining the sip3D() method ele.sip3D = types.MethodType(lambda self : self._sip3d, ele, ele.__class__) for ele in allelectrons: ele.rho = float(self.handles['rhoEle'].product()[0]) SCEta = abs(ele.sourcePtr().superCluster().eta()) if (abs(SCEta) >= 0.0 and abs(SCEta) < 1.0 ) : ele.EffectiveArea = 0.130; if (abs(SCEta) >= 1.0 and abs(SCEta) < 1.479 ) : ele.EffectiveArea = 0.137; if (abs(SCEta) >= 1.479 and abs(SCEta) < 2.0 ) : ele.EffectiveArea = 0.067; if (abs(SCEta) >= 2.0 and abs(SCEta) < 2.2 ) : ele.EffectiveArea = 0.089; if (abs(SCEta) >= 2.2 and abs(SCEta) < 2.3 ) : ele.EffectiveArea = 0.107; if (abs(SCEta) >= 2.3 and abs(SCEta) < 2.4 ) : ele.EffectiveArea = 0.110; if (abs(SCEta) >= 2.4) : ele.EffectiveArea = 0.138; if self.cfg_ana.doElectronScaleCorrections: for ele in allelectrons: calibratedPatEle = ele.sourcePtr().get() self.electronEnergyCalibrator.correctLite(calibratedPatEle, calibratedPatEle.r9(), event.run) ele.setP4(calibratedPatEle.p4(calibratedPatEle.P4_COMBINATION)) muForEleCrossCleaning = [] if self.cfg_ana.doEleMuCrossCleaning: for mu in event.selectedLeptons + event.looseLeptons: if abs(mu.pdgId()) == 13 and (mu.isGlobal() or mu.sourcePtr().userFloat("isPFMuon")>0.5): muForEleCrossCleaning.append(mu) for ele in allelectrons: ele.associatedVertex = event.goodVertices[0] ## remove muons if muForEleCrossCleaning is not empty if bestMatch(ele, muForEleCrossCleaning)[1] < 0.02: continue ## apply selection if ele.pt()>7 and abs(ele.eta())<2.5 and abs(ele.dxy())<0.5 and abs(ele.dz())<1. and ele.numberOfHits()<=1: if (self.relaxId or ele.mvaIDZZ() and ele.sip3D()<10) and ele.relIso(dBetaFactor=0.5)<self.cfg_ana.isolationCut: event.selectedLeptons.append(ele) else: event.looseLeptons.append(ele) event.looseLeptons.sort(key = lambda l : l.pt(), reverse = True) event.selectedLeptons.sort(key = lambda l : l.pt(), reverse = True) for lepton in event.selectedLeptons: if hasattr(self,'efficiency'): self.efficiency.attachToObject(lepton) #print "Found ",len(event.looseLeptons)," loose leptons" #print "Found ",len(event.selectedLeptons)," good leptons" def makePhotons(self, event): event.allphotons = map( Photon, self.handles['photons'].product() ) event.allphotons.sort(key = lambda l : l.pt(), reverse = True) def process(self, iEvent, event): self.readCollections( iEvent ) eventNumber = iEvent.eventAuxiliary().id().event() #print 'Event ',eventNumber #import pdb; pdb.set_trace() #call the leptons/photons functions self.makeLeptons(event) self.makePhotons(event) ret = False if len(event.selectedLeptons) >= self.cfg_ana.minGoodLeptons: ret = True if hasattr(self.cfg_ana, 'maxGoodLeptons') and len(event.selectedLeptons) > self.cfg_ana.maxGoodLeptons: ret = False #if self.cfg_ana.doSSLeptons and len(event.selectedLeptons) >= 2: # if event.selectedLeptons[0].charge() == event.selectedLeptons[1].charge(): # ret = True return ret
class ElectronCalibrator: def __init__(self,isMC,reReco=False,correctionType=1,combinationType=1,verbose=0): self.correctionType = correctionType self.combinationType = combinationType tag = "Summer12_DR53X_HCP2012" if isMC else "Moriond2013"; base = "%s/src/" % os.environ['CMSSW_BASE']; pathData = base+"EgammaAnalysis/ElectronTools/data/scalesMoriond.csv" pathLin = base+"EgammaAnalysis/ElectronTools/data/linearityNewReg-May2013.csv" self.electronEnergyCalibrator = ElectronEnergyCalibrator( pathData, pathLin, tag, ## dataset correctionType, False, # apply linearity 0.607, # smearing ratio 1 if isMC else 0, # isMC True, # updateEnergyError, verbose, False, #verbose, sync TRandom3(0)) # random number generator self.myCombinator = ElectronEPcombinator() self.isMC = isMC def correct(self,cmgelectron,run,verbose=False): ele = cmgelectron.sourcePtr().get() elClass = ele.classification(); combinedMomentumError = ele.p4Error(ele.candidateP4Kind()) # FIXME : p4Error not filled for pure tracker electrons # Recompute it using the parametrization implemented in # RecoEgamma/EgammaElectronAlgos/src/ElectronEnergyCorrector.cc::simpleParameterizationUncertainty() if not ele.ecalDrivenSeed(): momentum = max(15., ele.p()); #(combinedMomentum<15. ? 15. : combinedMomentum); if ele.isEB() : parEB = ( 5.24e-02, 2.01e-01, 1.00e-02 ); combinedMomentumError = momentum * sqrt( pow(parEB[0]/sqrt(momentum),2) + pow(parEB[1]/momentum,2) + pow(parEB[2],2) ); elif ele.isEE(): parEE = ( 1.46e-01, 9.21e-01, 1.94e-03 ) ; combinedMomentumError = momentum * sqrt( pow(parEE[0]/sqrt(momentum),2) + pow(parEE[1]/momentum,2) + pow(parEE[2],2) ); mySimpleElectron = SimpleElectron( run, ele.classification(), ele.r9(), ele.correctedEcalEnergy(), ele.correctedEcalEnergyError(), ele.trackMomentumAtVtx().R(), ele.trackMomentumError(), ele.p(), # regressionEnergy, ele.p4Error(ele.candidateP4Kind()), # regressionEnergyError, ele.p(), combinedMomentumError, ele.superCluster().eta(), ele.isEB(), 1 if self.isMC else 0, ele.ecalDriven(), ele.trackerDrivenSeed()); # energy calibration for ecalDriven electrons if ele.ecalDrivenSeed() or self.correctionType==2 or self.combinationType==3: self.electronEnergyCalibrator.calibrate(mySimpleElectron); # E-p combination if self.combinationType == 0: if verbose: print "[CalibratedGsfElectronProducer] You choose not to combine." elif self.combinationType == 1: if verbose: print "[CalibratedGsfElectronProducer] You choose corrected regression energy for standard combination" self.myCombinator.setCombinationMode(1); self.myCombinator.combine(mySimpleElectron); elif self.combinationType == 2: if verbose: print "[CalibratedGsfElectronProducer] You choose uncorrected regression energy for standard combination" self.myCombinator.setCombinationMode(2); self.myCombinator.combine(mySimpleElectron); elif self.combinationType == 3: if verbose: print "[CalibratedGsfElectronProducer] You choose regression combination." #self.myEpCombinationTool.combine(mySimpleElectron); #self.theEnCorrector.correctLinearity(mySimpleElectron); else: raise RuntimeError, "CalibratedgsfElectronProducer|ConfigError: Unknown combination Type !!!" oldMomentum = ele.p4(ele.P4_COMBINATION); newMomentum = ele.p4(ele.P4_COMBINATION); scale = mySimpleElectron.getCombinedMomentum()/oldMomentum.t() newMomentum.SetPxPyPzE( oldMomentum.x()*scale, oldMomentum.y()*scale, oldMomentum.z()*scale, mySimpleElectron.getCombinedMomentum()) ele.correctMomentum( newMomentum, mySimpleElectron.getTrackerMomentumError(), mySimpleElectron.getCombinedMomentumError()); cmgelectron.setP4(newMomentum)
class ttHLepAnalyzerBase(Analyzer): def __init__(self, cfg_ana, cfg_comp, looperName): super(ttHLepAnalyzerBase, self).__init__(cfg_ana, cfg_comp, looperName) if self.cfg_ana.doElectronScaleCorrections: tag = "Summer12_DR53X_HCP2012" if cfg_comp.isMC else "Moriond2013" self.electronEnergyCalibrator = ElectronEnergyCalibrator( tag, ## dataset True, # isAOD cfg_comp.isMC, # isMC True, # updateEnergyError, 999, # applyCorrections (999 = correct and/or smear for SC-based energy estimation) 0.607, # smearing ratio False, False, #verbose, sync TRandom3(0), ) # random number generator if hasattr(cfg_comp, 'efficiency'): self.efficiency = EfficiencyCorrector(cfg_comp.efficiency) self.relaxId = cfg_ana.relaxId if hasattr(cfg_ana, 'relaxId') else False #---------------------------------------- # DECLARATION OF HANDLES OF LEPTONS STUFF #---------------------------------------- def declareHandles(self): super(ttHLepAnalyzerBase, self).declareHandles() #leptons self.handles['muons'] = AutoHandle(self.cfg_ana.muons, "std::vector<cmg::Muon>") self.handles['electrons'] = AutoHandle(self.cfg_ana.electrons, "std::vector<cmg::Electron>") #rho for muons self.handles['rhoMu'] = AutoHandle((self.cfg_ana.rhoMuon, 'rho'), 'double') #rho for electrons self.handles['rhoEle'] = AutoHandle((self.cfg_ana.rhoElectron, 'rho'), 'double') #photons (a la hzz4l definition) self.handles['photons'] = AutoHandle(('cmgPhotonSel', ''), 'std::vector<cmg::Photon>') def beginLoop(self): super(ttHLepAnalyzerBase, self).beginLoop() #------------------ # MAKE LEPTON LISTS #------------------ # the muons are already corrected with Rochester corrections, are already cleaned with the ghost cleaning # the electrons have already the electron energy regression and calibration applied # the V5_10_0 cmgTuple, have been corrected with Mike's patch for the SIP computation -> cmgMuons have been remade -> # (cvs up -r michalis_sipPatchBranch CMGTools/Common/src/MuonFactory.cc) # nb: the event vertex needs to be defined first -> using the vertex analyzer # nb: in the following dxy and dz are computed with respect to the PV good vertex, sip with respect to the PV def makeLeptons(self, event): event.looseLeptons = [] event.selectedLeptons = [] #muons allmuons = map(Muon, self.handles['muons'].product()) if self.cfg_ana.doRecomputeSIP3D: for mu in allmuons: if mu.sourcePtr().innerTrack().isNonnull(): ## compute the variable and set it mu._sip3d = abs(signedSip3D(mu, event.goodVertices[0])) ## attach it to the object redefining the sip3D() method mu.sip3D = types.MethodType(lambda self: self._sip3d, mu, mu.__class__) if self.cfg_ana.doRochesterCorrections: for mu in allmuons: corp4 = rochcor.corrected_p4(mu, event.run) mu.setP4(corp4) if self.cfg_ana.doSegmentBasedMuonCleaning: isgood = cmgMuonCleanerBySegments.clean( self.handles['muons'].product()) newmu = [] for i, mu in enumerate(allmuons): if isgood[i]: newmu.append(mu) allmuons = newmu for mu in allmuons: mu.associatedVertex = event.goodVertices[0] if (mu.isGlobal() or mu.isTracker() and mu.numberOfMatches() > 0 ) and mu.pt() > 5 and abs(mu.eta()) < 2.4 and abs( mu.dxy()) < 0.5 and abs(mu.dz()) < 1.: if mu.sourcePtr().userFloat("isPFMuon") > 0.5 and ( self.relaxId or mu.sip3D() < 10) and mu.relIso( dBetaFactor=0.5) < self.cfg_ana.isolationCut: event.selectedLeptons.append(mu) else: event.looseLeptons.append(mu) #electrons allelectrons = map(Electron, self.handles['electrons'].product()) if self.cfg_ana.doRecomputeSIP3D: for ele in allelectrons: if ele.sourcePtr().gsfTrack().isNonnull(): ## compute the variable and set it ele._sip3d = abs(signedSip3D(ele, event.goodVertices[0])) ## attach it to the object redefining the sip3D() method ele.sip3D = types.MethodType(lambda self: self._sip3d, ele, ele.__class__) for ele in allelectrons: ele.rho = float(self.handles['rhoEle'].product()[0]) SCEta = abs(ele.sourcePtr().superCluster().eta()) if (abs(SCEta) >= 0.0 and abs(SCEta) < 1.0): ele.EffectiveArea = 0.130 if (abs(SCEta) >= 1.0 and abs(SCEta) < 1.479): ele.EffectiveArea = 0.137 if (abs(SCEta) >= 1.479 and abs(SCEta) < 2.0): ele.EffectiveArea = 0.067 if (abs(SCEta) >= 2.0 and abs(SCEta) < 2.2): ele.EffectiveArea = 0.089 if (abs(SCEta) >= 2.2 and abs(SCEta) < 2.3): ele.EffectiveArea = 0.107 if (abs(SCEta) >= 2.3 and abs(SCEta) < 2.4): ele.EffectiveArea = 0.110 if (abs(SCEta) >= 2.4): ele.EffectiveArea = 0.138 if self.cfg_ana.doElectronScaleCorrections: for ele in allelectrons: calibratedPatEle = ele.sourcePtr().get() self.electronEnergyCalibrator.correctLite( calibratedPatEle, calibratedPatEle.r9(), event.run) ele.setP4(calibratedPatEle.p4(calibratedPatEle.P4_COMBINATION)) muForEleCrossCleaning = [] if self.cfg_ana.doEleMuCrossCleaning: for mu in event.selectedLeptons + event.looseLeptons: if abs(mu.pdgId()) == 13 and ( mu.isGlobal() or mu.sourcePtr().userFloat("isPFMuon") > 0.5): muForEleCrossCleaning.append(mu) for ele in allelectrons: ele.associatedVertex = event.goodVertices[0] ## remove muons if muForEleCrossCleaning is not empty if bestMatch(ele, muForEleCrossCleaning)[1] < 0.02: continue ## apply selection if ele.pt() > 7 and abs(ele.eta()) < 2.5 and abs( ele.dxy()) < 0.5 and abs( ele.dz()) < 1. and ele.numberOfHits() <= 1: if (self.relaxId or ele.mvaIDZZ() and ele.sip3D() < 10) and ele.relIso( dBetaFactor=0.5) < self.cfg_ana.isolationCut: event.selectedLeptons.append(ele) else: event.looseLeptons.append(ele) event.looseLeptons.sort(key=lambda l: l.pt(), reverse=True) event.selectedLeptons.sort(key=lambda l: l.pt(), reverse=True) for lepton in event.selectedLeptons: if hasattr(self, 'efficiency'): self.efficiency.attachToObject(lepton) #print "Found ",len(event.looseLeptons)," loose leptons" #print "Found ",len(event.selectedLeptons)," good leptons" def makePhotons(self, event): event.allphotons = map(Photon, self.handles['photons'].product()) event.allphotons.sort(key=lambda l: l.pt(), reverse=True) def process(self, iEvent, event): self.readCollections(iEvent) eventNumber = iEvent.eventAuxiliary().id().event() #print 'Event ',eventNumber #import pdb; pdb.set_trace() #call the leptons/photons functions self.makeLeptons(event) self.makePhotons(event) ret = False if len(event.selectedLeptons) >= self.cfg_ana.minGoodLeptons: ret = True if hasattr(self.cfg_ana, 'maxGoodLeptons') and len( event.selectedLeptons) > self.cfg_ana.maxGoodLeptons: ret = False #if self.cfg_ana.doSSLeptons and len(event.selectedLeptons) >= 2: # if event.selectedLeptons[0].charge() == event.selectedLeptons[1].charge(): # ret = True return ret