Пример #1
0
class JetAnalyzer(Analyzer):
    """Taken from RootTools.JetAnalyzer, simplified, modified, added corrections    """
    def __init__(self, cfg_ana, cfg_comp, looperName):
        super(JetAnalyzer, self).__init__(cfg_ana, cfg_comp, looperName)
        mcGT = cfg_ana.mcGT if hasattr(cfg_ana, 'mcGT') else "PHYS14_25_V2"
        dataGT = cfg_ana.dataGT if hasattr(cfg_ana,
                                           'dataGT') else "GR_70_V2_AN1"
        self.shiftJEC = self.cfg_ana.shiftJEC if hasattr(
            self.cfg_ana, 'shiftJEC') else 0
        self.recalibrateJets = self.cfg_ana.recalibrateJets
        if self.recalibrateJets == "MC":
            self.recalibrateJets = self.cfg_comp.isMC
        elif self.recalibrateJets == "Data":
            self.recalibrateJets = not self.cfg_comp.isMC
        elif self.recalibrateJets not in [True, False]:
            raise RuntimeError, "recalibrateJets must be any of { True, False, 'MC', 'Data' }, while it is %r " % self.recalibrateJets
        self.doJEC = self.recalibrateJets or (self.shiftJEC != 0)
        if self.doJEC:
            if self.cfg_comp.isMC:
                self.jetReCalibrator = JetReCalibrator(
                    mcGT, self.cfg_ana.recalibrationType, False,
                    cfg_ana.jecPath)
            else:
                self.jetReCalibrator = JetReCalibrator(
                    dataGT, self.cfg_ana.recalibrationType, True,
                    cfg_ana.jecPath)
        self.doPuId = getattr(self.cfg_ana, 'doPuId', True)
        self.jetLepDR = getattr(self.cfg_ana, 'jetLepDR', 0.4)
        self.jetLepArbitration = getattr(self.cfg_ana, 'jetLepArbitration',
                                         lambda jet, lepton: lepton)
        self.lepPtMin = getattr(self.cfg_ana, 'minLepPt', -1)
        self.lepSelCut = getattr(self.cfg_ana, 'lepSelCut', lambda lep: True)
        self.jetGammaDR = getattr(self.cfg_ana, 'jetGammaDR', 0.4)
        if (self.cfg_ana.doQG):
            self.qglcalc = QGLikelihoodCalculator(
                "%s/src/PhysicsTools/Heppy/data/pdfQG_AK4chs_antib_13TeV_v1.root"
                % os.environ['CMSSW_BASE'])
        if not hasattr(self.cfg_ana, "collectionPostFix"):
            self.cfg_ana.collectionPostFix = ""

    def declareHandles(self):
        super(JetAnalyzer, self).declareHandles()
        self.handles['jets'] = AutoHandle(self.cfg_ana.jetCol,
                                          'std::vector<pat::Jet>')
        self.handles['genJet'] = AutoHandle(self.cfg_ana.genJetCol,
                                            'vector<reco::GenJet>')
        self.shiftJER = self.cfg_ana.shiftJER if hasattr(
            self.cfg_ana, 'shiftJER') else 0
        self.handles['rho'] = AutoHandle(self.cfg_ana.rho, 'double')

    def beginLoop(self, setup):
        super(JetAnalyzer, self).beginLoop(setup)

    def process(self, event):
        self.readCollections(event.input)
        rho = float(self.handles['rho'].product()[0])
        self.rho = rho

        ## Read jets, if necessary recalibrate and shift MET
        if self.cfg_ana.copyJetsByValue:
            import ROOT
            allJets = map(
                lambda j: Jet(ROOT.pat.Jet(j)), self.handles['jets'].product(
                ))  #copy-by-value is safe if JetAnalyzer is ran more than once
        else:
            allJets = map(Jet, self.handles['jets'].product())

        self.deltaMetFromJEC = [0., 0.]
        #        print "before. rho",self.rho,self.cfg_ana.collectionPostFix,'allJets len ',len(allJets),'pt', [j.pt() for j in allJets]
        if self.doJEC:
            #            print "\nCalibrating jets %s for lumi %d, event %d" % (self.cfg_ana.jetCol, event.lumi, event.eventId)
            self.jetReCalibrator.correctAll(allJets,
                                            rho,
                                            delta=self.shiftJEC,
                                            metShift=self.deltaMetFromJEC)
        self.allJetsUsedForMET = allJets
        #        print "after. rho",self.rho,self.cfg_ana.collectionPostFix,'allJets len ',len(allJets),'pt', [j.pt() for j in allJets]

        if self.cfg_comp.isMC:
            self.genJets = [x for x in self.handles['genJet'].product()]
            self.matchJets(event, allJets)
            if getattr(self.cfg_ana, 'smearJets', False):
                self.smearJets(event, allJets)

##Sort Jets by pT
        allJets.sort(key=lambda j: j.pt(), reverse=True)
        ## Apply jet selection
        self.jets = []
        self.jetsFailId = []
        self.jetsAllNoID = []
        self.jetsIdOnly = []
        for jet in allJets:
            if self.testJetNoID(jet):
                self.jetsAllNoID.append(jet)
                if self.testJetID(jet):

                    if (self.cfg_ana.doQG):
                        self.computeQGvars(jet)
                        jet.qgl = self.qglcalc.computeQGLikelihood(jet, rho)

                    self.jets.append(jet)
                    self.jetsIdOnly.append(jet)
                else:
                    self.jetsFailId.append(jet)
            elif self.testJetID(jet):
                self.jetsIdOnly.append(jet)

        ## Clean Jets from leptons
        leptons = []
        if hasattr(event, 'selectedLeptons'):
            leptons = [
                l for l in event.selectedLeptons
                if l.pt() > self.lepPtMin and self.lepSelCut(l)
            ]
        if self.cfg_ana.cleanJetsFromTaus and hasattr(event, 'selectedTaus'):
            leptons = leptons[:] + event.selectedTaus
        if self.cfg_ana.cleanJetsFromIsoTracks and hasattr(
                event, 'selectedIsoCleanTrack'):
            leptons = leptons[:] + event.selectedIsoCleanTrack
        self.cleanJetsAll, cleanLeptons = cleanJetsAndLeptons(
            self.jets, leptons, self.jetLepDR, self.jetLepArbitration)
        self.cleanJets = [
            j for j in self.cleanJetsAll
            if abs(j.eta()) < self.cfg_ana.jetEtaCentral
        ]
        self.cleanJetsFwd = [
            j for j in self.cleanJetsAll
            if abs(j.eta()) >= self.cfg_ana.jetEtaCentral
        ]
        self.discardedJets = [
            j for j in self.jets if j not in self.cleanJetsAll
        ]
        if hasattr(event,
                   'selectedLeptons') and self.cfg_ana.cleanSelectedLeptons:
            event.discardedLeptons = [
                l for l in leptons if l not in cleanLeptons
            ]
            event.selectedLeptons = [
                l for l in event.selectedLeptons
                if l not in event.discardedLeptons
            ]

        ## Clean Jets from photons
        photons = []
        if hasattr(event, 'selectedPhotons'):
            if self.cfg_ana.cleanJetsFromFirstPhoton:
                photons = event.selectedPhotons[:1]
            else:
                photons = [g for g in event.selectedPhotons]

        self.gamma_cleanJetsAll = cleanNearestJetOnly(self.cleanJetsAll,
                                                      photons, self.jetGammaDR)
        self.gamma_cleanJets = [
            j for j in self.gamma_cleanJetsAll
            if abs(j.eta()) < self.cfg_ana.jetEtaCentral
        ]
        self.gamma_cleanJetsFwd = [
            j for j in self.gamma_cleanJetsAll
            if abs(j.eta()) >= self.cfg_ana.jetEtaCentral
        ]
        ###

        ## Associate jets to leptons
        leptons = event.inclusiveLeptons if hasattr(
            event, 'inclusiveLeptons') else event.selectedLeptons
        jlpairs = matchObjectCollection(leptons, allJets, self.jetLepDR**2)

        for jet in allJets:
            jet.leptons = [l for l in jlpairs if jlpairs[l] == jet]

        for lep in leptons:
            jet = jlpairs[lep]
            if jet is None:
                lep.jet = lep
            else:
                lep.jet = jet
        ## Associate jets to taus
        taus = getattr(event, 'selectedTaus', [])
        jtaupairs = matchObjectCollection(taus, allJets, self.jetLepDR**2)

        for jet in allJets:
            jet.taus = [l for l in jtaupairs if jtaupairs[l] == jet]
        for tau in taus:
            tau.jet = jtaupairs[tau]

        #MC stuff
        if self.cfg_comp.isMC:
            self.deltaMetFromJetSmearing = [0, 0]
            for j in self.cleanJetsAll:
                if hasattr(j, 'deltaMetFromJetSmearing'):
                    self.deltaMetFromJetSmearing[
                        0] += j.deltaMetFromJetSmearing[0]
                    self.deltaMetFromJetSmearing[
                        1] += j.deltaMetFromJetSmearing[1]
            self.cleanGenJets = cleanNearestJetOnly(self.genJets, leptons,
                                                    self.jetLepDR)

            if self.cfg_ana.cleanGenJetsFromPhoton:
                self.cleanGenJets = cleanNearestJetOnly(
                    self.cleanGenJets, photons, self.jetLepDR)

            #event.nGenJets25 = 0
            #event.nGenJets25Cen = 0
            #event.nGenJets25Fwd = 0
            #for j in event.cleanGenJets:
            #    event.nGenJets25 += 1
            #    if abs(j.eta()) <= 2.4: event.nGenJets25Cen += 1
            #    else:                   event.nGenJets25Fwd += 1

            self.jetFlavour(event)

        setattr(event, "rho" + self.cfg_ana.collectionPostFix, self.rho)
        setattr(event, "deltaMetFromJEC" + self.cfg_ana.collectionPostFix,
                self.deltaMetFromJEC)
        setattr(event,
                "deltaMetFromJetSmearing" + self.cfg_ana.collectionPostFix,
                self.deltaMetFromJetSmearing)
        setattr(event, "allJetsUsedForMET" + self.cfg_ana.collectionPostFix,
                self.allJetsUsedForMET)
        setattr(event, "genJets" + self.cfg_ana.collectionPostFix,
                self.genJets)
        setattr(event, "cleanGenJets" + self.cfg_ana.collectionPostFix,
                self.cleanGenJets)
        setattr(event, "jets" + self.cfg_ana.collectionPostFix, self.jets)
        setattr(event, "jetsFailId" + self.cfg_ana.collectionPostFix,
                self.jetsFailId)
        setattr(event, "jetsAllNoID" + self.cfg_ana.collectionPostFix,
                self.jetsAllNoID)
        setattr(event, "jetsIdOnly" + self.cfg_ana.collectionPostFix,
                self.jetsIdOnly)
        setattr(event, "cleanJetsAll" + self.cfg_ana.collectionPostFix,
                self.cleanJetsAll)
        setattr(event, "cleanJets" + self.cfg_ana.collectionPostFix,
                self.cleanJets)
        setattr(event, "cleanJetsFwd" + self.cfg_ana.collectionPostFix,
                self.cleanJetsFwd)
        setattr(event, "discardedJets" + self.cfg_ana.collectionPostFix,
                self.discardedJets)
        setattr(event, "gamma_cleanJetsAll" + self.cfg_ana.collectionPostFix,
                self.gamma_cleanJetsAll)
        setattr(event, "gamma_cleanJets" + self.cfg_ana.collectionPostFix,
                self.gamma_cleanJets)
        setattr(event, "gamma_cleanJetsFwd" + self.cfg_ana.collectionPostFix,
                self.gamma_cleanJetsFwd)
        setattr(event, "bqObjects" + self.cfg_ana.collectionPostFix,
                self.bqObjects)
        setattr(event, "cqObjects" + self.cfg_ana.collectionPostFix,
                self.cqObjects)
        setattr(event, "partons" + self.cfg_ana.collectionPostFix,
                self.partons)
        setattr(event, "heaviestQCDFlavour" + self.cfg_ana.collectionPostFix,
                self.heaviestQCDFlavour)

        return True

    def testJetID(self, jet):
        jet.puJetIdPassed = jet.puJetId()
        jet.pfJetIdPassed = jet.jetID('POG_PFID_Loose')
        if self.cfg_ana.relaxJetId:
            return True
        else:
            return jet.pfJetIdPassed and (jet.puJetIdPassed
                                          or not (self.doPuId))

    def testJetNoID(self, jet):
        # 2 is loose pile-up jet id
        return jet.pt() > self.cfg_ana.jetPt and \
               abs( jet.eta() ) < self.cfg_ana.jetEta

    def computeQGvars(self, jet):

        jet.mult = 0
        sum_weight = 0.
        sum_pt = 0.
        sum_deta = 0.
        sum_dphi = 0.
        sum_deta2 = 0.
        sum_detadphi = 0.
        sum_dphi2 = 0.

        for ii in range(0, jet.numberOfDaughters()):

            part = jet.daughter(ii)

            if part.charge() == 0:  # neutral particles

                if part.pt() < 1.: continue

            else:  # charged particles

                if part.trackHighPurity() == False: continue
                if part.fromPV() <= 1: continue

            jet.mult += 1

            deta = part.eta() - jet.eta()
            dphi = deltaPhi(part.phi(), jet.phi())
            partPt = part.pt()
            weight = partPt * partPt
            sum_weight += weight
            sum_pt += partPt
            sum_deta += deta * weight
            sum_dphi += dphi * weight
            sum_deta2 += deta * deta * weight
            sum_detadphi += deta * dphi * weight
            sum_dphi2 += dphi * dphi * weight

        a = 0.
        b = 0.
        c = 0.

        if sum_weight > 0:
            jet.ptd = math.sqrt(sum_weight) / sum_pt
            ave_deta = sum_deta / sum_weight
            ave_dphi = sum_dphi / sum_weight
            ave_deta2 = sum_deta2 / sum_weight
            ave_dphi2 = sum_dphi2 / sum_weight
            a = ave_deta2 - ave_deta * ave_deta
            b = ave_dphi2 - ave_dphi * ave_dphi
            c = -(sum_detadphi / sum_weight - ave_deta * ave_dphi)
        else:
            jet.ptd = 0.

        delta = math.sqrt(math.fabs((a - b) * (a - b) + 4. * c * c))

        if a + b - delta > 0:
            jet.axis2 = -math.log(math.sqrt(0.5 * (a + b - delta)))
        else:
            jet.axis2 = -1.

    def jetFlavour(self, event):
        def isFlavour(x, f):
            id = abs(x.pdgId())
            if id > 999: return (id / 1000) % 10 == f
            if id > 99: return (id / 100) % 10 == f
            return id % 100 == f

        self.bqObjects = [
            p for p in event.genParticles
            if (p.status() == 2 and isFlavour(p, 5))
        ]
        self.cqObjects = [
            p for p in event.genParticles
            if (p.status() == 2 and isFlavour(p, 4))
        ]

        self.partons = [
            p for p in event.genParticles
            if ((p.status() == 23 or p.status() == 3) and abs(p.pdgId()) > 0
                and (abs(p.pdgId()) in [1, 2, 3, 4, 5, 21]))
        ]
        match = matchObjectCollection2(self.cleanJetsAll,
                                       self.partons,
                                       deltaRMax=0.3)

        for jet in self.cleanJetsAll:
            parton = match[jet]
            jet.partonId = (parton.pdgId() if parton != None else 0)
            jet.partonMotherId = (parton.mother(0).pdgId() if parton != None
                                  and parton.numberOfMothers() > 0 else 0)

        for jet in self.jets:
            (bmatch, dr) = bestMatch(jet, self.bqObjects)
            if dr < 0.4:
                jet.mcFlavour = 5
            else:
                (cmatch, dr) = bestMatch(jet, self.cqObjects)
                if dr < 0.4:
                    jet.mcFlavour = 4
                else:
                    jet.mcFlavour = 0

        self.heaviestQCDFlavour = 5 if len(
            self.bqObjects) else (4 if len(self.cqObjects) else 1)

    def matchJets(self, event, jets):
        match = matchObjectCollection2(jets,
                                       event.genbquarks + event.genwzquarks,
                                       deltaRMax=0.3)
        for jet in jets:
            gen = match[jet]
            jet.mcParton = gen
            jet.mcMatchId = (gen.sourceId if gen != None else 0)
            jet.mcMatchFlav = (abs(gen.pdgId()) if gen != None else 0)

        match = matchObjectCollection2(jets, self.genJets, deltaRMax=0.3)
        for jet in jets:
            jet.mcJet = match[jet]

    def smearJets(self, event, jets):
        # https://twiki.cern.ch/twiki/bin/viewauth/CMS/TWikiTopRefSyst#Jet_energy_resolution
        for jet in jets:
            gen = jet.mcJet
            if gen != None:
                genpt, jetpt, aeta = gen.pt(), jet.pt(), abs(jet.eta())
                # from https://twiki.cern.ch/twiki/bin/view/CMS/JetResolution
                factor = 1.052 + self.shiftJER * math.hypot(0.012, 0.062)
                if aeta > 2.3:
                    factor = 1.288 + self.shiftJER * math.hypot(0.127, 0.154)
                elif aeta > 1.7:
                    factor = 1.134 + self.shiftJER * math.hypot(0.035, 0.066)
                elif aeta > 1.1:
                    factor = 1.096 + self.shiftJER * math.hypot(0.017, 0.063)
                elif aeta > 0.5:
                    factor = 1.057 + self.shiftJER * math.hypot(0.012, 0.056)
                ptscale = max(0.0,
                              (jetpt + (factor - 1) * (jetpt - genpt)) / jetpt)
                #print "get with pt %.1f (gen pt %.1f, ptscale = %.3f)" % (jetpt,genpt,ptscale)
                jet.deltaMetFromJetSmearing = [
                    -(ptscale - 1) * jet.rawFactor() * jet.px(),
                    -(ptscale - 1) * jet.rawFactor() * jet.py()
                ]
                if ptscale != 0:
                    jet.setP4(jet.p4() * ptscale)
                # leave the uncorrected unchanged for sync
                jet._rawFactorMultiplier *= (1.0 /
                                             ptscale) if ptscale != 0 else 1
Пример #2
0
class JetAnalyzer( Analyzer ):
    """Taken from RootTools.JetAnalyzer, simplified, modified, added corrections    """
    def __init__(self, cfg_ana, cfg_comp, looperName):
        super(JetAnalyzer,self).__init__(cfg_ana, cfg_comp, looperName)
        mcGT   = cfg_ana.mcGT   if hasattr(cfg_ana,'mcGT')   else "PHYS14_25_V2"
        dataGT = cfg_ana.dataGT if hasattr(cfg_ana,'dataGT') else "GR_70_V2_AN1"
        self.shiftJEC = self.cfg_ana.shiftJEC if hasattr(self.cfg_ana, 'shiftJEC') else 0
        self.recalibrateJets = self.cfg_ana.recalibrateJets
        if   self.recalibrateJets == "MC"  : self.recalibrateJets =     self.cfg_comp.isMC
        elif self.recalibrateJets == "Data": self.recalibrateJets = not self.cfg_comp.isMC
        elif self.recalibrateJets not in [True,False]: raise RuntimeError, "recalibrateJets must be any of { True, False, 'MC', 'Data' }, while it is %r " % self.recalibrateJets
        self.doJEC = self.recalibrateJets or (self.shiftJEC != 0)
        if self.doJEC:
          if self.cfg_comp.isMC:
            self.jetReCalibrator = JetReCalibrator(mcGT,"AK4PFchs", False,cfg_ana.jecPath)
          else:
            self.jetReCalibrator = JetReCalibrator(dataGT,"AK4PFchs", True,cfg_ana.jecPath)
        self.doPuId = getattr(self.cfg_ana, 'doPuId', True)
        self.jetLepDR = getattr(self.cfg_ana, 'jetLepDR', 0.4)
        self.jetLepArbitration = getattr(self.cfg_ana, 'jetLepArbitration', lambda jet,lepton: lepton) 
        self.lepPtMin = getattr(self.cfg_ana, 'minLepPt', -1)
        self.jetGammaDR =  getattr(self.cfg_ana, 'jetGammaDR', 0.4)
        if(self.cfg_ana.doQG):
            self.qglcalc = QGLikelihoodCalculator("/afs/cern.ch/user/t/tomc/public/qgTagger/QGLikelihoodDBFiles/QGL_v1a/pdfQG_AK4chs_antib_13TeV_v1.root")

    def declareHandles(self):
        super(JetAnalyzer, self).declareHandles()
        self.handles['jets']   = AutoHandle( self.cfg_ana.jetCol, 'std::vector<pat::Jet>' )
        self.handles['genJet'] = AutoHandle( 'slimmedGenJets', 'vector<reco::GenJet>' )
        self.shiftJER = self.cfg_ana.shiftJER if hasattr(self.cfg_ana, 'shiftJER') else 0
        self.handles['rho'] = AutoHandle( ('fixedGridRhoFastjetAll','',''), 'double' )
    
    def beginLoop(self, setup):
        super(JetAnalyzer,self).beginLoop(setup)
        
    def process(self, event):
        self.readCollections( event.input )
        rho  = float(self.handles['rho'].product()[0])
        event.rho = rho

        ## Read jets, if necessary recalibrate and shift MET
        allJets = map(Jet, self.handles['jets'].product()) 

        event.deltaMetFromJEC = [0.,0.]
        if self.doJEC:
            #print "\nCalibrating jets %s for lumi %d, event %d" % (self.cfg_ana.jetCol, event.lumi, event.eventId)
            self.jetReCalibrator.correctAll(allJets, rho, delta=self.shiftJEC, metShift=event.deltaMetFromJEC)
        event.allJetsUsedForMET = allJets

        if self.cfg_comp.isMC:
            event.genJets = [ x for x in self.handles['genJet'].product() ]
            self.matchJets(event, allJets)
            if getattr(self.cfg_ana, 'smearJets', False):
                self.smearJets(event, allJets)
        
	##Sort Jets by pT 
        allJets.sort(key = lambda j : j.pt(), reverse = True)
        
	## Apply jet selection
        event.jets = []
        event.jetsFailId = []
        event.jetsAllNoID = []
        event.jetsIdOnly = []
        for jet in allJets:
            if self.testJetNoID( jet ): 
                event.jetsAllNoID.append(jet) 
                if self.testJetID (jet ):
                    
                    if(self.cfg_ana.doQG):
                        self.computeQGvars(jet)
                        jet.qgl = self.qglcalc.computeQGLikelihood(jet, rho)


                    event.jets.append(jet)
                    event.jetsIdOnly.append(jet)
                else:
                    event.jetsFailId.append(jet)
            elif self.testJetID (jet ):
                event.jetsIdOnly.append(jet)

        ## Clean Jets from leptons
        leptons = []
        if hasattr(event, 'selectedLeptons'):
            leptons = [ l for l in event.selectedLeptons if l.pt() > self.lepPtMin ]
        if self.cfg_ana.cleanJetsFromTaus and hasattr(event, 'selectedTaus'):
            leptons = leptons[:] + event.selectedTaus
        if self.cfg_ana.cleanJetsFromIsoTracks and hasattr(event, 'selectedIsoCleanTrack'):
            leptons = leptons[:] + event.selectedIsoCleanTrack
        event.cleanJetsAll, cleanLeptons = cleanJetsAndLeptons(event.jets, leptons, self.jetLepDR, self.jetLepArbitration)
        event.cleanJets    = [j for j in event.cleanJetsAll if abs(j.eta()) <  self.cfg_ana.jetEtaCentral ]
        event.cleanJetsFwd = [j for j in event.cleanJetsAll if abs(j.eta()) >= self.cfg_ana.jetEtaCentral ]
        event.discardedJets = [j for j in event.jets if j not in event.cleanJetsAll]
        if hasattr(event, 'selectedLeptons'):
            event.discardedLeptons = [ l for l in leptons if l not in cleanLeptons ]
            event.selectedLeptons  = [ l for l in event.selectedLeptons if l not in event.discardedLeptons ]

        ## Clean Jets from photons
        photons = []
        if hasattr(event, 'selectedPhotons'):
            if self.cfg_ana.cleanJetsFromFirstPhoton:
                photons = event.selectedPhotons[:1]
            else:
                photons = [ g for g in event.selectedPhotons ] 

        event.gamma_cleanJetsAll = cleanNearestJetOnly(event.cleanJetsAll, photons, self.jetGammaDR)
        event.gamma_cleanJets    = [j for j in event.gamma_cleanJetsAll if abs(j.eta()) <  self.cfg_ana.jetEtaCentral ]
        event.gamma_cleanJetsFwd = [j for j in event.gamma_cleanJetsAll if abs(j.eta()) >= self.cfg_ana.jetEtaCentral ]
        ###


        ## Associate jets to leptons
        leptons = event.inclusiveLeptons if hasattr(event, 'inclusiveLeptons') else event.selectedLeptons
        jlpairs = matchObjectCollection( leptons, allJets, self.jetLepDR**2)

        for jet in allJets:
            jet.leptons = [l for l in jlpairs if jlpairs[l] == jet ]

        for lep in leptons:
            jet = jlpairs[lep]
            if jet is None:
                lep.jet = lep
            else:
                lep.jet = jet
        ## Associate jets to taus 
        taus = getattr(event,'selectedTaus',[])
        jtaupairs = matchObjectCollection( taus, allJets, self.jetLepDR**2)

        for jet in allJets:
            jet.taus = [l for l in jtaupairs if jtaupairs[l] == jet ]
        for tau in taus:
            tau.jet = jtaupairs[tau]

        #MC stuff
        if self.cfg_comp.isMC:
            event.deltaMetFromJetSmearing = [0, 0]
            for j in event.cleanJetsAll:
                if hasattr(j, 'deltaMetFromJetSmearing'):
                    event.deltaMetFromJetSmearing[0] += j.deltaMetFromJetSmearing[0]
                    event.deltaMetFromJetSmearing[1] += j.deltaMetFromJetSmearing[1]
            event.cleanGenJets = cleanNearestJetOnly(event.genJets, leptons, self.jetLepDR)
            
            #event.nGenJets25 = 0
            #event.nGenJets25Cen = 0
            #event.nGenJets25Fwd = 0
            #for j in event.cleanGenJets:
            #    event.nGenJets25 += 1
            #    if abs(j.eta()) <= 2.4: event.nGenJets25Cen += 1
            #    else:                   event.nGenJets25Fwd += 1
                    
            self.jetFlavour(event)
        
    
        return True

        

    def testJetID(self, jet):
        jet.puJetIdPassed = jet.puJetId() 
        jet.pfJetIdPassed = jet.jetID('POG_PFID_Loose') 
        if self.cfg_ana.relaxJetId:
            return True
        else:
            return jet.pfJetIdPassed and (jet.puJetIdPassed or not(self.doPuId)) 
        
    def testJetNoID( self, jet ):
        # 2 is loose pile-up jet id
        return jet.pt() > self.cfg_ana.jetPt and \
               abs( jet.eta() ) < self.cfg_ana.jetEta;

    def computeQGvars(self, jet):

       jet.mult = 0
       sum_weight = 0.
       sum_pt = 0.
       sum_deta = 0.
       sum_dphi = 0.
       sum_deta2 = 0.
       sum_detadphi = 0.
       sum_dphi2 = 0.



       for ii in range(0, jet.numberOfDaughters()) :

         part = jet.daughter(ii)

         if part.charge() == 0 : # neutral particles 

           if part.pt() < 1.: continue

         else : # charged particles

           if part.trackHighPurity()==False: continue
           if part.fromPV()<=1: continue


         jet.mult += 1

         deta = part.eta() - jet.eta()
         dphi = deltaPhi(part.phi(), jet.phi())
         partPt = part.pt()
         weight = partPt*partPt
         sum_weight += weight
         sum_pt += partPt
         sum_deta += deta*weight
         sum_dphi += dphi*weight
         sum_deta2 += deta*deta*weight
         sum_detadphi += deta*dphi*weight
         sum_dphi2 += dphi*dphi*weight




       a = 0.
       b = 0.
       c = 0.

       if sum_weight > 0 :
         jet.ptd = math.sqrt(sum_weight)/sum_pt
         ave_deta = sum_deta/sum_weight
         ave_dphi = sum_dphi/sum_weight
         ave_deta2 = sum_deta2/sum_weight
         ave_dphi2 = sum_dphi2/sum_weight
         a = ave_deta2 - ave_deta*ave_deta
         b = ave_dphi2 - ave_dphi*ave_dphi
         c = -(sum_detadphi/sum_weight - ave_deta*ave_dphi)
       else: jet.ptd = 0.

       delta = math.sqrt(math.fabs((a-b)*(a-b)+4.*c*c))

       if a+b-delta > 0: jet.axis2 = -math.log(math.sqrt(0.5*(a+b-delta)))
       else: jet.axis2 = -1.


    def jetFlavour(self,event):
        def isFlavour(x,f):
            id = abs(x.pdgId())
            if id > 999: return (id/1000)%10 == f
            if id >  99: return  (id/100)%10 == f
            return id % 100 == f



        event.bqObjects = [ p for p in event.genParticles if (p.status() == 2 and isFlavour(p,5)) ]
        event.cqObjects = [ p for p in event.genParticles if (p.status() == 2 and isFlavour(p,4)) ]

        event.partons   = [ p for p in event.genParticles if ((p.status() == 23 or p.status() == 3) and abs(p.pdgId())>0 and (abs(p.pdgId()) in [1,2,3,4,5,21]) ) ]
        match = matchObjectCollection2(event.cleanJetsAll,
                                       event.partons,
                                       deltaRMax = 0.3)

        for jet in event.cleanJetsAll:
            parton = match[jet]
            jet.partonId = (parton.pdgId() if parton != None else 0)
            jet.partonMotherId = (parton.mother(0).pdgId() if parton != None and parton.numberOfMothers()>0 else 0)
        
        for jet in event.jets:
           (bmatch, dr) = bestMatch(jet, event.bqObjects)
           if dr < 0.4:
               jet.mcFlavour = 5
           else:
               (cmatch, dr) = bestMatch(jet, event.cqObjects) 
               if dr < 0.4:
                   jet.mcFlavour = 4
               else:
                   jet.mcFlavour = 0

        event.heaviestQCDFlavour = 5 if len(event.bqObjects) else (4 if len(event.cqObjects) else 1);
 

    def matchJets(self, event, jets):
        match = matchObjectCollection2(jets,
                                       event.genbquarks + event.genwzquarks,
                                       deltaRMax = 0.3)
        for jet in jets:
            gen = match[jet]
            jet.mcParton    = gen
            jet.mcMatchId   = (gen.sourceId     if gen != None else 0)
            jet.mcMatchFlav = (abs(gen.pdgId()) if gen != None else 0)

        match = matchObjectCollection2(jets,
                                       event.genJets,
                                       deltaRMax = 0.3)
        for jet in jets:
            jet.mcJet = match[jet]


 
    def smearJets(self, event, jets):
        # https://twiki.cern.ch/twiki/bin/viewauth/CMS/TWikiTopRefSyst#Jet_energy_resolution
       for jet in jets:
            gen = jet.mcJet 
            if gen != None:
               genpt, jetpt, aeta = gen.pt(), jet.pt(), abs(jet.eta())
               # from https://twiki.cern.ch/twiki/bin/view/CMS/JetResolution
               factor = 1.052 + self.shiftJER*math.hypot(0.012,0.062);
               if   aeta > 2.3: factor = 1.288 + self.shiftJER*math.hypot(0.127,0.154)
               elif aeta > 1.7: factor = 1.134 + self.shiftJER*math.hypot(0.035,0.066)
               elif aeta > 1.1: factor = 1.096 + self.shiftJER*math.hypot(0.017,0.063)
               elif aeta > 0.5: factor = 1.057 + self.shiftJER*math.hypot(0.012,0.056)
               ptscale = max(0.0, (jetpt + (factor-1)*(jetpt-genpt))/jetpt)
               #print "get with pt %.1f (gen pt %.1f, ptscale = %.3f)" % (jetpt,genpt,ptscale)
               jet.deltaMetFromJetSmearing = [ -(ptscale-1)*jet.rawFactor()*jet.px(), -(ptscale-1)*jet.rawFactor()*jet.py() ]
               if ptscale != 0:
                  jet.setP4(jet.p4()*ptscale)
               # leave the uncorrected unchanged for sync
               jet._rawFactorMultiplier *= (1.0/ptscale) if ptscale != 0 else 1
Пример #3
0
class JetAnalyzer(Analyzer):
    """Taken from RootTools.JetAnalyzer, simplified, modified, added corrections    """
    def __init__(self, cfg_ana, cfg_comp, looperName):
        super(JetAnalyzer, self).__init__(cfg_ana, cfg_comp, looperName)
        mcGT = cfg_ana.mcGT if hasattr(cfg_ana, 'mcGT') else "PHYS14_25_V2"
        dataGT = cfg_ana.dataGT if hasattr(cfg_ana,
                                           'dataGT') else "GR_70_V2_AN1"
        self.shiftJEC = self.cfg_ana.shiftJEC if hasattr(
            self.cfg_ana, 'shiftJEC') else 0
        self.recalibrateJets = self.cfg_ana.recalibrateJets
        if self.recalibrateJets == "MC":
            self.recalibrateJets = self.cfg_comp.isMC
        elif self.recalibrateJets == "Data":
            self.recalibrateJets = not self.cfg_comp.isMC
        elif self.recalibrateJets not in [True, False]:
            raise RuntimeError, "recalibrateJets must be any of { True, False, 'MC', 'Data' }, while it is %r " % self.recalibrateJets
        self.doJEC = self.recalibrateJets or (self.shiftJEC != 0)
        if self.doJEC:
            if self.cfg_comp.isMC:
                self.jetReCalibrator = JetReCalibrator(mcGT, "AK4PFchs", False,
                                                       cfg_ana.jecPath)
            else:
                self.jetReCalibrator = JetReCalibrator(dataGT, "AK4PFchs",
                                                       True, cfg_ana.jecPath)
        self.doPuId = self.cfg_ana.doPuId if hasattr(self.cfg_ana,
                                                     'doPuId') else True
        self.jetLepDR = self.cfg_ana.jetLepDR if hasattr(
            self.cfg_ana, 'jetLepDR') else 0.5
        self.lepPtMin = self.cfg_ana.minLepPt if hasattr(
            self.cfg_ana, 'minLepPt') else -1
        self.jetGammaDR = self.cfg_ana.jetGammaDR if hasattr(
            self.cfg_ana, 'jetGammaDR') else 0.4
        if (self.cfg_ana.doQG):
            self.qglcalc = QGLikelihoodCalculator(
                "/afs/cern.ch/user/t/tomc/public/QG_pdfs_13TeV_2014-10-12/pdfQG_AK4chs_antib_NoQC_13TeV.root"
            )

    def declareHandles(self):
        super(JetAnalyzer, self).declareHandles()
        self.handles['jets'] = AutoHandle(self.cfg_ana.jetCol,
                                          'std::vector<pat::Jet>')
        self.handles['genJet'] = AutoHandle('slimmedGenJets',
                                            'vector<reco::GenJet>')
        self.shiftJER = self.cfg_ana.shiftJER if hasattr(
            self.cfg_ana, 'shiftJER') else 0
        self.handles['rho'] = AutoHandle(('fixedGridRhoFastjetAll', '', ''),
                                         'double')

    def beginLoop(self, setup):
        super(JetAnalyzer, self).beginLoop(setup)

    def process(self, event):
        self.readCollections(event.input)
        rho = float(self.handles['rho'].product()[0])
        event.rho = rho

        ## Read jets, if necessary recalibrate and shift MET
        allJets = map(Jet, self.handles['jets'].product())

        event.deltaMetFromJEC = [0., 0.]
        if self.doJEC:
            #print "\nCalibrating jets %s for lumi %d, event %d" % (self.cfg_ana.jetCol, event.lumi, event.eventId)
            self.jetReCalibrator.correctAll(allJets,
                                            rho,
                                            delta=self.shiftJEC,
                                            metShift=event.deltaMetFromJEC)
        event.allJetsUsedForMET = allJets

        if self.cfg_comp.isMC:
            event.genJets = [x for x in self.handles['genJet'].product()]
            self.matchJets(event, allJets)
            if getattr(self.cfg_ana, 'smearJets', False):
                self.smearJets(event, allJets)

        ## Apply jet selection
        event.jets = []
        event.jetsFailId = []
        event.jetsAllNoID = []
        event.jetsIdOnly = []
        for jet in allJets:
            if self.testJetNoID(jet):
                event.jetsAllNoID.append(jet)
                if self.testJetID(jet):

                    if (self.cfg_ana.doQG):
                        self.computeQGvars(jet)
                        jet.qgl = self.qglcalc.computeQGLikelihood(jet, rho)

                    event.jets.append(jet)
                    event.jetsIdOnly.append(jet)
                else:
                    event.jetsFailId.append(jet)
            elif self.testJetID(jet):
                event.jetsIdOnly.append(jet)

        ## Clean Jets from leptons
        leptons = []
        if hasattr(event, 'selectedLeptons'):
            leptons = [
                l for l in event.selectedLeptons if l.pt() > self.lepPtMin
            ]
        if self.cfg_ana.cleanJetsFromTaus and hasattr(event, 'selectedTaus'):
            leptons = leptons[:] + event.selectedTaus
        if self.cfg_ana.cleanJetsFromIsoTracks and hasattr(
                event, 'selectedIsoCleanTrack'):
            leptons = leptons[:] + event.selectedIsoCleanTrack
        event.cleanJetsAll = cleanNearestJetOnly(event.jets, leptons,
                                                 self.jetLepDR)
        event.cleanJets = [
            j for j in event.cleanJetsAll
            if abs(j.eta()) < self.cfg_ana.jetEtaCentral
        ]
        event.cleanJetsFwd = [
            j for j in event.cleanJetsAll
            if abs(j.eta()) >= self.cfg_ana.jetEtaCentral
        ]

        ## Clean Jets from photons
        photons = []
        if hasattr(event, 'selectedPhotons'):
            photons = [g for g in event.selectedPhotons]
        event.gamma_cleanJetsAll = cleanNearestJetOnly(event.cleanJetsAll,
                                                       photons,
                                                       self.jetGammaDR)
        event.gamma_cleanJets = [
            j for j in event.gamma_cleanJetsAll
            if abs(j.eta()) < self.cfg_ana.jetEtaCentral
        ]
        event.gamma_cleanJetsFwd = [
            j for j in event.gamma_cleanJetsAll
            if abs(j.eta()) >= self.cfg_ana.jetEtaCentral
        ]
        ###

        ## Associate jets to leptons
        leptons = event.inclusiveLeptons if hasattr(
            event, 'inclusiveLeptons') else event.selectedLeptons
        jlpairs = matchObjectCollection(leptons, allJets, self.jetLepDR**2)

        for jet in allJets:
            jet.leptons = [l for l in jlpairs if jlpairs[l] == jet]

        for lep in leptons:
            jet = jlpairs[lep]
            if jet is None:
                lep.jet = lep
            else:
                lep.jet = jet

        if self.cfg_comp.isMC:
            event.deltaMetFromJetSmearing = [0, 0]
            for j in event.cleanJetsAll:
                if hasattr(j, 'deltaMetFromJetSmearing'):
                    event.deltaMetFromJetSmearing[
                        0] += j.deltaMetFromJetSmearing[0]
                    event.deltaMetFromJetSmearing[
                        1] += j.deltaMetFromJetSmearing[1]
            event.cleanGenJets = cleanNearestJetOnly(event.genJets,
                                                     event.selectedLeptons,
                                                     0.5)

            #event.nGenJets25 = 0
            #event.nGenJets25Cen = 0
            #event.nGenJets25Fwd = 0
            #for j in event.cleanGenJets:
            #    event.nGenJets25 += 1
            #    if abs(j.eta()) <= 2.4: event.nGenJets25Cen += 1
            #    else:                   event.nGenJets25Fwd += 1

            self.jetFlavour(event)

        return True

    def testJetID(self, jet):
        jet.puJetIdPassed = jet.puJetId()
        jet.pfJetIdPassed = jet.jetID('POG_PFID_Loose')
        if self.cfg_ana.relaxJetId:
            return True
        else:
            return jet.pfJetIdPassed and (jet.puJetIdPassed
                                          or not (self.doPuId))

    def testJetNoID(self, jet):
        # 2 is loose pile-up jet id
        return jet.pt() > self.cfg_ana.jetPt and \
               abs( jet.eta() ) < self.cfg_ana.jetEta

    def computeQGvars(self, jet):

        jet.mult = 0
        sum_weight = 0.
        sum_pt = 0.
        sum_deta = 0.
        sum_dphi = 0.
        sum_deta2 = 0.
        sum_detadphi = 0.
        sum_dphi2 = 0.

        for ii in range(0, jet.numberOfDaughters()):

            part = jet.daughter(ii)

            usePart = True

            if part.charge() == 0:  # neutral particles

                if part.pt() > 1.: jet.mult += 1

            else:  # charged particles

                jet.mult += 1

                if part.trackHighPurity() == False: usePart = False
                if part.fromPV() <= 1: usePart = False

            if usePart:
                deta = part.eta() - jet.eta()
                dphi = deltaPhi(part.phi(), jet.phi())
                partPt = part.pt()
                weight = partPt * partPt
                sum_weight += weight
                sum_pt += partPt
                sum_deta += deta * weight
                sum_dphi += dphi * weight
                sum_deta2 += deta * deta * weight
                sum_detadphi += deta * dphi * weight
                sum_dphi2 += dphi * dphi * weight

        a = 0.
        b = 0.
        c = 0.

        if sum_weight > 0:
            jet.ptd = math.sqrt(sum_weight) / sum_pt
            ave_deta = sum_deta / sum_weight
            ave_dphi = sum_dphi / sum_weight
            ave_deta2 = sum_deta2 / sum_weight
            ave_dphi2 = sum_dphi2 / sum_weight
            a = ave_deta2 - ave_deta * ave_deta
            b = ave_dphi2 - ave_dphi * ave_dphi
            c = -(sum_detadphi / sum_weight - ave_deta * ave_dphi)
        else:
            jet.ptd = 0.

        delta = math.sqrt(math.fabs((a - b) * (a - b) + 4. * c * c))

        if a + b - delta > 0:
            jet.axis2 = -math.log(math.sqrt(0.5 * (a + b - delta)))
        else:
            jet.axis2 = -1.

    def jetFlavour(self, event):
        def isFlavour(x, f):
            id = abs(x.pdgId())
            if id > 999: return (id / 1000) % 10 == f
            if id > 99: return (id / 100) % 10 == f
            return id % 100 == f

        event.bqObjects = [
            p for p in event.genParticles
            if (p.status() == 2 and isFlavour(p, 5))
        ]
        event.cqObjects = [
            p for p in event.genParticles
            if (p.status() == 2 and isFlavour(p, 4))
        ]

        event.partons = [
            p for p in event.genParticles
            if ((p.status() == 23 or p.status() == 3) and abs(p.pdgId()) > 0
                and (abs(p.pdgId()) in [1, 2, 3, 4, 5, 21]))
        ]
        match = matchObjectCollection2(event.cleanJetsAll,
                                       event.partons,
                                       deltaRMax=0.3)

        for jet in event.cleanJetsAll:
            parton = match[jet]
            jet.partonId = (parton.pdgId() if parton != None else 0)
            jet.partonMotherId = (parton.mother(0).pdgId() if parton != None
                                  and parton.numberOfMothers() > 0 else 0)

        for jet in event.jets:
            (bmatch, dr) = bestMatch(jet, event.bqObjects)
            if dr < 0.4:
                jet.mcFlavour = 5
            else:
                (cmatch, dr) = bestMatch(jet, event.cqObjects)
                if dr < 0.4:
                    jet.mcFlavour = 4
                else:
                    jet.mcFlavour = 0

        event.heaviestQCDFlavour = 5 if len(
            event.bqObjects) else (4 if len(event.cqObjects) else 1)

    def matchJets(self, event, jets):
        match = matchObjectCollection2(jets,
                                       event.genbquarks + event.genwzquarks,
                                       deltaRMax=0.3)
        for jet in jets:
            gen = match[jet]
            jet.mcParton = gen
            jet.mcMatchId = (gen.sourceId if gen != None else 0)
            jet.mcMatchFlav = (abs(gen.pdgId()) if gen != None else 0)

        match = matchObjectCollection2(jets, event.genJets, deltaRMax=0.3)
        for jet in jets:
            jet.mcJet = match[jet]

    def smearJets(self, event, jets):
        # https://twiki.cern.ch/twiki/bin/viewauth/CMS/TWikiTopRefSyst#Jet_energy_resolution
        for jet in jets:
            gen = jet.mcJet
            if gen != None:
                genpt, jetpt, aeta = gen.pt(), jet.pt(), abs(jet.eta())
                # from https://twiki.cern.ch/twiki/bin/view/CMS/JetResolution
                factor = 1.052 + self.shiftJER * math.hypot(0.012, 0.062)
                if aeta > 2.3:
                    factor = 1.288 + self.shiftJER * math.hypot(0.127, 0.154)
                elif aeta > 1.7:
                    factor = 1.134 + self.shiftJER * math.hypot(0.035, 0.066)
                elif aeta > 1.1:
                    factor = 1.096 + self.shiftJER * math.hypot(0.017, 0.063)
                elif aeta > 0.5:
                    factor = 1.057 + self.shiftJER * math.hypot(0.012, 0.056)
                ptscale = max(0.0,
                              (jetpt + (factor - 1) * (jetpt - genpt)) / jetpt)
                #print "get with pt %.1f (gen pt %.1f, ptscale = %.3f)" % (jetpt,genpt,ptscale)
                jet.deltaMetFromJetSmearing = [
                    -(ptscale - 1) * jet.rawFactor() * jet.px(),
                    -(ptscale - 1) * jet.rawFactor() * jet.py()
                ]
                if ptscale != 0:
                    jet.setP4(jet.p4() * ptscale)
                # leave the uncorrected unchanged for sync
                jet._rawFactorMultiplier *= (1.0 /
                                             ptscale) if ptscale != 0 else 1